Skip to main content

MCP 2.0 深度解析:2026-07-28 无状态协议、完整差异与实战指南

Rainy
雨落无声,代码成诗 —— 致力于技术与艺术的极致平衡
Rainy
25 MIN READ... VIEWS

MCP 2026-07-28 技术架构:Host 内多个 Client 分别连接提供 Tools、Resources 与 Prompts 的 Server

2026 年 7 月 28 日发布的 Model Context Protocol 最新规范 不是一次普通增量更新。它移除了协议级会话和初始化握手,把版本与能力协商移到每一个请求,用 MRTR 重构服务器向客户端索取信息的方式,并将长任务移出核心协议。

如果把早期 MCP 看成“为桌面 AI 应用连接本地工具的会话协议”,那么这次修订更像是“可穿过网关、负载均衡器和无状态计算平台的 Agent 基础设施协议”。

先澄清版本名称

MCP 官方使用日期作为协议版本,例如 2025-11-252026-07-28官方没有发布名为 MCP 1.0MCP 2.0 的语义化版本

为方便理解,本文将官方称为 Legacy2025-11-25 及更早版本简称为“MCP 1.0”,将官方称为 Modern2026-07-28 版本简称为“MCP 2.0”。这是社区化表达,不是官方版本名。生产代码必须使用日期版本。


一、先看结论:MCP 2.0 改变了什么?

一句话概括:

MCP 2.0 把协议状态从“连接和会话”搬进了“每个请求、显式参数和可验证句柄”。

最重要的变化有九类:

  1. 删除 initialize / notifications/initialized 握手。
  2. 删除协议级 Session 和 Mcp-Session-Id
  3. 每个请求通过 _meta 携带版本、客户端身份和能力。
  4. 新增服务器必须实现的 server/discover
  5. 用 MRTR 的 input_required 结果替代服务器主动反向请求。
  6. subscriptions/listen 统一承载长期变更通知。
  7. 所有成功结果必须有 resultType,普通结果为 complete
  8. 长任务从核心移到 io.modelcontextprotocol/tasks 官方扩展。
  9. 加入缓存提示、标准 HTTP 头、OpenTelemetry 上下文和更严格的授权规则。

Legacy MCP 与 Modern MCP 的架构差异:从持久会话走向自包含请求

这张图左侧表示 Legacy MCP:客户端先穿过初始化握手,随后依赖连接上的会话状态,双向请求和事件也共享长连接语境。右侧表示 Modern MCP:每个请求自带版本和能力,可以落到任意服务器实例;发现、请求级进度和长期订阅各自拥有清晰通道。


二、MCP 到底解决什么问题?

MCP 是连接 LLM 应用与外部数据、工具和工作流的开放协议。它使用 JSON-RPC 2.0 定义 Host、Client 和 Server 之间的交互,让 AI 应用不必为每一个数据库、代码仓库、SaaS 或本地工具单独设计插件协议。

2.1 三个核心角色

  • Host:LLM 应用和总协调者,管理用户授权、上下文聚合、多个 Client 与模型调用。
  • Client:Host 内部与一个特定 Server 通信的连接器;每个 Client 只对应一个 Server。
  • Server:提供聚焦能力的服务,可以是本地进程,也可以是远程 HTTP 服务。

安全边界非常重要:Server 默认不应看到完整对话,也不应看到其他 Server 的上下文。Host 决定把哪些信息交给哪个 Server。

2.2 Server 暴露的三类原语

原语控制者用途例子
Resources应用控制向模型提供可读取的上下文和数据文件、数据库记录、API 响应
Prompts用户控制提供可复用的提示模板和工作流入口代码审查模板、事故复盘模板
Tools模型控制允许模型在用户同意下执行动作查询、写文件、创建工单、部署

MCP 2.0 没有抛弃这三个核心原语,而是重新设计了承载它们的基础协议。


三、MCP 1.0 与 MCP 2.0 完整差异表

官方 Key Changes2026-07-28 与前一版 2025-11-25 的变化分为重大变化、次要变化和弃用项。下面按工程影响重新整理。

