mcpField
M
MCP Compliance

MCP Compliance

本地服务
yaw.sh开发工具22 周前更新

关于 MCP Compliance

MCP Compliance 是用于检查 MCP 服务规范兼容性的 CLI、MCP 服务和程序化 API,面向开发与 CI 测试。它支持 HTTP 和 stdio 目标,并按规范版本运行测试、生成评分报告。

主要功能

  1. 01覆盖两版 MCP 规范测试
  2. 02自动检测或指定规范版本
  3. 03按声明能力调整测试
  4. 04生成 A–F 等级与评分
  5. 05支持 CI 严格模式及 JSON、SARIF
  6. 06提供 CLI、MCP 服务和 API

适用场景

  1. 01发布前验证 MCP 服务
  2. 02在 CI 中阻止必需测试失败
  3. 03检查传输、工具与资源行为

MCP 相关

作为 MCP 服务,它向 AI 助手暴露规范合规性测试能力;也能通过 CLI 或 API 测试 MCP 服务。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"yawlabs-mcp-compliance": {
"command": "npx",
"args": [
"-y",
"@yawlabs/mcp-compliance"
]
}
}
}
启动命令npx -y @yawlabs/mcp-compliance

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@yawlabs/mcp-compliance0.21.0

工具

2

收录的工具列表 · 更新于 3 周前

参数类型必填说明
urlstring是要测试的 MCP 服务 URL(必须使用 HTTP 或 HTTPS)
authstring否Authorization 请求头值(例如:"Bearer tok123")
onlyarray否仅运行匹配这些类别或测试 ID 的测试
skiparray否跳过匹配这些类别或测试 ID 的测试
headersobject否在所有请求中附加的请求头(例如:{"X-Api-Key": "abc"})
retriesinteger否失败测试的重试次数(默认:0,最大:10)
timeoutinteger否请求超时时间,单位为毫秒(默认:15000,最大:300000)
specVersionenum否要测试的 MCP 规范修订版。"auto"(默认)会探测服务器,并根据其支持的最新修订版进行评分;指定 "2025-11-25" 或 "2026-07-28" 可强制使用相应套件。auto | 2025-11-25 | 2026-07-28

详细介绍

@yawlabs/mcp-compliance

Add to Yaw MCP

点击一次即可将其添加到本地 Yaw MCP 配置中,使其在每个 Yaw Terminal 会话中都可用。也可以按下文所述手动安装。

npm version License: MIT GitHub stars

