详解 MCP 核心架构
MCP 协议核心架构
MCP 协议遵循互联网常见的 C / S 架构,即客户端(Client)- 服务器(Server)架构。
MCP 协议引入了主机(Host)的概念,组成了基本的主机(Host)- 客户端(Client)- 服务器(Server)架构。
接下来,我们详细解析架构中的每一部分及其功能。
1. 主机
MCP 协议里的主机就是大模型应用,类似 Claude 桌面客户端、Cursor 编辑器这种应用。可以在主机内调度客户端进程,发起到服务器的连接。
主机充当协调者的角色:
- 创建和管理多个客户端实例
- 控制客户端连接权限和生命周期
- 执行安全政策和同意要求
- 处理用户授权决策
- 协调 AI / 大模型集成和采样
- 管理跨客户端的上下文聚合
2. 客户端
MCP 协议里的客户端可以理解为主机内的一个业务进程,可以与服务器进程进行连接,实现数据交互,帮助主机应用获取外部资源。
客户端进程的主要职责:
- 为每个服务器建立一个有状态的会话
- 处理协议协商和能力交换
- 路由协议消息双向传输
- 管理订阅和通知
- 维护服务器之间的安全边界
❝什么是进程? 进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。
一个主机应用可以创建和管理多个客户端进程,每个客户端进程与一个特定的服务器进程维持 1:1 的独立连接。
3. 服务器
MCP 协议中的服务器是在主机外运行的,用于提供特定资源和能力的外部程序。
服务器程序的主要特点:
- 通过 MCP 协议提供资源、工具和提示词
- 独立运作,承担明确责任
- 通过客户端接口请求采样
- 必须遵守安全限制
- 可以是本地进程或远程服务
MCP 协议应用场景举例
举个实际的例子,我们在电脑上安装了 Anthropic 公司开发的 Claude Desktop 桌面应用(以下简称 Claude)。
在 Claude 的 MCP 服务器配置文件中,写入两个 MCP 服务器的配置信息:
{
"mcpServers": {
"amap-maps": {
"command": "npx",
"args": ["-y", "@amap/amap-maps-mcp-server"],
"env": {
"AMAP_MAPS_API_KEY": "amap_api_key"
}
},
"flomo": {
"command": "npx",
"args": ["-y", "@chatmcp/mcp-server-flomo"],
"env": {
"FLOMO_API_URL": "https://flomoapp.com/iwh/xxx/xxx/"
}
}
}
}
- amap-maps 是高德地图 MCP,提供多个工具,用于查询地理位置相关信息。
- flomo 是浮墨笔记 MCP,提供一个写笔记的工具,可以写入文本内容。
配置完成后,重启 Claude 客户端。
然后可以在 Claude 工具页面看到配置的两个服务器,一共提供了 13 个工具。
在 Claude 对话框中输入下面的内容:
我想从广州开车去武汉看樱花,请帮我规划一下路线,把行程计划保存到我的笔记。
Claude 开始处理,在响应过程中调用了 amap-maps 服务器提供的四个工具,查询位置和天气信息,最后调用 flomo 服务器的 write_note 工具,把行程计划保存到了浮墨笔记。
用 MCP 协议的"主机-客户端-服务器"架构来理解:
- Claude 桌面应用是主机
- amap-maps 和 flomo 是两个服务器
- Claude 主机上存在着两个客户端,连接上了 amap-maps 和 flomo 两个服务器
"主机-客户端-服务器"的协作流程:
1.读取服务器配置文件。在主机启动的时候,读取了服务器配置文件,发现了两个服务器。
2.启动本地服务器进程。主机按照配置的服务器运行方式(command + args + env),在本地电脑运行服务器。每个服务器启动一个本地进程,通过进程监听的方式,等待客户端连接。
3.启动客户端进程。主机启动两个子进程,作为客户端,分别连接到两个本地服务器。客户端进程与服务器进程之间交换数据,保持通信连接。
4.获取工具集合。主机维持着多个客户端与服务器之间的 1:1 配对连接,主机在连接建立之后获取到了所有服务器提供的所有工具(Tool)集合。
5.处理用户请求。主机接收到用户的输入,向大模型发送请求,并将所有服务器提供的工具集合传递给大模型。由大模型进行意图识别和调度规划,告诉主机应该调用哪些工具来满足用户需求。
6.并行执行多个工具调用。主机根据大模型返回的工具名称和参数,定位到对应的客户端和服务器组合,由客户端进程向服务器进程发送工具调用(CallTool)请求,得到服务器的响应数据。
7.生成回复。主机使用请求服务器得到的内容,拼接对话上下文,请求大模型做总结输出。
8.程序退出流程。主机退出时,所有的客户端子进程结束,与服务器的连接关闭,服务器进程结束。
为了方便大家更形象地理解这一过程,我将这个协作流程用一张图展示出来。
MCP 协议设计原则
MCP 协议建立在几个关键设计原则上,这些原则指导其架构和实现:
1. 服务器应极其易于构建
- 由主机应用来处理复杂的编排任务
- 服务器专注于实现特定且明确的能力
- 用简单的接口来最小化实现开销
- 用清晰的分离原则使代码可维护
2. 服务器应高度可组合
- 每个服务器专注于提供独立的功能
- 多个服务器可以无缝结合
- 用共享协议实现互操作性
- 用模块化设计支持可扩展性
3. 服务器不应该读取整个对话,也不应该"窥视"其他服务器
- 服务器只接收必要的上下文信息
- 完整的对话历史与主机保持一致
- 每个服务器连接保持隔离
- 跨服务器交互由主机控制
- 由主机进程来限制安全边界
4. 功能可以逐步添加到服务器和客户端
- 核心协议提供最小所需功能
- 服务器与客户端根据需要协商额外能力
- 服务器和客户端独立演进
- 协议设计需要可扩展,以支持未来的一些特性
- 协议保持向后兼容性
MCP 协议关键组件
MCP 协议由几个关键组件组成,它们协同工作:
1. 基础协议
在协议层面,对以下内容进行基本的定义和约束:
- JSON-RPC 通信基础:约定了客户端与服务器通信过程中,消息应该如何编码
- 连接生命周期:定义了客户端与服务器通信的完整流程
- 传输机制:定义了客户端与服务器通信的消息应该怎样传递
- 能力协商:由服务器与客户端双方协商可以提供给对方的功能
2. 功能特性
服务器与客户端都能各自实现丰富的特性。
其中服务器可以向客户端提供以下功能:
- 资源:上下文资料和数据,供用户或 AI 模型使用
- 提示词:为用户准备的模板消息和工作流
- 工具:提供给 AI 模型执行的功能函数
客户端可以向服务器提供以下功能:
- 采样:实现服务器代理功能
- 根目录:限制服务器的可操作目录
3. 额外工具
MCP 协议还定义了一些额外的工具,供服务器和客户端通信使用:
- 配置
- 进度追踪
- 取消通信
- 错误报告
- 日志记录
4. 认证授权
MCP 提供了一个授权框架,用于与 HTTP 一起使用。使用基于 HTTP 的传输实现应当符合此规范,而使用 stdio 传输的实现则不应遵循此规范,而是从环境获取凭据。
此外,客户端和服务器可以协商自己的自定义身份验证和授权策略。
MCP 协议的实现方必须支持 JSON-RPC 通信基础和生命周期管理。其他能力可根据应用程序的具体需求进行实现。
MCP 协议采用模块化设计,在明确和分离关注点的同时,保证了客户端和服务器之间可实现丰富的交互。
MCP 协议消息类型
所有 MCP 客户端和服务器之间的消息必须遵循 JSON-RPC 2.0 规范。该协议定义了以下类型的消息:
1. 请求:带有方法和参数、期望得到响应的双向消息
请求从客户端发送到服务器,反之亦然,以启动操作。
{
jsonrpc: "2.0";
id: string | number;
method: string;
params?: {
[key: string]: unknown;
};
}
- 请求必须包含一个字符串或整数 ID。
- 与基础 JSON-RPC 不同,ID 必须不是 null。
- 请求 ID 在同一会话中必须未被请求方之前使用过。
2. 响应:与特定请求 ID 匹配的成功结果或错误
响应是作为对请求的回复发送的,包含操作的结果或错误。
{
jsonrpc: "2.0";
id: string | number;
result?: {
[key: string]: unknown;
}
error?: {
code: number;
message: string;
data?: unknown;
}
}
- 响应必须包含与它们对应的请求相同的 ID。
- 响应进一步细分为成功结果或错误。必须设置结果或错误之一。响应不得同时设置两者。
- 结果可以遵循任何 JSON 对象结构,而错误至少必须包含错误代码和消息。错误代码必须是整数。
3. 通知:单向消息,不需要响应
通知从客户端发送到服务器或反之亦然,作为单向消息。接收者不得发送响应。
{
jsonrpc: "2.0";
method: string;
params?: {
[key: string]: unknown;
};
}
- 通知中必须不包含 ID。
4. 批处理
JSON-RPC 还定义了一种方法,可以通过将多个请求和通知发送到一个数组中来批量处理。MCP 实现者可能支持发送 JSON-RPC 批处理,但必须支持接收 JSON-RPC 批处理。
MCP 协议能力协商机制
MCP 协议使用基于能力的协商系统,其中客户端和服务器在初始化期间明确声明它们支持的功能。能力决定了会话期间可用的协议功能。
- 服务器声明的能力包括资源订阅、工具支持和提示模板
- 客户端声明的能力包括采样支持和通知处理
- 双方必须在整个会话中尊重声明的功能
- 可以通过对协议的扩展协商额外的功能
MCP 客户端与 MCP 服务器进行能力协商的流程:
每项能力在会话期间解锁一项特定的由协议支持的特性。例如:
- 已实现功能的服务器必须在其能力字段中展现其支持的能力
- 发出资源订阅通知需要服务器声明支持订阅
- 工具调用需要服务器声明工具功能
- 采样需要客户端在其能力中声明支持
这种能力协商确保客户端和服务器对支持的功能有清晰的理解,同时保持协议的可扩展性。
MCP 协议通信安全
MCP 协议通过任意数据访问和代码执行路径提供了强大的功能。伴随着这种强大的功能而来的是重要的安全和信任考虑因素,所有实现者都必须谨慎处理。
关键原则:
1. 用户同意与控制
- 用户必须明确同意并理解所有数据访问和操作
- 用户必须保留控制权,决定共享哪些数据和采取哪些行动
- 协议实现者应提供清晰的用户界面以审查和授权活动
2. 数据隐私
- 主机在向服务器暴露用户数据之前必须获得用户的明确同意
- 主机不得在未经用户同意的情况下将资源数据传输到其他地方
- 用户数据应通过适当的访问控制得到保护
3. 工具安全
- 工具代表任意代码执行,必须谨慎对待。
特别是,工具行为描述(如注释)应被视为不可信,除非来自受信任的服务器。
- 主机在调用任何工具之前必须获得用户的明确同意
- 用户在授权使用之前应了解每个工具的功能
4. LLM 采样控制
- 用户必须明确批准任何 LLM 采样请求
- 用户应控制:
- 是否进行采样
- 实际要发送的提示
- 服务器可以看到的结果
- 协议有意限制了服务器对提示的可见性
实施指南
虽然 MCP 本身无法在协议级别强制执行这些安全原则,MCP 协议实现者应当:
1.将稳健的同意和授权流程构建到他们的应用程序中
2.提供关于安全影响的清晰文档
3.实施适当的访问控制和数据保护
4.在他们的集成中遵循安全最佳实践
5.在他们的功能设计中考虑隐私影响
总结
MCP 协议是一个基于主机-客户端-服务器架构的通信协议,旨在为大模型应用提供安全、可扩展的外部能力集成方案。本篇内容详细介绍了 MCP 协议的核心架构和关键特性:
核心架构
- 采用主机-客户端-服务器三层架构
- 主机负责协调和管理多个客户端实例
- 客户端与服务器建立 1:1 的独立连接
- 服务器提供特定资源和能力的外部程序
协议设计原则
- 服务器构建简单,专注于特定能力
- 服务器高度可组合,支持模块化扩展
- 服务器隔离设计,不读取完整对话
- 功能可逐步添加,保持向后兼容
关键组件
- 基础协议:JSON-RPC 通信、连接生命周期、传输机制
- 功能特性:资源、提示词、工具、采样等
- 额外工具:配置、进度追踪、错误报告等
- 认证授权:基于 HTTP 的授权框架
消息类型
- 请求:双向消息,包含方法和参数
- 响应:匹配请求 ID 的结果或错误
- 通知:单向消息,无需响应
- 支持批处理消息
安全机制
- 强调用户同意与控制
- 保护数据隐私
- 严格控制工具执行
- 管理 LLM 采样权限
MCP 协议通过这种架构设计,实现了大模型应用与外部服务的安全、高效集成,同时保持了良好的可扩展性和灵活性。这种设计使得大模型应用能够安全地访问和使用外部资源,为用户提供更丰富的功能体验。
文章来自于“艾逗笔”,作者“idoubi”。
全部评论
留言在赶来的路上...
发表评论