MCP无状态化革命:从连接级会话到显式句柄的架构跃迁
MCP无状态化革命:从连接级会话到显式句柄的架构跃迁
2026年7月28日,MCP协议发布了自诞生以来最大规模的架构升级——放弃连接级session,拥抱无状态设计。这场革命让MCP Server像普通HTTP服务一样挂在负载均衡器后面横向扩展,从根本上重塑了AI Agent与真实世界的连接方式。
引言:当AI Agent从“对话”走向“执行”
2026年7月28日,Model Context Protocol(MCP)发布了自2024年底诞生以来最大规模的规范修订。这一天,MCP的月度SDK下载量已突破4亿次门槛。
这次更新的核心变化只有一个词:无状态化。MCP协议去掉了从v1.0沿用至今的initialize握手和Mcp-Session-Id会话头,每个HTTP请求变成了一个自包含的独立单元,任何服务器实例都能处理任何请求。
无状态化的深层含义是:Agent协议正在离开“怎样把模型接到工具上”的早期阶段,转向面对一个更像组织管理的问题——一个会说话、会规划、还会行动的系统,到底能替谁做什么,谁要为那次行动负责。
一、旧版MCP的“原罪”:为什么需要无状态化?
1.1 有状态架构的三个致命缺陷
在2026-07-28规范之前,MCP的Streamable HTTP传输要求客户端先完成initialize/notifications/initialized握手,服务器返回一个Mcp-Session-Id,后续所有请求必须携带这个ID,将客户端“钉”在发出该session的服务器实例上。
这种设计带来三个问题:
| 问题 | 具体表现 |
|---|---|
| 扩展瓶颈 | 负载均衡器需要启用“粘性会话”,无法用普通轮询方式分发请求。水平扩展变成了运维噩梦 |
| 容错脆弱 | 持有session的实例崩溃,会话状态全部丢失。客户端必须重新握手建立新session,中断不可避免 |
| 开发者负担 | 服务端要维护session生命周期、处理垃圾回收;客户端要管理重连和状态恢复逻辑 |
一个行业专家的评价很到位:“基于会话的模型在MCP还是开发者本地进程时是合理的,但进入生产环境后,它就变成了一种运维负担。当基础设施团队问MCP服务能否像其他云应用一样弹性扩展时,以前的答案是‘不完全行’,转向无状态架构之后,答案就变成了‘可以’。”
1.2 会话的“未定义生命周期”
MCP规范从未明确定义session何时开始、何时结束,因为它完全取决于宿主应用。在实践中,不同客户端的实现差异巨大:
| 客户端类型 | 会话生命周期 |
|---|---|
| ChatGPT | 每次工具调用创建一个全新session |
| Claude.ai(旧版) | 每个对话一个session |
| 桌面/IDE客户端 | 应用启动时创建,直到进程结束 |
| Web客户端 | 每次页面加载创建新session |
服务器作者无法预测session在自己服务器上会对应什么——是一个用户回合、一个Agent进程、还是一个长对话。这让session作为应用状态容器变得不可靠。
二、无状态化的三大支柱:SEP-2575、SEP-2567与SEP-2322
2.1 SEP-2575:移除初始化握手
SEP-2575的核心是将initialize/notifications/initialized握手彻底移除。在2026-07-28规范中,每个请求在_meta字段中携带自己的协议版本、客户端信息与能力声明:
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: create_basket
Content-Type: application/json
Accept: application/json,text/event-stream
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_basket",
"arguments": {},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {"name": "my-app", "version": "1.0"},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
客户端可通过新的server/discover方法随时查询服务器能力,替代旧版的握手协商。
2.2 SEP-2567:移除Mcp-Session-Id
如果说SEP-2575移除了session的“创建仪式”,SEP-2567则移除了session本身的存在依据。规范删除了Mcp-Session-Id头,并明确声明协议在每一层都是无会话(sessionless)的。
2.3 SEP-2322:多轮往返请求(MRTR)
无状态架构面临一个核心矛盾:如果一个工具需要中途向用户提问(比如“确认删除吗?”),旧版依赖持久session通道的“服务器发起请求”模式不再适用。
MRTR的解决方案是:服务器返回一个InputRequiredResult,携带一个requestState不透明字符串和一个或多个输入请求。客户端收集输入后,用同样的requestState重新发起同一个tools/call请求。由于所有连续性信息都在请求体中传递,任何服务器实例都能处理重试。
以下是一个C#服务器实现中,工具请求用户确认的例子:
[McpServerTool, Description("Closes a customer account")]
public static async Task<CallToolResponse> CloseAccount(
[Description("The customer ID")] string customerId,
IMcpServer server,
CancellationToken cancellationToken)
{
if (await IsCustomerEligible(customerId, cancellationToken))
{
// 需要用户确认
throw new InputRequiredException(
"Confirm account closure",
InputRequest.ForElicitation(
"confirm_deletion",
"Are you sure you want to close this account? This action cannot be undone."
),
requestState: JsonSerializer.Serialize(new { customerId })
);
}
await CloseAccountInternal(customerId, cancellationToken);
return new CallToolResponse()
.AddText($"Account {customerId} closed successfully.");
}
三、显式句柄:从隐式会话到显式状态的范式转移
3.1 核心思想:状态是数据,不是连接
有状态架构把状态藏在连接里(Mcp-Session-Id隐式绑定了购物车、浏览器实例、数据库事务)。无状态化之后,状态成为显式对象——服务器生成一个句柄(handle),在工具结果中返回,模型后续调用时作为普通参数传回。
SEP-2567的核心表述是:“显式状态句柄不是一个新协议构造——没有针对它们的schema或wire格式。它们是工具设计模式。”
3.2 代码对比:旧模式 vs 新模式
旧模式(隐式session状态):
// 会话隐式绑定了购物车
POST /mcp
Mcp-Session-Id: abc123
{"method":"tools/call","params":{"name":"add_item","arguments":{"sku":"shoes"}}}
新模式(显式句柄):
第一步:创建购物车,获得句柄
POST /mcp
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: create_basket
Content-Type: application/json
Accept: application/json,text/event-stream
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {"name": "create_basket", "arguments": {}}
}
响应:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [{"type": "text", "text": "Created basket bsk_a1b2c3"}],
"structuredContent": {"basket_id": "bsk_a1b2c3"}
}
}
第二步:用句柄执行操作
POST /mcp
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: add_item
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "add_item",
"arguments": {"basket_id": "bsk_a1b2c3", "sku": "shoes"}
}
}
句柄模式的威力在于模型可以跨工具组合状态:一个购物车ID可以在add_item、apply_discount、checkout之间传递,甚至在不同的子Agent之间共享。session做不到这一点——购物车被锁死在创建它的连接里。
四、路由头与边缘计算:让HTTP基础设施“看见”MCP
无状态化还解锁了另一个关键能力:MCP请求可以被标准HTTP基础设施理解。
2026-07-28规范引入了一组标准化HTTP头(SEP-2243),让负载均衡器、API网关、WAF能在不解析JSON-RPC请求体的情况下理解请求:
| HTTP头 | 作用 |
|---|---|
MCP-Protocol-Version |
声明协议版本 |
Mcp-Method |
声明JSON-RPC方法(如tools/call) |
Mcp-Name |
声明具体工具名称(如get_order_status) |
以下C#示例展示了如何将工具参数提升为路由头,让负载均衡器据此分发请求:
[McpServerTool(Name = "get_order_status"),
Description("Gets order status from the regional orders service")]
public static async Task<string> GetOrderStatus(
OrdersServiceClient orders,
[McpHeader("Region"), Description("Orders service region")] string region,
[Description("The order to look up")] string orderId)
{
// 客户端会将region复制到请求头: Mcp-Param-Region: eastus2
return await orders.GetStatusAsync(region, orderId);
}
五、无状态化的工程实践
5.1 ASP.NET Core中的无状态MCP服务器
Microsoft官方MCP C# SDK v2.0中,无状态是默认配置:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMcpServer()
.WithHttpTransport() // stateless by default now
.WithToolsFromAssembly();
var app = builder.Build();
app.MapMcp();
app.Run("http://localhost:3001");
部署到负载均衡器后面无需任何同步配置。
5.2 AgentScope的双模式支持
AgentScope框架同时提供有状态和无状态两种MCP客户端,开发者可根据场景选择:
# 有状态客户端:维护持久会话
stateful_client = HttpStatefulClient(
name="mcp_services_stateful",
transport="streamable_http",
url="https://mcp.amap.com/mcp?key=xxx"
)
# 无状态客户端:每次调用独立建立和销毁会话
stateless_client = HttpStatelessClient(
name="mcp_services_stateless",
transport="streamable_http",
url="https://mcp.amap.com/mcp?key=xxx"
)
六、总结:无状态化之后,Agent协议真正竞争什么?
无状态化让MCP可以像HTTP一样部署和扩展。它完成了从“怎样把模型接到工具上”到“一个会说话、会规划、还会行动的系统,到底能替谁做什么”的转变。当Agent开始替人做不可逆的动作时,决定性的不再是协议本身的技术细节,而是身份验证、权限拆分、授权审计和追责机制。MCP 2026-07-28版本的企业级管理认证和OAuth 2.1强化,正是向这一方向迈出的关键一步。
参考文献:
- Announcing v2.0 of the official MCP C# SDK,.NET Blog,2026-07-27
- SEP-2575: Make MCP Stateless,Model Context Protocol
- SEP-2567: Sessionless MCP via Explicit State Handles,Model Context Protocol
- How AgentCore Gateway supports the MCP 2026-07-28 spec,AWS Blog,2026-07-27
- MCP无状态化之后:Agent协议真正开始竞争什么?,IT168,2026-07-30
- July 28 MCP Update: Safe Migration with agentgateway,AAIF,2026-07-28
- MCP协议转向无状态架构,让企业级AI扩展更简单,至顶网,2026-07-30
- chump_mcp_lifecycle,Docs.rs
- go-sdk v1.7.0-pre.1 Release Notes,GitHub
- 探索 MCP 传输的未来,Model Context Protocol,2025-12-19
- AgentScope MCP Tutorial,GitHub
更多推荐


所有评论(0)