维度MCP 1.0 / Legacy(≤ 2025-11-25MCP 2.0 / Modern(2026-07-28工程影响
协议状态连接/会话承载状态协议无状态,每次请求自包含易于横向扩容和故障转移
初始化initializenotifications/initialized删除初始化握手首次请求不必绑定后续连接
SessionStreamable HTTP 可用 Mcp-Session-Id删除协议级 Session不再需要粘性会话
版本声明初始化时协商每个请求 _meta 都带版本请求可独立校验和路由
HTTP 版本头MCP-Protocol-Version 已存在于部分版本每个 POST 必须携带,且必须与 _meta 一致网关可快速拒绝错误版本
能力协商初始化时声明一次每个请求携带 Client capabilities能力按请求生效
服务器发现依赖初始化响应Server 必须实现 server/discover可预先发现版本、能力和身份
版本不兼容初始化失败或实现自定义处理标准 UnsupportedProtocolVersion,错误码 -32022客户端可选择共同版本后重试
服务端反向请求Server 可主动发 roots/list、Sampling、Elicitation禁止主动请求,改用 MRTR更适配无状态 HTTP 和负载均衡
多轮交互同一连接上的双向 JSON-RPCinput_required → Client 收集输入 → 新 ID 重试原请求每一轮可落到不同实例
成功结果结果没有统一判别字段所有结果必须包含 resultType支持 completeinput_required、扩展结果
普通成功任意结果对象resultType: "complete"客户端必须按结果类型分发
长任务Tasks 曾是核心实验能力移到 io.modelcontextprotocol/tasks 扩展核心更小,异步能力可独立演进
长任务取结果阻塞式 tasks/resulttasks/get 轮询,tasks/update 提交中途输入断线后可通过 task handle 恢复
长期通知HTTP GET 流、资源订阅 RPC 和连接事件混合单一 subscriptions/listen POST 响应流订阅意图明确,可按类型选择
资源订阅resources/subscribe / resources/unsubscribesubscriptions/listenresourceSubscriptions 替代统一通知模型
请求级通知与其他长流容易混合只走发起该请求的响应 SSEProgress/Logging 与请求严格关联
Streamable HTTP GET可建立独立 GET SSE 流删除 GET,只保留 POSTMCP Endpoint 更简单
SSE 恢复Last-Event-ID 和事件重放删除可恢复性与消息重发断流后用新 request ID 重发请求
Ping核心 ping删除存活检测交给传输和平台
日志级别logging/setLevel每请求 _meta.io.modelcontextprotocol/logLevel不再依赖连接级设置
日志通知Server 可持续发送只有请求明确带 logLevel 时才可发送降低意外数据泄露与噪声
Roots 变化通知notifications/roots/list_changed删除Roots 本身也进入弃用阶段
列表缓存客户端自行决定ttlMs + cacheScope 成为必需提示降低重复发现与 Token 成本
列表顺序未强调稳定排序Tools 应确定性排序提高 LLM Prompt Cache 命中率
HTTP 路由头中间件需解析 JSON Body必须有 Mcp-Method,部分请求必须有 Mcp-Name网关/WAF 可不解析 Body 即路由
工具参数转 Header无标准机制JSON Schema 支持 x-mcp-header可将区域、租户等参数镜像为 Header
JSON Schema约束较保守完整支持 JSON Schema 2020-12 关键字和 $ref工具输入输出表达力更强
Structured Content以对象为主可为任意 JSON 值数组、标量、null 都合法
可观测性实现自行约定_meta 约定 traceparenttracestatebaggage与 OpenTelemetry 链路贯通
扩展实验能力常进入核心Capabilities 新增 extensions 映射双方显式选择 Tasks、Apps 等扩展
OAuth Issuer规则较弱建议授权响应带 iss,Client 必须校验已出现的 iss防授权服务器混淆攻击
Client 凭证容易按 MCP Server 保存必须按 Authorization Server issuer 绑定禁止跨 Issuer 复用凭证
动态注册OAuth DCR 是主要路径之一DCR 弃用,转向 Client ID Metadata Documents更适合现代 OAuth 客户端发现
功能生命周期缺少统一退役机制Active → Deprecated → Removed,至少 12 个月弃用窗口迁移节奏更可预测

3.1 这不是“改几个字段”

旧实现常把初始化结果、能力、Session ID、订阅和反向请求绑定到一个连接对象。Modern MCP 要求这些假设全部拆开:

Legacy: Connection = Version + Capabilities + Session + Reverse Requests

Modern: Request = Version + Client Capabilities + Auth + Parameters
Server State = Explicit Handle / requestState / Task ID
Notifications = Dedicated subscriptions/listen Stream

因此,声称支持 2026-07-28 的实现不能只修改协议版本字符串。


四、核心变化详解

4.1 无状态:删除握手与协议 Session

Legacy 客户端首先发送 initialize,服务器返回选定版本、能力和实现信息,客户端再发送 notifications/initialized。Streamable HTTP 还可以用 Mcp-Session-Id 把后续请求绑定到同一会话。

Modern MCP 删除了整个流程。每个请求必须在 params._meta 中声明:

{
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "rainlib-client",
"version": "2.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {
"elicitation": {},
"extensions": {
"io.modelcontextprotocol/tasks": {}
}
}
}

这让负载均衡器可以把连续两次工具调用分配给不同实例。若业务本身需要跨调用状态,Server 应签发显式 handle,并让 Client 像普通工具参数一样回传,而不是偷偷依赖连接内存。

无状态不等于没有状态

协议不再提供隐式 Session,但业务仍然可以有任务、事务、游标和工作流状态。差别在于这些状态必须通过明确的 taskId、cursor、tool argument 或受保护的 requestState 表达。

4.2 server/discover:服务器能力的新入口

Modern Server 必须实现 server/discover。Client 可在其他请求前调用它,获取:

  • supportedVersions
  • capabilities
  • serverInfo
  • 可选的 instructions
  • ttlMscacheScope
{
"jsonrpc": "2.0",
"id": "discover-1",
"method": "server/discover",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "rainlib-client",
"version": "2.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}

Server 返回的 serverInfo 是自报信息,只适合展示、日志和调试,不能用于安全决策。Client 也可以跳过 discovery,直接调用目标 RPC;若版本不支持,Server 返回 -32022 和支持版本列表,Client 再选择共同版本重试。

4.3 MRTR:服务器不再主动“反向调用”客户端

Legacy MCP 中,Server 可以在处理 tools/call 时主动向 Client 发出 elicitation/createsampling/createMessageroots/list 请求。这要求双方保持可双向通信的活跃连接,也给代理和水平扩容增加了复杂度。

Modern MCP 引入 Multi Round-Trip Requests:Server 不主动发请求,而是返回“我还缺什么”。

MCP MRTR 多轮请求:input_required、用户输入、携带 requestState 的独立重试

流程如下:

  1. Client 用 JSON-RPC ID 1 发起 tools/call
  2. Server 返回 resultType: "input_required",其中包含 inputRequests 和可选 requestState
  3. Host 根据请求向用户收集信息、调用模型或提供 Roots。
  4. Client 用新的 JSON-RPC ID 2 重试原始 tools/call,附带 inputResponses,并原样回传 requestState
  5. 任意 Server 实例仅凭新请求即可继续处理,最终返回 resultType: "complete"

requestState 对 Client 是不透明字符串,Client 不得解析或修改。Server 必须把它当成攻击者可控输入;若它影响授权或业务逻辑,应使用 HMAC 或 AEAD 保护完整性,并绑定用户、短 TTL 和原始请求摘要。

4.4 subscriptions/listen:把长期通知放到专用流

Modern Streamable HTTP 只有一个支持 POST 的 MCP Endpoint:

长期变更通知只走 subscriptions/listen 的响应 SSE;notifications/progress 和按请求日志只走所属请求的响应流。两者不混用。

旧的 HTTP GET 流、resources/subscriberesources/unsubscribe 被替换。SSE 也不再支持 Last-Event-ID 恢复:请求流断开就视为本次请求丢失,Client 应使用新 ID 重新发起。

4.5 结果多态:resultType 成为必需字段

所有成功结果现在都必须带 resultType

resultType所属含义
completeCore请求已经完成
input_requiredCoreServer 需要 Client 补充输入并重试
taskTasks 扩展Server 已创建可持久化长任务

为了向后兼容,Modern Client 遇到旧 Server 返回的无 resultType 结果时,必须把它当作 complete。但 Modern Server 不能省略该字段。

4.6 Tasks:长任务成为正式扩展

Tasks 扩展 适用于 CI、批处理、部署、模型训练、人工审批等不应一直占用连接的操作:

Client 与 Server 都在 capabilities 中声明 io.modelcontextprotocol/tasks 后,Server 可返回 resultType: "task" 和持久化 taskId。Client 使用:

  • tasks/get:轮询状态和最终结果
  • tasks/update:提交任务中途需要的输入
  • tasks/cancel:请求协作式取消
  • subscriptions/listen:可选接收 notifications/tasks

断线重连后仍可用相同 taskId 恢复,这正是它相对“保持一个超长 SSE 响应”的价值。

4.7 缓存:为工具列表和资源读取降低成本

以下 complete 结果必须返回 ttlMscacheScope

  • server/discover
  • tools/list
  • prompts/list
  • resources/list
  • resources/templates/list
  • resources/read

ttlMs 是新鲜度提示,语义类似 HTTP max-agecacheScope 只能是:

  • public:可跨用户、跨授权上下文共享缓存。
  • private:只能在同一授权上下文复用。

通知和 TTL 可以组合:TTL 避免频繁拉取,收到 list_changed 或资源更新通知时立即让缓存失效。

工具列表还应保持确定性顺序。工具定义常被注入模型上下文,稳定排序能减少 Prompt 变化,提高 LLM Prompt Cache 命中率。

4.8 Streamable HTTP 更适合网关

每个 POST 除了 MCP-Protocol-Version,还必须镜像关键字段到 HTTP Header:

Header来源何时需要
MCP-Protocol-Version_meta.io.modelcontextprotocol/protocolVersion所有 POST
Mcp-MethodJSON-RPC method所有请求
Mcp-Nameparams.nameparams.uritools/callresources/readprompts/get

这让 API Gateway、WAF 和可观测性组件无需解析 JSON Body 就能按方法和工具名执行路由、限流与审计。

工具的 JSON Schema 还可以用 x-mcp-header 把非敏感的原始参数镜像到 Mcp-Param-* Header,例如 regiontenant。密码、Token 和 PII 不应放入 Header,因为中间网络组件可能记录它们。


五、MCP 2.0 的主要特点

5.1 云原生和横向扩展友好

请求不依赖连接 Session,可被任意实例处理;滚动发布、自动扩缩容、Serverless 和多区域部署不再要求粘性会话。显式状态 handle 也更容易审计和设置生命周期。

5.2 能力按请求最小化

Client 不必在连接开始时永久开放全部能力。每个请求声明当前愿意支持的 Elicitation、Roots 或扩展,Server 不得发送 Client 未声明的 inputRequests。这形成更细的最小权限面。

5.3 核心更小,扩展更清晰

Tasks、MCP Apps 等能力通过双方显式协商启用:

  • Tasks:长任务、断线恢复、人工审批、进度状态。
  • MCP Apps:在对话内渲染沙箱化图表、表单、Dashboard 和媒体界面。
  • Skills over MCP:面向 Agent 工作流的结构化指令发现与消费;相关规范仍应关注官方工作组进度。

一方不支持扩展时,支持方必须回退到 Core 行为或明确拒绝,不能假设对端理解额外字段。

5.4 可观察、可缓存、可治理

OpenTelemetry trace context、标准 Header、确定性工具顺序、显式 TTL、标准错误码和新的功能生命周期,使 MCP 更像生产级基础设施协议,而不只是桌面插件接口。

5.5 安全边界更明确

  • 工具调用应始终允许用户拒绝,尤其是写操作。
  • Tool annotations 必须视为不可信,除非来自可信 Server。
  • Streamable HTTP Server 必须验证 Origin,本地服务建议只绑定 127.0.0.1
  • requestState 必须防篡改、防跨用户复用并设置短 TTL。
  • OAuth Client 凭证必须绑定授权服务器 Issuer,不能跨 Issuer 复用。
  • serverInfo 仅是自报元数据,不能作为身份认证依据。

六、哪些功能被弃用?

MCP 2.0 首次正式引入 Active、Deprecated、Removed 生命周期。Deprecated 功能仍在规范中,但新实现不应采用。根据官方弃用表

弃用功能推荐迁移路径最早可移除时间
Roots通过工具参数、Resource URI 或 Server 配置传目录/文件2027-07-28 之后首个修订版
SamplingServer 直接集成 LLM Provider API2027-07-28 之后首个修订版
Loggingstdio 写 stderr;生产可观测性使用 OpenTelemetry2027-07-28 之后首个修订版
Dynamic Client RegistrationClient ID Metadata Documents2027-07-28 之后首个修订版
HTTP+SSEStreamable HTTPSEP-2596 Final 后三个月
includeContext: thisServer/allServers省略或使用 none跟随 Sampling
Deprecated 不等于 Removed

Roots、Sampling 和 Logging 在当前规范中仍可工作,但新项目不应再围绕它们设计架构。双时代 Client 仍需兼容旧 Server,但应该为功能退出准备迁移路径。


七、如何使用 MCP 2.0:TypeScript Server 实战

下面用官方 TypeScript SDK 建立一个最小天气 Server。SDK 会处理协议层细节;业务代码重点是声明 Tool、Schema 和返回内容。

7.1 创建项目

官方教程要求 Node.js 20 或更高版本:

mkdir weather-mcp
cd weather-mcp
npm init -y
npm install @modelcontextprotocol/server zod
npm install -D typescript @types/node

package.json 至少配置 ESM 和构建命令:

{
"type": "module",
"scripts": {
"build": "tsc"
}
}

7.2 注册一个 Tool

import { McpServer } from "@modelcontextprotocol/server";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import { z } from "zod";

const server = new McpServer({
name: "rainlib-weather",
version: "2.0.0",
});

server.registerTool(
"get_weather",
{
description: "Get current weather for a city",
inputSchema: z.object({
city: z.string().min(1).describe("City name"),
}),
},
async ({ city }) => {
// 实际项目应调用可信天气 API,并设置超时与错误处理。
const result = {
city,
temperatureC: 26,
condition: "Cloudy",
};

return {
content: [
{
type: "text",
text: `${city}: ${result.temperatureC}°C, ${result.condition}`,
},
],
structuredContent: result,
};
},
);

const transport = new StdioServerTransport();
await server.connect(transport);

// stdio Server 不能 console.log,否则会污染 JSON-RPC stdout。
console.error("Weather MCP Server is running");
SDK 版本与协议版本是两件事

McpServer 中的 version: "2.0.0" 是你的 Server 软件版本,不是 MCP 协议版本。协议使用日期 2026-07-28,由支持 Modern era 的 SDK/Transport 写入请求元数据并完成协商。升级前要确认所用 SDK 的协议支持矩阵,而不是只改应用版本号。

7.3 构建并运行

npx tsc
node build/index.js

对于 stdio Server,Host 通常通过配置启动本地命令:

{
"mcpServers": {
"weather": {
"command": "node",
"args": ["/ABSOLUTE/PATH/weather-mcp/build/index.js"]
}
}
}

Host 是否已经支持 2026-07-28 需要查看产品说明。Modern 与 Legacy 的传输行为存在破坏性差异,不能假设所有 MCP Client 都会立即升级。


八、直接调用 Modern Streamable HTTP

理解原始请求有助于排查 SDK、代理和 Header 不一致问题。一个符合 Modern MCP 的 tools/call 请求大致如下:

curl https://api.example.com/mcp \
-X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2026-07-28' \
-H 'Mcp-Method: tools/call' \
-H 'Mcp-Name: get_weather' \
--data '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {"city": "Shanghai"},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "rainlib-cli",
"version": "2.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}'

正常 JSON 响应必须包含:

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"content": [
{
"type": "text",
"text": "Shanghai: 26°C, Cloudy"
}
],
"isError": false
}
}

