了解 MCP 如何连接客户端、服务端和 LLM
模型上下文协议( MCP )基于一个灵活、可扩展的架构,使 LLM 应用程序和集成之间的通信无缝衔接。本文档涵盖了核心架构组件和概念。
MCP 遵循客户端-服务端架构,其中:
flowchart LR subgraph Host a1[MCP Client] a2[MCP Client] end subgraph Server Process b1[MCP Server] end subgraph Server Process b2[MCP Server] end a1 <-- Transport Layer --> b1 a2 <-- Transport Layer --> b2
协议层处理消息框架、请求/响应链接和高级通信模式。
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 传输
HTTP 与 SSE 传输
所有传输都使用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`请求,包含协议版本和能力 2. 服务端响应其协议版本和能力 3. 客户端发送`initialized`通知作为确认 4. 正常消息交换开始
初始化后,支持以下模式:
任一方都可以终止连接:
close()
进行干净关闭MCP 定义了这些标准错误代码:
enum ErrorCode { // 标准 JSON-RPC 错误代码 ParseError = -32700, InvalidRequest = -32600, MethodNotFound = -32601, InvalidParams = -32602, InternalError = -32603 }
SDK 和应用程序可以在-32000 以上定义自己的错误代码。
错误通过以下方式传播:
以下是一个实现 MCP 服务端的基本示例:
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)
本地通信
远程通信
请求处理
进度报告
错误管理
传输安全
消息验证
资源保护
错误处理
日志记录
诊断
测试
1 lideshun123 198 天前 mcp 服务端为啥不出个 golang 端,golang 打包后不挑环境,不熟悉 py 和 js |
2 hmxxmh 198 天前 @lideshun123 好像有,mcp-1panel 就是 go 的 |
![]() | 3 liangdi 197 天前 via Android @lideshun123 任何语言都可以写啊 |