Jixue AI学习库
返回知识库
MCP进阶

MCP 会话生命周期与错误码

MCP 会话从 initialize 握手开始,协商协议版本与能力,initialized 通知就绪后进入请求/响应循环,直到连接终止。

01

为什么重要

绝大多数“工具调不动”的故障出在生命周期早期:版本没协商、能力没对上、通知顺序错。按生命周期分层排查,比只盯模型输出有效得多。

02

核心原理

握手由 Client 发 initialize 发起,携带它支持的 protocolVersion(协议版本按日期命名,如 2025-06-18);Server 回应一个双方兼容的版本——本站的实现是:请求版本在支持列表(2024-11-05、2025-03-26、2025-06-18)内就照用,否则回退到服务端最新版本,由 Client 决定是否继续。同一条响应还完成 capability negotiation(能力协商):Server 声明提供什么能力(如 tools.listChanged 表示工具列表变化时是否主动通知),Client 也在 initialize 里声明自己的能力(如 roots、sampling),此后只能使用双方都声明过的能力。Client 确认后必须发 notifications/initialized(通知是没有 id、不应答的消息),会话才算就绪,之后才是 tools/list、tools/call 这类正常请求/响应。协议错误用 JSON-RPC 标准错误码:-32700 解析失败、-32600 非法请求(如缺 id)、-32601 未知方法、-32602 参数不合法;注意工具执行失败不是协议错误,按 MCP 约定返回带 isError: true 的正常结果。终止没有专门方法:stdio 关进程、HTTP 断连接或删会话。本站 /labs/mcp-tools 把 initialize 到 notifications/initialized、tools/list、tools/call 的完整轨迹逐帧展示,可直接观察每条消息原文。

03

工程实现

  • 先核对 protocolVersion 与错误码,再怀疑业务逻辑
  • 只调用协商过的能力;listChanged 为 false 就别等变更推送
  • -32602 是参数问题,isError 是执行问题,处置路径不同
  • notifications/* 不应答,等响应就是死等
04

展开说明

对 POST /api/mcp 发 initialize 并指定 protocolVersion 为 2024-11-05,响应回同一版本、capabilities { tools: { listChanged: false } } 与 serverInfo;不带 id 发 notifications/initialized 得到 202 空响应,再 tools/list 拿工具清单——这套轨迹可在 /labs/mcp-tools 逐帧复现。

05

常见误区

  • 跳过 initialize 直接 tools/call
  • 把 isError 的工具失败当成协议错误去重连
  • 凭服务名猜能力,不看 initialize 返回的 capabilities
06

面试怎么说

生命周期是 initialize 协商版本与能力,initialized 通知就绪,然后请求/响应循环,最后连接终止。错误分两层:协议层走标准错误码 -32700/-32600/-32601/-32602,工具执行失败走结果里的 isError;分清这两层,排障才不会乱。