fernforge/mcp-conform

GitHub: fernforge/mcp-conform

一款面向 MCP server 作者的发布前一致性与安全 linter,通过确定性规则检测注解缺失、schema 缺陷、工具投毒模式及注册表元数据问题。

Stars: 0 | Forks: 0

# mcp-conform 一款用于 MCP server 的 eslint。它是一个确定性的、作者端的一致性与安全 linter,可在你将 [Model Context Protocol](https://modelcontextprotocol.io) server 发布到 npm、PyPI 或官方 MCP 注册表之前运行。 它能检测出那些会导致 server 被应用目录拒绝,或导致 agent 错误调用你工具的问题:缺失 tool 注解、单薄或模糊的 schema、描述中的 tool 投毒模式,以及不完整的注册表元数据。每个问题都附带了一行修复建议。 ``` npx @fernforge/mcp-conform --cmd "node dist/index.js" ``` ``` mcp-conform — 7 tool(s) checked delete_record ✖ error ann/missing-destructive-hint Tool "delete_record" may modify state but does not set destructiveHint. fix: Set annotations.destructiveHint (true for irreversible ops like delete). ✖ error safety/injection-phrase Tool description contains an injection-style phrase (instruction override). fix: Remove instruction-like text; describe behavior, don't issue commands to the agent. 1 error · 4 warning · 5 info Conformance score: 76/100 FAIL ``` 无需 LLM 密钥,无需网络,完全确定性。它是一个 linter 而不是模型,因此可以安全地在 CI 中运行,一天免费运行上千次,且其判定结果永远不会漂移。 ## 2026-07-28 规范会破坏你的 server。准确找出问题所在。 2026-07-28 MCP 规范是自发布以来最大的一次修订,且不向下兼容。协议层中的 Session 已被移除(移除了 `Mcp-Session-Id`,SEP-2567),`initialize`/`initialized` 握手被移除(SEP-2575),错误码 `-32002` 变更为 `-32602`,新增了两个必需的路由 header(`Mcp-Method`, `Mcp-Name`),并且 `roots`/`sampling`/`logging` 已被弃用。关于这些内容有很多详细的说明文章。但唯独缺少一个工具能够读取*你的*代码,并告诉你究竟是哪几行出了问题。 `spec-migrate` 规则包就是为此而生的。它会扫描你的 TypeScript/JavaScript/Python 源代码,查找被移除和更改的 API,并针对每个匹配项报告 `file:line` 及其修复建议: ``` npx @fernforge/mcp-conform --ruleset spec-migrate --project . ``` ``` server.ts:18 ✖ error migrate/session-id-header Mcp-Session-Id is removed (SEP-2567). The 2026-07-28 transport is stateless; this header no longer exists. fix: Read protocol version, client info and capabilities from params._meta on each request instead of a per-session store. server.ts:21 ✖ error migrate/error-code-32002 JSON-RPC error code -32002 is reassigned to -32602 (Invalid Params). fix: Change -32002 to -32602. ``` 严重的破坏性变更(sessions、握手、错误码)会被视为错误;处于 12 个月过渡期内的弃用功能(`roots`/`sampling`/`logging`,Tasks 转 extension)会被视为警告。这样一来,CI 就会在那些第一天就会导致破坏的问题上直接报错,而对其余部分仅作提示。运行 `--ruleset all` 可将其与常规的一致性 lint 结合使用。 它只对实际发布的内容进行 lint。将其指向你 server 的启动命令,它就会通过 stdio 启动该 server,调用 `tools/list`,并检查你的用户将会接收到的真实 schema,而不是根据你的源码进行猜测。 开箱即用的 GitHub Action 会为每个 PR 打分,并生成一份 job 总结。 ## 为什么会有这个工具 MCP 生态系统正在交付数以万计的 server,而应用目录对于收录标准已变得非常严格。 不良的 tool 注解是 ChatGPT 和 Claude 应用目录拒绝收录的首要原因。规范指出,当缺失提示时,客户端必须按最坏情况(破坏性、开放世界)来处理,因此如果你没有设置 `readOnlyHint` / `destructiveHint` / `openWorldHint` / `title`,客户端就会将你安全的只读工具视为危险工具。 Tool 描述是一个注入面。它们会被直接注入到 agent 的上下文中,因此描述中的“忽略之前的指令”这一行,或者不可见的 Unicode 负载,都是真实的 tool 投毒载体。 官方注册表现在支持命名空间验证发布。反向 DNS 名称、`server.json` 清单以及干净的包元数据,都是确保你的 server 可发布且能被发现的前提。 社区正在起草一份发布前的一致性检查清单([modelcontextprotocol Discussion #2682](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions))。`mcp-conform` 会将其自动化。 现有的 MCP 安全工具都是面向消费者/运行时的:它们扫描的是你即将安装的 server。而 `mcp-conform` 的作用正好相反。它能在任何人安装之前,让你的 server 达到合规要求。 ## 安装 使用 npx 运行,无需安装: ``` npx @fernforge/mcp-conform --cmd "node dist/index.js" ``` 若要在 CI 中固定版本或将其作为开发依赖项: ``` npm install --save-dev @fernforge/mcp-conform ``` 需要 Node ≥ 18。MCP SDK 是一个可选的 peer dependency,仅在实时 `--cmd` 内省时需要(大多数项目通常已经包含了它)。 ## 用法 `mcp-conform` 始终会检查你的**项目元数据**(`package.json`、`server.json`),并从以下三个来源之一获取要 lint 的 **tools**: ### 1. 实时 server(推荐 — 检查实际发布的内容) ``` mcp-conform --cmd "node dist/index.js" mcp-conform --cmd "python -m my_server" mcp-conform --cmd "uvx my-mcp-server" ``` 它会通过 stdio 启动 server,初始化一个客户端,并对真实的 `tools/list` 输出以及能力/传输协议的规范性进行 lint。 ### 2. 保存的 tools 清单 ``` mcp-conform --manifest tools.json ``` 这里的 `tools.json` 可以是 `tools/list` 的结果(`{ "tools": [...] }`),也可以是纯粹的工具定义数组。非常适合用于 Python/Go server 或者在测试中进行快照。 ### 3. 仅元数据 ``` mcp-conform # checks package.json + server.json in the current dir ``` ### 输出 & CI ``` mcp-conform --cmd "node dist/index.js" --json # machine-readable mcp-conform --cmd "node dist/index.js" --markdown --out report.md mcp-conform --cmd "node dist/index.js" --min-score 80 # fail under 80 mcp-conform --cmd "node dist/index.js" --max-warnings 0 # fail on any warning ``` 当存在任何严重级别为 error 的检查结果时,`mcp-conform` 会以非零状态码退出,因此默认情况下它会导致 CI 失败。你可以使用 `--min-score` 和 `--max-warnings` 来收紧限制门槛。 ## GitHub Action 将 `.github/workflows/mcp-conform.yml` 添加到你的 server 仓库中: ``` name: MCP Conformance on: [pull_request, push] jobs: conform: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 20 } - run: npm ci && npm run build - uses: fernforge/mcp-conform@v0.2.0 with: cmd: "node dist/index.js" min-score: "80" ``` 它会在 job 总结中写入一份 Markdown 报告,并在分数低于你设定的阈值时使检查失败。 ## 检查内容 | 类别 | 示例 | | --- | --- | | **Annotations** | 缺失 `readOnlyHint` / `destructiveHint` / `openWorldHint`;缺失人类可读的 `title`;被标记为只读的 `delete_*`/`update_*` 工具 | | **Schema hygiene** | 缺失/单薄的 tool 描述;没有描述或类型的参数;缺失 `inputSchema`;未设置 `additionalProperties`;缺失 `outputSchema` | | **Safety / tool-poisoning** | “忽略之前的指令”及掩饰性词汇;隐藏的零宽 / bidi / Unicode 标记字符;超长描述;弱化了自身影响范围的高权限(`exec`/`sql`/`write_file`)工具 | | **Distribution metadata** | 缺失 `name`/`version`/`license`/`repository`;没有 `keywords` 或没有 `mcp` 关键字;没有 `bin`/`main`;没有 `engines` | | **Registry** | 没有 `server.json`;名称不是反向 DNS 命名空间格式;缺失清单字段 | | **Transport** *(仅限实时模式)* | 声明了能力但未提供对应内容,或提供了 tools 但未声明相关能力 | 每条检查结果都包含一个 `rule` ID、一个严重级别(`error` / `warning` / `info`)以及具体的**修复建议**。**一致性得分 (0–100)** 是一个你可以随时间跟踪的确定性单一数值。 ## 编程 API ``` import { lint, introspect, loadProjectMetadata } from "mcp-conform"; const live = await introspect({ command: "node", args: ["dist/index.js"] }); const meta = await loadProjectMetadata(process.cwd()); const result = lint({ ...live, ...meta }); console.log(result.score, result.pass); for (const f of result.findings) console.log(f.severity, f.rule, f.message); ``` ## 路线图 - 用于机械化修复注解/元数据缺失的 `--fix` - 一个配置文件 (`mcpconform.json`),用于设置严重级别和禁用规则 - 发布一个 `mcpconform-config-recommended` 规则集,随着社区一致性检查清单的最终确定而保持同步更新 欢迎提交 Issues 和规则建议 —— 这个规则集旨在随着标准的形成而不断跟进。 ## 许可证 MIT © fernforge
标签:AI安全, Chat Copilot, MCP, MITM代理, SOC Prime, TypeScript, 云安全监控, 安全插件, 开发工具, 数据可视化, 文档结构分析, 暗色界面, 自动化攻击, 逆向工具, 静态分析