MCP 2026-07-28 stateless 规范精读
B1→B50 我们一直在「进程内」把工具暴露给 LLM——评测方法论(B1)、attention/KV(B2)、agent loop(B3)、reasoning/multi-agent(B4)、tool/context engineering(B5)。B5 收口时(Day 50)已经能用双模型 + κ 给「v2 工具带来 Δ」做数字归因,但所有工具调用都还停在同一个 Node 进程里的函数调用。B
阶段: B6 · 真 MCP server (2026-07-28 spec)(Day 51-60) 标签: #mcp #stateless #json-rpc #protocol-design
今日导引(由浅入深)
B1→B50 我们一直在「进程内」把工具暴露给 LLM——评测方法论(B1)、attention/KV(B2)、agent loop(B3)、reasoning/multi-agent(B4)、tool/context engineering(B5)。B5 收口时(Day 50)已经能用双模型 + κ 给「v2 工具带来 Δ」做数字归因,但所有工具调用都还停在同一个 Node 进程里的函数调用。B6 这十天要把这层「工具契约」抬到网络边界上:让工具真正变成一个能被任意 MCP 客户端(含 LLM)通过 HTTP 调用的远端 server。今天是 B6 的第 0 步——先读懂 2026-07-28 规范为什么是 stateless,并把仓库里已有的进程内 mock(toolRegistry.ts)对照规范,列出「要变成真 server 还差哪 5 项」。今日最小可判定产出:一张 5 行差距表 + docs/aipa/day51-mcp-spec.md。
0. 协议背景速记
- MCP 定位:Anthropic 2024-11 提出的开放协议,把「LLM ↔ 外部工具/数据」的连接标准化,避免 N×M 的私有集成。
- 本批次任务线:B6(Day 51-60)把仓库里已有的进程内工具 mock 抬到 MCP 网络边界,最终在 Day 56 把 AML 工具集真正暴露成可被 LLM 客户端调用的远端工具。
- 今天定位:纯规范精读 + 差距分析,不写网络代码、不跑模型——为后面 9 天的构建定下「按 2026-07-28 stateless 语义来」的总基调。
1. 机理精读
MCP 的核心抽象:Model Context Protocol 把「LLM 能调用的外部能力」标准化为三类原语:
- tools:可被 LLM 调用的函数(带 name/description/inputSchema)。
- resources:可读上下文(按 URI 寻址的只读数据)。
- prompts:可复用的提示模板。
本批次只聚焦 tools,因为它直接对应我们前 50 天攒的 AML/agent 工具集。tools 的协议形状是 JSON-RPC 2.0:
- 客户端发
tools/list→ 发现有哪些工具、各自契约。 - 客户端发
tools/call→ 执行某个工具、拿回结构化结果。
2026-07-28 规范的核心变化是 stateless 化。要理解它,先看旧版 session-based 的痛点:
- 旧版 Streamable HTTP transport 要求服务端维护 session:客户端先
initialize握手拿到一个Mcp-Session-Id。 - 之后每个请求都带这个 id,server 端按 id 维护一条 SSE 长连接来推送通知。
- 致命的运维代价是必须粘性路由(sticky session):同一个客户端的所有请求必须打到持有它 session 的那台机器,否则 session 找不到。
- 结果:MCP server 没法简单地跑在普通负载均衡器后面,水平扩容很别扭、某台机器崩了会话就丢。
session vs stateless 的对照:
| 维度 | 旧版 session-based | 2026-07-28 stateless core |
|---|---|---|
| 握手 | 必需 initialize + Mcp-Session-Id | 每请求独立,会话头降级为可选 |
| 路由 | 粘性路由(sticky) | 普通 round-robin LB |
tools/list | 每会话维护 | 纯发现、可按 TTL 缓存 |
| 扩容 | 受会话亲和约束 | 无状态横向扩容 |
| 上下文 | server 端记忆 | 客户端每请求携带 |
为什么 stateless 是对的设计:新规范允许 server 把每个 JSON-RPC 请求当成独立的 HTTP 调用处理——不需要先握手、不需要会话头、不需要把状态留在某台机器上。三个直接好处:
- 能直接跑在普通 HTTP round-robin 负载均衡器后面,任意节点都能回任意请求。
tools/list是纯发现操作、对所有客户端返回相同结果,于是可以被客户端按 TTL 缓存,省掉重复往返。- server 端无状态意味着可以无脑横向扩容、崩了重启不丢会话。
关键权衡:上下文搬到客户端。stateless 不是免费的:
- server 不再替你记住「这个会话之前发生了什么」,所以上下文需要由客户端在每次请求里携带。
- 对 tools 这类无副作用/幂等的发现+调用来说代价很小(每次 call 自带全部参数本来就是合理的)。
- 但对需要长任务/进度推送的场景,2026 规范把这部分从核心挪进了 Tasks extension(
tasks/get|update|cancel),不强加给所有 server。 - 这是「核心极简、复杂度按需扩展」的典型权衡——把状态成本从「所有 server 默认承担」改成「需要的人显式选用扩展」。
与相邻概念的边界:stateless ≠ 无 SSE。
- 规范仍允许 GET 升级为 SSE 做 server→client 推送(明天 Day 52 会落地),只是不再强制用 session 头绑定。
- 也就是说
Mcp-Session-Id从「必需握手」降级为「可选优化」——这正是下次复查点要确认的字段(07-28 定稿是否真把它降级为 optional)。 - 还要区分:stateless 是协议层无会话,不代表工具 handler 内部不能有自己的持久化(DB 写入仍可有副作用)——无状态约束的是 MCP 协议会话,不是业务数据。
2. 推导 / 手算 / 代码走读
今天是代码对照日。Read src/agent/mcp/toolRegistry.ts,它是仓库里真实存在的进程内 mock。关键符号与行为:
McpToolRegistry(line 147):进程内注册表,用Map<string, RegisteredTool>存工具。这是「同进程内存」,不是网络边界。register(spec, handler)(line 151):声明name/description/inputSchema(JSON-Schema),重名抛错、name 不合法抛错、inputSchema.type非 object 抛错——契约校验做得不错,但全在本进程。list()(line 169):tools/list的进程内版,返回按 name 稳定排序的 spec 列表(a.name.localeCompare(b.name))。注释明确写了 "stateless:不依赖任何会话,结果可被客户端按 ttl 缓存"——形状对了,但没有 HTTP。handle(req)(line 199):JSON-RPC dispatch,但它是个纯函数调用,不是 HTTP handler——req直接是构造好的JsonRpcRequest对象,没有经过任何 transport 反序列化。- 错误码常量
RPC(line 85):METHOD_NOT_FOUND: -32601、INVALID_PARAMS: -32602、INTERNAL_ERROR: -32603、TOOL_NOT_FOUND: -32001——这里已经映射到标准 JSON-RPC 码,比 seed 里担心的「自定义 throw 未映射」要好。但注意call()(line 183,非信封版)抛的是McpCallError,要靠handle()在 line 211 把它折成response.error才完成映射——网络版需要确保这层映射在 transport 边界仍然成立。
进程内 mock 缺哪 5 项(差距表):
| # | 缺失项 | 规范要求 | mock 现状 |
|---|---|---|---|
| 1 | transport | HTTP endpoint(POST 收 JSON-RPC / GET 升 SSE) | 只是函数调用 handle(req),无网络 |
| 2 | auth | Bearer / OAuth 2.1 授权 | 无任何鉴权,谁都能调 |
| 3 | 跨进程边界 | 客户端与 server 跨网络/跨进程 | 同进程内存 Map,非网络边界 |
| 4 | SSE 通道 | GET 升级 SSE 做 server→client 推送 | 无 GET 流式通道 |
| 5 | 错误码 transport 映射 | 校验失败必须经 JSON-RPC -32xxx 跨网络返回 | call() 抛 McpCallError,仅 handle() 折叠,跨网络未验证 |
注:第 5 项现状比 seed 描述的乐观——常量已映射,但「跨网络往返时仍正确返回」要等 Day 55 在真 transport 上验。
5 项的补齐节奏(B6 路线图):
- 第 1 项 transport → Day 52(
StreamableHTTPServerTransport+ curl 通initialize)。 - 输入声明从手写 JsonSchema → Zod → Day 53(
server.tool+ Zod 单一真相源)。 - 第 4 项发现层网络语义 → Day 54(Inspector 调
tools/list,核对排序稳定)。 - 第 5 项执行层 + 错误码 → Day 55(
tools/call成功content/ 失败-32602)。 - 业务工具上网 → Day 56(AML 三工具:
assessCase/draftSar/listTypologies)。 - 第 2 项 auth(OAuth 2.1)+ 安全 + CI gate → 下一批 B7。
这条节奏说明今天的差距表不是清单堆砌,而是后面 9 天的施工图——每一项都对应一个可判定的产出日。
3. 今日实战
- Read
src/agent/mcp/toolRegistry.ts,逐行对照上面 5 项。 - 把 5 行差距表落进
docs/aipa/day51-mcp-spec.md,每行写清「规范要求 / mock 现状 / 补齐方式」。 - 在文档里标注「本日纯文档+差距分析,不写网络代码、不跑模型」,并写明 W11 真 server 构建必须排在 07-28 规范定稿之后。
- 不改动
toolRegistry.ts——它作为进程内对照基线保留。
4. 今日实测 / 产出
- 待建——提交
docs/aipa/day51-mcp-spec.md,含 5 行差距表。 toolRegistry.ts已在仓库(进程内 mock 真实存在),本日仅文档 + 差距分析。- 无需 key、无需跑模型。
5. 常见误区 / 陷阱
- 把 stateless 误读成「server 不能有 SSE」:stateless 只是不强制 session 头,SSE 推送仍允许,只是改成可选优化。
- 以为进程内 mock 已经是「server」:它只复刻了协议形状(JSON-RPC 信封 + tools/list + tools/call + schema 校验),缺 transport/auth/跨进程,离真 server 还有 5 项。
- 把「协议无状态」误读成「业务无状态」:MCP 会话层无状态,但工具 handler 内部仍可写 DB、产生副作用——两层别混。
- 抢跑 W11:规范 07-28 才定稿,现在按 RC(2026-05-21 锁定)写代码有返工风险,本日只做文档。
- 忽视
Mcp-Session-Id的状态变化:旧叙事把它当必需握手,新规范可能降级为可选——不要照搬旧文档。
6. 学习资源(每条带 YYYY-MM)
- MCP Specification — stateless core / Streamable HTTP 章节(草案,2026-07-28 预定定稿)
- MCP Specification RC(2026-05-21 锁定)——本笔记写作时的最新冻结版
src/agent/mcp/toolRegistry.ts头部注释(2026-06)——仓库内对 stateless 语义的诚实标注与 MCPTox/NIST CAISI 引用- JSON-RPC 2.0 Specification(2010 起,长期有效)——
tools/list/tools/call信封与-32xxx错误码的底层标准 - Anthropic《Model Context Protocol》官方介绍(2024-11 首发,持续更新)
SOTA检查 (2026-06 更新)
- 当前主流:MCP 2026-07-28 stateless core 是 agent 工具暴露的事实标准方向;进程内 mock 复刻其协议形状是合理的预研手段。
- 是否仍 SOTA:规范在本笔记写作时尚未最终定稿——硬日期复查点 07-28。届时重验
Mcp-Session-Id是否真被降级为可选、Tasks/Apps 扩展是否进核心。 - 过时黑名单(AVOID):旧的 session-based Streamable HTTP 叙事作主线;把粘性路由当成 MCP 的必要前提。
- 下次复查点:07-28 规范定稿当天;W11 server 构建必须排在其后。
衔接
- 昨天:Day 50 — Block 收口与归因(用双模型 + κ 给 v2 工具 Δ 做数字归因,进程内工具集定稿)
- 今天:读懂 2026-07-28 stateless 规范,列进程内 mock 缺的 5 项,确立「抬到网络边界」的路线图
- 明天:Day 52 — Streamable HTTP transport + 官方 TS SDK v1.x(用
McpServer真起一个本地 HTTP server,curl 通initialize)