注意四个常见错误:

  1. Header 的日期版本和 Body _meta 不一致,会返回 HeaderMismatch
  2. Server 不支持目标版本,应返回 -32022supported 列表。
  3. tools/call 缺少 Mcp-Name 不符合 Modern Streamable HTTP 规范。
  4. 断开的 SSE 请求不能用 Last-Event-ID 恢复,必须换新 JSON-RPC ID 重试。

九、使用 MCP Inspector 测试

MCP Inspector 是官方参考调试工具,能够协商 Legacy 与 Modern 协议时代。当前文档要求 Node.js 22.19.0 或更高版本。

9.1 Web UI

npx @modelcontextprotocol/inspector node build/index.js

适合查看 Tool、Resource、Prompt、原始协议消息、Capability 和错误响应。

9.2 CLI

# 列出工具
npx @modelcontextprotocol/inspector --cli \
node build/index.js \
--method tools/list

# 调用远程工具
npx @modelcontextprotocol/inspector --cli \
https://api.example.com/mcp \
--transport http \
--method tools/call \
--tool-name get_weather \
--tool-arg city=Shanghai \
--format json

9.3 TUI

npx @modelcontextprotocol/inspector --tui node build/index.js

在没有浏览器或通过 SSH 调试时,TUI 比 Web UI 更方便。

