核心摘要

MCP 是有版本的协议。可靠的升级说明必须回答四个问题:

  1. 固定了哪个规范版本?
  2. 选择了哪个 Transport 和 Authorization Profile?
  3. 哪些行为来自 SDK 或 Host,而不是协议?
  4. 哪些安全决策仍属于应用策略?

2025 年的版本引入了重要的远程和授权概念,包括 Streamable HTTP 和更明确的 Protected Resource 流程。本文讨论的 2025-03-26 是历史固定版本,文末一手来源链接指向较晚的 2025-11-25 规范;部署时必须选择并固定一个精确版本。任何版本都没有让 Tool Annotation、Discovery Metadata、Registry、Schema 或模型拒答成为授权边界。本文讲的是迁移方法,不声称所有 Client 都支持所有能力。

正确阅读规范变更

实现前先给每条结论分类:

类别 含义 实现决策
Normative Protocol 固定 MCP 版本要求的行为 实现并运行一致性测试
Optional Capability 只有协商后才可使用 声明 Capability 并测试
Authorization Profile OAuth/Resource Server 行为 配置 Issuer、Audience/Resource、Scope 和 Key Rotation
SDK Behavior Library 特有 API 或兼容行为 固定版本并检查测试
Host Convention UI、审批或模型集成 不能当作 Server 授权
Ecosystem Service Registry、Catalog、Gateway 或厂商产品 执行来源和生命周期治理

这样可以避免把示例、SDK 便利方法或 Host 功能误读成所有实现都必须具备的协议保证。

版本差异矩阵

规范版本核对时至少回答:

表面 要回答的问题
Lifecycle Initialization、Notification 或 Capability 是否变化?
Transport 使用 stdio、当前 Streamable HTTP 还是兼容旧路由?
Session 谁生成 ID,如何绑定,如何重连?
Authorization 适用哪些 Metadata、Issuer、Resource、Scope 和 Token Profile?
Tools 支持哪些 Annotation、Structured Result、Pagination 和取消?
JSON-RPC 两端是否支持同样的 Notification、Error、Correlation 和 Batch 行为?
Compatibility 哪些旧 Client 需要 Adapter 或独立路由?

不要用时间线替代矩阵。发布日期不能证明某个 Client、SDK 或 Provider 已实现该能力。

Remote HTTP 与旧式 SSE

旧式 HTTP+SSE 通常使用 Server→Client 事件流和独立消息端点。当前 Streamable HTTP Profile 可以在一个 MCP Endpoint 上按规范处理请求、响应和流式行为。

迁移不只是改 URL:

  • 固定支持的 Content-Type 和响应形状;
  • 保留 JSON-RPC Request ID 和取消;
  • 将 Session 绑定到已认证 Principal 和 Tenant;
  • 明确请求是无状态还是依赖 Session;
  • 只有在 Profile 支持时才测试 Last-Event-ID 或等价恢复行为;
  • 验证 Proxy Buffering、空闲超时和优雅 Drain;
  • 旧 Client 无法迁移时,保留明确标注的兼容路由。

不要把旧式 SSE 称为“MCP 的流式协议”,也不要认为单端点自动提供双向或可恢复语义;这些是 Profile 和实现行为。

Authorization:OAuth 不是捷径

远程 MCP 需要可信的调用者身份和 Protected Resource 策略。具体 Authorization Profile 可能根据拓扑和版本使用 OAuth Metadata、Resource Indicator、PKCE、Bearer Token 或 Workload Identity。

Resource Server 仍需:

  1. 校验可信 Issuer 和目标 Audience/Resource;
  2. 校验签名、Algorithm、Expiry、Not-Before、Key Rotation 和时钟策略;
  3. 将 Provider Claims 映射为内部 Principal;
  4. 每次操作检查 Scope 和 Tenant Policy;
  5. 授权精确对象和副作用;
  6. 从 Telemetry 中脱敏 Token 和敏感 Claims。

不要在没有引用精确 Authorization Profile 的情况下写“所有 MCP Client 都强制 OAuth 2.1”。也不要在示例中用应用 Secret 签发 Token,就把它称作生产 OAuth Authorization Server。

动态客户端注册

动态注册可以减少公开 Client 的手工配置,但也会创建完整的客户端生命周期:

  • 谁可以注册;
  • 接受哪些 Redirect URI;
  • 本地和生产 Redirect 如何区分;
  • Registration 如何过期和撤销;
  • Client Metadata 如何审核;
  • Tenant 如何选择;
  • Secret 和 Token 如何存储。

如果 Authorization Server 不支持或不允许动态注册,应使用受控 Provisioning 流程。注册不是访问 Tenant 或 Tool 的授权。

Tool Annotation 是 Hint

Annotation 可以帮助 Host 展示风险或选择确认 UI:

Hint 可能表达什么 不能证明什么
Read-Only 预期不修改外部状态 实际行为或对象访问
Destructive 预期有高影响变更 这次调用是否被授权
Idempotent 预期重复行为 超时后的持久幂等性
Open-World 预期与外部实体交互 安全性或目标可信

Server 必须执行它声明的行为。过期或恶意 Descriptor 可以撒谎,部署升级后 Tool 行为也可能与描述不一致。

JSON-RPC 与可选能力

使用可选 JSON-RPC 行为前,必须确认两端支持:

  • Request 和 Notification 语义;
  • Error Code 和 data
  • Request ID 与乱序响应;
  • Cancellation;
  • Structured 或分页 Result;
  • 如果规范和 SDK Profile 确实支持,再使用 Batch。

除非精确规范明确要求且 SDK 通过一致性测试,不要声称所有 MCP 实现都必须接受任意 JSON-RPC Batch。Batch 还需要逐项授权、大小限制、顺序规则和部分失败语义。