测试任意 MCP 服务是否符合规范。 两套测试套件——针对 MCP 2025-11-25 的 88 项测试,以及针对 MCP 2026-07-28 的 103 项测试——涵盖传输、生命周期、工具、资源、提示词、错误处理、架构验证和安全性。该工具会探测服务并根据其支持的最新规范修订版进行评分,也可以通过 --spec-version 固定版本。既适用于 HTTP 端点(https://my-server.com/mcp),也适用于 stdio 服务(npx @modelcontextprotocol/server-filesystem /tmp)。提供 CLI、MCP 服务和编程 API。

由 Yaw Labs 构建并维护。

为什么选择此工具?

MCP 服务的数量正在迅速增长,但大多数服务在发布时都没有经过合规性测试。传输处理故障、错误代码缺失、架构格式错误以及未提示的能力违规十分常见。手动编写测试脚本既繁琐又不完整。

此工具解决了这些问题:

  • 两个规范修订版,一个工具 — 针对 MCP 2025-11-25(initialize + 会话时代)的 88 项测试,以及针对 MCP 2026-07-28(无状态、每个请求的 _meta、server/discover、缓存提示、MRTR)的 103 项测试。两者都涵盖相同的 8 个类别:传输、生命周期、工具、资源、提示词、错误处理、架构验证和安全性。HTTP 专属测试(CORS、TLS、标头验证、速率限制)不会在 stdio 上运行:2025-11-25 测试套件在 HTTP 上运行 85 项测试,在 stdio 上运行 55 项;2026-07-28 测试套件则分别运行 99 项和 75 项。
  • 自动检测修订版 — 一次 server/discover 探测即可告知工具服务支持哪个时代;同时支持两个时代的服务将按 2026-07-28 评分,并附带警告。可通过 --spec-version 固定任一修订版。请参阅规范版本。
  • 由能力驱动 — 测试会根据服务声明的能力进行调整。如果服务声明支持工具,工具测试就会成为必测项。服务未声明支持的功能不会导致误报。
  • 分级评分 — 采用 A-F 字母等级和加权分数(必测测试占 70%,可选测试占 30%)。用一个数字即可传达合规情况。
  • 适用于 CI — --strict 模式会在必测项失败时以代码 1 退出。可直接将其接入任何流水线。
  • 引用规范 — 每项测试都链接到其所验证的 MCP 规范中的确切章节。测试内容和原因一目了然。
  • 三种接口 — 面向用户的 CLI、面向 AI 助手的 MCP 服务,以及用于集成的编程 API。
  • 公开的方法论 — 测试方法论和规则目录均采用开放许可(CC BY 4.0),任何人都可以据此构建兼容工具或派生规则。

快速开始

远程 HTTP 服务:

npx @yawlabs/mcp-compliance@latest test https://my-server.com/mcp

本地 stdio 服务(npm 上绝大多数 MCP 服务):

# Pass the command directly, Inspector-style
npx @yawlabs/mcp-compliance@latest test npx @modelcontextprotocol/server-filesystem /tmp

# Or a local build
npx @yawlabs/mcp-compliance@latest test node ./dist/server.js

# With env vars
npx @yawlabs/mcp-compliance@latest test -E GITHUB_TOKEN=$GITHUB_TOKEN -- npx @modelcontextprotocol/server-github

全局安装:

npm install -g @yawlabs/mcp-compliance
mcp-compliance test https://my-server.com/mcp

就是这样。你将看到彩色终端报告,其中包含字母等级(A-F)、逐项测试的通过/失败状态以及合规分数。

CLI 用法

HTTP 目标
# Terminal output with colors and grade
mcp-compliance test https://my-server.com/mcp

# JSON / SARIF for scripting + GitHub Code Scanning
mcp-compliance test https://my-server.com/mcp --format json
mcp-compliance test https://my-server.com/mcp --format sarif > compliance.sarif

# Strict mode for CI — exits 1 on required-test failure
mcp-compliance test https://my-server.com/mcp --strict

# Auth (shorthand or full header)
mcp-compliance test https://my-server.com/mcp --auth "Bearer tok123"
mcp-compliance test https://my-server.com/mcp -H "X-Api-Key: abc"

# Focus the run
mcp-compliance test https://my-server.com/mcp --only transport,lifecycle
mcp-compliance test https://my-server.com/mcp --skip prompts,resources
mcp-compliance test https://my-server.com/mcp --verbose
stdio 目标

将命令及其参数作为位置参数传递(MCP Inspector 风格)。如果目标所需的标志与我们的标志冲突,请使用 -- 消除歧义。

# npm-distributed stdio servers
mcp-compliance test npx -y @modelcontextprotocol/server-filesystem /tmp
mcp-compliance test uvx mcp-server-git

# Local build
mcp-compliance test node ./dist/server.js

# With env vars (repeatable -E, or --env-file)
mcp-compliance test -E API_KEY=secret -E REGION=us-east-1 -- npx my-server
mcp-compliance test --env-file .env -- node ./server.js

# Set working directory
mcp-compliance test --cwd ./services/mcp -- node ./dist/server.js

# Target uses a flag that collides with ours — use `--` to separate
mcp-compliance test --verbose -- node ./server.js --verbose

在 Windows 上,npx 和其他 .cmd 垫片会自动通过 shell 启动。

规范版本

该工具针对其支持的每个 MCP 规范修订版提供一套测试目录:2025-11-25(88 项测试:initialize 握手、会话、ping)和 2026-07-28(103 项测试:无状态、按请求设置的 _meta、server/discover、缓存提示、MRTR)。每次运行只对一个修订版进行评分,由 --spec-version 选择:

# auto (default): probe the server, grade the newest revision it speaks
mcp-compliance test https://my-server.com/mcp

# pin a revision — no probe, the named catalog runs regardless of what the server answers
mcp-compliance test https://my-server.com/mcp --spec-version 2026-07-28
mcp-compliance test https://my-server.com/mcp --spec-version 2025-11-25

# --list never connects: under auto (the default) it prints every catalog in its own
# section; --spec-version <date> previews just that one
mcp-compliance test --list --spec-version 2026-07-28 --transport stdio

auto 如何依据规范自身针对双时代客户端的规则作出判断:工具会发送一个符合规范的 2026-07-28 server/discover(通过 HTTP 时,它同时充当预检连接检查,因此检测不会增加额外的往返;通过 stdio 时,它是首次交互)。收到 DiscoverResult,或带有现代错误代码(-32020、-32021、-32022)的 JSON-RPC 错误时,会选择 2026-07-28。其他任何情况——-32601、-32000、400“未初始化”、404、HTML 页面,或超时内无响应——都会选择 2025-11-25;如果 401/403 没有现代错误正文,也会选择 2025-11-25,说明中会指出无法确定所属时代,且报告中的第一条警告(适用于所有输出格式)会说明以下评分没有参考意义。如果未配置 Authorization 标头,401 或携带 WWW-Authenticate: Bearer 质询的 403 表示需要身份验证(说明为 authentication required -- pass --auth;警告建议使用 --auth 重新运行)。如果已配置该标头,401 或 Bearer 质询中带有 error 参数的 403 表示凭据被拒绝(说明为 credential rejected -- check --auth;警告会指出该错误中的原因,例如 invalid_token 表示令牌无效或已过期,insufficient_scope 表示缺少作用域或权限)。其他任何 403(例如 SDK 在隧道主机名后进行的 Host 验证、Origin 验证或网关拦截)都会采用中性措辞,无论是否有标头:说明为 forbidden -- Host/Origin validation, a gateway, or missing credentials(有标头时为 ... or token permissions);如果正文包含 JSON-RPC 错误消息,警告会引用该消息,并优先指出 Host/Origin 验证和任何网关;未配置标头时,只有服务器确实要求凭据才会建议使用 --auth。回退逻辑不会只依据某个特定错误代码;即使旧版服务器忽略未知方法,也仍会被正确分类,只是需要等到超时后才会确定。报告头部会注明原因(auto-detected from server/discover: supportedVersions [2026-07-28]、... JSON-RPC error -32601, legacy、... no response, legacy),JSON 中的 warnings 也会包含相同说明(Spec version auto-detected as <v> (server/discover -> <reason>). Pin with --spec-version to override.)。无法访问的服务器会按 2025-11-25 进行评分,因此所有需要服务器的测试都会失败(如果没有收到任何内容,2026-07-28 的事后扫描也会失败,而不会在空记录上通过)。 探测有两项超时限制。在 stdio 模式下,超时由 --startup-timeout 限定;在终端模式下,约 2 s 后会在 stderr 上显示一条暗色状态行,说明正在等待以及跳过 --spec-version 2025-11-25,这样,对于遇到未知方法时保持静默的旧版服务,就不会让人误以为程序卡住了。如果子进程在探测时退出(例如,某个旧版服务的分发器会对 initialize 之前的未知方法抛出异常),报告会显示警告,其中包含退出代码和 stderr 的末尾内容,随后启动一个新实例,并按 2025-11-25 为其评分。如果新实例也在启动时退出,尚未响应 initialize,警告会说明服务器无论是否进行探测都会在启动时退出,并将排查重点指向命令、参数和环境,而不是建议固定版本。benchmark 也会以同样方式重新启动被探测终止的子进程,使用自己的 --startup-timeout 限制探测时间,打印相同的状态行,并在输出中附带警告。在 HTTP 模式下,探测即预检,超时由 --preflight-timeout 限定;如果预检超时,会在 --startup-timeout 限定的时间内再探测一次,然后才将本次运行默认按 2025-11-25 处理,这样,冷启动缓慢的服务就会按其实际所属时期评分,而不会被判定为无法访问。

能响应两个时期的服务器(基于官方 SDK 2.0 构建的服务器默认如此)会按 2026-07-28 评分,报告会附带警告,指出另一个时期以及如何固定版本。判断依据是 supportedVersions 列出了 2025-11-25,或 信息性探测 lifecycle-dual-era 收到了 InitializeResult(SDK 2.0 服务器只会公布现代版本,但仍会响应 initialize;在 stdio 模式下,该探测会发往一个新进程,因为双时期服务器会按进程固定时期)。如需同时评估其旧版行为,请使用 --spec-version 2025-11-25 再运行一次。若服务器能响应 initialize,却拒绝符合规范的 server/discover,则它并非双时期,而是仅支持旧版:lifecycle-dual-era 会显示 legacy-only: ...,警告会提示你使用 --spec-version 2025-11-25(或 auto)重新运行。报告中的 specVersion 始终是解析后的版本,绝不会是 auto。

固定版本运行会按指定版本运行对应目录中的测试,不论服务器如何响应,但有两点说明需要注意。在 HTTP 模式下,预检仍会发送现代的 server/discover,因此,如果服务器明确以另一时期响应,固定版本运行会收到警告(Server answered the 2026-07-28 server/discover probe with a DiscoverResult ...; this run is pinned to 2025-11-25. Re-run with --spec-version 2026-07-28 (or auto) to grade it)。警告必须有时期信号作为依据——DiscoverResult、JSON-RPC 正文或 HTTP 4xx;5xx 或 HTML 页面无法表明所属时期,因此不会触发警告。若双时期服务器的 supportedVersions 列出了 2025-11-25,且运行固定到 2025-11-25,则会提示 Server is dual-era (...); this run grades its 2025-11-25 side.,而不是建议切换到另一个固定版本。另外,仅支持旧版的服务器若固定到 2026-07-28,则 lifecycle-discover 和六项 _meta/标准标头拒绝测试都会标记为不可评估:拒绝符合规范的 server/discover 的服务器,即使也拒绝格式错误的变体,也不能证明任何问题,因此这些必需测试会判定为失败,而不会记为通过。

在 CI 中依赖 auto 时,需要了解以下两点:

  • 即使配置未变,评分也可能变化。 服务器升级到支持 2026-07-28 的 SDK 后,auto 就会切换测试套件:测试 ID、必需测试集和新的基准都会不同。如果你希望只有在明确指定时才切换套件,请固定 --spec-version(或在配置文件中设置 "specVersion")。
  • diff 拒绝比较不同版本的报告(ID 只能在同一目录中比较),并会告知你应该固定哪个 --spec-version。SARIF 上传会按版本分别跟踪(automationDetails.id 为 mcp-compliance/<specVersion>/),因此切换版本会创建一组新的提醒,而不会悄无声息地关闭旧提醒。 --only / --skip 的值会与已解析的测试目录进行匹配;如果某个值在其中匹配不到任何项(例如在 2026-07-28 的运行中指定 lifecycle-init),系统会发出警告,而不会默默地执行空测试。空测试会显示 No tests ran -- check --only/--skip,而不是 All tests passed。在 2026-07-28 的测试套件中,筛选后的运行仍会测量服务:被筛掉的功能测试原本会缓存的 tools/list / resources/list / prompts/list 结果,会按需获取一次,由需要这些结果的测试调用。因此,--only security、--only schema 或 --only lifecycle 会执行实际检查,而不会因跳过测试而误报通过。如果此类列表调用失败,而对应的 -list 测试被筛掉了,那么需要该列表的检查会根据记录的原因判定失败(tools/list failed (JSON-RPC error -32603 (boom)); no tools list to validate),而不会在列表调用已损坏的情况下仍评为 A。对于只匹配因目标传输方式而被禁用的测试(在 stdio 服务上指定 transport-post)的 --only 值,系统也会发出警告;--list 会在其列出的每个测试目录下显示相同的警告。
选项
选项适用对象说明
--spec-version <v>两者要评测的 MCP 规范修订版:auto(探测服务,优先使用最新版本)、2025-11-25 或 2026-07-28(默认值:auto,或配置中的 specVersion)。请参阅规范版本
--format <format>两者输出格式:terminal、json、sarif、github、markdown 或 html(默认值:terminal)
--config <path>两者从配置文件加载默认值(默认值:当前工作目录中的 mcp-compliance.config.json)
--output <file>两者运行后将本地 SVG 徽章写入指定路径
--list两者打印在当前筛选条件下将运行的测试 ID,然后退出(不建立连接;使用默认值 --spec-version auto 时,每个目录会单独列出;使用 --spec-version <date> 时则预览指定版本)
--transport <kind>两者按 http 或 stdio 筛选(仅在未提供目标且使用 --list 时生效)
--strict两者任何必需测试失败时都以代码 1 退出(用于 CI)
--min-grade <grade>两者等级低于此门槛(A–F)时以代码 1 退出
-H, --header <h>HTTP为所有请求添加标头,格式为 "Key: Value"(可重复指定)
--auth <token>HTTP-H "Authorization: <token>" 的简写
-E, --env <var>stdio为 stdio 命令设置环境变量,格式为 "KEY=VALUE"(可重复指定)
--env-file <path>stdio从文件加载环境变量(每行一个 KEY=VALUE)
--cwd <dir>stdiostdio 命令的工作目录
--watchstdio当前目录下的文件发生变化时重新运行测试套件(防抖 500 ms;忽略 node_modules、.git、dist、coverage、构建缓存以及日志、交换和临时文件),直到按下 Ctrl+C。仅适用于 stdio 目标,且 --format 只能为 terminal、markdown 或 html;--strict 和 --min-grade 不适用
--timeout <ms>两者初始交互后每个请求的超时时间,单位为毫秒(默认值:15000)
--startup-timeout <ms>两者为服务的首次响应设定的时限:auto 模式下的 stdio 时代探测、任一传输方式上的 2025-11-25 initialize 握手,以及 HTTP 预检超时时发送的第二次时代探测(默认值:max(--timeout, 60000);包含 stdio 服务启动前冷缓存中的 npx 获取时间)
--preflight-timeout <ms>HTTPserver/discover 预检请求的截止时间;在 auto 模式下,该请求也用于时代探测。此处超时后,会在 --startup-timeout 内再次探测,然后在运行开始时默认使用 2025-11-25(默认值:min(--timeout, 10000))
--retries <n>两者失败测试的重试次数(默认值:0)
--only <items>两者仅运行与这些类别或测试 ID 匹配的测试(以逗号分隔)
--skip <items>两者跳过与这些类别或测试 ID 匹配的测试(以逗号分隔)
--concurrency <n>两者同时运行的可安全并行测试的最大数量(默认值:1;调高可缩短总耗时,但可能影响对时序敏感的服务)
--verbose两者运行时打印每项测试结果,显示为 PASS、FAIL 或 SKIP(同时转发 stdio stderr)
--no-color两者禁用彩色输出(设置 NO_COLOR 环境变量也有相同效果)
CI 集成

GitHub Action(可直接添加到任意 .github/workflows/*.yml 文件中):

- uses: YawLabs/mcp-compliance@v0
  with:
    target: 'node ./dist/server.js'   # or a URL like https://my-server.com/mcp
    format: github                     # ::error per required failure, ::warning per optional failure and per report warning, ::notice summary with the spec version
    strict: 'true'                     # exit non-zero if any required test fails
    min-grade: 'A'                     # also exit if grade slips
    spec-version: auto                 # or pin 2025-11-25 / 2026-07-28; the resolved value is the `spec-version` output

手动调用 CLI:

# GitHub Actions: ::error per required failure, ::warning per optional failure and per
# report warning, and a ::notice summary naming the grade and the spec version graded
mcp-compliance test https://my-server.com/mcp --format github --strict

# Slack/Linear/PR comment: drop the body straight into a comment
mcp-compliance test https://my-server.com/mcp --format markdown > report.md

# HTML report (self-contained, share anywhere — issue comments, S3, GitHub Pages)
mcp-compliance test https://my-server.com/mcp --format html > report.html

# Block release if grade slips below B
mcp-compliance test https://my-server.com/mcp --min-grade B

# Preview which tests will run before connecting (handy for --only/--skip authoring)
mcp-compliance test --list --transport stdio --skip security --spec-version 2026-07-28

# Diff two runs — exit 1 if anything that was passing (or skipped) is now failing;
# checks that start or stop skipping are listed as "Newly skipped" / "No longer skipped" and never fail the diff.
# A baseline from an earlier version works too: its skips are read from their wording, and both
# reports are scored from their results as this version scores them (skips left out).
# Both reports must grade the same spec revision; pin --spec-version on both runs
# so a server upgrade cannot flip the suite under the baseline.
mcp-compliance test https://my-server.com/mcp --format json --spec-version 2026-07-28 > current.json
mcp-compliance diff baseline.json current.json

# Watch mode for stdio dev loop — re-runs on file changes in cwd
mcp-compliance test --watch -- node ./dist/server.js

# Latency benchmark (--spec-version and --startup-timeout work as for test)
mcp-compliance benchmark -- node ./dist/server.js -r 200 -c 4

Docker:

docker run --rm ghcr.io/yawlabs/mcp-compliance test https://my-server.com/mcp
创建配置文件
mcp-compliance init

交互式提示会引导你设置传输方式(http/stdio)、命令或 URL、环境变量、超时时间和严格模式,然后写入可提交的 mcp-compliance.config.json。

配置文件

将 mcp-compliance.config.json 纳入版本控制,这样 CI 和本地开发流程就可以不带参数运行 mcp-compliance test。支持的位置(按搜索顺序):mcp-compliance.config.json、.mcp-compliancerc.json、.mcp-compliancerc,以及 package.json 的 "mcp-compliance" 字段。传入 --config <path> 可加载指定文件。

HTTP:

{
  "target": {
    "type": "http",
    "url": "https://my-server.com/mcp",
    "headers": { "Authorization": "Bearer tok123" }
  },
  "timeout": 20000,
  "specVersion": "2026-07-28",
  "strict": true
}

stdio:

{
  "target": {
    "type": "stdio",
    "command": "node",
    "args": ["./dist/server.js"],
    "env": { "LOG_LEVEL": "error" }
  },
  "skip": ["security"],
  "strict": true
}

优先级:CLI 标志 > 配置文件 > 默认值。任何字段都可以通过命令行覆盖。specVersion 接受 auto、2025-11-25 或 2026-07-28,并在 0.19 中新增——较旧的工具版本(包括 0.18.x)会将设置了该字段的配置视为包含未知键并拒绝,因此凡是使用此配置的地方,都应固定为 @yawlabs/mcp-compliance@^0.19。

本地 SVG 徽章

生成反映实际评级的本地 SVG,并将其提交到代码库:

mcp-compliance test https://my-server.com/mcp --output badge.svg
mcp-compliance test node ./dist/server.js --output badge.svg

然后将其嵌入 README:

![MCP Compliance](./badge.svg)

88 项测试检查的内容(2025-11-25)

2025-11-25 目录对 initialize + 会话时代的协议进行评级。对于所有未响应现代 server/discover 的服务,它是 --spec-version auto 选择的版本。

传输(16 项测试)

仅 HTTP(13 项):

  • transport-post — 服务接受 HTTP POST 请求(必需)
  • transport-content-type — 响应类型为 application/json 或 text/event-stream(必需)
  • transport-notification-202 — 通知恰好返回 202 Accepted
  • transport-content-type-reject — 拒绝非 JSON 请求 Content-Type
  • transport-session-id — 初始化后强制要求 MCP-Session-Id
  • transport-session-invalid — 未知会话 ID 返回 404
  • transport-get — GET 返回 SSE 流或 405
  • transport-delete — 接受 DELETE 请求或返回 405
  • transport-batch-reject — 拒绝 JSON-RPC 批量请求(必需)
  • transport-content-type-init — 初始化响应具有有效的内容类型
  • transport-get-stream — 携带会话的 GET 请求返回 SSE 或 405
  • transport-concurrent — 处理并发请求
  • transport-sse-event-field — SSE 响应包含必需的 event: message 字段

仅 stdio(3 项):

  • stdio-framing — 以换行符分隔的 JSON 帧格式(必需)
  • stdio-unicode — UTF-8 Unicode 往返可保留非 ASCII 负载
  • stdio-unknown-method-recovers — 未知方法返回 -32601,且服务继续运行
生命周期(21 项测试) - **lifecycle-init** — 初始化握手成功(必需) - **lifecycle-proto-version** — 返回有效的 YYYY-MM-DD 协议版本(必需) - **lifecycle-server-info** — 包含带有名称的 serverInfo - **lifecycle-capabilities** — 返回 capabilities 对象(必需) - **lifecycle-jsonrpc** — 响应符合有效的 JSON-RPC 2.0 格式(必需) - **lifecycle-ping** — 响应 ping 方法(必需) - **lifecycle-instructions** — 如果存在,Instructions 字段为有效字符串 - **lifecycle-id-match** — 响应 ID 与请求 ID 匹配(必需) - **lifecycle-string-id** — 支持字符串请求 ID(JSON-RPC 2.0) - **lifecycle-version-negotiate** — 妥善处理未知协议版本 - **lifecycle-reinit-reject** — 拒绝第二次 initialize 请求 - **lifecycle-logging** — 接受 logging/setLevel(如果声明了 logging capability,则为必需) - **lifecycle-completions** — 接受 completion/complete(如果声明了 completions capability,则为必需) - **lifecycle-cancellation** — 处理取消通知 - **lifecycle-progress** — 妥善处理进度通知 - **lifecycle-list-changed** — 接受已声明 capabilities 的 listChanged 通知 - **lifecycle-progress-token** — 支持通过 SSE 在请求中使用进度令牌 - **lifecycle-sampling-capability** — 对服务端使用客户端 sampling capability 进行提示性检查 - **lifecycle-roots-capability** — 对服务端使用客户端 roots capability 进行提示性检查 - **lifecycle-elicitation-capability** — 对 2025-11-25 客户端 elicitation capability 进行提示性检查 - **lifecycle-meta-tolerance** — 服务端忽略传入请求中未知的 `_meta` 字段
工具(4 项测试)
  • tools-list — tools/list 返回有效数组(如果声明了 tools capability,则为必需)
  • tools-call — tools/call 返回格式正确的响应
  • tools-pagination — tools/list 支持基于游标的分页
  • tools-content-types — 工具内容项具有有效类型
资源(5 项测试)
  • resources-list — resources/list 返回有效数组(如果声明了 resources capability,则为必需)
  • resources-read — resources/read 返回内容项
  • resources-templates — resources/templates/list 可正常工作或返回 method-not-found
  • resources-pagination — resources/list 支持基于游标的分页
  • resources-subscribe — 资源订阅/取消订阅(如果声明了 subscribe capability,则为必需)
提示词(3 项测试)
  • prompts-list — prompts/list 返回有效数组(如果声明了 prompts capability,则为必需)
  • prompts-get — prompts/get 返回有效消息
  • prompts-pagination — prompts/list 支持基于游标的分页
错误处理(10 项测试)
  • error-unknown-method — 对未知方法返回 JSON-RPC 错误(必需)
  • error-method-code — 使用正确的 -32601 错误代码
  • error-invalid-jsonrpc — 处理格式错误的 JSON-RPC(必需)
  • error-invalid-json — 处理无效的 JSON 请求体
  • error-missing-params — 对缺少 name 的 tools/call 返回错误
  • error-parse-code — 对无效 JSON 返回 -32700
  • error-invalid-request-code — 对无效请求返回 -32600
  • tools-call-unknown — 对不存在的工具名称返回错误
  • error-capability-gated — 拒绝未声明 capabilities 对应的方法
  • error-invalid-cursor — 妥善处理无效的分页游标
架构验证(6 项测试) - **tools-schema** — 所有工具都具有有效的名称和 inputSchema(声明了 tools 能力时为必需项) - **tools-annotations** — 存在时,工具注释有效 - **tools-title-field** — 工具包含 title 字段(2025-11-25) - **tools-output-schema** — 包含 outputSchema 的工具有效(2025-11-25) - **prompts-schema** — 提示词具有有效的 name 字段(声明了 prompts 能力时为必需项) - **resources-schema** — 资源具有有效的 uri 和 name(声明了 resources 能力时为必需项)
安全性(23 项测试)
  • security-auth-required — 拒绝未经身份验证的请求
  • security-www-authenticate — 401 响应包含 WWW-Authenticate 标头
  • security-auth-malformed — 拒绝格式错误的身份验证凭据
  • security-tls-required — 强制使用 HTTPS/TLS
  • security-session-entropy — 会话 ID 具有高熵
  • security-session-not-auth — 会话 ID 不会绕过身份验证
  • security-oauth-metadata — 存在受保护资源元数据端点(RFC 9728)
  • security-token-in-uri — 拒绝查询字符串中的身份验证令牌
  • security-cors-headers — CORS 标头受到严格限制
  • security-origin-validation — 验证 Origin 标头以防范 DNS 重绑定
  • security-command-injection — 防范工具参数中的命令注入
  • security-sql-injection — 防范工具参数中的 SQL 注入
  • security-path-traversal — 防范工具参数中的路径遍历
  • security-ssrf-internal — 防范针对内部网络的 SSRF
  • security-oversized-input — 妥善处理超大输入
  • security-extra-params — 拒绝或忽略多余的工具参数
  • security-tool-schema-defined — 所有工具都定义了 inputSchema
  • security-tool-rug-pull — 工具定义在多次调用之间保持稳定
  • security-tool-description-poisoning — 工具描述不含注入模式
  • security-tool-cross-reference — 工具不会通过名称引用其他工具
  • security-error-no-stacktrace — 错误响应不会泄露堆栈跟踪
  • security-error-no-internal-ip — 错误响应不会泄露内部 IP
  • security-rate-limiting — 已实施速率限制

这 103 项测试的检查内容(2026-07-28)

2026-07-28 版目录评估无状态、按请求传递 _meta 的时代:使用 server/discover 而不是 initialize,不使用会话,在每个可缓存结果上提供缓存提示,在每个结果上提供 resultType,使用 MRTR input_required 结果而不是由服务端发起的请求,并对缺失资源返回 -32602。与 2025-11-25 列表共用的 ID 指向同一功能,但两个目录的评判标准和必选标记可能不同(stdio-framing 和 error-invalid-jsonrpc 在此处为可选,error-method-code 为必选),因此 ID 只能在同一目录内比较;判定结果有变化的检查会获得新 ID,而 diff 会拒绝比较不同修订版的报告。事后测试会扫描运行期间服务端发送的每条消息记录(如果没有收到任何消息,则会判定失败,而不是空洞地通过)。_meta 和标准标头拒绝测试可追溯归因:只有在提供了符合规范的 server/discover 时,拒绝才会计入,因此仅支持旧版协议的服务端使用此目录测试时,这些测试会以“无法评估”判定失败。设置阶段的 server/discover 在收到 429 后会重发一次,每条读取它的规则都会以最终采用的答复作为判定依据。会将任何拒绝计入的检查——transport-batch-reject、transport-content-type-reject、lifecycle-jsonrpc、lifecycle-subscriptions-listen 和六项错误检查(error-unknown-method、error-invalid-jsonrpc、error-invalid-json、error-missing-params、error-capability-gated、error-invalid-cursor),以及 error-parse-code 和 error-invalid-request-code 接受的无响应正文 4xx——也会确认答复来自谁:网关返回的带 -32001 正文的 401、看起来像拒绝身份验证的 403(未使用 --auth 时,任何 Bearer 质询都符合;使用 --auth 时,需带有 error 参数)、重发一次后仍为 429 的 429,或者任何其他 403——若符合规范的同类请求无法通过(server/discover;对于 error-invalid-cursor,则是未带游标的列表方法),则判定为“无法评估”;若 5xx 不含该检查专属的错误代码,则判定为服务端处理请求失败。lifecycle-jsonrpc 的探测本身就是符合规范的 server/discover,因此不会发送同类请求:对此探测返回的任何 403,以及不带服务端专属拒绝代码的 5xx,都会判定为“无法评估”。如果设置阶段的 server/discover 本身遭到拒绝,transport-batch-reject 和 transport-content-type-reject 也会将任何拒绝判定为“无法评估”。tools-call-unknown 目前尚未采用这种判定方式:网关对其 tools/call 返回 -32001 仍会使其通过。四项注入测试会从最安全且包含字符串参数的注解层级中选择单个(工具,参数)目标——依次为 readOnlyHint: true、destructiveHint: false、未标注的工具(规范默认 destructiveHint 为 true),然后是 destructiveHint: true;警告中会列出跳过和实际探测的工具——并使用符合架构的占位值填充其他必需参数,同时报告被拒绝、返回且无执行证据,或从未到达工具的载荷数量(全部未到达表示结果不确定,会附带警告并标记为跳过)。在 stdio 上,如果检查自身的请求导致服务端退出(注入载荷、1 MB 参数、未知工具参数、stdio-unicode 的中日韩文字/表情符号探测,以及 lifecycle-progress-token 的某次调用),则会重启服务端,以供之后的检查使用;每次都会重启,包括 --retries 指定的重试。安全检查和 stdio-unicode 会因服务端退出而失败;随后 security-tool-rug-pull 会比较新进程的两份列表。stdio-unicode 和 lifecycle-progress-token 也会将作答后立即退出的子进程计为失败(答复后会紧接着发送普通的 server/discover);若 stdio-unicode 收到答复后服务端停止响应,该检查也会失败。若存在只读且无需参数的工具,security-rate-limiting 会向其突发发送 50 个 tools/call 请求;突发请求未造成问题即可通过,并会附带警告。

传输(20 项测试) 仅 HTTP(15 项): - **transport-post** — 接受 HTTP POST(必需) - **transport-content-type** — 响应为 JSON 或 SSE(必需) - **transport-content-type-reject** — 拒绝非 JSON 请求 Content-Type - **transport-batch-reject** — 拒绝 JSON-RPC 批量请求(必需) - **transport-notification-202** — 通知返回 202 Accepted - **transport-concurrent** — 处理并发请求 - **transport-get-removed** — GET 返回 405 - **transport-delete-removed** — DELETE 返回 405 - **transport-session-ignored** — 忽略 Mcp-Session-Id - **transport-header-version-required** — 拒绝缺少 MCP-Protocol-Version 标头的请求(必需) - **transport-header-version-mismatch** — 拒绝标头/_meta 版本不匹配的请求(必需) - **transport-header-method-required** — 拒绝缺少 Mcp-Method 标头的请求(必需) - **transport-header-method-mismatch** — 拒绝 Mcp-Method 与请求正文不匹配的请求(必需) - **transport-header-name-mismatch** — 拒绝 Mcp-Name 与请求正文不匹配的请求 - **transport-header-case-insensitive** — 标头名称不区分大小写

两种传输方式均适用(1 项,事后检查):

  • transport-no-server-requests — 任何流上都没有由服务端发起的请求(必需)

仅 stdio(4 项):

  • stdio-framing — 以换行符分隔的 JSON 帧
  • stdio-unicode — UTF-8 Unicode 往返
  • stdio-unknown-method-recovers — 遇到未知方法后恢复
  • stdio-cancellation — 忽略对未知请求的取消
生命周期(22 项测试)
  • lifecycle-discover — server/discover 返回 DiscoverResult(必需)
  • lifecycle-discover-versions — supportedVersions 格式正确(必需)
  • lifecycle-discover-caching — server/discover 包含缓存提示(必需)
  • lifecycle-jsonrpc — 响应是有效的 JSON-RPC 2.0(必需)
  • lifecycle-id-match — 响应 id 与请求 id 匹配(必需)
  • lifecycle-string-id — 支持字符串请求 id
  • lifecycle-capabilities — 返回 capabilities 对象(必需)
  • lifecycle-server-info — 在 _meta 中包含 serverInfo
  • lifecycle-instructions — Instructions 字段有效
  • lifecycle-meta-required — 拒绝不含 _meta 的请求(必需)
  • lifecycle-meta-protocol-version-required — 拒绝 _meta 不含 protocolVersion 的请求(必需)
  • lifecycle-meta-client-capabilities-required — 拒绝 _meta 不含 clientCapabilities 的请求(必需)
  • lifecycle-meta-client-info-optional — 接受不含 clientInfo 的 _meta(必需)
  • lifecycle-version-unsupported — 拒绝不支持的协议版本(必需)
  • lifecycle-removed-methods — 拒绝已移除的旧版方法
  • lifecycle-dual-era — 旧版 initialize 探测(仅供参考)
  • lifecycle-capability-handlers-match — 能力声明与处理程序相符
  • lifecycle-subscriptions-listen — subscriptions/listen 会先确认
  • lifecycle-log-level-gating — 未设置 logLevel 时不发送日志通知(必需)
  • lifecycle-meta-tolerance — 容忍未知的 _meta 键
  • lifecycle-completions — 接受 completion/complete(声明了 completions 能力时必需)
  • lifecycle-progress-token — 进度通知会回显令牌
工具(6 项测试)
  • tools-list — tools/list 返回有效响应(声明了 tools 能力时必需)
  • tools-list-caching — tools/list 包含缓存提示(声明了 tools 能力时必需)
  • tools-list-deterministic-order — tools/list 顺序确定
  • tools-call — tools/call 正确响应(声明了 tools 能力时必需)
  • tools-content-types — 工具内容项的类型有效(声明了 tools 能力时必需)
  • tools-pagination — tools/list 支持分页
资源(8 项测试) - **resources-list** — resources/list 返回有效响应(如果声明了 resources 能力,则为必需项) - **resources-list-caching** — resources/list 携带缓存提示(如果声明了 resources 能力,则为必需项) - **resources-read** — resources/read 返回内容(如果声明了 resources 能力,则为必需项) - **resources-read-caching** — resources/read 携带缓存提示(如果声明了 resources 能力,则为必需项) - **resources-not-found** — 不存在的资源返回 -32602(如果声明了 resources 能力,则为必需项) - **resources-templates** — resources/templates/list 返回有效响应 - **resources-templates-caching** — resources/templates/list 携带缓存提示 - **resources-pagination** — resources/list 支持分页
提示词(4 项测试)
  • prompts-list — prompts/list 返回有效响应(如果声明了 prompts 能力,则为必需项)
  • prompts-list-caching — prompts/list 携带缓存提示(如果声明了 prompts 能力,则为必需项)
  • prompts-get — prompts/get 返回有效消息(如果声明了 prompts 能力,则为必需项)
  • prompts-pagination — prompts/list 支持分页
错误处理(12 项测试)
  • error-unknown-method — 未知方法返回 JSON-RPC 错误(必需)
  • error-method-code — 未知方法使用 -32601(必需)
  • error-invalid-jsonrpc — 处理格式错误的 JSON-RPC
  • error-invalid-json — 处理无效的 JSON 请求体
  • error-parse-code — JSON 无效时返回 -32700
  • error-invalid-request-code — 请求无效时返回 -32600
  • error-missing-params — 不带 name 的 tools/call 返回错误
  • tools-call-unknown — 未知工具名称返回错误
  • error-capability-gated — 拒绝未声明能力对应的方法
  • error-invalid-cursor — 处理无效的分页游标
  • error-id-echo — 错误响应回显请求 id
  • error-retired-codes — 不使用已弃用的错误代码
架构验证(10 项测试)
  • tools-schema — 所有工具都有 name 和 inputSchema
  • tools-annotations — 工具注释有效
  • tools-title-field — 工具包含 title 字段
  • tools-output-schema — 带有 outputSchema 的工具有效
  • prompts-schema — 提示词有 name 字段
  • resources-schema — 资源有 uri 和 name
  • schema-result-type — 每个结果都带有 resultType(必需)
  • schema-no-input-required-on-lists — input_required 仅用于 MRTR 方法(必需)
  • schema-input-required-shape — InputRequiredResult 格式正确
  • schema-wire-valid — 消息符合 2026-07-28 架构
安全(21 项测试) - **security-auth-required** — 拒绝未经身份验证的请求 - **security-www-authenticate** — 401 响应包含 WWW-Authenticate - **security-auth-malformed** — 拒绝格式错误的身份验证凭据 - **security-tls-required** — 强制使用 HTTPS/TLS - **security-oauth-metadata** — 受保护资源元数据端点存在 - **security-token-in-uri** — 拒绝查询字符串中的身份验证令牌 - **security-cors-headers** — CORS 标头限制严格 - **security-origin-validation** — 验证 Origin 标头 - **security-command-injection** — 防止工具参数中的命令注入 - **security-sql-injection** — 防止工具参数中的 SQL 注入 - **security-path-traversal** — 防止工具参数中的路径遍历 - **security-ssrf-internal** — 防止针对内部网络的 SSRF - **security-oversized-input** — 妥善处理超大输入 - **security-extra-params** — 拒绝或忽略多余的工具参数 - **security-tool-schema-defined** — 所有工具均定义 inputSchema - **security-tool-rug-pull** — 工具定义在多次调用间保持稳定 - **security-tool-description-poisoning** — 工具描述不含注入模式 - **security-tool-cross-reference** — 工具不会通过名称引用其他工具 - **security-error-no-stacktrace** — 错误响应不会泄露堆栈跟踪 - **security-error-no-internal-ip** — 错误响应不会泄露内部 IP - **security-rate-limiting** — 已启用速率限制

评分

等级分数
A90-100
B75-89
C60-74
D40-59
F0-39

必需测试占总分的 70%,可选测试占 30%,按实际测得结果的测试计算。未测得任何结果的测试(跳过项)完全不计入分数,既不算通过也不算失败;当所有必需测试或所有可选测试都被跳过时,另一组测试将占据全部分数;如果一次运行中的所有测试都被跳过,则得分为 0(F),与没有运行任何测试的情况相同。终端、Markdown、HTML 和 GitHub 报告、SARIF 调用属性(note)以及 MCP mcp_compliance_test 工具都会显示“没有测试测得任何结果”;JSON 报告会在计数中显示这一点(summary.skipped 等于 summary.total)。跳过项仍计入通过总数(summary.passed 和类别计数);每种报告格式都会统计或列出它们(终端会在 SKIPPED CHECKS 下列出),终端类别进度条和 HTML 类别卡片按实际测得的结果评分,--verbose 会将跳过项显示为 SKIP,而 diff 会列出开始或停止跳过的检查。0.19.0 及更早版本生成的报告会将跳过项计为通过,因此相同结果的得分会更高。分数下降幅度取决于运行情况:在参考服务上,四舍五入后的分数没有变化;但随着某个测试组中的失败数与跳过数增加,分数降幅也会增大,甚至可能使必需检查全部通过的服务降低一个完整等级;大多数检查未测得结果时,分数可能下降好几个等级。diff 会按照此版本的方式,根据结果为两份报告评分,因此与 0.19.0 及更早版本生成的基准报告比较时仍然公平,并会注明该文件记录的分数。请参阅方法文档中的完整评分算法。

CI 集成

# GitHub Actions example
- name: MCP Compliance Check
  run: npx @yawlabs/mcp-compliance@latest test ${{ env.MCP_SERVER_URL }} --strict
# With JSON output for parsing
- name: MCP Compliance Check
  run: |
    npx @yawlabs/mcp-compliance@latest test ${{ env.MCP_SERVER_URL }} --format json > compliance.json
    cat compliance.json | jq '.grade'
# With retries for flaky network conditions
- name: MCP Compliance Check
  run: npx @yawlabs/mcp-compliance@latest test ${{ env.MCP_SERVER_URL }} --strict --retries 2 --timeout 30000
# SARIF output for GitHub Code Scanning
- name: MCP Compliance Check
  run: npx @yawlabs/mcp-compliance@latest test ${{ env.MCP_SERVER_URL }} --format sarif > compliance.sarif
- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: compliance.sarif

MCP 服务(适用于 Claude Code、Cursor 等)

此软件包还提供一个 MCP 服务,其中包含 2 个工具,可在 Claude Code、Cursor 或任何 MCP 客户端中使用。

设置

Claude Code(单行命令):

claude mcp add mcp-compliance -- npx -y @yawlabs/mcp-compliance@latest mcp

或在项目根目录中创建 .mcp.json:

macOS / Linux / WSL:

{
  "mcpServers": {
    "mcp-compliance": {
      "command": "npx",
      "args": ["-y", "@yawlabs/mcp-compliance@latest", "mcp"]
    }
  }
}

Windows:

{
  "mcpServers": {
    "mcp-compliance": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@yawlabs/mcp-compliance@latest", "mcp"]
    }
  }
}

提示: 此文件可以安全地提交到代码仓库,不包含任何机密信息。

重启 MCP 客户端,并在出现提示时批准该服务。

工具
  • mcp_compliance_test — 针对 HTTP MCP 端点(URL)运行完整的合规性测试套件。支持身份验证、自定义标头、超时、重试、类别/测试筛选,以及 specVersion(auto | 2025-11-25 | 2026-07-28,默认值为 auto)。返回等级、分数、解析后的 specVersion 和详细结果(每项测试均标记为 PASS、FAIL 或 SKIP;Tests 行会统计跳过项)。stdio 目标仅支持 CLI。
  • mcp_compliance_explain — 说明特定测试 ID 检查的内容及其重要性,并附上规范章节链接。ID 按目录划分:传入 specVersion 可读取单个目录,省略则搜索两个目录(共享 ID 会在每个套件中各说明一次,并注明所需标志/类别是否也不同;仅存在于另一个套件中的 ID 则会特别指出)。

所有工具都带有 MCP 工具注解(readOnlyHint、destructiveHint、idempotentHint、openWorldHint),因此 MCP 客户端可以跳过安全操作的确认对话框。

编程方式使用

import { runComplianceSuite } from '@yawlabs/mcp-compliance';

const report = await runComplianceSuite('https://my-server.com/mcp');
console.log(`Grade: ${report.grade} (${report.score}%)`);

// With options
const report2 = await runComplianceSuite('https://my-server.com/mcp', {
  headers: { 'Authorization': 'Bearer tok123' },
  timeout: 30000,
  retries: 1,
  only: ['transport', 'lifecycle'],
  specVersion: '2026-07-28', // 'auto' (default) | '2025-11-25' | '2026-07-28'
});
console.log(report2.specVersion); // always the resolved revision, never 'auto'

// Per-revision catalogs and helpers
import { getTestDefinitions, specBaseFor, SUPPORTED_SPEC_VERSIONS } from '@yawlabs/mcp-compliance';
getTestDefinitions('2026-07-28'); // 103 TestDefinitions; TEST_DEFINITIONS stays the 2025-11-25 list
specBaseFor(report2.specVersion); // base URL for that revision's spec links

// Live progress for streaming UIs (e.g. server-sent-events to a browser)
await runComplianceSuite('https://my-server.com/mcp', {
  onTestComplete: (result) => {
    // result has the full TestResult: id, name, category, required,
    // passed, skipped (true when the check measured nothing), details,
    // durationMs, specRef. Push it to your client. (onProgress carries no
    // skip flag: a skip arrives there as passed.)
    sendToClient(result);
  },
  // Pre-test status lines: the stdio era probe still waiting after ~2 s,
  // or an HTTP preflight timeout being re-probed within startupTimeout.
  // The CLI prints these dimmed on stderr in terminal mode only.
  onStatus: (message) => sendToClient({ status: message }),
});

报告架构

测试套件的 JSON 输出是一份稳定且有版本号的契约。每份报告的顶层都包含 schemaVersion 字段。完整的 JSON Schema 位于 schemas/report.v1.json,并随 npm 包一同发布。

{
  "schemaVersion": "1",        // bumped on breaking changes to the report shape
  "specVersion": "2026-07-28", // MCP spec revision the run graded — the RESOLVED value ("2025-11-25" or "2026-07-28"), never "auto"
  "toolVersion": "0.19.0",     // mcp-compliance version that produced the report
  "url": "...",
  "timestamp": "...",
  "grade": "A",
  "score": 92.5,
  "summary": { "total": 99, "passed": 97, "failed": 2, "required": 24, "requiredPassed": 24, "skipped": 4 },
  "tests": [                   // ids are only meaningful together with specVersion
    { "id": "security-auth-malformed", "passed": true, "skipped": true,
      "details": "Skipped: needs a valid credential to compare against (pass --auth)", ... },
    ...
  ],
  // ...
}

如果某项测试已运行但未测得任何内容(没有 --auth、未声明工具、检查不适用于该传输方式,或先前检查无法归因的拒绝),则会将其记录为 passed: true 且 skipped: true;summary.skipped 和每个 categories[*].skipped 都会统计这些项目。跳过项计入 passed,但不计入 score(0.19.0 及更早版本生成的报告会将其作为通过项计分),因此在将通过总数视为证据之前,请同时查看 skipped 和 passed。SARIF 输出的 results 仅包含失败项,并会在本次运行的调用属性中列出跳过项(testsSkipped、skippedTests),因此 Code Scanning 不会为它们生成警报。

使用者指南:

  • 根据 schemaVersion 固定版本。遇到未知版本的报告时应拒绝,而不是猜测其结构。
  • 解读 tests 前先检查 report.specVersion。从 0.19 开始,同一工具版本可生成任一修订版的报告,因此仅以 toolVersion 为依据的仪表板会看到同一版本生成的 2025-11-25 和 2026-07-28 报告;测试 ID、必需集合和 serverInfo.protocolVersion 都属于该字段所指定的修订版。对待未知 specVersion 时,应与对待未知 schemaVersion 一样:拒绝,不要猜测。
  • 任何 Draft 2020-12 验证器(例如 ajv)都可以验证该架构。该架构采用严格模式(additionalProperties: false),因此应使用生成报告的工具版本随附的 report.v1.json 验证报告:0.19 为 v1 添加了可选的 skipped 字段(位于测试项、summary 和 categories 中),旧版架构副本会拒绝这些字段。
  • 重命名、移除或类型变更都会提升 schemaVersion;除此之外,报告结构在同一主版本内保持稳定。
  • 对同一服务端进行两次运行,会得到等效的等级、分数和逐项测试通过/失败结果(计时/时间戳除外)——前提是两次解析得到的 specVersion 相同。使用 auto 时,具体结果取决于服务端,因此若部署间需要保持确定性,请固定 --spec-version。

方法论与文档

测试方法论公开发布,以便对评分过程进行审查:

  • 测试方法论 — 按规范修订版划分的测试执行模型、评分算法,以及全部 88 + 103 条测试规则及其通过/失败标准(CC BY 4.0)
  • 机器可读的规则目录 — 每条规则均标注其适用的规范修订版,供程序使用(通过 src/tests/catalog-parity.test.ts 与代码保持同步)
  • 为什么选择 mcp-compliance — 问题、现有替代方案,以及此工具的不同之处
  • 修复常见失败 — 针对最常见测试失败的处理方法和代码片段,适用于两个修订版
  • 规范版本策略 — 一个工具版本,多个规范目录:auto 如何做出选择、如何固定版本,以及服务升级时会有哪些变化
  • 性能深入解析 — 套件采用顺序执行的原因,以及并行执行的代价
  • 规范 PR 草案 — 针对我们遇到的模糊情况提出的 MCP 规范澄清建议

此方法论并非权威的一致性标准,而是单个工具的选择,并将其公开发布,以供审查、采用或分叉。官方 MCP 规范(2025-11-25、2026-07-28)定义了服务必须执行的操作;本文档介绍 @yawlabs/mcp-compliance 如何验证这些要求。

要求

  • Node.js 20+
运行时

mcp-compliance 命令是一个小型启动器。若已安装可用的 oam 运行时,它会优先使用;否则会直接使用 npm 已启动的 Node 运行 CLI,不产生额外开销。CLI 在两种运行时上的行为相同。

变量作用
MCP_COMPLIANCE_RUNTIME=auto默认值。使用找到的最新 oam 0.18.0 或更高版本,否则回退到 Node。如果找到的 oam 不可用,或 OAM_BIN 设置有误,它会在 stderr 中说明(mcp-compliance: ...; using Node instead.)。
MCP_COMPLIANCE_RUNTIME=oam仅使用 oam。如果找不到 oam 0.18.0 或更高版本,则退出并返回代码 1,并提供修复方法:对于过时的 oam,运行 oam self-update;对于 OAM_BIN,提供相应的修复方法;如果完全没有 oam,则提供安装链接。
MCP_COMPLIANCE_RUNTIME=node仅使用 Node,即使已安装 oam 也不例外。
OAM_BIN=/path/to/oam在搜索其他位置之前,先尝试使用此 oam。如果该文件不存在、版本低于 0.18.0 或无法运行,启动器会说明情况并继续搜索。
OAM_INSTALL_DIR=/dir除了 ~/.oam/bin、%LOCALAPPDATA%\oam\bin 和 PATH,还会检查此目录;oam 安装程序会将二进制文件放在这里。

oam 的最低版本要求是 0.18.0,这是最新的 oam 版本。此要求不可更改,因为 CLI 仅在此版本上经过检查。在 0.9.0 之前,oam 的 child_process 会以某些方式处理 stdio 和参数,导致一致性测试评估的是运行时,而不是服务。要更新旧版 oam,请运行 oam self-update。

oam run <path-to-package>/dist/index.js -- test <target> 可直接在 oam 上运行 CLI,并跳过启动器。此时,上述规则均不适用:不会检查最低版本,不会回退,也不会切换运行时。

贡献

git clone https://github.com/YawLabs/mcp-compliance.git
cd mcp-compliance
npm install
npm run build
npm test

开发命令:

命令说明
npm run build使用 tsup 编译
npm run dev监视模式
npm test运行测试(vitest)
npm run lint使用 Biome 检查
npm run lint:fix使用 Biome 自动修复
npm run typecheckTypeScript 类型检查
npm run test:ci构建并运行测试(适用于 CI)

链接

License

MIT — see LICENSE.

Follow @YawLabs on X

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。