MCP 架构
Host、Client、Server 三个角色与能力协商。
一句话理解:Host 是装着模型的 AI 应用,它为每个外部系统创建一个 Client,每个 Client 只连一个 Server;Server 暴露能力,Host 掌控对话、权限和用户同意,双方通过“能力声明”知道对方支持什么。
评审一个 MCP 方案时,最常听到的困惑是:“MCP Client 是什么?是我们的 Agent 吗?”“Server 能看到用户的完整对话吗?”“权限到底在哪一层控制?”这些问题的答案,都藏在 MCP 的三角色架构里。
本课以 2026-07-28 版规范为准,同时说明它与早期版本的主要差异。很多 Host 和 Server 仍在使用早期版本,读文档、排查问题时经常会遇到两套说法。
先看全景:下图把本模块的核心概念放在一张图里,后面几课会逐一展开。
三个角色
| 角色 | 是什么 | 职责 | 例子 |
|---|---|---|---|
| Host | 用户直接使用的 AI 应用,装着模型 | 创建与管理多个 Client;决定哪些 Server 可以连接;执行安全策略与用户同意;汇总上下文交给模型 | Claude Code、Cursor、VS Code、你自研的客服 Agent |
| Client | Host 内部的连接器 | 与 恰好一个 Server 通信;每次请求都携带协议版本与自身能力;转发消息、管理订阅;隔离不同 Server | Host 为“订单 Server”创建的那个连接 |
| Server | 提供能力的独立程序或服务 | 通过 Tools、Resources、Prompts 暴露能力;只负责明确的一块职责;遵守安全约束 | 内部订单 MCP Server、GitHub MCP Server |
一个 Host 可以同时连接多个 Server,但每个连接都对应一个独立的 Client,是 1:1 的关系:
规范写明的四条设计原则
MCP 规范对架构有几条明确的设计原则,它们直接决定了安全边界:
- Server 应该非常容易构建。 复杂的编排交给 Host,Server 只专注于明确的能力。
- Server 应该高度可组合。 每个 Server 职责独立,多个 Server 可以无缝组合。
- Server 不能读取完整对话,也不能“看到”其他 Server。 Server 只接收必要的上下文信息,完整的对话历史留在 Host 里,跨 Server 的交互由 Host 控制。
- 能力可以渐进地添加。 核心协议只提供最小功能,其他能力按需声明与协商。
第 3 条对产品设计意义重大:订单 Server 只会收到 get_order 的参数,看不到用户之前聊了什么,也看不到 GitHub Server 返回了什么。数据最小化是架构层面的默认设定,而不是靠 Server 自觉。
一次调用的完整路径
用户在 Claude Code 里问:“ORD2026090142 为什么还没退款?”
整个过程如下图:
可以看到,是 Host 决定要不要执行、要不要确认。MCP 规范在安全原则里要求:Host 在调用任何工具之前,都必须获得用户的明确同意。实践中,各 Host 会用逐次确认、按工具授权、预先配置允许规则等不同方式来落实这一要求。这就是为什么同一个 MCP Server,在不同 Host 里的确认体验可能完全不同。
能力声明:双方怎么知道对方支持什么
MCP 用“能力(capabilities)”机制让双方逐步扩展功能,而不是要求所有实现支持全部特性。
- Server 声明:是否支持
tools、resources(以及资源订阅)、prompts,列表变化时是否会发通知(listChanged)等。 - Client 声明:是否支持向用户征集信息(elicitation)等由客户端提供的能力。
- 扩展:Tasks、MCP Apps 等可选扩展,也需要双方都声明支持才会启用。
这里是新旧版本差异最大的地方:
| 早期版本(至 2025-11-25) | 2026-07-28 版 | |
|---|---|---|
| 建立连接 | 先 initialize 握手,协商版本与能力,之后在同一个会话里通信 |
没有握手。每个请求都在 _meta 里携带协议版本、客户端信息与客户端能力 |
| 了解 Server 能力 | 握手响应中返回 | 可选调用 server/discover 提前获取,不强制 |
| 会话 | 远程传输可用 Mcp-Session-Id 维持会话 |
取消协议级会话,任意请求可以落到任意一台服务器实例 |
| Server 向 Client 要东西 | Server 可以主动发起请求(如向用户征集信息、请 Host 调用模型) | Server 在结果里返回 input_required,Client 带着答案重发原请求(多轮往返请求,MRTR) |
| 变化通知 | 在会话流上推送 | Client 通过 subscriptions/listen 主动打开通知流 |
对产品和运维的影响:无状态让远程 MCP Server 可以放在普通负载均衡后面水平扩展,不需要共享会话存储。需要跨调用保持状态的场景(比如一个多步的购物车或事务),规范建议由工具显式返回一个句柄(如 basket_id),让模型在后续调用中传回;Server 每次都要校验这个句柄是否属于当前调用者。
向用户“要东西”:MRTR
有时 Server 执行到一半需要用户补充信息,比如“这张工单要指派给谁”。2026-07-28 版把这种交互统一成了多轮往返请求:
好处是 Server 不需要保持长连接等待用户回应,协议保持无状态。代价是需要 Host 实现对应的界面,接入前要确认目标 Host 是否支持。
常见误区
- “MCP Client 就是我们的 Agent。” Agent 通常是 Host(或 Host 的一部分);Client 是 Host 里面负责连接某个 Server 的组件,一般由 SDK 提供,不需要你从零实现。
- “MCP Server 能看到全部对话,所以不能接敏感系统。” 按规范设计,Server 只收到调用参数和必要信息。真正要担心的,是 Server 返回的内容会进入模型上下文,以及恶意 Server 的工具描述。
- “权限在 Server 里控制就够了。” Server 控制“能不能访问数据”,Host 控制“要不要执行、要不要问用户”。两层都需要。
产品经理检查清单
- 我们的产品在 MCP 架构里扮演 Host、Server,还是两者都是?
- 作为 Host:用户如何添加、审批、禁用 Server?工具调用的确认规则是什么?
- 作为 Server:每个请求如何识别调用者?数据权限在哪里校验?
- 需要跨调用保持状态吗?如果需要,句柄如何生成、校验与过期?
- 目标 Host 与我们的 Server 支持哪个规范版本?新旧版本客户端是否都要兼容?
练习
画出“工程师在 Claude Code 里排查订单异常”的 MCP 架构图(30 分钟):
- 标出 Host、各个 Client 与 Server(至少包括代码仓库、订单系统、工单系统)。
- 标出每条连接的传输方式(本地还是远程)。
- 用箭头画出一次
get_order调用的完整路径,并在“需要用户确认”和“校验数据权限”的位置分别打上标记。 - 写一句话回答:订单 Server 能不能看到工程师上一轮问了 GitHub 什么?为什么?
延伸阅读
- MCP Architecture(2026-07-28):三角色、设计原则与能力协商的规范原文。
- The 2026-07-28 Specification:无状态核心、MRTR 与各项变化的官方说明。
下一步
Server 能暴露的不只是工具。下一课「三类原语」讲 Tools、Resources、Prompts 分别由谁触发、解决什么问题。