测试 Modern Server 时,至少检查:

  • server/discover 能返回版本、能力、身份和缓存字段。
  • 每个请求都有正确 _meta
  • HTTP Header 与 Body 中的方法、名称、版本一致。
  • 所有成功结果都有 resultType
  • input_required 重试使用新 ID,并原样回传 requestState
  • 列表和资源读取包含非负 ttlMs 与正确 cacheScope
  • Server 不依赖 Mcp-Session-Id 或粘性负载均衡。

十、从 MCP 1.0 迁移到 MCP 2.0

10.1 Server 迁移清单

  • 实现 server/discover
  • 删除 initializenotifications/initialized 依赖。
  • 删除 Mcp-Session-Id 与连接级状态。
  • 将跨调用状态改为显式、受保护、有 TTL 的 handle。
  • 所有成功结果添加 resultType
  • 把服务器反向请求重构为 MRTR。
  • subscriptions/listen 替代 GET 流和资源订阅 RPC。
  • 为可缓存操作返回 ttlMscacheScope
  • 确保 Tools、Prompts、Resources 列表顺序稳定。
  • 为 Streamable HTTP 校验 Origin、版本头和标准请求头。
  • 将长任务迁移到 Tasks 扩展或显式业务 Job API。
  • 用 OpenTelemetry / stderr 替代对核心 Logging 的新依赖。

