协议升级后的验收深度实践: MCP迁移实战:用官方 Conformance Suite 给 Client/Server 加回归门禁
承接: 协议升级深度实践:MCP无状态化迁移清单(网关、任务与鉴权) · 代码审查进阶:Copilot Code Review 的 Agent Skills 与 MCP 已 GA,如何接入并守住只读边界
调研日期:2026-08-02
本文目标:将 MCP 官方 Conformance Test Framework 纳入自建 MCP client/server 的持续验收,既验证协议升级,也避免让 Agent 或人工评审以“看起来能连上”替代可重复的证据。
MCP 2026-07-28 修订版将协议核心改为无状态,并将 initialize/会话生命周期替换为请求级元数据和 server/discover 等机制。对远程 MCP Server 来说,这意味着负载均衡、缓存和网关可以更简单;对已有实现来说,却意味着一条“工具能调用”的冒烟测试已经不足以证明兼容。
2026-07-23,GitHub 宣布 GitHub MCP Server 已在正式发布日期前支持新规范,并特别提到官方 conformance tests。MCP 官方仓库也已提供可执行的 Conformance Test Framework,用于检查 MCP client 和 server 是否符合规范。它给工程团队提供了一个更可靠的升级标准:把协议要求编码成测试,让每次 SDK、传输层、网关或 Agent 改动都重新给出证据。
本文不假设所有客户端、SDK 或扩展已经升级完成。GitHub 的公告说明其 GitHub MCP Server 与 Tier 1 SDK 的兼容策略,不能自动推导为你所使用的自研组件、第三方 SDK、代理或插件也同样兼容。协议层无状态也不等于业务状态消失:任务进度、审批和长作业仍要由应用以显式 ID、存储和授权边界管理。
适用前提: 你维护至少一个可启动的 MCP client 或 server,能在 CI 的隔离环境中运行测试端点,并可固定 Node/SDK/Conformance Suite 的版本。不要把 conformance runner 直接指向生产 MCP 服务,更不要在测试命令中放入真实 OAuth client secret、生产 Token 或客户数据。
一、先分清三类“通过”:连通、协议一致和业务正确
| 层次 | 要回答的问题 | 推荐证据 | 不能证明什么 |
| 连通性 | URL、TLS、认证和基本路由是否能建立? | 健康检查、一次低风险 | 请求/响应是否符合全部协议语义 |
| 协议一致性 | client/server 是否按规范协商、收发和处理场景? | 官方 Conformance Suite 的检查结果与基线 | 你的工具业务逻辑是否正确、授权是否最小 |
| 业务验收 | 工具结果、权限、审计、超时、幂等和人工审批是否符合产品要求? | 项目自己的集成/端到端测试 | 其他实现是否符合 MCP 规范 |
Conformance Suite 正好处在第二层。它会在 client 模式下启动测试 server、运行被测 client 并检查交互;在 server 模式下连接到正在运行的被测 server,发送测试请求并检查行为。不要用“所有单测绿色”跳过这层,也不要用 conformance 绿色跳过业务与安全测试。
二、把MCP的变化转成明确的测试矩阵
先把真实部署拆成可验证的组合,而不是只记录一个笼统的“已升级 MCP”。建议将下面矩阵放进迁移 PR 或发布单:
| 维度 | 至少覆盖的组合 | 需要观察的风险 |
| 被测端 | 自建 server、客户端、网关/代理各至少一条路径 | 只测 server,漏掉 client 的请求级元数据或兼容降级 |
| 协议代际 | 仍要支持的旧版本 | 新旧握手、版本协商、弃用接口和错误码处理混在一起 |
| 传输 | 实际使用的 Streamable HTTP 与 stdio 等 | 反向代理丢弃标准 header、URL 规则与超时不一致 |
| 核心能力 | discover、tools list/call、资源/提示词(如使用) | 只验证一个 tool call,忽略能力发现和异常响应 |
| 扩展 | 实际启用的 Tasks、MCP Apps、授权或 elicitation | 将未协商的扩展当作必备能力,或把实验 API 当成稳定 API |
| 安全边界 | 无凭据、最小测试凭据、拒绝路径 | conformance 输出或日志意外携带生产 token/正文 |
关键不是“删掉一个初始化函数”而已。官方发布说明中,client info 与 capabilities 会随请求的 _meta 传递,server/discover 用于获取能力;长任务以 Tasks extension 的方式运行;扩展通过能力协商进入。每个实际启用的变化,都应在矩阵中拥有一条能失败的测试。
三、先在本地隔离端点执行官方 runner
官方框架提供以下 server 端快速检查。将 URL 换成仅供测试的本地或 CI 端点:
npx @modelcontextprotocol/conformance server \
--url http://127.0.0.1:3000/mcp
若想先查看当前 runner 能运行的 server 场景,不要凭博客文章或旧版清单硬编码名称:
npx @modelcontextprotocol/conformance list --server
client 的测试方式不同:runner 会启动某个场景的测试 server,再执行你的 client 命令,并将 server URL 作为参数传入。下面是框架 README 形式的最小命令;项目应替换为自己的可执行 client,并确保它不会触发真实外部写操作。
npx @modelcontextprotocol/conformance client \
--command "node ./dist/conformance-client.js" \
--scenario initialize
执行前要做三件小事:
- 固定依赖。 把 Conformance Suite、Node 和被测 SDK 固定到审查过的版本或不可变提交,并在升级 PR 中一起更新结果基线。
- 隔离服务。 用只监听 CI 网络的测试 server、临时数据库和伪造身份提供方;不要让工具访问生产仓库、真实 secrets 或公网写接口。
- 保存结构化结果。 官方 runner 会在
results/下生成checks.json,client 模式还包含 stdout/stderr。将它们作为受访问控制的 CI artifact,而不是复制整段日志到 PR 评论。
四、将 runner 放进 CI,但把启动方式留给项目自己
下面的 workflow 展示门禁结构。start:mcp:test 必须由你的项目实现为一个无生产凭据的测试端点,并在作业结束时被清理;它不是 MCP 官方规定的脚本名。
name: mcp-conformance
on:
pull_request:
paths:
- "src/mcp/**"
- "package.json"
- "package-lock.json"
- ".github/workflows/mcp-conformance.yml"
jobs:
server-conformance:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
- run: npm ci
- name: Start an isolated MCP test server
run: npm run start:mcp:test -- --port 3000 &
- name: Wait for the test endpoint
run: |
for i in {1..30}; do
curl --fail --silent http://127.0.0.1:3000/health && exit 0
sleep 1
done
exit 1
- name: Run MCP conformance checks
run: >-
npx @modelcontextprotocol/conformance server
--url http://127.0.0.1:3000/mcp
--expected-failures ./conformance-baseline.yml
- name: Upload protected diagnostics on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: mcp-conformance-results
path: results/
if-no-files-found: ignore
retention-days: 7
这段示例的要点有四个:
- runner 的非零退出码让 PR 直接失败;不要在命令后追加
|| true。 - workflow 只有
contents: read,并且不读取 Secrets;协议一致性测试不需要把部署权限送给测试进程。 - 健康检查路径和启动脚本是项目自定义内容,必须与真实测试 server 匹配。若你的 server 没有
/health,改为安全的本地探针,而不是删除等待步骤。 - artifact 只在失败时短期保存,并应受仓库访问控制保护。stdout、stderr 与协议报文可能包含实现细节。
如果你的项目不是 Node,仍可保留同一结构:用项目的语言启动隔离 server,再调用 npx @modelcontextprotocol/conformance。Conformance runner 是协议测试工具,不要求被测实现采用 TypeScript。
五、把 expected failures 当作到期债务,而不是永久绿灯
官方框架允许维护一个 YAML 基线,用来区分已知失败和新回归。例如:
server:
- tools-call-with-progress
client:
- sse-retry
基线的语义非常有价值:一个失败若列在基线中,当前运行可以返回成功;但一个未列出的失败会使运行失败,而一个已经通过、却仍留在基线中的项目也会使运行失败,提醒团队删掉陈旧豁免。这样基线既不会掩盖新增退化,也不会让“技术债已修复”被静悄悄地遗忘。
建议给每项豁免附带一份可评审的说明,而不是只留下场景名:
# conformance-exceptions.yml(团队自定义记录,不传给 runner)
exceptions:
- scenario: tools-call-with-progress
owner: platform-mcp
reason: "等待内部代理透传进度事件的修复"
tracking_issue: "PLAT-1234"
expires_on: "2026-08-30"
conformance-baseline.yml 仍只保留 runner 要识别的结构;说明文件由 CODEOWNERS、定时检查或发布门禁验证到期日。没有 owner、issue 和到期日的基线不应被合并。
六、让 Agent 帮忙定位失败,但不让它自行宣布兼容
GitHub 在 MCP Server 公告中建议为 Agent 提供 Conformance Suite、规范草案和 Tier 1 SDK 实现,这确实能提高排错效率。一个安全的协作流程是:
- CI 运行已固定版本的 runner,输出
checks.json与受限诊断 artifact。 - 人工或只读 Agent 根据失败的场景名、检查字段和规范链接,定位到 transport、header、版本协商或能力声明的最小修改范围。
- 编码 Agent 只能在隔离分支草拟补丁与测试;不得修改基线来掩盖失败,也不得访问生产 MCP endpoint 或部署凭据。
- 新 PR 必须同时展示失败场景转绿、业务集成测试结果,以及基线删除或过期说明。由协议 owner 审核后才能合并。
请特别防范一个常见的“修复”:Agent 看到新版本失败,就把客户端强制降级到旧版本,或把失败场景加入基线。前者会吞掉能力升级,后者会吞掉回归信号;二者都只能作为经过人工批准、有明确期限的兼容策略。
七、验收矩阵:升级日与日常回归各测什么
| 场景 | 升级时必须验证 | 日常 PR 回归验证 |
| 新协议核心 | 请求级 metadata、discover、实际传输 header 和错误处理 | 被改动的 client/server 仍通过相关 conformance 场景 |
| 旧版兼容 | 仍在支持清单中的 legacy client/server 是否协商到预期版本 | 每次 SDK/网关改动不破坏该路径,或有公开的退役计划 |
| 工具调用 | tools list/call、无效参数、超时和失败响应 | 工具契约、权限拒绝和幂等性仍符合业务测试 |
| 长任务/扩展 | 实际启用的 Tasks 或其他 extension 的协商与取消路径 | 扩展变更不绕过核心协议门禁 |
| 网关 | header 不被重写/丢弃,负载均衡不依赖旧会话粘性 | 配置变更后冒烟 + conformance 同时通过 |
| 安全与审计 | 测试身份最小、日志不含 secrets、artifact 可访问范围正确 | 失败诊断与异常基线仍遵守留存/访问策略 |
八、六个常见误区
1)把 server 冒烟测试当成 client/server 双向兼容
server mode 只能说明 server 侧行为。若你维护 client、代理或 SDK 封装,也应运行 client 模式或覆盖对应端到端路径。
2)把 initialize 场景名当作新协议仍需旧式握手
场景名称来自 runner 的测试集合。判断新协议实现时,应以当前规范、runner 所列可用场景和实际协商结果为准,而不是根据名称自行推断 wire behavior。
3)把所有失败塞进 expected failures
基线只适合暂时、可追踪的已知缺口。无到期日的例外会把 conformance 从门禁变成静音器。
4)直接对生产 URL 跑 conformance
测试会发送协议请求、生成日志并暴露错误细节。生产端点还可能触发真实工具调用、速率限制或审计噪声。应使用隔离测试端点与无害工具实现。
5)认为协议无状态后就无需保存状态
协议请求可以被任意实例处理,但业务作业、任务 handle、授权上下文和审计关联仍可能需要显式存储。移除粘性会话之前,先证明应用状态已由可验证的键和后端承载。
6)把 conformance 通过写成“安全已验证”
规范检查不会替你审计工具权限、Token scope、prompt injection、数据保留或业务副作用。它是必要证据之一,不是安全认证。
结语
MCP的价值不止是减少会话依赖,更在于协议演进开始有了可自动验证的共同语言。将官方 Conformance Suite 固定进 CI,并给每个例外加上 owner 和到期日,才能让升级从一次性的迁移文档变成持续可信的工程能力。
从一个本地 server、一个 client、一个 legacy 兼容路径开始。让每次改动都留下 runner 结果、业务验收和人工审批三类证据;当它们同时通过时,Agent 才有可靠边界可以协助修复,而不是凭感觉宣布“兼容”。
来源与延伸阅读
- The 2026-07-28 MCP Specification Release Candidate:MCP 官方发布说明;无状态核心、扩展、Tasks、兼容与 conformance 的背景。
- GitHub MCP Server supports the next MCP specification:GitHub 官方公告;GitHub MCP Server 的升级要点与官方 conformance tests。
- MCP Conformance Test Framework:官方 runner、client/server 命令、结果文件、expected failures 与 GitHub Actions 示例。
- 代码审查进阶:Copilot Code Review 的 Agent Skills 与 MCP 已 GA,如何接入并守住只读边界:在代码审查场景中让仓库规则、工具白名单和只读边界共同生效。
- Copilot Agent 会话流式审计实战:从 48 小时补数到脱敏告警闭环:为 Agent 协议测试之外的会话活动保留可审计证据。
标签: MCP · Model Context Protocol · AI Agent · 协议测试 · CI/CD
更多推荐

所有评论(0)