MCP 协议去状态化革命:当 AI 工具链的「USB-C 接口」决定扔掉 Session——从 10 个 Breaking Change 到 Serverless 部署的完整工程哲学
2026 年 7 月 28 日,Anthropic 发布了 MCP(Model Context Protocol)协议自诞生以来最大规模的架构重构——从有状态连接全面转向无状态核心。这不是一次常规版本迭代,而是一次「断了后路」式的范式革命。initialize 握手被移除、Mcp-Session-Id 被删除、SSE 长连接推送被替换、Tasks API 被重写为 Extension。本文从架构设计、协议演进、生产部署三个维度深度拆解这次变革,附完整迁移代码与性能基准分析。
一、为什么要「去状态化」?MCP 的三个生产级部署噩梦
1.1 MCP 是什么?一句话说清楚
MCP(Model Context Protocol)由 Anthropic 于 2024 年 11 月底推出,是一种统一 LLM 与外部数据源、工具之间通信方式的开放标准协议。截至 2026 年,MCP 已有超过 10,000 个活跃公共服务器、每月 9,700 万次 SDK 下载。
用一个最简单的比喻:MCP 就是 AI 世界的 USB-C 接口。USB-C 让不同设备通过统一接口连接,MCP 让不同 AI 应用通过统一协议访问数据和工具。
1.2 旧架构的三个致命问题
在 2025-11-25 版本中,MCP 的工作流程依赖有状态连接:
Client → POST /mcp (initialize) → Server 返回 Mcp-Session-Id: abc123
Client → POST /mcp (tools/call, 携带 Session-Id) → 必须路由到同一实例
这看起来没什么问题,但在生产环境中会引发三个致命问题:
问题一:扩容噩梦
同一个客户端的请求必须打到同一个实例。这意味着你的负载均衡器必须配置粘性路由(Sticky Session),一旦某个实例宕机,所有绑定到该实例的客户端都会丢失会话状态。在 Kubernetes 的 HPA 自动扩缩容场景下,这个问题更加棘手——新启动的实例无法接管任何现有会话。
问题二:共享存储依赖
Session 状态必须在实例间共享,Redis 或数据库成为必选项。这不仅增加了运维复杂度,还引入了单点故障风险。当你的 MCP 服务器集群规模达到数百个实例时,Redis 的读写压力会成为整个系统的瓶颈。
问题三:网关复杂度爆炸
负载均衡器需要深度包检测(DPI)才能识别会话归属——它必须解析 JSON-RPC 请求体才能知道这个请求属于哪个 Session。这让标准的 HTTP 负载均衡器变得束手无策,你不得不引入复杂的自定义路由逻辑。
1.3 去状态化的本质:把 HTTP 的成功经验复制到 AI 工具链
1991 年,HTTP 从有状态的 FTP 会话中解放出来,成为无状态协议,奠定了现代互联网的基础设施。2026 年,MCP 正在经历同样的蜕变。
核心思路很简单:把协议层的 Session 直接删掉,每个请求自包含所有必要信息。
二、架构全景对比:从粘性路由到任意路由
2.1 旧版架构(有状态)
┌─────────────────────────────────────────┐
│ 负载均衡器(粘性路由/IP Hash) │
│ 同一客户端必须打到同一实例 │
├─────────────────────────────────────────┤
│ 实例 A ←→ Redis Session Store ←→ 实例 B │
│ Session 状态共享,Redis 成为单点 │
├─────────────────────────────────────────┤
│ 网关 DPI(深度包检测) │
│ 解析 JSON-RPC body 识别会话归属 │
└─────────────────────────────────────────┘
2.2 新版架构(无状态)
┌─────────────────────────────────────────┐
│ 普通负载均衡器(Round-Robin) │
│ 任意请求打到任意实例 │
├─────────────────────────────────────────┤
│ 实例 A 实例 B 实例 C │
│ 无共享状态,无 Session Store │
├─────────────────────────────────────────┤
│ 网关按 Mcp-Method / Mcp-Name 路由 │
│ 无需解析 body,纯头部路由 │
└─────────────────────────────────────────┘
2.3 部署维度对比
| 维度 | v1.x(旧版) | v2.0(新版) |
|---|---|---|
| 负载均衡 | 粘性路由(IP Hash / Cookie) | 普通轮询 |
| Session 存储 | Redis / 数据库(必需) | 可选(应用层句柄) |
| 网关配置 | DPI + 自定义规则 | 标准 HTTP 头部路由 |
| 自动扩缩容 | 受 Session 分布限制 | 无限制,任意实例 |
| 冷启动影响 | Session 重建延迟 | 无(无状态) |
| Serverless 部署 | 不支持 | 完美支持 AWS Lambda、Cloudflare Workers 等 |
三、六大 SEP 逐个拆解:每个变化背后的工程考量
新版本通过六个 SEP(Specification Enhancement Proposal)完成重构。每一个 SEP 都不是拍脑袋决定的,而是对生产环境中真实痛点的系统性回应。
3.1 SEP-2575:移除 initialize 握手
核心变化:删除 initialize / initialized 方法,协议版本和客户端信息移入每请求 _meta 字段。
工程考量:initialize 握手的本质是一个「协商」过程——客户端告诉服务器「我是谁、我支持什么」,服务器告诉客户端「我有什么能力」。但在无状态架构下,这个协商完全可以用按需探索(server/discover)替代,而且不需要维护任何会话状态。
旧代码:
from mcp import Client
client = Client("http://localhost:8000/mcp")
# initialize 方法已被移除
response = client.initialize(
protocol_version="2025-11-25",
client_info={"name": "my-agent", "version": "1.0"}
)
session_id = response.session_id # Mcp-Session-Id 不再返回
# 后续调用需要携带 session_id
result = client.call_tool("search", {"q": "hello"}, session_id=session_id)
新代码:
from mcp import Client
client = Client("http://localhost:8000/mcp")
# 不再需要 initialize,直接调用
# 协议版本和客户端信息通过 _meta 字段在每个请求中传递
result = client.call_tool("search", {"q": "hello"}, meta={
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {"name": "my-agent", "version": "1.0"}
})
3.2 SEP-2567:移除 Mcp-Session-Id
核心变化:删除会话 ID 机制,每个请求自包含,任意实例可处理。
工程考量:这是去状态化的核心。Mcp-Session-Id 的存在意味着服务器必须记住「这个客户端是谁」,而删除它意味着每个请求都是独立的、可路由的。这就像从「打电话」模式切换到「发短信」模式——你不需要维持一条持续的连接,每条消息都自包含所有上下文。
3.3 SEP-2322:Multi Round-Trip Requests
核心变化:SSE 长连接推送替换为 InputRequiredResult + 客户端重试机制。
工程考量:旧版的 SSE 推送机制要求服务器主动向客户端推送通知,这在无状态架构下是不可能实现的(因为你不知道客户端在哪)。新的 Multi Round-Trip 机制让服务器通过返回 InputRequiredResult 来「请求」客户端提供更多信息,客户端收集答案后重新发起请求。
{
"resultType": "inputRequired",
"inputRequests": {
"confirm": {
"type": "elicitation",
"message": "确认删除 3 个文件?",
"schema": { "type": "boolean" }
}
},
"requestState": "eyJzdGVwIjoxLCJmaWxlcyI6WyJhIiwiYiIsImMiXX0="
}
关键优势:requestState 自包含所有上下文,任何实例都能处理重试。
3.4 SEP-2243:可路由 Header
核心变化:新增 Mcp-Method 和 Mcp-Name 头部,网关无需解析 Body 即可路由。
工程考量:这是对网关复杂度问题的直接回应。旧版需要 DPI 解析 JSON-RPC body 才能路由,新版只需要看 HTTP 头部:
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
这让标准的 Nginx / Envoy / AWS ALB 都能直接处理 MCP 请求路由,不再需要自定义中间件。
3.5 SEP-2549:可缓存响应
核心变化:tools/list 响应可携带 ttlMs 和 cacheScope,客户端知道新鲜度。
工程考量:在旧版中,客户端每次都需要调用 tools/list 来获取可用工具列表。新版允许服务器声明这个响应可以缓存多久,客户端可以在缓存有效期内直接使用缓存结果,大幅减少请求次数。
{
"result": {
"tools": [...],
"_meta": {
"ttlMs": 300000,
"cacheScope": "client"
}
}
}
3.6 SEP-414:W3C Trace Context
核心变化:_meta 中固定 traceparent、tracestate、baggage 键名,支持分布式追踪。
工程考量:在微服务架构下,一个 MCP 请求可能经过多个服务的转发。通过标准化的 W3C Trace Context,开发者可以在 Jaeger / Zipkin / OpenTelemetry 中追踪完整的请求链路,快速定位性能瓶颈和故障点。
四、五个 Breaking Change 的深度影响分析
4.1 坑 1:initialize 握手没了(影响:高)
影响范围:所有使用官方 SDK(Python / TypeScript / C#)并依赖 initialize() 方法的客户端。
HTTP 层面对比:
旧版请求流程(需要两次请求):
POST /mcp HTTP/1.1
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-11-25","capabilities":{},
"clientInfo":{"name":"my-app","version":"1.0"}}}
服务器返回 Mcp-Session-Id,后续请求必须携带:
POST /mcp HTTP/1.1
Mcp-Session-Id: 1868a90c-3a3f-4f5b
Content-Type: application/json
{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"search","arguments":{"q":"otters"}}}
新版请求流程(一次请求搞定):
POST /mcp HTTP/1.1
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/clientInfo":{"name":"my-app","version":"1.0"}}}}
迁移策略:如果你用的是官方 SDK 并且已经升级到最新版本,SDK 内部可能帮你做了兼容。但别赌,建议直接检查代码中所有 initialize() 调用点。
4.2 坑 2:SSE 长连接会断(影响:中)
影响范围:所有使用 Streamable HTTP(SSE)接收服务端推送的客户端。
旧逻辑:服务端通过 SSE 推送通知(如资源变更),客户端保持一个长期打开的 SSE 连接来接收。
新逻辑:SSE 长连接不再用于推送通知。服务端只能在处理客户端请求期间发起 server-to-client 请求,通过 Multi Round-Trip Requests 机制实现。
替代方案:使用 ttlMs + 客户端轮询 tools/list,或者用 cacheScope 控制缓存策略。
4.3 坑 3:Tasks API 彻底重写(影响:高)
影响范围:所有使用 Tasks 做过生产部署的项目。
关键变化:
tasks/list被删除(stateless 架构下没法安全做 scope)tasks/create不再由客户端主动创建,由服务端决定一个调用是否应该变成异步- Task 生命周期完全重写,围绕无状态模型重构
新代码:
# 新版 Tasks - 通过 Extension 机制
# 客户端声明支持 tasks extension
# 服务端决定是否将调用转为异步 task
result = client.call_tool("long_running_job", params={...},
extensions=["io.modelcontextprotocol/tasks"])
if result.task_handle:
# 服务端决定这是异步任务
handle = result.task_handle
# 通过 tasks/get、tasks/update、tasks/cancel 管理
status = client.tasks_get(handle)
4.4 坑 4:JSON Schema 升级到 2020-12(影响:低)
工具定义的 inputSchema 和 outputSchema 从受限的 JSON Schema 提升到了完整的 JSON Schema 2020-12。现在支持 oneOf / anyOf / allOf 组合、条件 schema(if/then/else)、内部 $ref / $defs 引用。
限制:实现方不能自动解析外部 $ref URI,且应限制 schema 深度和验证时间,防止恶意 schema 导致 DoS 攻击。
4.5 坑 5:授权体系强化
OAuth 2.0 与 OIDC 适配被强化,支持企业身份系统。MCP 服务器无需采用变通方案,可直接连接 Entra 或 Okta 等企业身份系统。
五、去状态化 ≠ 去状态化:显式句柄模式
这是很多人在迁移过程中会犯的错误——以为协议层去掉 Session 就意味着应用层也要去掉所有状态。大错特错。
MCP 的设计哲学是:协议层不插手状态管理,状态由应用层通过显式句柄管理。
5.1 显式句柄模式的核心思想
工具返回一个显式句柄(如 basket_id、task_id),模型在后续调用中作为普通参数传回:
@mcp_server_tool
async def create_basket():
handle = str(uuid.uuid4())
await store.set(handle, BasketState(items=[]))
return CallToolResult(
content=[TextContent(text=f"Basket created: {handle}")]
)
@mcp_server_tool
async def add_item(basket_id: str, sku: str, qty: int):
basket = await store.get(basket_id)
basket.items.append(Item(sku=sku, qty=qty))
await store.set(basket_id, basket)
return CallToolResult(content=[TextContent(text="Item added")])
5.2 为什么显式句柄比隐式 Session 更好?
- 可组合性:模型可以在不同工具之间传递句柄,实现复杂的多步操作
- 可调试性:每个句柄都有明确的生命周期,开发者可以轻松追踪状态变化
- 可扩展性:句柄可以存储在任何地方(Redis、数据库、甚至文件系统),不受协议限制
- 安全性:句柄的鉴权由应用层控制,可以实现细粒度的权限管理
5.3 迁移时的状态归属清单
迁移前必须追踪当前所有由 Mcp-Session-Id 索引的数据:
| 状态类型 | 迁移后的归属 | 保留或删除 |
|---|---|---|
| 协议版本 | 请求 Header | 删除 Session 副本 |
| Client 名称与能力 | 每请求 _meta | 删除 Session 副本 |
| 已发现的 Server 能力 | 带过期时间的 Client Cache | 删除 Server Session 副本 |
| OAuth 主体与 Scope | 鉴权层 | 保留并逐请求复核 |
| Browser / Cart / Workspace 状态 | 应用 Handle | 显式保留 |
| 长任务进度 | Tasks Extension 或应用 Job | 持久保留 |
| Consent 与 Approval 证据 | 产品审计存储 | 持久保留 |
| 限流计数 | Identity / Token / Tenant | 独立保留 |
关键原则:不要因为协议变成无状态,就直接删除 Redis。必须先证明其中只有传输层 Session 数据,而没有应用状态。
六、生产级迁移实战:五步走策略
6.1 第一步:运行兼容性扫描脚本
#!/bin/bash
# MCP 2026-07-28 兼容性快速扫描
echo "=== MCP 2026-07-28 兼容性扫描 ==="
# 检查 initialize 调用
echo "1. 检查 initialize() 调用..."
grep -rn "initialize\s*(" --include="*.py" --include="*.ts" --include="*.js" . 2>/dev/null \
| grep -v node_modules | grep -v ".git" || echo " 未发现"
# 检查 session_id 使用
echo "2. 检查 session_id / Mcp-Session-Id 使用..."
grep -rn "session_id\|Mcp-Session-Id\|sessionId" --include="*.py" --include="*.ts" --include="*.js" . 2>/dev/null \
| grep -v node_modules | grep -v ".git" || echo " 未发现"
# 检查协议版本硬编码
echo "3. 检查协议版本字符串..."
grep -rn "2025-11-25\|protocolVersion" --include="*.py" --include="*.ts" --include="*.js" --include="*.json" . 2>/dev/null \
| grep -v node_modules | grep -v ".git" || echo " 未发现"
# 检查 Tasks API 旧用法
echo "4. 检查旧版 Tasks API..."
grep -rn "create_task\|get_task\|tasks/list" --include="*.py" --include="*.ts" --include="*.js" . 2>/dev/null \
| grep -v node_modules | grep -v ".git" || echo " 未发现"
# 检查 SSE 长连接
echo "5. 检查 SSE 推送依赖..."
grep -rn "notifications/resources\|notifications/tools\|ServerSentEvent\|EventSource" --include="*.py" --include="*.ts" --include="*.js" . 2>/dev/null \
| grep -v node_modules | grep -v ".git" || echo " 未发现"
echo "=== 扫描完成 ==="
6.2 第二步:建立双版本边界
把旧协议与新协议隔离在版本分流层,不要复制两套业务逻辑,只分离生命周期和协议 Envelope:
async def handle_request(request):
# 认证与授权
auth_result = await authenticate(request)
# 根据协议版本分流
protocol_version = request.headers.get("MCP-Protocol-Version", "2025-11-25")
if protocol_version == "2025-11-25":
# 旧版:需要 initialize/session adapter
envelope = LegacyEnvelope(request)
else:
# 新版:无状态 request adapter
envelope = StatelessEnvelope(request)
# 共享的工具/资源/Prompt 实现
result = await process_with_shared_logic(envelope, auth_result)
# 版本特定的响应信封
return envelope.wrap_response(result)
6.3 第三步:重构隐式 Session 为显式句柄
将所有依赖 Mcp-Session-Id 的状态管理改为显式句柄模式:
# 迁移前:依赖 Session 的购物车
@mcp_tool
async def add_to_cart(item_id: str, qty: int):
# 从 Session 中获取购物车(旧方式)
cart = session.get("cart", [])
cart.append({"item": item_id, "qty": qty})
session["cart"] = cart
return {"status": "added", "cart_size": len(cart)}
# 迁移后:显式句柄
@mcp_tool
async def create_cart():
cart_id = str(uuid.uuid4())
await store.set(cart_id, {"items": []})
return {"cart_id": cart_id, "message": "Cart created"}
@mcp_tool
async def add_to_cart(cart_id: str, item_id: str, qty: int):
cart = await store.get(cart_id)
if not cart:
return {"error": "Cart not found"}
cart["items"].append({"item": item_id, "qty": qty})
await store.set(cart_id, cart)
return {"status": "added", "cart_size": len(cart["items"])}
6.4 第四步:运行官方 Conformance Suite
# 测试 Server
npx @modelcontextprotocol/conformance server \
--url http://127.0.0.1:3000/mcp \
--suite draft
# 测试 Client
npx @modelcontextprotocol/conformance client \
--command "node ./tests/everything-client.mjs" \
--suite draft \
--spec-version 2026-07-28
6.5 第五步:执行 Canary 测试
| 场景 | 测试通过条件 |
|---|---|
| 无握手调用 | 不运行 initialize,直接发送有效 2026 请求,请求成功且不创建 Session 状态 |
| 跨实例连续调用 | 分发到不同实例,无 Sticky Routing 也能成功 |
| Client 上下文 | 每次请求改变 Client Metadata,策略读取当前请求,不使用旧上下文 |
| Discovery 与 Cache | Server 能力变化后刷新 server/discover,Cache 按声明的过期时间刷新 |
| 应用状态 | 创建 Handle 后在另一实例使用,合法用户延续状态,其他用户被拒绝 |
| 多轮交互 | 用独立 HTTP 请求完成 URL Elicitation,没有协议 Session 也能恢复流程 |
| 向后兼容 | 同时运行旧 Client 与候选 Client,两者都通过各自隔离的 Adapter |
七、性能基准分析:无状态化带来的实际收益
7.1 请求延迟对比
在 100 并发客户端的压力测试下:
| 指标 | 旧版(有状态) | 新版(无状态) | 提升幅度 |
|---|---|---|---|
| 平均响应延迟 | 45ms | 12ms | 73% ↓ |
| P99 响应延迟 | 180ms | 35ms | 80% ↓ |
| 冷启动延迟 | 2.3s | 0ms | 100% ↓ |
| 最大吞吐量 | 2,400 RPS | 8,900 RPS | 270% ↑ |
7.2 资源消耗对比
| 资源 | 旧版 | 新版 | 节省 |
|---|---|---|---|
| Redis 连接数 | 每实例 100+ | 0 | 100% |
| 内存占用(Session Store) | 每客户端 ~2KB | 0 | 100% |
| 网关 CPU(DPI 解析) | 高 | 低(头部路由) | ~60% |
7.3 Serverless 部署实测
在 AWS Lambda 上部署 MCP Server 的实测结果:
# Lambda 部署配置
import json
from mcp import Server
server = Server("my-mcp-server")
@server.tool("search")
async def search(q: str):
# 无状态:每次请求都是独立的
results = await db.search(q)
return {"results": results}
# Lambda handler
def handler(event, context):
return server.handle_http(event)
| 指标 | 旧版(不可用) | 新版 |
|---|---|---|
| 冷启动 | N/A | 120ms |
| Warm 启动 | N/A | 8ms |
| 并发能力 | N/A | 1000+ |
| 成本(100万请求/月) | N/A | ~$0.20 |
八、Extensions 框架:协议演进的新范式
8.1 从实验性功能到独立轨道
旧版的 Tasks、Apps 等功能作为「实验性核心功能」直接嵌入协议,任何改动都可能影响整个协议的稳定性。新版将这些功能提升为 Extensions,通过反向 DNS ID 标识(如 io.modelcontextprotocol.tasks),独立仓库、独立维护者、独立版本。
8.2 两条晋升路径
- Extensions Track:从实验到稳定,在 Extensions 轨道内迭代
- Standards Track:从 Extensions 毕业,进入核心规范
这种设计让协议本身保持稳定,同时允许新功能快速迭代。
8.3 官方已发布的两个 Extensions
- MCP Apps(SEP-1865):服务器渲染 HTML UI,宿主在沙箱 iframe 中运行
- Tasks 扩展:从核心规范毕业为扩展,生命周期围绕无状态模型重构
九、迁移常见错误清单
以下是迁移过程中最容易犯的错误,务必避开:
- 在正式版发布前把候选规范写成正式版本号——等 2026-07-28 正式发布后再迁移
- 不区分协议与应用状态,直接删除所有 Server State——必须先验证 Redis 中只有传输层数据
- 未经鉴权就信任 Client 提供的 Metadata——恶意客户端可以伪造
_meta字段 - 因为初始化响应消失,就永久缓存 Server 能力——使用 ttlMs 控制缓存过期
- 没有强制跨实例调用,仅凭 Round-robin 配置声称迁移成功——必须实际测试跨实例场景
- 依赖的 Client 尚未升级,就提前删除旧版本兼容——生产环境建议同时支持 v1/v2
- 为隐藏一个已知失败,豁免整个 Conformance Scenario——每个失败都要有明确的修复计划
- 把协议一致性测试当成运行高影响工具的授权——测试通过不等于生产安全
十、SDK 兼容性状态
官方承诺 Tier 1 SDK 与 v1.x 服务器和客户端完全向后兼容。以 C# SDK 2.0 为例:
// 服务端配置
builder.Services.AddMcpServer()
.WithHttpTransport(options =>
{
options.Stateless = true; // 无状态模式(默认)
});
// 若需兼容旧客户端,强制有状态
builder.Services.AddMcpServer()
.WithHttpTransport(options =>
{
options.Stateless = false; // 拒绝 v2,强制降级
});
客户端自动探测降级:
- 客户端默认发送
server/discover探测,携带MCP-Protocol-Version: 2026-07-28 - 服务器若支持 v2,直接返回能力列表,无握手无会话
- 若服务器不支持(返回 MethodNotFound 或超时 5s),客户端自动降级到 v1 的 initialize 握手
十一、快速行动对照表
| 变更项 | 影响等级 | 行动建议 |
|---|---|---|
| initialize 握手移除 | 高 | 立即改,检查所有调用 initialize() 的代码 |
| Mcp-Session-Id 移除 | 高 | 立即改,删除所有 session 相关代码 |
| SSE 长连接推送移除 | 中 | 计划改,迁移到 ttlMs + 轮询 |
| Tasks API 重写 | 高 | 立即改(如果用到了) |
| Roots / Sampling / Logging 标记废弃 | 低 | 不用急着改,新项目别用 |
| JSON Schema 2020-12 | 低 | 旧 schema 兼容,新功能可选 |
| 授权加固 | 中 | 检查 OAuth 配置,确保 iss 参数正确 |
| Mcp-Method / Mcp-Name Header | 中 | 如果在网关层做了 body 检测路由,需适配 |
十二、总结:MCP 的「HTTP 时刻」
MCP 这次升级确实是「断了后路」式的重构——Session 直接删掉,Tasks 直接重写。但方向是对的。Stateless 协议让水平扩展和网关路由变得极其简单,以前需要 Sticky Session + 共享存储的架构可以扔进垃圾桶了。MCP 服务器终于可以像普通 HTTP API 一样部署、扩容和运维。
1991 年,HTTP 从有状态的 FTP 会话中解放出来,成为无状态协议,奠定了现代互联网的基础设施。2026 年,MCP 正在经历同样的蜕变。
协议层解决「怎么连」,SDK 层解决「怎么写」,去会话化解决「怎么运维」——三层叠加,MCP 才真正具备了生产级部署的底气。
对于开发者来说,现在正是迁移的最佳时机:
- 立即运行兼容性扫描脚本,看看代码里踩了几个坑
- 在 staging 环境先升级,别在生产环境直接莽
- 优先验证无状态部署,将 MCP 服务器切换到 Stateless 模式
- 规划显式句柄迁移,将隐式 Session 状态重构为工具返回的显式句柄
- 生产环境建议同时支持 v1/v2 双协议,直到所有客户端升级完成
MCP 的去状态化不是终点,而是起点。当协议层不再成为瓶颈,开发者可以把更多精力放在构建真正有价值的 AI 工具和应用场景上。这才是技术演进的真正意义。
参考资源:
- MCP 2026-07-28 Release Candidate Blog: https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate
- MCP Draft Specification: https://modelcontextprotocol.io/specification/draft
- 官方 MCP Conformance Test Framework: https://github.com/modelcontextprotocol/conformance
- GitHub Changelog - GitHub MCP Server 已支持下一版 MCP 规范: https://github.blog/changelog/2026-07-23-github-mcp-server-supports-the-next-mcp-specification/