一、改版规模:一份可核对的事实表

下面这张表把本次规范更替的关键事实集中列出,每条都能追溯到公开 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 请求,附带 protocolVersioncapabilities,服务端在响应里回填自身能力,客户端再发 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 _meta on 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/listresources/listprompts/list 不再随连接变化;服务端若需要跨调用状态,必须用"显式、服务端签发、作为普通工具参数传递"的 handle 来承载(Major changes 第 1 条,SEP-2567)。
  • SSE 流续传与消息重投被移除。即 Last-Event-ID 头与 SSE event ID 不再支持。响应流一旦中断,正在进行的请求即丢失,客户端必须用新 request id 重发原请求(Major changes 第 9 条)。

同时,pinglogging/setLevelnotifications/roots/list_changed 被移除(Major changes 第 5 条);日志级别改为按请求通过 _meta.io.modelcontextprotocol/logLevel 设置,且服务端不得为未带该字段的请求发送 notifications/messageresources/subscribe / resources/unsubscribe 与 HTTP GET 端点被 subscriptions/listen 取代(Major changes 第 4 条):客户端按 toolsListChangedpromptsListChangedresourcesListChangedresourceSubscriptions 等类型订阅,服务端用 io.modelcontextprotocol/subscriptionId 标记通知。

迁移含义:依赖 Mcp-Session-Id 做粘性路由的网关、依赖 SSE Last-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/listsampling/createMessageelicitation/create 这类请求,旧的服务端主动请求模式不再支持,属破坏性变更。

流程上,客户端先发请求,服务端若需要更多信息就回一个 InputRequiredResultresultType: "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 必须是 ElicitRequestCreateMessageRequestListRootsRequest 之一。客户端重试时把 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/getresources/readtools/call 三类请求上。

迁移含义:以前用 sampling/createMessageelicitation/createroots/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"思路的一个缩影——ClientCapabilitiesServerCapabilities 新增了 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-MethodMcp-Name 标准头,并支持通过 x-mcp-header 从工具参数注入自定义头。
  • 可缓存结果(SEP-2549):tools/listprompts/listresources/listresources/readresources/templates/list 的结果必须带 ttlMscacheScope"public" / "private"),作为新鲜度提示供客户端缓存、减少轮询。
  • 工具列表确定性顺序:服务端应使 tools/list 返回顺序确定,以利于客户端缓存并提升 LLM prompt cache 命中率。
  • OpenTelemetry trace 上下文(SEP-414):_meta 约定 traceparenttracestatebaggage 键用于链路追踪上下文传播。
  • 错误码分区-32000-32019 留给实现自定义(既有 SDK 用法 grandfathered),-32020-32099 保留给规范。本次引入的 HeaderMismatchMissingRequiredClientCapabilityUnsupportedProtocolVersion 被重编号为 -32020 / -32021 / -32022,资源未找到错误由 -32002 改为 -32602(Invalid Params)以对齐 JSON-RPC。

九、迁移检查清单

把上面的变更落到代码上,可以按下面这张清单逐项核对。

迁移项 旧做法 新做法 依据
连接握手 先 initialize 再发请求 每请求在 _meta 带协议版本、clientInfo、capabilities SEP-2575
会话路由 依赖 Mcp-Session-Id 跨调用状态用显式服务端 handle 经工具参数传递 SEP-2567
断线续传 SSE Last-Event-ID 续传 流断开后用新 request id 重发原请求 SEP-2575
心跳/日志 pinglogging/setLevel 按请求 _meta.io.modelcontextprotocol/logLevel SEP-2575
资源订阅 resources/subscribe subscriptions/listen 单流,按类型订阅 SEP-2575
服务端主动请求 直接发 roots/list 返回 InputRequiredResult,客户端重试 SEP-2322
结果标记 resultType 所有结果带 resultTypecomplete / 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-28 changelog,以及规范 GitHub 仓库 README,未对任何具体 SDK 做运行时验证。具体行为、字段是否必填、边界情形,以官方 schema.ts 与各 SDK 实现为准。
  • 文中给出的请求 _meta JSON 为依据 changelog 字段描述整理的示意结构,目的是说明字段归属,不保证与某 SDK 序列化结果逐字节一致;MRTR 的 InputRequiredResult 示例摘自官方规范页。
  • 本文不引用 star 数、用户数、benchmark、commit 数等动态或未核对指标;规范 GitHub 仓库页未直接显示确切的 star 数值,故不写。
  • 文中配图为说明性示意图,标注为 diagram,不作为运行时证据
  • 选题时间说明:2026-07-28 规范距本文撰写日约 8 天,略超出"最近 7 天"窗口,属最近 30 天内的真实热点,故按降级规则在 INDEX 中说明后采用。

项目链接

Logo

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

更多推荐