MCP (Model Context Protocol) 框架介绍文档
最近在学习MCP的功能,记录一些学习笔记。
1. 架构概述
MCP(Model Context Protocol)是一个专为大模型应用设计的协议框架,旨在标准化大模型与外部数据源、工具之间的交互方式。该框架采用客户端-服务器架构,通过JSON-RPC 2.0协议实现高效、可靠的通信。
2. 核心组件
2.1 Host(宿主应用)
- 角色定位:最终承载大模型和用户界面的应用
- 核心功能:
- 启动时在内部创建MCP Client实例
- 管理大模型的交互逻辑和用户界面
- 处理Client返回的数据并整合到模型提示中
- 职责范围:
- 业务逻辑处理
- 用户交互管理
- 模型调用协调
2.2 Client(客户端)
- 角色定位:MCP协议的客户端实现
- 核心功能:
- 接受上层业务或大模型交互产生的请求
- 将请求打包成符合JSON-RPC 2.0规范的消息
- 通过底层传输通道与Server进行通信
- 接收来自Server的Notification消息
- 数据处理:
- 将Server返回的数据交回给Host
- 数据可用于拼接到模型的Prompt中
- 支持数据的二次处理和分析
2.3 Server(服务器)
- 角色定位:提供上下文内容和工具执行能力的进程或服务
- 核心功能:
- 启动时注册一系列接口能力
- 监听来自Client的JSON-RPC消息
- 执行具体的工具操作和数据查询
- 管理资源列表和工具定义
- 服务能力:
- 数据源接入(数据库、API、文件系统等)
- 工具执行(计算、转换、分析等)
- 资源管理(权限控制、连接池等)
3. 底层协议层
3.1 BaseSession(基础会话)
核心职责:提供所有JSON-RPC消息的读写、帧解析、请求-响应关联、通知分发的通用逻辑
架构设计:
- 承担对所有JSON-RPC消息的统一管理和生命周期控制
- 封装通用逻辑:发送请求、等待响应、发出单向通知,接收并分发对端消息等
泛型参数设计:
Generic[SendRequestT, # Request 请求类型SendNotificationT, # Notification 类型 SendResultT, # 发出的Response(Result)类型ReceiveRequestT, # 接收的Request类型ReceiveNotificationT, # 接收的Notification类型ReceiveResultT # 接收的Response(Result)类型
]
核心函数实现:
3.1.1 send_request(发送请求)
处理流程:
- 分配请求ID:request_id自增取新ID
- 创建响应流:为ID注册一个缓冲大小为1的内存流
- 构造JSONRPCRequest:将pydantic模型request序列化成JSONRPC格式,附带ID
- 写入_write_stream:发往对端
- 等待响应:在对应的响应流上阻塞读取,设置超时
- 错误处理:
- 若拿到JSONPRCError就抛McpError
- 若超时就抛带Http 408码的McpError
- 否则,把result部分反序列化为ReceiveResultT返回
- 清理:无论成功或失败,都要把流和注册记录删除并关闭
3.1.2 send_response(发送响应)
处理逻辑:
- 如果是正常结果的SendResultT,构造JSONRPCResponse(含ID+result字段)
- 如果是错误ErrorData,构造JSONRPCError,同样写入_write_stream
3.1.3 send_notification(发送通知)
特点:只需要单向推送,不需要回复的事件等静悄悄发给对端而不阻塞
实现:构造JSONRPCNotification
3.1.4 receive_loop(消息接收循环)
持续处理流程:
- 不断从底层流里读入任何一方发来的JSON-RPC消息
- 按类型分流到请求处理、通知处理或回应分发的正确管道里
- 消息类型分流:
- JSONRPCRequest → 请求处理
- JSONRPCNotification → 通知处理
- JSONRPCResponse/JSONRPCError → 回应分发
重写钩子:子类可以通过重写特定钩子方法来自定义处理逻辑
3.2 ClientSession(客户端会话)
初始化配置:
- 通过构造函数将下游的读写流、超时设置以及各类回调注入会话实例
- 回调包括:取样、列出根目录、日志和通用消息处理
握手流程:
- 调用
initialize()时,客户端首先向服务端发送一个initialize请求 - 收到initializeResult后,再发出一条InitializedNotification通知
- 完成握手过程,建立正式通信
3.3 ServerSession(服务器会话)
握手逻辑设计:
- 协议的握手逻辑内嵌在
received_request和receive_notification的两个钩子里 - 首次InitializeRequest处理:
- 服务器将请求参数保存到
self._client_params - 利用
responder.respond(...)返回包含服务端能力集、版本号和说明文字的InitializeResult
- 服务器将请求参数保存到
- InitializedNotification处理:
- 当接收到InitializedNotification时,状态机才真正进入Initialized阶段
- 任何在未完成初始化前到来的其他请求或通知都会被触发RuntimeError
- 确保交互顺序的正确性
能力检查机制:
check_client_capability(cap)方法读取客户端在初始化时声明的能力集- 根据传入的能力需求判断哪些功能可用
- 提供细粒度的功能权限控制
4. 交互流程
4.1 握手初始化阶段
- Initialize请求:Host的MCP Client向Server发起initialize请求
- 能力交换:双方交换协议版本信息与能力列表
- 确认通知:通过Initialized通知确认连接建立
- 资源注册:Server向Client注册可用的资源和工具
4.2 正常通讯阶段
- 双向通信:Client和Server可双向发起通信
- 同步调用:通过Request-Response模式进行同步调用
- 异步事件:通过Notification模式发送单向异步事件
- 简化接口:大模型应用只需按需调用Client的接口即可
4.3 优雅收尾阶段
- 主动关闭:任意一端可调用close()方法主动关闭连接
- 被动断开:因底层通道断开而触发连接关闭
- 资源清理:释放占用的资源和连接
5. 消息类型
5.1 Request(请求)
- 定义:期待收到响应的消息类型
- 使用场景:
- 工具调用请求
- 资源列表查询
- 数据读取操作
- 特点:需要等待Server的响应
5.2 Result(结果)
- 定义:请求成功时的响应消息
- 内容:
- 执行结果数据
- 操作状态信息
- 可能的错误信息(即使成功也可能包含警告)
5.3 Error(错误)
- 定义:请求失败时的返回消息
- 错误类型:
- 参数错误(InvalidParams)
- 方法不存在(MethodNotFound)
- 内部错误(InternalError)
- 资源不存在(ResourceNotFound)
5.4 Notification(通知)
- 定义:单向消息,无需响应
- 使用场景:
- 初始化完成通知
- 资源变更通知
- 状态更新通知
- 日志输出通知
6. 协议特性
6.1 标准化
- 基于JSON-RPC 2.0协议
- 统一的错误处理机制
- 标准化的消息格式
6.2 可扩展性
- 支持动态资源注册
- 灵活的工具定义
- 可扩展的消息类型
6.3 安全性
- 支持传输层安全
- 可选的认证机制
- 权限控制支持
6.4 可靠性
- 完善的错误处理和重试机制
- 严格的握手状态管理
- 资源生命周期控制
7. 应用场景
7.1 数据增强
- 实时数据查询和整合
- 外部知识库接入
- 多源数据融合
7.2 工具扩展
- 计算工具集成
- 文件操作支持
- 第三方API调用
7.3 上下文管理
- 动态上下文更新
- 会话状态维护
- 资源生命周期管理
8. 优势总结
- 解耦设计:将大模型与具体工具实现分离
- 标准化接口:统一的通信协议和消息格式
- 灵活扩展:支持动态添加新的工具和数据源
- 高效通信:基于JSON-RPC的轻量级通信机制
- 错误恢复:完善的错误处理和重试机制
- 状态管理:严格的握手和状态转换控制
- 能力协商:动态的能力检查和权限控制
