一、改版规模:一份可核对的事实表
下面这张表把本次规范更替的关键事实集中列出,每条都能追溯到公开 URL,方便你在评审或对外说明时引用。
| 事实项 | 取值 | 来源 |
|---|---|---|
| 规范版本 | 2026-07-28 | 官方规范页 modelcontextprotocol.io/specification/2026-07-28 |
| 上一修订版本 | 2025-11-25 | changelog 首句"changes since the previous revision, 2025-11-25" |
| 协议核心 | Stateless、self-contained requests、per-request capability negotiation | 规范页 Overview / Base Protocol |
| 消息格式 | JSON-RPC 2.0 | 规范页 Base Protocol |
| Major changes | 9 项 | changelog "Major changes" 段 |
| Minor changes | 12 项 | changelog "Minor changes" 段 |
| Deprecated | 4 项 | changelog "Deprecated" 段 |
| 治理更新 | 特性生命周期与弃用策略(Active/Deprecated/Removed,最少 12 个月弃用窗口) | changelog "Governance and process updates" |
| 权威 schema | TypeScript 优先,同时提供 JSON Schema | github.com/modelcontextprotocol/specification README |
| 协议要素 | Host / Client / Server;Server 提供 Resources/Prompts/Tools,Client 可提供 Elicitation | 规范页 Architecture |
规范 GitHub 仓库(modelcontextprotocol/specification)以 MIT 协议开源,schema 以 TypeScript 优先定义并同步生成 JSON Schema,便于非 TS 生态消费。本文不引用 star 数等动态指标,因为它们随时间变化且本次未在仓库页直接核对到确切数值。
图 1:从有状态握手到无状态自描述请求的协议形态转变(示意图,非运行时截图)
二、破坏性变更一:去掉 initialize 握手,请求自描述
变更核心来自 changelog Major changes 第 2 条(SEP-2575):MCP 转为无状态,移除initialize/notifications/initialized握手。每个请求现在必须把协议版本和客户端能力放进_meta,并由客户端在每次请求里声明自己。
在2025-11-25及更早的实现里,连接生命周期大致是:客户端先发initialize请求,附带protocolVersion与capabilities,服务端在响应里回填自身能力,客户端再发notifications/initialized表示就绪,之后双方共享一个会话上下文。2026-07-28把这套握手整体取消,改为"每个请求自带身份"。
按 Architecture 页的描述,客户端在每次请求的_meta.io.modelcontextprotocol/clientCapabilities中声明能力,服务端在响应的_meta.io.modelcontextprotocol/serverInfo中声明自己。结合 changelog,一次请求的_meta结构示意如下:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "search", "arguments": { "query": "mcp 2026-07-28" } }, "_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientInfo": { "name": "demo-client", "version": "1.0.0" }, "io.modelcontextprotocol/clientCapabilities": { "tools": {}, "elicitation": {} } } }上面这段 JSON 是依据 changelog 字段描述与 Architecture 页"clients include their capabilities in_metaon every request"整理的示意结构,便于理解字段归属;具体字段是否必填、是否还需扩展,以官方 schema.ts 为准。版本不匹配时返回UnsupportedProtocolVersionError(Major changes 第 2 条)。
迁移含义很直接:任何依赖"先 initialize 再发请求"的客户端、任何在 initialize 响应里缓存能力并长期复用的实现,都要改成每请求携带能力。服务端则不能再假设"对面那个客户端已经 initialize 过了"。
三、破坏性变更二:Mcp-Session-Id 退场与 SSE 续传取消
这两条是 Streamable HTTP 传输层的硬变更,出自 changelog Major changes 第 1 条与第 9 条(均为 SEP-2575 体系):
- 协议级会话与
Mcp-Session-Id头被移除。tools/list、resources/list、prompts/list不再随连接变化;服务端若需要跨调用状态,必须用"显式、服务端签发、作为普通工具参数传递"的 handle 来承载(Major changes 第 1 条,SEP-2567)。 - SSE 流续传与消息重投被移除。即
Last-Event-ID头与 SSE event ID 不再支持。响应流一旦中断,正在进行的请求即丢失,客户端必须用新 request id 重发原请求(Major changes 第 9 条)。
同时,ping、logging/setLevel、notifications/roots/list_changed被移除(Major changes 第 5 条);日志级别改为按请求通过_meta.io.modelcontextprotocol/logLevel设置,且服务端不得为未带该字段的请求发送notifications/message。resources/subscribe/resources/unsubscribe与 HTTP GET 端点被subscriptions/listen取代(Major changes 第 4 条):客户端按toolsListChanged、promptsListChanged、resourcesListChanged、resourceSubscriptions等类型订阅,服务端用io.modelcontextprotocol/subscriptionId标记通知。
迁移含义:依赖Mcp-Session-Id做粘性路由的网关、依赖 SSELast-Event-ID做断线续传的客户端,都要重写。需要跨调用状态时,不要再借助会话,而是显式签发 handle 并通过工具参数回传。
四、server/discover:新的能力发现 RPC
变更出自 Major changes 第 3 条(SEP-2575):服务端必须实现server/discover,用于声明其支持的协议版本、能力与身份。客户端可在发起任何其他请求前调用它做"前置版本选择",也可在 STDIO 上把它当作向后兼容探测。
这填补了取消握手后留下的"怎么先探一下对方"的空缺:握手没了,但server/discover给了一个轻量的、可单次调用的发现入口。注意它是 MUST 实现,不是可选——新写的 server 必须提供这个 RPC。
五、MRTR 模式:替代 server-initiated requests
这是对存量代码冲击最大的一条。changelog Major changes 第 7 条(SEP-2322)引入 Multi Round-Trip Requests(MRTR)模式,替代旧的"服务端主动请求"做法。规范明确:服务端必须用 MRTR 来发送roots/list、sampling/createMessage、elicitation/create这类请求,旧的服务端主动请求模式不再支持,属破坏性变更。
流程上,客户端先发请求,服务端若需要更多信息就回一个InputRequiredResult(resultType: "input_required"),客户端收集到输入后用新的 request id 重发原请求,服务端据此完成。规范在 MRTR 页给了一个完整的InputRequiredResult示例,下面是其中关键结构(摘自官方规范页,已省略部分注释):
{ "jsonrpc": "2.0", "id": 1, "result": { "resultType": "input_required", "inputRequests": { "github_login": { "method": "elicitation/create", "params": { "mode": "form", "message": "Please provide your GitHub username", "requestedSchema": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"] } } } }, "requestState": "AEAD-protected blob" } }inputRequests的 key 由服务端分配,value 必须是ElicitRequest、CreateMessageRequest或ListRootsRequest之一。客户端重试时把inputResponses与原样回传的requestState一起带上。规范对requestState有明确的安全要求(MRTR 页"Server Requirements"):
- 客户端必须原样回传
requestState,不得解析、修改或对其内容做任何假设;不带时不得自行添加。 - 服务端必须把
requestState视为攻击者可控输入。若它影响授权、资源访问或业务逻辑,必须用 HMAC 或 AEAD 保护完整性,并拒绝校验失败的状态。 - 为防重放,服务端应在受完整性保护的
requestState中携带:已认证主体、短有效期 TTL、原始请求标识(方法名与关键参数摘要)。
另外,Major changes 第 8 条(SEP-2322)规定:所有结果现在都必须带resultType字段,普通结果为"complete",MRTR 中间结果为"input_required";客户端必须把不带该字段的旧版本结果视为"complete"。MRTR 仅允许出现在prompts/get、resources/read、tools/call三类请求上。
迁移含义:以前用sampling/createMessage、elicitation/create、roots/list做服务端主动请求的实现,都要改写成"返回InputRequiredResult→ 客户端重试"的回合制;任何在服务端内存里持有"这个会话正在等输入"的状态机,都要迁到requestState自包含的形态。
六、Tasks 移出核心,成为官方扩展
变更出自 Major changes 第 6 条(SEP-2663):实验性 tasks 从核心协议移出,成为官方扩展io.modelcontextprotocol/tasks。重新设计后的扩展做了几件事:
- 用
tasks/get轮询取代原先阻塞的tasks/result; - 新增
tasks/update用于客户端到服务端的输入; - 移除
tasks/list; - 允许服务端在无需每请求 opt-in 的情况下,主动返回 task handle。
规范页在 Extensions 段把 Tasks 描述为"异步执行长耗时操作,支持轮询、中途输入与持久化 handle"。迁移含义:把 Tasks 当核心能力直接调用的旧实现,要改成声明扩展支持、走tasks/get/tasks/update的新路径。这也是2026-07-28"核心瘦身、能力外移到 extensions"思路的一个缩影——ClientCapabilities与ServerCapabilities新增了extensions字段(Minor changes 第 1 条)来承载这种可选扩展协商。
七、三大弃用:Roots / Sampling / Logging 的迁移路径
changelog Deprecated 第 1 条(SEP-2577)把 Roots、Sampling、Logging 三个特性标记为弃用。它们在弃用窗口内仍可用,但新实现不应再新增支持。官方给出了明确的迁移建议:
| 弃用特性 | 官方建议的替代做法 |
|---|---|
| Roots | 改用工具参数、resource URI 或服务端配置来传递目录或文件 |
| Sampling | 直接对接 LLM provider API,而不是经由 MCP Sampling |
| Logging | 在 stdio 下输出到stderr,或改用 OpenTelemetry |
此外还有两条相关的弃用:HTTP+SSE 传输被重分类为 Deprecated(Deprecated 第 2 条,SEP-2596),应迁移到 Streamable HTTP;includeContext的"thisServer"/"allServers"取值被重分类为 Deprecated(Deprecated 第 3 条),建议省略该字段或使用"none"。OAuth 2.0 Dynamic Client Registration(RFC7591)作为客户端注册机制被弃用,改用 Client ID Metadata Documents(Deprecated 第 4 条,PR #2858)。
结合治理策略(最少 12 个月弃用窗口),这意味着你有大约一年的缓冲期,但新写的代码现在就应按替代方案走。
八、值得顺手记下的 Minor 变更
下面几条 Minor 虽不破坏二进制兼容,但影响新代码写法,建议在迁移时一并处理:
- 标准请求头(SEP-2243):Streamable HTTP POST 必须带
Mcp-Method、Mcp-Name标准头,并支持通过x-mcp-header从工具参数注入自定义头。 - 可缓存结果(SEP-2549):
tools/list、prompts/list、resources/list、resources/read、resources/templates/list的结果必须带ttlMs与cacheScope("public"/"private"),作为新鲜度提示供客户端缓存、减少轮询。 - 工具列表确定性顺序:服务端应使
tools/list返回顺序确定,以利于客户端缓存并提升 LLM prompt cache 命中率。 - OpenTelemetry trace 上下文(SEP-414):
_meta约定traceparent、tracestate、baggage键用于链路追踪上下文传播。 - 错误码分区:
-32000至-32019留给实现自定义(既有 SDK 用法 grandfathered),-32020至-32099保留给规范。本次引入的HeaderMismatch、MissingRequiredClientCapability、UnsupportedProtocolVersion被重编号为-32020/-32021/-32022,资源未找到错误由-32002改为-32602(Invalid Params)以对齐 JSON-RPC。
九、迁移检查清单
把上面的变更落到代码上,可以按下面这张清单逐项核对。
| 迁移项 | 旧做法 | 新做法 | 依据 |
|---|---|---|---|
| 连接握手 | 先 initialize 再发请求 | 每请求在_meta带协议版本、clientInfo、capabilities | SEP-2575 |
| 会话路由 | 依赖Mcp-Session-Id | 跨调用状态用显式服务端 handle 经工具参数传递 | SEP-2567 |
| 断线续传 | SSELast-Event-ID续传 | 流断开后用新 request id 重发原请求 | SEP-2575 |
| 心跳/日志 | ping、logging/setLevel | 按请求_meta.io.modelcontextprotocol/logLevel | SEP-2575 |
| 资源订阅 | resources/subscribe | subscriptions/listen单流,按类型订阅 | SEP-2575 |
| 服务端主动请求 | 直接发roots/list等 | 返回InputRequiredResult,客户端重试 | SEP-2322 |
| 结果标记 | 无resultType | 所有结果带resultType(complete/input_required) | SEP-2322 |
| 能力发现 | initialize 响应里读 | server/discover(MUST 实现) | SEP-2575 |
| 长任务 | Tasks 在核心协议 | 走io.modelcontextprotocol/tasks扩展,tasks/get/tasks/update | SEP-2663 |
| Roots | 用 Roots 传目录/文件 | 改用工具参数、resource URI、服务端配置 | SEP-2577 |
| Sampling | 经 MCP Sampling 调 LLM | 直接对接 LLM provider API | SEP-2577 |
| Logging | 用 Logging 特性 | stdio 下写stderr,或用 OpenTelemetry | SEP-2577 |
| HTTP 传输 | HTTP+SSE | Streamable HTTP | SEP-2596 |
十、限制与说明
为避免把"规范说的"和"实测出来的"混在一起,这里把本文的边界说清楚:
- 本文所有特性描述均来自 MCP 官方规范页与
2026-07-28changelog,以及规范 GitHub 仓库 README,未对任何具体 SDK 做运行时验证。具体行为、字段是否必填、边界情形,以官方schema.ts与各 SDK 实现为准。 - 文中给出的请求
_metaJSON 为依据 changelog 字段描述整理的示意结构,目的是说明字段归属,不保证与某 SDK 序列化结果逐字节一致;MRTR 的InputRequiredResult示例摘自官方规范页。 - 本文不引用 star 数、用户数、benchmark、commit 数等动态或未核对指标;规范 GitHub 仓库页未直接显示确切的 star 数值,故不写。
- 文中配图为说明性示意图,标注为 diagram,不作为运行时证据。
- 选题时间说明:
2026-07-28规范距本文撰写日约 8 天,略超出"最近 7 天"窗口,属最近 30 天内的真实热点,故按降级规则在 INDEX 中说明后采用。
项目链接
- 官方规范(2026-07-28):Specification - Model Context Protocol
- 完整变更日志:Key Changes - Model Context Protocol
- MRTR 模式说明:Multi Round-Trip Requests - Model Context Protocol
- 架构说明:Architecture - Model Context Protocol
- 规范仓库(含 schema.ts):GitHub - modelcontextprotocol/modelcontextprotocol: Specification and documentation for the Model Context Protocol · GitHub
- 版本对比:Comparing 2025-11-25...2026-07-28 · modelcontextprotocol/modelcontextprotocol · GitHub