核心架构
模型上下文协议(MCP)建立在灵活、可扩展的架构之上,使LLM应用程序和集成之间能够无缝通信。本文档涵盖核心架构组件和概念。
概述
MCP遵循客户端-服务器架构,其中:
- 主机是发起连接的LLM应用程序(如Claude Desktop或IDE)
- 客户端在主机应用程序内与服务器保持1:1连接
- 服务器向客户端提供上下文、工具和提示
核心组件
协议层
协议层处理消息帧、请求/响应链接和高级通信模式。
- TypeScript
- Python
class Protocol<Request, Notification, Result> {
// 处理传入请求
setRequestHandler<T>(schema: T, handler: (request: T, extra: RequestHandlerExtra) => Promise<Result>): void
// 处理传入通知
setNotificationHandler<T>(schema: T, handler: (notification: T) => Promise<void>): void
// 发送请求并等待响应
request<T>(request: Request, schema: T, options?: RequestOptions): Promise<T>
// 发送单向通知
notification(notification: Notification): Promise<void>
}
class Session(BaseSession[RequestT, NotificationT, ResultT]):
async def send_request(
self,
request: RequestT,
result_type: type[Result]
) -> Result:
"""
发送请求并等待响应。如果响应包含错误,则抛出McpError。
"""
# 请求处理实现
async def send_notification(
self,
notification: NotificationT
) -> None:
"""发送不期望响应的单向通知。"""
# 通知处理实现
async def _received_request(
self,
responder: RequestResponder[ReceiveRequestT, ResultT]
) -> None:
"""处理来自另一方的传入请求。"""
# 请求处理实现
async def _received_notification(
self,
notification: ReceiveNotificationT
) -> None:
"""处理来自另一方的传入通知。"""
# 通知处理实现
关键类包括:
Protocol
Client
Server
传输层
传输层处理客户端和服务器之间的实际通信。MCP支持多种传输机制:
-
Stdio传输
- 使用标准输入/输出进行通信
- 适用于本地进程
-
HTTP with SSE传输
- 使用服务器发送事件进行服务器到客户端的消息传递
- 使用HTTP POST进行客户端到服务器的消息传递
所有传输都使用JSON-RPC 2.0来交换消息。有关模型上下文协议消息格式的详细信息,请参见规范。
消息类型
MCP有以下主要类型的消息:
-
请求期望从另一方获得响应:
interface Request { method: string; params?: { ... }; }
-
结果是对请求的成功响应:
interface Result { [key: string]: unknown; }
-
错误表示请求失败:
interface Error { code: number; message: string; data?: unknown; }
-
通知是不期望响应的单向消息:
interface Notification { method: string; params?: { ... }; }
连接生命周期
1. 初始化
- 客户端发送带有协议版本和能力的
initialize
请求 - 服务器响应其协议版本和能力
- 客户端发送
initialized
通知作为确认 - 开始正常的消息交换
2. 消息交换
初始化后,支持以下模式:
- 请求-响应:客户端或服务器发送请求,另一方响应
- 通知:任一方发送单向消息
3. 终止
任一方都可以终止连接:
- 通过
close()
进行清理关闭 - 传输断开连接
- 错误条件
错误处理
MCP定义了这些标准错误代码:
enum ErrorCode {
// 标准JSON-RPC错误代码
ParseError = -32700,
InvalidRequest = -32600,
MethodNotFound = -32601,
InvalidParams = -32602,
InternalError = -32603
}
SDK和应用程序可以在-32000以上定义自己的错误代码。
错误通过以下方式传播:
- 对请求的错误响应
- 传输上的错误事件
- 协议级错误处理器
实现示例
这是实现MCP服务器的基本示例:
- TypeScript
- Python
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server({
name: "example-server",
version: "1.0.0"
}, {
capabilities: {
resources: {}
}
});
// 处理请求
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "example://resource",
name: "示例资源"
}
]
};
});
// 连接传输
const transport = new StdioServerTransport();
await server.connect(transport);
import asyncio
import mcp.types as types
from mcp.server import Server
from mcp.server.stdio import stdio_server
app = Server("example-server")
最佳实践
在实现MCP时:
- 遵循协议规范
- 实现适当的错误处理
- 使用类型安全
- 处理连接生命周期
- 实现重连机制
- 添加日志记录
- 考虑性能优化
- 实现安全措施
- 测试边界情况
- 保持代码可维护性
安全考虑
在实现MCP时:
- 加密通信
- 验证消息完整性
- 实现访问控制
- 防止消息注入
- 处理敏感数据
- 监控异常活动
- 实现速率限制
- 审计系统日志