【翻译、转载】MCP 核心架构


核心架构

了解 MCP 如何连接客户端、服务器和 LLM

模型上下文协议 (MCP) 构建在一个灵活、可扩展的架构之上,能够实现 LLM 应用程序与集成之间的无缝通信。本文档涵盖了核心的架构组件和概念。

概述

MCP 遵循客户端-服务器 (client-server) 架构,其中:

  • 宿主 (Host) 是发起连接的 LLM 应用程序(如 Claude 桌面版或 IDE)。
  • 客户端 (Client) 在宿主应用程序内部与服务器保持 1:1 连接。
  • 服务器 (Server) 向客户端提供上下文、工具和提示 (prompts)。


宿主 (Host) 服务器进程 (Server Process) MCP 客户端 传输层 MCP 服务器

核心组件

协议层

协议层处理消息帧、请求/响应关联以及高级通信模式。

Python

python 复制代码
class Session(BaseSession[RequestT, NotificationT, ResultT]):
    async def send_request(
        self,
        request: RequestT,
        result_type: type[Result]
    ) -> Result:
        """Send request and wait for response. Raises McpError if response contains error."""
        # Request handling implementation

    async def send_notification(
        self,
        notification: NotificationT
    ) -> None:
        """Send one-way notification that doesn't expect response."""
        # Notification handling implementation

    async def _received_request(
        self,
        responder: RequestResponder[ReceiveRequestT, ResultT]
    ) -> None:
        """Handle incoming request from other side."""
        # Request handling implementation

    async def _received_notification(
        self,
        notification: ReceiveNotificationT
    ) -> None:
        """Handle incoming notification from other side."""
        # Notification handling implementation

关键类包括:

  • Protocol (协议)
  • Client (客户端)
  • Server (服务器)

传输层

传输层处理客户端和服务器之间的实际通信。MCP 支持多种传输机制:

  • Stdio 传输
    • 使用标准输入/输出 (standard input/output) 进行通信。
    • 非常适合本地进程。
  • 带 SSE 的 HTTP 传输
    • 使用服务器发送事件 (Server-Sent Events, SSE) 处理服务器到客户端的消息。
    • 使用 HTTP POST 处理客户端到服务器的消息。

所有传输都使用 JSON-RPC 2.0 来交换消息。有关模型上下文协议消息格式的详细信息,请参阅规范文档。

消息类型

MCP 有以下主要的消息类型:

  • 请求 (Request) 期望从对方获得响应:
typescript 复制代码
interface Request {
  method: string; // 方法名
  params?: { ... }; // 参数 (可选)
}
  • 结果 (Result) 是对请求的成功响应:
typescript 复制代码
interface Result {
  [key: string]: unknown; // 任意键值对
}
  • 错误 (Error) 表明请求失败:
typescript 复制代码
interface Error {
  code: number; // 错误代码
  message: string; // 错误消息
  data?: unknown; // 额外数据 (可选)
}
  • 通知 (Notification) 是不期望响应的单向消息:
typescript 复制代码
interface Notification {
  method: string; // 方法名
  params?: { ... }; // 参数 (可选)
}

连接生命周期

1. 初始化

时序图


服务器 客户端 initialize 请求 (协议版本, 能力) initialize 响应 (协议版本, 能力) initialized 通知 (确认) 连接准备就绪 服务器 客户端

  • 客户端发送包含协议版本和能力的 initialize 请求。
  • 服务器以其协议版本和能力进行响应。
  • 客户端发送 initialized 通知作为确认。
  • 开始正常的消息交换。

2. 消息交换

初始化后,支持以下模式:

  • 请求-响应 (Request-Response):客户端或服务器发送请求,另一方响应。
  • 通知 (Notification):任意一方发送单向消息。

3. 终止

任意一方都可以终止连接:

  • 通过 close() 进行干净关闭。
  • 传输断开。
  • 错误条件。

错误处理

MCP 定义了这些标准错误代码:

typescript 复制代码
enum ErrorCode {
  // 标准 JSON-RPC 错误代码
  ParseError = -32700,       // 解析错误
  InvalidRequest = -32600,   // 无效请求
  MethodNotFound = -32601,   // 方法未找到
  InvalidParams = -32602,    // 无效参数
  InternalError = -32603     // 内部错误
}

