承接: 协议升级深度实践: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、认证和基本路由是否能建立?

健康检查、一次低风险 tools/list

请求/响应是否符合全部协议语义

协议一致性

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

执行前要做三件小事:

  1. 固定依赖。 把 Conformance Suite、Node 和被测 SDK 固定到审查过的版本或不可变提交,并在升级 PR 中一起更新结果基线。
  2. 隔离服务。 用只监听 CI 网络的测试 server、临时数据库和伪造身份提供方;不要让工具访问生产仓库、真实 secrets 或公网写接口。
  3. 保存结构化结果。 官方 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

这段示例的要点有四个:

  1. runner 的非零退出码让 PR 直接失败;不要在命令后追加 || true
  2. workflow 只有 contents: read,并且不读取 Secrets;协议一致性测试不需要把部署权限送给测试进程。
  3. 健康检查路径和启动脚本是项目自定义内容,必须与真实测试 server 匹配。若你的 server 没有 /health,改为安全的本地探针,而不是删除等待步骤。
  4. 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 实现,这确实能提高排错效率。一个安全的协作流程是:

  1. CI 运行已固定版本的 runner,输出 checks.json 与受限诊断 artifact。
  2. 人工或只读 Agent 根据失败的场景名、检查字段和规范链接,定位到 transport、header、版本协商或能力声明的最小修改范围。
  3. 编码 Agent 只能在隔离分支草拟补丁与测试;不得修改基线来掩盖失败,也不得访问生产 MCP endpoint 或部署凭据。
  4. 新 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 才有可靠边界可以协助修复,而不是凭感觉宣布“兼容”。


来源与延伸阅读

标签: MCP · Model Context Protocol · AI Agent · 协议测试 · CI/CD

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