10.2 Client / Host 迁移清单

  • 每个请求都携带协议版本、ClientInfo 和 ClientCapabilities。
  • 支持 server/discover-32022 版本回退。
  • 将结果解析改成按 resultType 分发。
  • 实现 input_required 的收集输入与独立重试流程。
  • requestState 当不透明值原样回传。
  • 通过 subscriptions/listen 管理变更通知。
  • 处理请求 SSE 断流后的新 ID 重试,不再发送 Last-Event-ID
  • 缓存键包含方法、有效参数和授权上下文。
  • private 缓存不得跨 Access Token 或用户共享。
  • Tool annotations 和 serverInfo 均按不可信输入处理。
  • 按 Authorization Server issuer 存储 OAuth Client 凭证。

10.3 双时代兼容策略

官方允许实现同时支持 Modern 与 Legacy:

  • stdio:先用 server/discover 探测;遇到非 Modern 已知错误时回退到 Legacy initialize
  • Streamable HTTP:先尝试 Modern 请求,检查 400 Bad Request 的 JSON-RPC Body 再决定是否回退。

推荐把协议适配封装在 Transport/Protocol Adapter,而不是让 Tool 业务处理器到处判断版本:


十一、设计 MCP 2.0 服务的最佳实践

11.1 Tool 要小而明确

