MCP规范移除有状态约束,改用全 stateless 架构,支持 serverless 部署和标准轮询负载均衡,引入 MRTR 处理长时任务。
随着 Agent 工作流不断部署、用户规模持续扩大,瓶颈点也在不断变化。2024 年底,Model Context Protocol(MCP)首次亮相时,提供了一个优雅的、面向会话的框架,让 LLM 能够协商能力、调用外部工具、检索上下文资源。它非常适合单机上单个客户端与单个服务器通信的场景,并针对 stdio 做了优化。
但当我们在 Google 内部将 MCP 服务器部署到云原生基础设施时,遇到了硬墙。原始协议层的会话模型需要持久状态、握手和会话绑定。简而言之,它建立在有状态传输之上,违背了现代云原生可扩展性的核心原则。
为此,Google 主导了将协议与有状态传输约束解耦的工作。我们的团队需要在 Google Cloud 上支持百万级并发查询,而且我们深知各位也希望 MCP 能够经受住真实企业级规模的考验。我们与 Hugging Face 及其他行业伙伴紧密合作,共同创立了 MCP Transports Working Group。
今天,我们非常激动地宣布这项工作的成果:2026-07-28 Model Context Protocol 规范候选版已发布,并正在被广泛采用。这一里程碑式的发布彻底移除了传输层会话管理,提供了可运行在普通 HTTP 负载均衡基础设施上的无状态协议核心。这是 MCP 规范自发布以来最大的变更,如果你不继续往下读,也要放心——这是一个向好的变化:更多扩展性、更高安全性、用起来同样简单。
在原始协议模型(规范版本 2025-11-25)[^392] 中,通过 HTTP 连接到 MCP 服务器需要经历一个状态化的初始化过程:
// POST /mcp - Legacy 2025-11-25 Handshake
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": {
"name": "my-app",
"version": "1.0"
}
}
}
服务器返回时带有 Mcp-Session-Id 头。此后客户端发起任何工具调用或资源查询,都必须在每个请求中携带那个唯一的会话 ID,从而将客户端绑定到持有其内存会话状态的具体容器或 Pod。
这种有状态约束破坏了云原生工程师所依赖的水平扩展模型:
负载均衡税:标准轮询负载均衡器不知道哪个容器持有哪些内存会话。部署在有三个 Pod 的 Kubernetes 集群后端时,客户端的第二个请求会随机打到另一个 Pod,返回 400 Session Not Found 错误。
粘性路由开销:开发者被迫在负载均衡器层面配置粘性会话亲和规则,这导致流量无法均匀分布,自动扩展效率极低。
零容错:如果某个 Pod 重启或崩溃,会话状态立即丢失,正在进行的客户端对话会收到瞬时错误,用户体验彻底崩坏。
复杂的基础设施需求:运行远程 MCP 服务器需要共享的 Redis 会话存储或复杂的网关层数据包检测,带来巨大的延迟和运维成本。
新的 2026-07-28 规范通过让协议核心完全无状态化来解决这个问题。握手没有了。initialize / initialized 握手(SEP-2575)和逻辑上的 Mcp-Session-Id 头(SEP-2567)被完全移除。
取而代之的是,每个请求现在都是自描述且独立的。曾在连接建立时交换一次的协议版本、客户端信息和客户端能力,现在以 _meta 字段的形式内联在每个请求中。
以下是新的 2026-07-28 规范下无状态工具调用的样子:
POST /mcp HTTP/1.1
Host: mcp-server.example
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "otters"
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {},
"io.modelcontextprotocol/clientInfo": {
"name": "my-app",
"version": "1.0"
}
}
}
}
标准轮询路由:由于任何容器实例都能处理任何传入请求,你可以将原有的有状态 MCP 服务器直接放到普通的轮询负载均衡器后面。
无缝 Serverless 部署:你现在可以将 MCP 服务器作为无服务器函数运行在 Google Cloud Run 或 Google Cloud Functions 等平台上。由于无需维护持久连接,服务器在空闲时可以缩减到零,大幅降低成本。
透明故障转移:Pod 重启、滚动更新和自动扩展事件对客户端完全透明。如果某个容器崩溃,负载均衡器会将下一个请求直接路由到健康的实例,实现零会话中断。
不再需要 Redis 会话:主要的生产服务器(如 GitHub MCP Server)已升级到该规范,完全移除了 Redis 会话存储,消除了每次调用时的数据库读写,使交互更加快速。
没有了协议会话,我们需要标准机制来高效地路由和管理流量。在 Transports Working Group 中,我们协助设计了 SEP-2243(HTTP 标准化)[^302, 542]。
可流式传输的 HTTP POST 请求现在携带特定的 HTTP 头:
Mcp-Protocol-Version:协议的版本。Mcp-Method:正在执行的 JSON-RPC 方法(如 tools/call)。Mcp-Name:正在调用的具体工具、提示词或资源名称。这些头与 JSON-RPC body 是镜像关系。如果两者不一致,服务器会以 -32020 头不匹配码拒绝请求。
通过将这些值提升为标准 HTTP 头,代理、网关和负载均衡器可以在不检查请求体的情况下路由、限速和审计流量。对于安全和日志团队来说,这是一个巨大的胜利,大幅降低了网关层的延迟和处理开销。
为了消除仅为监控工具或提示词列表是否变更而维持长时间 Server-Sent Events(SSE)连接的需求,规范引入了类比 HTTP Cache-Control 的缓存字段。工具和资源结果现在可以返回 ttlMs(以毫秒为单位的生存时间)和 cacheScope。客户端精确知道 tools/list 响应在多长时间内是新鲜的,以及是否可以在多个用户之间安全地缓存。
在无状态化世界中,我们面临的最复杂挑战之一是如何处理服务器到客户端的请求。在之前的版本中,如果 MCP 服务器需要用户澄清(一个"征求提示词")或在工具调用过程中需要确认,它必须保持一个 SSE 连接打开以将请求推送给客户端。
多轮次请求(SEP-2322)通过将交互生命周期重构为自包含步骤,优雅地解决了这个问题:
服务器不再阻塞线程或保持连接打开,而是立即返回一个包含 requestState 有效载荷的 InputRequiredResult,其中包含序列化的上下文[^398]:
// InputRequiredResult Returned from Server
{
"resultType": "inputRequired",
"inputRequests": {
"confirm": {
"type": "elicitation",
"message": "Are you sure you want to delete these 3 files?",
"schema": {
"type": "boolean"
}
}
},
"requestState": "eyJzdGVwIjoxLCJmaWxlcyI6WyJhIiwiYiIsImMiXX0="
}
客户端提示用户,收集布尔答案,然后重新发起调用,附带 inputResponses 和回显的 requestState。由于 requestState 包含了恢复任务所需的全部信息,负载均衡器后面的任何服务器实例都可以接收这个重试请求!
有时候工具调用就是需要很长时间才能运行完成。数据库备份、CRM 同步或通过支付网关退款可能需要 10 到 60 秒不等。保持客户端连接打开会阻塞客户对话并产生大量的连接队列。
任务扩展从实验性功能毕业为稳健的一等协议扩展。现在,当客户端调用一个长时间运行的工具时,服务器立即返回一个 taskId 并在后台启动执行:
// Example: Kicking off an async task in a TypeScript server
server.tool(
"process_refund",
{ orderId: z.string(), amount: z.number() },
async ({ orderId, amount }) => {
const taskId = randomUUID();
// Store initial task state in a shared datastore (e.g. Redis)
await setTaskState(taskId, { status: "working" });
// Process the refund asynchronously in the background
processRefundAsync(taskId, orderId, amount);
// Return immediately to keep the conversation flowing
return {
content: [
{
type: "text",
text: JSON.stringify({
taskId,
status: "working",
message: `Refund of $${amount} for order ${orderId} is processing. Task ID: ${taskId}`
})
}
]
};
}
);
客户端继续对话,告知用户请求正在处理中,并可以使用标准的 tasks/get 和 tasks/update 原语进行轮询或订阅,以监控进度并获取最终结果。
随着管理状态的责任从传输层转移到应用层,安全性变得至关重要。2026-07-28 规范带来了几项关键的安全增强:
签发者验证(RFC 9207):公共客户端必须在授权响应上验证 iss 参数,防止多服务器架构中的会话劫持和基于重定向的攻击。
资源指示符(RFC 8707):客户端明确指定令牌针对哪个 MCP 服务器,解决了"混乱副手"委托问题。
完整的 JSON Schema 2020-12 用于工具:输入模式现在可以使用高级组合结构(如 oneOf、anyOf、allOf)和本地 $ref 定义,使参数具有高度描述性和严格验证。
MCP 首次拥有了正式的弃用策略。功能经历结构化的 Active -> Deprecated -> Removed 生命周期,最短 12 个月的过渡窗口。以下三个功能从即日起进入弃用阶段:
所有四个一级 SDK(TypeScript、Python、Go 和 C#)已有支持 2026-07-28 规范的 Beta 版本可用。我们强烈建议你现在就开始在预发环境中测试。
在 Python 中,MCPServer 装饰器 API 完全兼容[^303]。你可以直接用以下命令安装 Beta 版:
pip install "mcp[cli]==2.0.0b1"
TypeScript v2 用模块化、专注的库取代了单一的 @modelcontextprotocol/sdk 包,以保持依赖轻量。用以下命令安装:
npm install @modelcontextprotocol/server@beta
npm install @modelcontextprotocol/client@beta
提供了一个方便的 codemod 来处理标准的 API 重命名(如将 .tool() 重命名为 registerTool):
npx @modelcontextprotocol/codemod@beta v1-to-v2 .
2026-07-28 规范标志着 Model Context Protocol 的一个分水岭时刻,将其从一个有前景的本地集成层转变为企业级 AI 应用的基础性开放基础设施。
感谢 MCP Transports Working Group 全体成员以及为此付出巨大努力的其他团队,感谢来自多家公司的贡献。也要感谢 Google 团队中维护 Go MCP SDK 并在 7 月 28 日发布 v1.7.0 的同仁,他们在上线首日就准备就绪,为 GitHub MCP Server 等主要集成提供了支持。
Google 推动无状态传输是出于自身需求。我们需要一种足够强大的协议来处理全球开发者的海量规模,我们也希望确保每一位开发者——无论是在 Google Cloud 上构建还是在其他任何地方——都能获得高度可靠、安全且无限可扩展的 Agent 基础设施。
通过将状态从传输层解耦,我们让负载均衡变得无聊、自动扩展变得无缝、Serverless 部署成为现实。我们迫不及待想看到你们基于这个全新的无状态基础构建出令人难以置信的可扩展 AI Agent!
阅读完整的 2026-07-28 规范。
查看 TypeScript SDK 升级指南。
Star 并贡献 Go SDK 和示例。