首页 > 编程笔记 > 通用技能 阅读:17

MCP核心架构详解(新手必看)

MCP 遵循客户端-服务器架构,其中宿主应用程序会连接到多个服务器,如下图所示。架构中的每一个组件在使 LLM 与外部资源交互方面都扮演着特定角色。

MCP核心组件

MCP 建立在灵活、可扩展的架构之上,旨在实现 LLM 应用程序与集成之间的无缝通信。该架构下的元素大致分为三个主要的核心角色,分别是宿主、服务器和客户端:
MCP 架构由 3 个紧密相关的核心组件构成:协议层、传输层和消息类型。这三大组件共同构建了一个完整的通信框架,每个组件都扮演着不可或缺的角色,确保客户端和服务器之间的高效、可靠通信。

协议层(Protocol Layer)是 MCP 的“大脑”,负责处理消息的框架结构、请求/响应的关联,以及高级通信模式。它定义了如何组织和解释消息,确保双方能够理解彼此的意图。

传输层(Transport Layer)是 MCP 的“神经系统”,负责客户端和服务器之间实际的数据传输。MCP 支持多种传输机制,包括适用于本地进程的标准输入/输出(Stdio)传输,以及利用服务器发送事件(SSE)和 HTTP POST 的网络传输。所有传输方式都使用 JSON-RPC 2.0 作为消息交换格式,提供了标准化的通信基础。

协议消息类型(Message Types)是 MCP 的“语言”,定义了通信双方如何表达不同类型的意图和信息。它们不仅是数据结构,更是系统交互的基本单位。

1、协议层

协议层(Protocol Layer)是MCP架构的高级逻辑层,负责处理消息封装、请求与响应的关联,以及通信模式的定义与实现。该层提供了客户端和服务器交互的核心功能和接口。

我们可以将协议层划分为以下关键组件。
MCP TypeScript SDK 对这些组件做了良好的抽象,我们来看看具体的核心代码片段。

Protocol 核心代码片段如下:
/**
* Implements MCP protocol framing on top of a pluggable transport,
* including features like request/response linking, notifications, and progress.
*/
export abstract class Protocol<
  SendRequestT  extends Request,
  SendNotificationT extends Notification,
  SendResultT   extends Result
> {
  private _transport?: Transport;
  private _requestMessageId = 0;
  private _requestHandlers = new Map<
    string,
    (
      request: JSONRPCRequest,
      extra: RequestHandlerExtra
    ) => Promise<SendResultT>
  > = new Map();
  private _requestHandlerAbortControllers = new Map<RequestId, AbortController>();
  private _notificationHandlers = new Map<
    string,
    (notification: JSONRPCNotification) => Promise<void>
  > = new Map();
  private _responseHandlers = new Map<
    number,
    (response: JSONRPCResponse | Error) => void
  > = new Map();
  private _progressHandlers = new Map<number, ProgressCallback>();
  private _timeoutInfo = new Map<number, TimeoutInfo>();
}

Client 核心代码片段如下:
export class Client<
  RequestT extends Request = Request,
  NotificationT extends Notification = Notification,
  ResultT extends Result = Result
> extends Protocol<
  ClientRequest | RequestT,
  ClientNotification | NotificationT,
  ClientResult | ResultT
> {
  private _serverCapabilities?: ServerCapabilities;
  private _serverVersion?: Implementation;
  private _capabilities: ClientCapabilities;
  private _instructions?: string;
}

Server 核心代码片段如下:
export class Server<
  RequestT extends Request = Request,
  NotificationT extends Notification = Notification,
  ResultT extends Result = Result
> extends Protocol<
  ServerRequest | RequestT,
  ServerNotification | NotificationT,
  ServerResult | ResultT
> {
  private _clientCapabilities?: ClientCapabilities;
  private _clientVersion?: Implementation;
  private _capabilities: ServerCapabilities;
  private _instructions?: string;
}
协议层还负责处理错误管理、资源保护和安全验证等重要功能,确保 MCP 通信的可靠性和安全性。

2、传输层

传输层(Transport Layer)在 MCP 中提供了客户端和服务器之间通信的基础,定义并实现了消息发送和接收的底层机制。接下来介绍传输层的消息格式和传输机制。

1) 消息格式

MCP 使用 JSON-RPC 2.0 作为其通信格式。传输层负责将 MCP 协议消息转换为 JSON-RPC 格式进行传输,并将接收到的 JSON-RPC 消息转换回 MCP 协议消息。MCP 使用 3 种类型的 JSON-RPC 消息,分别是请求(Request)、响应(Response)和通知(Notification)。

请求从一方发送到另一方,可以从客户端发送到服务器,也可以从服务器发送到客户端。请求包括以下主要元素:
请求的格式如下:
{
  "jsonrpc": "2.0",
  "id": number | string,
  "method": "string",
  "params"?: object
}

