第 3 章 协议版本演进与兼容

本章导读:网上大量 MCP 教程停留在 2025 年中的协议形态——2026-07-28 之后就过时了,照抄会踩坑。这一章把五个版本串成一条线:每个版本解决了什么问题、留下了什么债,以及最重要的——存量 Server 怎么迁到 latest。理解了演进,第 2 章的无状态模型就不再是「凭空的设计」,而是三次还债的结果。读完本章,你能:说出五个版本的发布时间线与各自主题;解释 2026-07-28 九大变更为什么发生;用七格兼容矩阵判断任意新旧组合的行为;按八步清单规划存量 Server 的迁移。

flowchart LR A["困惑
教程互相矛盾/新旧混跑"] --> B["版本演进与兼容
五版本 · 九大变更 · 七格矩阵"] B --> C["时间线
2024-11 → 2026-07 五版主题"] B --> D["2026-07-28 九大变更
无状态/MRTR/缓存/授权/弃用"] B --> E["七格兼容矩阵
Modern/Legacy/Dual-era"] B --> F["迁移八步
会话→meta→MRTR→授权"] C --> G["收益
选型有据 · 迁移有路
旧教程免疫"] D --> G E --> G F --> G

本章导览图

你什么时候需要它

接手了一个「不知道什么年代」的 MCP Server——先看 3.4 的七格矩阵与 3.3 的版本协商:跑一次 server/discover 或发一个带版本的请求,它属于哪一格、该怎么处理,立刻清楚。

要规划存量 Server 升级到 2026-07-28——直接看 3.5 的八步清单,每步对应官方 changelog 条目。

评估网上教程/文章是否可用——看 3.1 的五版时间线:任何未标注 spec 版本日期的 MCP 材料,默认按 2025 年中形态理解,对照后再用。

前置:第 2 章的 Modern 模型(_meta、discover、resultType)——本章讲它们「怎么来的」。

概述:五版时间线与官方术语

flowchart LR V1["2024-11-05
初版
stdio+SSE·握手"] --> V2["2025-03-26
Streamable HTTP
取代 SSE"] V2 --> V3["2025-06-18
OAuth 2.1
elicitation"] V3 --> V4["2025-11-25
一周年大版
Tasks/CIMD/extensions"] V4 --> V5["2026-07-28
无状态重构
MRTR/缓存/发现"]

官方术语(后文全程沿用):

五个版本,一条主线

2024-11-05(初版):stdio + HTTP+SSE 双传输;initialize 握手建立会话;tools/resources/prompts 三类能力成型。确立了「模型上下文」的协议骨架——后来所有版本都在还这一版「有状态」欠下的债:每个 Server 都要管会话,服务化困难。

2025-03-26:Streamable HTTP 取代 HTTP+SSE。SSE 的单向流 + 会话粘性难以服务化,传输层先向「普通 HTTP 服务」靠拢。信号明确:Server 要进生产。

2025-06-18:安全规范化。Server 正式定位为 OAuth 2.1 Resource Server;elicitation(Server 向用户收集输入)进入核心。规范化是起点,离「企业敢用」还有距离——下一版补课。

2025-11-25(协议一周年):企业化补课——

2026-07-28(无状态重构,破坏性):下一节专述。

2026-07-28 九大变更逐条读

官方 changelog 的 Major changes 九条,按主题归组(每条标注 SEP 编号可溯源):

组一:状态之死(SEP-2567、SEP-2575)

组二:交互与订阅重构(SEP-2322、SEP-2575)

组三:缓存一等公民(SEP-2549)

tools/list、prompts/list、resources/list、resources/read、resources/templates/list 的结果必须带 ttlMs(新鲜度)与 cacheScope(public/private);tools/list 返回确定性顺序——为 client 缓存与 LLM prompt cache 命中率。无状态协议没有会话可「记住」目录,缓存成为目录分发的正统机制。

组四:断流语义简化(SEP-2575)

移除 SSE 断流恢复与消息重投(Last-Event-ID):响应流断了,进行中的请求即丢失,client 必须以新 ID 重发。用复杂度换简单性——Server 不再需要事件重放缓冲。

组五:长任务转正为扩展(SEP-2663)

实验性 Tasks 移出核心,成为扩展 io.modelcontextprotocol/tasks,并重新设计:tasks/result 阻塞方法改为 tasks/get 轮询;新增 tasks/update 供 client 中途输入;移除 tasks/list;Server 可不经请求主动返回任务句柄。

弃用清单(Deprecated,12 个月窗口后移除)

弃用项 迁移建议
Roots(client 告知可访问目录) 目录/文件经工具参数、资源 URI 或 Server 配置传入
Sampling(借 Host 模型推理) 直接对接 LLM provider API
Logging(协议内建日志) stderr(stdio) 或 OpenTelemetry
HTTP+SSE 传输(2025-03-26 起废) Streamable HTTP
OAuth DCR(RFC 7591) 注册机制 CIMD(保留对旧 AS 的兼容)
includeContext 的 thisServer/allServers 省略或 none

这是全书最重要的迁移事实:Roots/Sampling/Logging 三个 v1 核心特性整体进入弃用——新实现不应再添加对它们的支持。

授权收紧(SEP-2468、SEP-837、SEP-2352)

其他值得知道的

版本协商:每请求声明 + 探针

无握手之后,「你说哪个版本」变成每请求的事:

  1. 每个请求在 _meta 声明 protocolVersion(HTTP 上另有 MCP-Protocol-Version 头,两者必须一致,第 8 章)
  2. Server 不支持时返回 -32022,data.supported 列出支持的版本:
    { "error": { "code": -32022, "message": "Unsupported protocol version",
      "data": { "supported": ["2026-07-28", "2025-11-25"], "requested": "2025-06-18" } } }
    
  3. client 从 supported 里选双方都支持的版本重试,或报错给人
  4. 想提前知道?先调 server/discover(可选,但接入前值得)

七格兼容矩阵:官方版

versioning 规范给出的完整矩阵(client × server 的 era 组合),比「新旧兼容」的笼统说法精确得多:

Client \ Server Modern Legacy Dual-era
Modern ✅ discover 可选;版本不匹配吃 -32022 后换版本重试 ❌ 失败——server 可能报实现自定义错误、沉默、甚至按 legacy 语义错误处理;stdio 上 client 应先 server/discover 确定性失败 ✅ client 保持 modern
Dual-era ✅ 探针返回 DiscoverResult 或 -32022 → 保持 modern ✅ 探针失败/超时 → 回退 initialize(HTTP 上可能再退到已废 HTTP+SSE) ✅
Legacy ❌ 失败——initialize 对 modern server 是未知方法且缺 _meta 必填;legacy client 没有前向机制 ✅ 按旧版语义 ✅ server 应答 initialize 并按协商的旧版本服务

三条工程结论:

  1. Dual-era Server 是迁移期的答案:按 client 的开场分流——带现代 _meta 的请求按新规范无状态服务;initialize 请求按协商的旧版本走 legacy 语义;同一端点可同时服务两代。TS SDK v2.4.0 实测(第 4 章):serveStdio 的 legacy: 'serve'(默认)应答旧握手,'reject' 拒绝并报支持的现代版本
  2. Modern client 连 Legacy Server 是最危险的格子:可能静默错误处理。规范因此规定 stdio 上 client 应先发 server/discover 探针——错误形态可识别(modern)则保持 modern,否则确定性回退
  3. Legacy client 无法前向:纯 modern Server 对 initialize 的报错里应列出支持的版本——那可能是 legacy 用户唯一能看到的诊断

Era 判定缓存于 Server 进程(stdio)/源(HTTP)生命周期,可跨重启保留、失效再重探。

存量迁移:八步清单

按序执行(每步对应 changelog 条目):

  1. 删握手与会话:移除 initialize/会话管理/Mcp-Session-Id;跨调用状态改用 Server 签发的显式句柄作为普通工具参数(SEP-2567,第 6 章句柄模式)
  2. _meta 每请求声明:协议版本必填、能力必填、身份建议带
  3. 交互改 MRTR:原 server→client 请求改写为 inputRequests;注意 Sampling/Roots 本身已弃用,优先直接迁到替代方案
  4. 长任务:Tasks 用法迁到扩展(轮询制),或自建异步+轮询工具对(第 7 章贯穿案例选后者,协议面更薄)
  5. 订阅改 listen:resources/subscribe 等迁到 subscriptions/listen;删 ping/setLevel 调用;日志级别走 _meta
  6. 缓存:list/read 结果补 ttlMs/cacheScope;tools/list 排序确定化
  7. 授权:client 加 iss 校验;消费端身份迁 CIMD;凭据按 issuer 键控
  8. 双代过渡:legacy 入口开启灰度,新旧 client 并行后收紧

选型建议

本章小结

  1. 主线:初版有状态 → 传输规范化 → 安全规范化 → 企业化补课 → 无状态重构。
  2. 九大变更四组:状态之死(会话/握手/discover)、交互重构(MRTR/listen/resultType)、缓存一等公民、授权收紧;另有 Roots/Sampling/Logging 整体弃用。
  3. 七格矩阵:Dual-era 是迁移期的桥;legacy client 无前向机制。
  4. 迁移八步:会话、meta、交互、长任务、订阅、缓存、授权、双代过渡。
  5. 选型:新项目 latest;存量按清单;外源教程先对版本。

→ 协议与生产的主体(第 2、4-8 章)完整;第 12 章谈组织与路线。

验收清单

读到这里,你应该能:

参考速查

项 值
版本时间线 2024-11-05 → 2025-03-26 → 2025-06-18 → 2025-11-25 → 2026-07-28(latest)
版本声明 _meta.io.modelcontextprotocol/protocolVersion(每请求);HTTP 头 MCP-Protocol-Version
版本不匹配 -32022 + data.supported 清单 → client 换版本重试
探针 server/discover(Server 必须实现;client 可选)
时代术语 Modern(2026-07-28+)/Legacy(≤2025-11-25)/Dual-era
弃用三特性 Roots / Sampling / Logging(12 个月窗口)
生命周期 Active / Deprecated / Removed;弃用窗最少 12 个月
错误码分区 -32000~-32019 legacy 区;-32020~-32099 规范保留区(HeaderMismatch/ MissingRequiredClientCapability/UnsupportedProtocolVersion)

延伸阅读

复核清单(发布前)