了解 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 4 天前
mcp 服务端为啥不出个 golang 端,golang 打包后不挑环境,不熟悉 py 和 js
|
2
hmxxmh 3 天前
@lideshun123 好像有,mcp-1panel 就是 go 的
|
![]() |
3
liangdi 3 天前 via Android
@lideshun123 任何语言都可以写啊
|