响应作为对请求的回复发送,其主要元素包括:
在响应数据中,分别用 result 与 error 字段表示请求处理的结果,以及异常情况下的错误信息。

格式如下:
{
  "jsonrpc": "2.0",
  "id": number | string,
  "result"?: object,
  "error"?: {
    "code": number,
    "message": string,
    "data"?: unknown
  }
}

通知是不需要响应的,属于单向消息,其主要元素包括:
格式如下:
{
  "jsonrpc": "2.0",
  "method": "string",
  "params"?: object
}

2) 传输机制

传输层负责服务器与客户端真正的通信工作,目前 MCP 支持两种传输机制,分别是 Stdio 和 HTTP SSE。所有传输机制都利用 JSON-RPC 2.0 实现服务端与客户端的消息交换。

Stdio(标准输入输出)是一种计算机系统中的基础数据传输机制,由 UNIX 系统首创并广泛应用于现代计算环境。它通过 3 个标准流(标准输入 stdin、标准输出 stdout 和标准错误 stderr)为程序提供了与外部环境交互的统一接口,使程序无需关心具体的输入输出设备。这一抽象机制极大简化了编程复杂度,支持数据重定向和管道操作,允许程序间数据流动,成为现代操作系统和编程语言的核心组件。Stdio 机制特别适合于本地部署运行的 MCP 服务器。

HTTP SSE(Server-Sent Events)是一种允许服务器向客户端推送实时更新的Web技术,它建立在HTTP协议之上,提供了一种单向通信机制,使服务器能够通过长连接持续向客户端发送消息,而无需客户端重复请求。与 WebSockets 不同,SSE 仅支持服务器到客户端的通信,但 SSE 的实现更简单,并且与 HTTP 的基础设施完全兼容。

服务器以特殊的 MIME 类型(text/event-stream)响应请求,每条消息由一对换行符分隔,以文本格式发送事件流。SSE 特别适用于需要实时更新的应用场景。在 HTTP SSE 机制下,MCP 客户端通过 HTTP POST 请求向 MCP 服务器发送消息。服务器则通过 SSE 消息通知客户端。

MCP连接的生命周期

每个 MCP 连接遵循以下生命周期,分别是初始化、消息交换和终止。

1) 初始化

MCP协议初始化阶段必须是客户端和服务器之间的第一次交互。这个阶段包含三个关键步骤:
这个过程使客户端和服务器能够建立协议版本兼容性、交换并协商各自的能力以及共享实现细节,如下图所示:


在初始化阶段,客户端与服务端完成主要完成版本与能力协商。在 initialize 请求中,客户端必须发送其支持的协议版本。这应该是客户端支持的最新版本。

如果服务器支持请求的协议版本,它必须以相同的版本回应。否则,服务器必须回应它支持的另一个协议版本。这应该是服务器支持的最新版本。

如果客户端不支持服务器响应中的版本,它应该断开连接。在初始化阶段,客户端与服务端交换能力信息,使得双方知晓对方所支持的功能。

以下是一个客户端发送的 initialize 请求示例:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "roots": {
        "listChanged": true
      },
      "sampling": {}
    },
    "clientInfo": {
      "name": "DemoClient",
      "version": "1.0.0"
    }
  }
}

以下是服务端 initialized 响应示例:
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "logging": {},
      "prompts": {
        "listChanged": true
      },
      "resources": {
        "subscribe": true,
        "listChanged": true
      },
      "tools": {
        "listChanged": true
      }
    },
    "serverInfo": {
      "name": "DemoServer",
      "version": "1.0.0"
    }
  }
}

2) 消息交换

初始化后,客户端和服务器可以进行以下操作,如下图所示。

3) 终止

客户端或服务端都可以终止连接。目前 MCP 协议并未定义明确的连接关闭消息。客户端与服务端应采用底层传输协议相应的机制通知连接关闭。

① Stdio 客户端应该通过以下步骤关闭连接:
如下图所示:


② 在以 HTTP 为传输协议的连接中,关闭 HTTP 连接意味着关闭了 MCP 连接。任何一方均可关闭 HTTP 连接,关闭连接意味着不再发送消息或接收来自对端的消息。这不仅适用于客户端,也适用于服务器。无论是客户端还是服务器,都可以根据需要选择关闭连接,从而终止当前的通信。

3) 错误处理

MCP 定义了标准错误代码和处理机制。服务器特定的错误代码应大于-32000。错误通过以下方式传播:
以 TypeScript SDK 的源代码为例,以下代码段定义了错误码:
export enum ErrorCode {
  // SDK error codes
  ConnectionClosed = -32000,
  RequestTimeout = -32001,

  // Standard JSON-RPC error codes
  ParseError = -32700,
  InvalidRequest = -32600,
  MethodNotFound = -32601,
  InvalidParams = -32602,
  InternalError = -32603,
}

相关文章