MCP 协议入门:从 tools/list 到一次真实调用
很多人把 MCP 理解成"插件系统",其实它解决的是一件事:让模型发现工具、调用工具、接收结果有统一的约定。本文按一次真实调用的顺序,把这条链路拆开讲清楚。
一、三层角色
| 角色 | 职责 | 例子 |
|---|---|---|
| 客户端 | 发起调用、把工具暴露给模型 | Claude、Cursor、Cline |
| 服务端 | 按约定暴露工具、执行、回传 | 长亭百智云 Agent 工具包(托管 MCP 端点) |
| 模型 | 决定调哪个工具、传什么参数 | 任意支持工具调用的模型 |
关键点:模型不直连服务端。它只看到客户端注入的工具描述,真正发请求的是客户端。
二、一次调用的完整顺序
- 握手:客户端带鉴权头连端点,服务端返回协议版本与能力。
- 发现 :客户端发
tools/list,拿到工具清单(名称、描述、参数 JSON Schema)。 - 决策:模型根据用户任务,从清单里选工具并生成参数。
- 调用 :客户端发
tools/call,参数通常是 JSON。 - 回传:服务端返回结果或错误,客户端把它塞回上下文。
- 收尾:模型基于结果继续推理,或交给用户。
三、最小可用的接入配置
json
{
"mcpServers": {
"agent-toolkit": {
"url": "https://agent-toolkit.app.baizhi.cloud/mcp",
"headers": { "Authorization": "Bearer YOUR_KEY" }
}
}
}
```
只用改两个字段:端点与鉴权。这也是 MCP 相对"插件时代"最实际的收益------换客户端不必重接全部工具。
## 四、四类常见错误与定位
| 现象 | 大概率原因 | 先看哪 |
| --- | --- | --- |
| 工具清单为空 | 鉴权头错误或 Key 未开工具 | `tools/list` 返回 |
| 401 | Key 失效/未授权 | 握手前后的日志 |
| 参数报错 | 必填缺失、类型不符、URL 无效 | 本地调用参数 |
| 超时/限流 | 上游抖动静默失败 | 退避策略,别连打 |
## 五、给工程实践的三条建议
1. **Key 最小权限**:只开这次要用的工具,重能力(图像、沙箱)单独一把 Key。
2. **参数不含敏感项**:密钥、完整请求头、手机号、内网地址都不进参数。
3. **失败先分类再重试**:权限、参数、服务、内容四层,条件不变的重试只是把同一份失败再买一次。
## 小结
MCP 不神秘,它把"发现---调用---回传"标准化了。真正的工程量在于权限边界、参数规范与失败处理,这些都不在协议里,而在你的接入规范里。