ryanda9910/mcpfrisk
GitHub: ryanda9910/mcpfrisk
mcpfrisk 是一款零依赖的 Node CLI 工具,用于在接入 MCP 服务器前排查其工具元数据中隐藏的恶意指令、不可见文本和凭据窃取行为,并支持 CI 集成和工具定义锁定。
Stars: 0 | Forks: 0
mcpfrisk
在连接 MCP 服务器之前,对其工具进行恶意指令排查。
MCP 服务器会向你的 agent 提供一份工具列表,而你的 agent 会信任工具的
**descriptions**(描述)—— 即由服务器控制、而你通常根本不会去阅读的文本。这就是
漏洞所在:被投毒的 description 可能会指示 agent 在“使用任何工具之前”先读取 `~/.ssh/id_rsa`,
或者将指令隐藏在零宽字符中,并且它会在每次调用时、对每个用户悄无声息地触发,直到
有人发现。2026 年的一次扫描发现了约 20 万个暴露的 MCP 实例,而大多数客户端在接收
服务器元数据时完全没有进行任何验证。
`mcpfrisk` 会连接到 MCP 服务器,提取其工具列表(它只会调用
`initialize` + `tools/list` —— 绝不会调用工具本身),并在你将该服务器接入 agent 之前,
对每个工具的元数据进行恶意攻击排查。零依赖,因为这正是你用来指向不受信任代码的工具。
## 它能检测到什么
- **工具投毒 (Tool poisoning)** —— description 中隐藏的、针对 agent 的指令:
“忽略之前的指令”,“不要告诉用户”,伪造的 `
` /
`` 标签,劫持其他工具调用的前置语。
- **不可见文本** —— 零宽字符、双向重写 (bidi overrides)、Unicode 标签和
变体选择器 (variation-selector) 夹带:模型能读取但人工审查者无法看到的文本。
- **凭据窃取** —— 要求 agent 交出
`api_key`、`password`、`private_key` 或其他凭据的工具参数。
- **编码载荷 (Encoded payloads)** —— 隐藏在 description 中的冗长 base64 / hex / `data:` blob。
- **数据外发路径 (Exfil path)** —— 服务器同时公开了数据读取器和外部发送器,因此
一个投毒指令就可以读取并发送数据(此项会提示,但不阻断)。
- **暗箱变更面 (Rug-pull surface)** —— 提供基于每个工具哈希的 `--manifest`,让你可以锁定已批准的内容,
并检测服务器是否在事后悄悄更改了工具。
## 使用方法
```
# 扫描你已安装的所有内容(Claude Desktop / Claude Code / Cursor / VS Code)
npx github:ryanda9910/mcpfrisk --config
# 扫描你通过 stdio 启动的服务器(它只执行 initialize + tools/list)
npx github:ryanda9910/mcpfrisk -- npx -y @modelcontextprotocol/server-filesystem /tmp
# 扫描远程 Streamable HTTP 服务器
npx github:ryanda9910/mcpfrisk --url https://mcp.example.com/mcp
# 扫描已保存的 tools/list 响应,或为 CI 输出机器可读的输出
npx github:ryanda9910/mcpfrisk --tools dump.json
npx github:ryanda9910/mcpfrisk --json -- node ./my-server.js
# 现在固定一个 manifest,如果服务器悄悄更改了某个工具(rug-pull),稍后会失败
npx github:ryanda9910/mcpfrisk --manifest -- npx -y some-server > pinned.json
npx github:ryanda9910/mcpfrisk --check pinned.json -- npx -y some-server
```
`--config` 会自动检测常见的配置文件位置(`claude_desktop_config.json`、
`~/.cursor/mcp.json`、项目中的 `.mcp.json` / `.vscode/mcp.json`),扫描那里声明的每台服务器,
对接入多个客户端的服务器进行去重,并运行一次
**跨服务器** 检查 —— 标记出覆盖或篡改另一台服务器工具的工具(这是单服务器扫描无法察觉的跨源劫持)。
对于在代码繁多仓库中的 CI 场景,`--sarif` 会输出 SARIF 2.1.0(检查结果会直接内嵌显示在 GitHub
代码扫描中),而 `--baseline ` 会接受已知的结果,使得任务仅在有
新问题出现时才失败(使用 `--write-baseline ` 生成基准文件)。
退出代码:干净(无问题)时为 `0`;当结果达到 `--fail-on`(默认为 `high`)或服务器偏离锁定版本时为 `1`;
发生用法或连接错误时为 `2` —— 因此你可以直接将其无缝接入 CI。
## 在 CI 中使用 (GitHub Action)
```
- uses: ryanda9910/mcpfrisk@main
with:
args: "-- node ./dist/server.js" # or "--url https://host/mcp", or "--config"
```
当出现任何 high(高)级别以上的问题时任务将失败。锁定工具定义并防范暗箱变更,可以使用
`args: "--check pinned.json -- node ./dist/server.js"`。完整示例请参见
[examples/github-workflow.yml](examples/github-workflow.yml)。
## 实际运行
这不是模拟演示。mcpfrisk 在被投毒的服务器中抓出了七个植入的攻击,在干净的服务器上保持
静默,并且对官方的 `@modelcontextprotocol/server-everything`(包含 13 个工具)没有产生任何高严重性的
误报。完整的原始输出详见
**[CASES.md](CASES.md)**。
## 为什么你可以信任输出结果
检测引擎是纯粹的且由测试覆盖,传输层 / 配置
解析 / 暗箱变更比对 (rug-pull diff) 都有它们自己的[集成测试套件](test/integration.test.mjs):
```
$ npm test
PASS — 13 passed, 0 failed # detection
PASS — 24 passed, 0 failed # stdio + HTTP + config + diff + cross-server + sarif
```
## 它不会做什么
它只读取元数据;它不会执行工具、遵循服务器的指令,也不会
对运行中的 agent 进行沙盒隔离。它是运行前的排查,而不是运行时的防火墙。对于它标记出的任何内容,请配合人工审查(human-in-the-loop)批准机制来处理。
## License
MIT。标签:AI智能体, DNS 反向解析, GNU通用公共许可证, MCP, MITM代理, Node.js, StruQ, 大模型安全, 恶意指令检测, 文档结构分析, 自定义脚本