Tool 名称应稳定、可区分,Schema 要限制输入边界。破坏性动作与只读查询分开,不要把“查询、修改、发布”塞进一个巨型工具。

11.2 不要假装无状态

把状态藏进进程全局 Map,再要求负载均衡器粘住连接,只是把 Legacy Session 换了名字。需要状态时应明确选择:

  • 短多轮交互:签名或加密的 requestState
  • 长任务:Tasks taskId
  • 分页:cursor
  • 业务实体:显式资源 ID / workflow ID

11.3 缓存要考虑授权

如果 tools/list 会因 Scope、租户或用户不同而变化,必须返回 cacheScope: "private",缓存键还要包含授权上下文。错误地标记为 public 可能向另一个用户暴露工具或资源元数据。

11.4 用户同意不能只靠描述

Tool 描述由 Server 提供,Host 不应无条件相信。对于转账、删除、发送消息、部署和权限修改:

  • 展示将要调用的 Server、Tool 和关键参数。
  • 明确区分只读与写入。
  • 允许用户拒绝和修改输入。
  • 返回后展示执行结果和失败原因。

11.5 为重试设计幂等性

Modern SSE 断流后 Client 会用新 ID 重发请求。Server 应为可能产生副作用的工具提供业务幂等键、去重机制或查询已完成结果的 handle,避免“网络断了但操作已经成功”导致重复付款、重复发布或重复创建。


