连接生命周期与初始化
一次 MCP 会话并非"连上就用",双方要先握手协商版本与能力,再进行常规调用,最后以取消或关闭收尾。本章按生命周期顺序梳理初始化、方法调用、ping、取消与结束。
会话从握手开始
生命周期分三个阶段:初始化(initialize)→ 常规操作 → 结束(shutdown)。所有消息都带 jsonrpc 字段与请求 id,用于配对请求与响应。
initialize 握手
客户端先发 initialize,声明协议版本与自身能力;服务器返回自己支持的版本与能力清单,两侧以较低共同点协商:
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {"name": "my-host", "version": "1.0.0"}}}
{"jsonrpc": "2.0", "id": 1, "result": {
"protocolVersion": "2025-06-18",
"capabilities": {"tools": {}, "resources": {}},
"serverInfo": {"name": "demo-server", "version": "1.0.0"}}}
capabilities 是关键:客户端可声明 sampling、roots 等能力,服务器声明 tools/resources/prompts 等;双方只调用对方声明过的能力。实际支持的协议版本随规范演进,以 modelcontextprotocol.io 官方规范为准。
initialized 通知
握手成功后,客户端必须发一条 initialized 通知,告诉服务器"可以开始常规操作":
{"jsonrpc": "2.0", "method": "notifications/initialized"}
之后客户端才能发送 tools/list 等业务请求;此前若发,服务器可拒绝。这也是"先协商再干活"的纪律体现。
常规方法调用序列
典型顺序为:初始化 → 通知 initialized → 列举并调用工具 / 读取资源 / 获取提示词。请求与响应通过 id 配对,响应无固定先后,可乱序返回:
{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
{"jsonrpc": "2.0", "id": 3, "method": "tools/call",
"params": {"name": "add", "arguments": {"a": 1, "b": 2}}}
保活:ping
连接空闲时可发 ping 探测对方是否存活,收到即回空 result:
{"jsonrpc": "2.0", "id": 4, "method": "ping"}
{"jsonrpc": "2.0", "id": 4, "result": {}}
取消:cancelled 通知
客户端不想等某个长请求时,用 notifications/cancelled 通知服务器放弃对应请求(携带被取消的请求 id 与原因);是否真的停止由服务器实现决定:
{"jsonrpc": "2.0", "method": "notifications/cancelled",
"params": {"requestId": 3, "reason": "user cancelled"}}
长任务期间服务器还可发 notifications/progress 上报进度(概念性了解即可,详见官方规范)。
结束会话:shutdown
- stdio 传输:客户端关闭子进程/管道即结束,服务器随之退出,无需专门结束消息。
- HTTP 传输:会话由传输层会话标识维系,客户端停止请求并释放会话即关闭。 具体关闭语义随传输与 SDK 而变,以官方规范为准。
小结
生命周期可记为"握手协商、通知开工、按 id 配对干活、ping 保活、cancelled 取消、关传输收尾"。下一章看承载这一切的传输层:stdio 与 Streamable HTTP。