MCP 架构与角色
本节目标
学完后,你应能:
- 画出 host、client、server 的关系,并解释为什么一个 host 通常为每个 server 创建一个 client。
- 分清数据层与传输层,避免把“HTTP 已连通”误当成“协议已兼容”。
- 说清 MCP 是双向协议:server 向 client 提供能力,server 也能请求 client 提供 roots、sampling 与 elicitation。
- 为模型、用户界面、协议适配和业务系统划出责任与信任边界。
从一个真实集成问题开始
假设桌面 AI 应用要访问本地项目、公司知识库和工单系统。没有共同协议时,应用要为每个系统分别实现发现、参数描述、调用、返回、错误和授权。MCP 统一的是这条集成边界上的消息与能力协商;它不规定 Agent 怎样规划,也不替业务系统做权限判断。
可以先记住一句话:
MCP 是 host 管理的、client 与 server 之间的有状态 JSON-RPC 协议,不是“一个能自己思考的 Agent”。
三个角色
| 角色 | 直觉 | 主要责任 | 不应默认承担 |
|---|---|---|---|
| host | 用户实际使用的 AI 应用 | 管理用户体验、模型、同意、权限策略与多个连接 | 把所有上下文无条件发给每个 server |
| client | host 内的一条 MCP 协议连接 | 初始化、协商能力、收发消息、维护请求与会话状态 | 替 server 决定业务权限,或替用户同意高风险操作 |
| server | 暴露一组领域能力的程序 | 提供 tools/resources/prompts,处理获准的请求,也可请求 client features | 控制 host 使用哪个模型,或把模型意图视为授权 |
官方架构是“一条 client—server 关系对应一个有状态会话”。一个 host 可同时管理多个 client:
host(IDE / 桌面 AI 应用)
├─ client A ── server A(本地项目)
├─ client B ── server B(工单系统)
└─ client C ── server C(企业知识库)这样做的价值不是画图整齐,而是隔离:
- 每条连接有自己的协议版本、capabilities、请求 ID 与生命周期状态。
- host 可对不同 server 设置不同的数据披露、工具确认和凭据。
- 一个 server 失效或被撤权,不必破坏其他连接。
两层架构
数据层
数据层回答“双方交换什么、以什么顺序交换”。它包含:
- JSON-RPC request、response、notification;
- initialize、能力协商与会话生命周期;
- server features、client features 和通用 utilities;
- schema、错误、进度、取消和实验性 Tasks。
传输层
传输层回答“消息字节怎样到达另一端”。当前规范定义两种标准传输:
stdio:client 启动本地 server 子进程,通过 stdin/stdout 交换按行分隔的 UTF-8 JSON-RPC。- Streamable HTTP:远程或独立 server 在一个 MCP endpoint 上处理 POST/GET,可用 SSE 流式传递消息。
两层的故障证据不同:
| 现象 | 首先属于 | 不能据此断言 |
|---|---|---|
| 子进程找不到、端口不通、HTTP 401 | 进程/传输/授权 | tool schema 一定有错 |
method not found、未声明 capability | 协议/协商 | 网络一定断开 |
| 工具参数缺字段 | 工具契约 | initialize 一定失败 |
| 下游工单系统拒绝写入 | 业务/权限 | MCP 消息一定不合法 |
MCP 是双向协议
只记 tools/resources/prompts 会得到一个残缺模型。当前规范的主要能力方向是:
| 能力拥有者 | 能力 | 谁发起相关请求 | 用途 |
|---|---|---|---|
| server | tools | client → server | 调用计算或外部操作 |
| server | resources | client → server | 列举、读取或订阅上下文 |
| server | prompts | client → server | 获取可复用提示模板 |
| client | roots | server → client | 查询 host 希望 server 关注的根范围;不是授权或沙箱边界 |
| client | sampling | server → client | 请求 host 使用其模型生成;host 保留模型与权限控制 |
| client | elicitation | server → client | 通过 host 向用户请求额外信息或外部交互 |
此外还有 logging、completion、ping、progress、cancellation,以及在 2025-11-25 中引入、仍标记为实验性的 Tasks。能力是“这一会话中可使用什么”的声明,不是对任意数据和操作的永久授权。
谁控制什么
把“协议可发起”与“最终控制权”分开:
- 模型可以建议调用 tool,但 host 应让用户看见暴露了哪些工具,并为高风险操作设置确认。
- server 可以请求 sampling,但 host 决定模型、访问范围、是否展示与是否批准请求。
- server 可以请求 elicitation,但 client 必须展示请求方,允许用户接受、拒绝或取消。
- client 可以给出 roots,但 root 只是建议性的协调范围;真正的文件访问限制仍由操作系统权限、沙箱和 host 策略执行,server 也要防路径穿越和越权。
- tool annotation、resource 内容和 server instructions 都是输入;当 server 不可信时,不能把描述中的“只读”当成事实。
贯穿示例:文档审查助手
需求:用户在 IDE 中选择一个项目,让 AI 读取 Markdown、总结风险,并在确认后创建 issue。
- host 维护对话、模型和用户确认。
- project server 提供 resources;client 只暴露用户选择的 root。
- issue server 提供
create_issuetool;server 使用最小权限账号。 - 若 project server 需要模型摘要,它可以发 sampling 请求,但 host 仍审查输入与模型调用。
- 若缺少 issue 标签,可用 form elicitation 请求普通结构化信息;不得借此索要 API key。
- 每条 server 连接独立授权、记录和撤销。
这个例子同时说明:MCP 负责组合边界,Agent 的规划循环、业务授权和下游幂等性仍需单独设计。
常见误区
- “一个 server 就是一个 Agent”:server 可以只是很薄的适配器,没有规划、记忆或模型。
- “client 就是桌面应用”:在协议术语中,client 通常是 host 内的一条连接组件。
- “server 只会被调用”:server 还能向 client 请求 roots、sampling、elicitation。
- “声明 capability 就代表已授权”:capability 只说明协议功能可协商,真实资源和操作仍需身份、scope、业务权限与同意。
- “MCP 会自动消除提示注入”:协议不可信内容仍可能进入模型上下文。
动手练习
为“IDE 同时连接代码仓库、数据库和消息系统”完成一张架构表:
- 画出一个 host、三个 client、三个 server。
- 对每条连接写出 server capabilities 与 client capabilities。
- 标出凭据由谁保存、用户在哪里确认、哪些数据不能跨连接传播。
- 为一种连接失败分别写出传输证据、协议证据和业务证据。
自测
- 为什么一个 host 通常为每个 server 建立独立 client?
sampling/createMessage为什么是 server → client,而tools/call通常是 client → server?- HTTP 200 是否足以证明 MCP initialize 成功?为什么?
- server 宣称某 tool “readOnly”时,host 还要验证什么?
能在不看表格的情况下解释“角色、两层、六类双向能力、控制权”四件事,才算掌握本节。
下一步
进入 Primitives 与工具契约,学习每类能力解决什么问题,以及如何选择。
参考资料
以下均为 MCP 第一方资料。规范链接获取/复核于 2026-07-14;Roots 的非安全边界说明于 2026-07-19 复核。