十二、常见问题

MCP 2.0 是否与旧版本二进制兼容?

不是。初始化、Session、服务器反向请求、订阅和 SSE 恢复均发生破坏性变化。但 Server 和 Client 可以实现 Dual-era 适配,同时支持 Legacy 与 Modern。

JSON-RPC 还是 2.0,为什么叫 MCP 2.0?

JSON-RPC 2.0 是底层消息格式,与 MCP 协议时代不是一回事。本文“MCP 2.0”只是对 Modern 2026-07-28 大版本式变化的方便称呼。

无状态是否意味着不能做多轮 Agent 工作流?

不意味着。短多轮交互使用 MRTR,长流程使用 Tasks,业务状态使用显式 handle。多轮能力保留了,只是不再隐式依附于连接。

stdio 也必须每次携带 _meta 吗?

是。Modern 协议的每个请求都必须带版本和 Client capabilities。HTTP 额外要求版本、方法和名称 Header;stdio 没有这些 HTTP Header。

是否应该在新项目中使用 Roots、Sampling 和 Logging?

不建议。它们目前仍可用但已 Deprecated。新 Server 应通过 Tool 参数/Resource URI 表达目录,通过 Provider API 完成模型调用,通过 stderr 或 OpenTelemetry 完成日志与观测。

现在应该立即升级吗?

如果你维护 SDK、网关、Inspector、远程 MCP 平台或需要大规模无状态部署,应尽快完成架构评估。普通 Server 作者首先应确认目标 Host 和官方 SDK 是否已经完整支持 2026-07-28,再采用 Dual-era 或分阶段升级。


十三、总结

MCP 2026-07-28 的真正价值不在于增加了多少新 RPC,而在于删除了一批会让协议依赖连接状态的机制:

  • Session 变成显式状态句柄。
  • 初始化协商变成每请求元数据和服务器发现。
  • 服务器反向请求变成 MRTR 返回与重试。
  • 混杂的长连接事件变成专用订阅流。
  • 长任务变成可选、可恢复的 Tasks 扩展。
  • 缓存、Header、Trace 和授权规则进入生产级治理。

它让 MCP 从适合单机桌面集成的插件协议,向可被云网关路由、可水平扩容、可观测、可缓存、可安全扩展的 Agent 基础设施迈进了一大步。

但也要记住:无状态不会自动带来安全和可靠性。 实现者仍需正确处理幂等、用户授权、缓存隔离、requestState 完整性、OAuth Issuer 绑定和工具输入验证。

如果你只记住一条迁移原则,可以记住这句:

不要把连接当作上下文。让每个请求说明自己是谁、会什么、要做什么;需要延续的状态,使用显式且可验证的句柄。


参考资料

Logo
RainLib

Exploring the frontiers of technology, design, and distributed systems. Building tools for the future developers.

Suggestions & Feedback

© 2026 RainLib. Built for the Future.
All rights reserved.
System Normal