返回 AICAP-180
B6 · Day 51真 MCP server (2026-07-28 spec)

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-based2026-07-28 stateless core
握手必需 initialize + Mcp-Session-Id每请求独立,会话头降级为可选
路由粘性路由(sticky)普通 round-robin LB
tools/list每会话维护纯发现、可按 TTL 缓存
扩容受会话亲和约束无状态横向扩容
上下文server 端记忆客户端每请求携带

为什么 stateless 是对的设计:新规范允许 server 把每个 JSON-RPC 请求当成独立的 HTTP 调用处理——不需要先握手、不需要会话头、不需要把状态留在某台机器上。三个直接好处:

  1. 能直接跑在普通 HTTP round-robin 负载均衡器后面,任意节点都能回任意请求。
  2. tools/list 是纯发现操作、对所有客户端返回相同结果,于是可以被客户端按 TTL 缓存,省掉重复往返。
  3. 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: -32601INVALID_PARAMS: -32602INTERNAL_ERROR: -32603TOOL_NOT_FOUND: -32001——这里已经映射到标准 JSON-RPC 码,比 seed 里担心的「自定义 throw 未映射」要好。但注意 call()(line 183,非信封版)抛的是 McpCallError,要靠 handle() 在 line 211 把它折成 response.error 才完成映射——网络版需要确保这层映射在 transport 边界仍然成立。

进程内 mock 缺哪 5 项(差距表)

#缺失项规范要求mock 现状
1transportHTTP endpoint(POST 收 JSON-RPC / GET 升 SSE)只是函数调用 handle(req),无网络
2authBearer / OAuth 2.1 授权无任何鉴权,谁都能调
3跨进程边界客户端与 server 跨网络/跨进程同进程内存 Map,非网络边界
4SSE 通道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. 今日实战

  1. Read src/agent/mcp/toolRegistry.ts,逐行对照上面 5 项。
  2. 把 5 行差距表落进 docs/aipa/day51-mcp-spec.md,每行写清「规范要求 / mock 现状 / 补齐方式」。
  3. 在文档里标注「本日纯文档+差距分析,不写网络代码、不跑模型」,并写明 W11 真 server 构建必须排在 07-28 规范定稿之后。
  4. 不改动 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