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_itemapply_discountcheckout之间传递,甚至在不同的子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强化,正是向这一方向迈出的关键一步。


参考文献:

  1. Announcing v2.0 of the official MCP C# SDK,.NET Blog,2026-07-27
  2. SEP-2575: Make MCP Stateless,Model Context Protocol
  3. SEP-2567: Sessionless MCP via Explicit State Handles,Model Context Protocol
  4. How AgentCore Gateway supports the MCP 2026-07-28 spec,AWS Blog,2026-07-27
  5. MCP无状态化之后:Agent协议真正开始竞争什么?,IT168,2026-07-30
  6. July 28 MCP Update: Safe Migration with agentgateway,AAIF,2026-07-28
  7. MCP协议转向无状态架构,让企业级AI扩展更简单,至顶网,2026-07-30
  8. chump_mcp_lifecycle,Docs.rs
  9. go-sdk v1.7.0-pre.1 Release Notes,GitHub
  10. 探索 MCP 传输的未来,Model Context Protocol,2025-12-19
  11. AgentScope MCP Tutorial,GitHub
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