安全迁移步骤

1. Inventory

记录现有 Client、SDK、Server 版本、Transport、认证、Session、Tools、Resources、Prompts、副作用和 Proxy 行为。

2. Pin

固定目标 MCP 版本、Transport、Authorization Profile、SDK 版本和 Feature Flag,并写入仓库和部署清单。

3. 建立兼容矩阵

text
client x SDK x transport x authorization x capability

每个单元标记 Supported、Unsupported、需要 Adapter 或未测试。不要从产品名称或宣传页推断支持情况。

4. 迁移边界

在独立路由或部署后运行新 Transport。只有存在明确兼容需求时才保留旧路由,并确保两条路径使用相同的 Tenant 和对象授权。

5. 一致性与滥用测试

测试 Initialization、Capability、Tool Discovery、Resource Read、Prompt Retrieval、Cancellation、畸形消息、过期 Token、未知 Key、跨 Tenant 对象、虚假 Annotation、超大 Result、重连、重复副作用和 Proxy 行为。

6. Shadow 与回滚

使用脱敏 Fixture 对两条路径进行回放,比较 Protocol Event 和业务结果,不只比较 HTTP 状态。直到错误、延迟、成本和授权分布明确前,保留回滚路径。

迁移清单

json
{
  "mcp_revision": "pinned-revision",
  "transport_profile": "pinned-profile",
  "authorization_profile": "pinned-profile",
  "sdk": {
    "name": "pinned-sdk",
    "version": "pinned-version"
  },
  "compatibility_routes": [
    {"name": "legacy-transport", "expires": "review-date"}
  ],
  "features": {
    "annotations": true,
    "structured_results": true,
    "batch": false
  },
  "tests": {
    "conformance": "suite-id",
    "abuse": "suite-id",
    "replay": "fixture-version"
  }
}

清单本身不是安全策略,Runtime 和部署仍需执行其中的限制与授权决策。

Registry 与 Discovery 治理

Registry 或 Catalog 可以改善发现,但也会带来供应链问题:

  • 验证发布者身份和 Package 来源;
  • 尽可能固定 Server 版本和 Hash;
  • 审核声明的 Tools 和副作用;
  • 扫描依赖和部署权限;
  • 隔离凭证与网络外发;
  • 支持撤销、卸载和删除;
  • 将描述与 Resource 视为不可信内容。

自动安装是高权限操作。Catalog 条目不能证明 Server 安全,也不能证明其全部 Tool 都应该暴露。

测试矩阵

测试 预期不变量
版本不匹配 在使用 Capability 前失败
Transport 不支持 清晰协商或兼容错误
面向其他 Resource 的 Token 在 Tool 执行前拒绝
Scope 缺失或 Tenant 错误 拒绝且不泄露对象存在性
Annotation 与行为矛盾 Server Policy 优先
Result 超大 有界失败或授权 Artifact 引用
请求取消 下游停止或执行补偿
重复 Mutation 确定性幂等结果
节点故障后重连 不恢复未授权 Session
恶意 Tool Result 按不可信数据处理

常见误读

  • “Streamable HTTP 替代所有 SSE。” 它改变当前 Profile,兼容路由仍可能存在。
  • “PKCE 认证用户。” PKCE 绑定 Authorization Code 交换,Token 和 Resource 授权是另一层。
  • “Annotation 驱动权限。” Annotation 是 Hint,Server 执行 Policy。
  • “Schema 防住注入。” Schema 约束形状,不约束意图、所有权或 Result 内容。
  • “Registry 自带信任。” Discovery 和安装需要供应链治理。
  • “Client 支持某版本就支持全部能力。” 仍需 Capability 和版本矩阵。

生产检查清单

  • [ ] 固定 MCP、Transport、Authorization Profile 和 SDK。
  • [ ] 区分规范要求、可选 Capability 与 Host 约定。
  • [ ] 记录 Host、Client、Server、外部系统和信任边界。
  • [ ] 校验 Issuer、Audience/Resource、Algorithm、Expiry、Scope 和 Key Rotation。
  • [ ] 将 Session 绑定到已认证 Principal 和 Tenant。
  • [ ] 将 Annotation、Descriptor、Resource 和 Result 视为不可信数据。
  • [ ] 测试取消、重连、重复投递、可选 Batch 和 Proxy 行为。
  • [ ] 隔离兼容路由并安排复审时间。
  • [ ] 治理 Registry 来源、版本、凭证、外发和删除。

常见问题

2025-03-26 是当前 MCP 规范吗?

它是一个版本。应固定部署实际使用的版本并阅读对应官方文档;后续版本和 SDK 可能改变行为。

每个 MCP 部署都必须 OAuth 2.1 和动态注册吗?

不必须。要求取决于 Authorization Profile 和拓扑。动态注册是 Client 生命周期能力,不是权限授予。

Tool Annotation 是安全控制吗?

不是。它是给 Host 的行为提示,Server 侧身份、Tenant、对象、Purpose 和副作用策略才是权威。

Streamable HTTP 会自动完成迁移吗?

不会。必须用真实 Client 测试 Transport、Session、取消、重连、授权、Proxy 和重复投递。

Registry 属于 MCP 核心吗?

不是通用信任边界。它是需要来源和生命周期治理的生态或部署服务。

总结

规范升级最安全的方式,是让每条结论都带有版本和边界。固定 MCP 版本,选择 Transport 与 Authorization Profile,核对真实 SDK 支持,并把应用 Policy 留在描述性 Hint 之外。只有一致性、安全、兼容、回滚和数据治理证据都通过,迁移才算完成。

一手来源