AI 调用 MCP 的全流程教程(基于 Streamable HTTP)
AI 调用 MCP 全流程摘要 MCP(Model Control Protocol)规范了AI系统与工具间的交互流程。核心步骤包括: 配置MCP Server地址(TOML/JSON) 模型解析用户请求,生成工具调用意图 建立MCP会话(initialize/initialized握手) 获取工具目录(tools/list) 执行工具调用(tools/call),支持JSON/SSE两种返回格式
AI 调用 MCP 的全流程教程(基于 Streamable HTTP)
协议基线:MCP
2025-11-25
更新时间:2026-03-25
1. 先分清三层职责
在实际系统里,通常有这 3 个角色:
Host:承载 AI 的应用(例如 Codex CLI、IDE 插件、你自己的 Agent 服务)MCP Client:Host 内部的协议执行器(负责发initialize/tools/list/tools/call)MCP Server:能力提供者(真正执行工具逻辑)
一句话:
模型负责“决策”,MCP Client 负责“调用”,MCP Server 负责“执行”。
2. 全流程总览(从用户到结果)
用户输入
-> Host 收到请求并交给模型
-> 模型判断需要工具调用
-> Host 选择 MCP Server
-> (首次) initialize + notifications/initialized
-> tools/list(必要时)
-> tools/call(JSON 或 SSE)
-> Host 接收工具结果
-> 结果回注给模型二次推理
-> 输出最终自然语言答案给用户
说明:
“如何选哪个 MCP Server”属于 Host 的实现策略。initialize/initialized/tools/list/tools/call是协议定义的交互动作。
3. 第 0 步:Host 里先有 MCP Server 配置
以 Codex CLI 为例(TOML):
[mcp_servers.chrome-mcp-server]
url = "http://localhost:12306/mcp"
或命令行添加:
codex mcp add chrome-mcp-server --url http://localhost:12306/mcp
codex mcp list
等价的通用 JSON 配置(很多其他客户端使用):
{
"mcpServers": {
"chrome-mcp-server": {
"url": "http://localhost:12306/mcp"
}
}
}
它们语义一致,只是“客户端配置格式”不同。
4. 第 1 步:用户输入到模型解析
用户输入示例:
帮我查询上海明天的天气,并给出穿衣建议
Host 把这些信息一起交给模型:
- 用户输入
- 会话上下文
- 当前可用 MCP server(及可用工具缓存)
- 策略约束(权限、预算、超时、可访问租户等)
模型产出工具意图(内部形态通常类似):
{
"need_tool": true,
"candidate_tool": "weather.get_forecast",
"arguments_draft": {
"city": "Shanghai",
"date": "2026-03-26"
}
}
5. 第 2 步:Host 选择调用哪个 MCP Server
这一步通常按策略执行,不是协议硬编码。
常见策略顺序:
- 看本地缓存中“工具名 -> server”映射
- 校验权限、租户、数据域匹配
- 比较稳定性、延迟、成本
- 命中失败时触发
tools/list重新发现
如果 server 发了 notifications/tools/list_changed:
- 失效本地缓存
- 重新拉取工具目录
- 重新做映射
6. 第 3 步:建立 MCP 会话(initialize)
当该 server 还没有会话时,先初始化。
6.1 请求示例
POST /mcp HTTP/1.1
Host: localhost:12306
Content-Type: application/json
Accept: application/json, text/event-stream
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {
"tools": {},
"resources": {},
"prompts": {}
},
"clientInfo": {
"name": "codex-cli",
"version": "x.y.z"
}
}
}
6.2 响应要点
- body 返回
InitializeResult - 服务端可能在响应头返回
MCP-Session-Id
示意:
HTTP/1.1 200 OK
Content-Type: application/json
MCP-Session-Id: a4f0a1de-xxxx
6.3 发送 initialized 通知
初始化成功后,客户端必须发送:
{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}
通知通常无 id,服务端可回 202 Accepted。
7. 第 4 步:拉取工具目录(tools/list)
请求:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {
"cursor": null
}
}
返回内容通常包含:
namedescriptioninputSchema- 可选
outputSchema - 可选分页
nextCursor
Host 的关键动作:
- 用
inputSchema做参数校验 - 对参数做类型修正(如日期、枚举、单位)
- 缓存工具目录以减少后续发现开销
8. 第 5 步:调用工具(tools/call)
请求示例:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "weather.get_forecast",
"arguments": {
"city": "Shanghai",
"date": "2026-03-26"
}
}
}
8.1 Streamable HTTP 下的两种返回形态
服务端可返回:
application/json(一次性返回)text/event-stream(SSE,流式返回)
8.2 SSE 返回时会发生什么
SSE 可能先发进度通知,再发最终 response。
示意:
event: message
data: {"jsonrpc":"2.0","method":"notifications/progress","params":{"progress":0.5}}
event: message
data: {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"18-23C, cloudy"}],"isError":false}}
重要点:
- 断开流不等于取消任务
- 要取消应发
notifications/cancelled - 若服务端支持恢复,可
GET /mcp+Last-Event-ID续流
9. 第 6 步:结果回注模型并生成最终答复
Host 收到 tools/call 的结果后,会把结果作为新上下文再喂给模型。
模型第二次推理通常做 3 件事:
- 提取工具核心信息
- 结合用户目标重写成自然语言
- 决定是否继续调用下一个工具
例如:
- 工具原始结果:
18-23C, cloudy - 模型输出给用户:
上海明天多云,18~23℃。建议薄外套+长裤,早晚加一层。
10. 第 7 步:错误处理、重试与降级
MCP 调用常见两类错误:
- JSON-RPC
error
- 协议错误、参数结构错误、方法不存在
- 处理:立刻修正请求,不要盲重试
result.isError = true
- 工具业务执行失败(例如第三方 API 超时)
- 处理:可重试、切换工具、或让模型改参数后重试
推荐重试策略:
- 网络类错误:指数退避 + 抖动(如 200ms, 800ms, 1600ms)
- 幂等工具可自动重试
- 非幂等工具需幂等键或人工确认
11. 第 8 步:会话管理与收尾
正常情况下会话可复用,减少反复握手成本。
每次请求应携带(如适用):
MCP-Session-IdMCP-Protocol-Version
不再需要会话时可主动结束:
DELETE /mcp
MCP-Session-Id: a4f0a1de-xxxx
如果服务端返回 404(会话失效):
- 重新
initialize - 发送
notifications/initialized - 恢复业务调用
12. 完整时序图
13. 最小可观测字段(建议日志)
建议每次调用都记录这些字段,排障效率会明显提升:
trace_idconversation_idserver_namemethod(initialize/tools/list/tools/call)request_id(JSON-RPC id)latency_msretry_counthttp_statusjsonrpc_error_code(若有)is_error(工具业务失败标记)
14. 安全与边界控制
- 仅信任白名单 MCP Server
- 高风险工具(写库/下单/删除)增加确认门禁
- 参数级策略校验(日期范围、金额上限、资源路径)
- HTTP 传输启用认证(Bearer/OAuth 等)
- 远程服务做 Origin 校验与速率限制
- 工具执行设置超时与资源配额
15. 常见误解
误解 1:模型直接调用了后端系统
不是。模型只做决策,真正发请求的是 Host 内的 MCP Client。
误解 2:tools/list 每次都必须调
不是。多数 Host 会缓存,收到 list_changed 再刷新。
误解 3:SSE 断开等于任务取消
不是。取消要走 notifications/cancelled。
误解 4:协议规定了“如何选择哪个 server”
不是。选择策略由 Host 实现,协议只定义交互方法与消息格式。
16. 一句话回顾
AI 调用 MCP 的本质是:
- 模型做“工具决策”
- MCP Client 做“协议调用”
- MCP Server 做“能力执行”
- Host 把结果再次交给模型生成最终用户答案
从工程角度看,关键成功点是:正确会话生命周期 + 可靠工具目录缓存 + 可恢复流式调用 + 严格错误与安全控制。
17. 附录 A:用 curl 手工跑通一遍
下面示例假设你的 MCP endpoint 是:
http://localhost:12306/mcp
17.1 initialize
curl -i -X POST http://localhost:12306/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"initialize",
"params":{
"protocolVersion":"2025-11-25",
"capabilities":{"tools":{}},
"clientInfo":{"name":"manual-client","version":"0.0.1"}
}
}'
你需要关注两点:
- 响应 body 是否有
result - 响应头是否有
MCP-Session-Id
17.2 notifications/initialized
如果上一步拿到了 session id,后续请求建议带上它:
curl -i -X POST http://localhost:12306/mcp \
-H 'Content-Type: application/json' \
-H 'MCP-Session-Id: <SESSION_ID>' \
-d '{
"jsonrpc":"2.0",
"method":"notifications/initialized"
}'
17.3 tools/list
curl -s -X POST http://localhost:12306/mcp \
-H 'Content-Type: application/json' \
-H 'MCP-Session-Id: <SESSION_ID>' \
-d '{
"jsonrpc":"2.0",
"id":2,
"method":"tools/list",
"params":{"cursor":null}
}'
拿到 name + inputSchema 后,再构造工具参数。
17.4 tools/call
curl -s -X POST http://localhost:12306/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Session-Id: <SESSION_ID>' \
-d '{
"jsonrpc":"2.0",
"id":3,
"method":"tools/call",
"params":{
"name":"<TOOL_NAME>",
"arguments":{}
}
}'
如果返回 text/event-stream,你会看到逐条事件;最终应有 id=3 的 response。
18. 附录 B:常见排障清单(含 WSL)
18.1 initialize 就失败
优先排查:
- URL 是否完整(必须到
/mcp) - Server 是否真的在监听该端口
- 请求头
Content-Type是否为application/json - 是否存在代理、证书或防火墙拦截
18.2 WSL 下 127.0.0.1 和 localhost 不一致
在某些 Windows + WSL 组合场景里,你会遇到:
http://localhost:12306/mcp可通http://127.0.0.1:12306/mcp不通
这是由本机回环映射、端口转发策略、以及服务绑定地址共同决定的,不是 MCP 协议问题。
实务上遵循两条:
- 哪个地址可用就用哪个(优先稳定)
- 服务端尽量明确绑定
0.0.0.0或期望网卡,并配合本机防火墙策略
18.3 tools/call 返回了但模型没给答案
常见原因:
- Host 没把工具结果回注给模型
- 工具结果字段结构异常(模型无法消费)
- 触发了安全策略拦截(高风险工具被阻断)
18.4 如何快速确认是“协议问题”还是“业务问题”
判断原则:
- 有 JSON-RPC
error:先按协议层排查(方法名、参数结构、会话头) result.isError=true:优先排查业务层(第三方 API、鉴权、数据源)
19. 官方规范入口(建议收藏)
- MCP 基础规范(2025-11-25):https://modelcontextprotocol.io/specification/2025-11-25/basic
- 生命周期(initialize / initialized):https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle
- 传输(Streamable HTTP):https://modelcontextprotocol.io/specification/2025-11-25/basic/transports
- Tools(tools/list / tools/call):https://modelcontextprotocol.io/specification/2025-11-25/server/tools
- 架构角色(Host / Client / Server):https://modelcontextprotocol.io/specification/2025-11-25/architecture
更多推荐



所有评论(0)