SDK 和应用程序可以定义自己的高于 -32000 的错误代码。

错误通过以下方式传播:

  • 对请求的错误响应。
  • 传输上的错误事件。
  • 协议级别的错误处理程序。

实现示例

这是一个实现 MCP 服务器的基本示例:

Python

python 复制代码
import asyncio
import mcp.types as types
from mcp.server import Server
from mcp.server.stdio import stdio_server

app = Server("example-server")

@app.list_resources()
async def list_resources() -> list[types.Resource]:
    return [
        types.Resource(
            uri="example://resource",
            name="Example Resource"
        )
    ]

async def main():
    async with stdio_server() as streams:
        await app.run(
            streams[0],
            streams[1],
            app.create_initialization_options()
        )

if __name__ == "__main__":
    asyncio.run(main())

最佳实践

传输选择

  • 本地通信
    • 对于本地进程,使用 stdio 传输。
    • 对于同一台机器上的通信效率高。
    • 进程管理简单。
  • 远程通信
    • 对于需要 HTTP 兼容性的场景,使用 SSE。
    • 考虑安全影响,包括身份验证和授权。

消息处理

  • 请求处理
    • 彻底验证输入。
    • 使用类型安全的模式 (schema)。
    • 优雅地处理错误。
    • 实现超时机制。
  • 进度报告
    • 对长时间操作使用进度令牌 (progress tokens)。
    • 增量报告进度。
    • 在已知总进度时包含该信息。
  • 错误管理
    • 使用适当的错误代码。
    • 包含有用的错误消息。
    • 在出错时清理资源。

安全注意事项

  • 传输安全
    • 对远程连接使用 TLS。
    • 验证连接来源。
    • 在需要时实施身份验证。
  • 消息验证
    • 验证所有传入消息。
    • 净化输入内容 (Sanitize inputs)。
    • 检查消息大小限制。
    • 验证 JSON-RPC 格式。
  • 资源保护
    • 实施访问控制。
    • 验证资源路径。
    • 监控资源使用情况。
    • 对请求进行速率限制。
  • 错误处理 (安全方面)
    • 不要泄露敏感信息。
    • 记录与安全相关的错误。
    • 实施正确的清理操作。
    • 处理拒绝服务 (DoS) 场景。

调试与监控

  • 日志记录
    • 记录协议事件。
    • 跟踪消息流。
    • 监控性能。
    • 记录错误。
  • 诊断
    • 实施健康检查。
    • 监控连接状态。
    • 跟踪资源使用情况。
    • 进行性能分析 (Profile)。
  • 测试
    • 测试不同的传输方式。
    • 验证错误处理。
    • 检查边缘情况。
    • 对服务器进行负载测试。

相关推荐
不懂的浪漫5 小时前
mqtt-plus 架构解析(六):多 Broker 管理,如何让一个应用同时连接多个 MQTT 服务
spring boot·分布式·物联网·mqtt·架构
不懂的浪漫5 小时前
mqtt-plus 架构解析(十):从内部项目到开源框架,mqtt-plus 的抽取过程与决策
spring boot·mqtt·架构·开源
CoovallyAIHub9 小时前
视频理解新范式:Agent不再被动看视频,LensWalk让它自己决定看哪里
算法·架构·github
CoovallyAIHub9 小时前
斯坦福丨AirVLA:将地面机械臂模型迁移至无人机实现空中抓取,成功率从23%提升至50%
算法·架构·github
竹之却10 小时前
【Agent-阿程】OpenClaw智能体架构深度解析与实战应用
架构·大模型应用·ai框架·openclaw
qq_4542450310 小时前
通用引用管理框架
数据结构·架构·c#
独特的螺狮粉10 小时前
云隙一言:鸿蒙Flutter框架 实现的随机名言应用
开发语言·flutter·华为·架构·开源·harmonyos
heimeiyingwang11 小时前
【架构实战】SQL调优实战:从执行计划到索引优化
数据库·sql·架构
两万五千个小时11 小时前
Claude Code 源码:Agent 工具 — 多 Agent 的路由与定义机制
人工智能·程序员·架构
leonkay12 小时前
到底应不应该写注释?
性能优化·架构·个人开发·注释·代码规范·设计·规格说明书