【MCP (Model Context Protocol) 服务技术详解】
MCP(Model Context Protocol)是Anthropic推出的标准化协议,用于大语言模型与外部工具间的通信。它采用客户端-服务器架构,支持本地stdio和远程SSE两种传输方式。服务器端通过FastMCP框架快速构建工具服务,客户端则管理会话并实现工具发现、调用和结果整合。MCP的核心优势包括标准化接口、双向通信和灵活的部署方式,使开发者能专注于业务逻辑,无需考虑底层模型差异。协
MCP (Model Context Protocol) 服务技术详解
1. MCP 技术概述
MCP 是 Anthropic 推出的模型上下文协议,它定义了大语言模型(LLM)与外部工具、数据源之间的标准化通信方式。MCP 采用客户端-服务器架构,支持两种主要传输机制。
MCP 的核心优势体现在三个方面:标准化接口让工具开发一次即可对接多种模型,双向通信支持实时数据交换,而传输灵活性则允许根据场景选择本地或远程部署方式。
2. 服务器端实现详解
2.1 FastMCP 框架
服务器端使用 FastMCP 框架快速构建 MCP 服务。代码通过 @mcp.tool() 装饰器将普通函数转换为 MCP 工具。
from mcp.server.fastmcp import FastMCP
import requests
mcp = FastMCP()
FastMCP 是 MCP 官方提供的高级框架,它自动处理协议解析、工具注册、请求路由等底层细节。开发者只需关注业务逻辑的实现。
2.2 工具定义
每个工具都是一个带有 @mcp.tool() 装饰器的 Python 函数。以下是一个天气查询工具的示例:
@mcp.tool()
def get_weather(city: str) -> str:
"""查询某个城市或区县的天气"""
api_key = "your_api_key_here"
url = f"https://api.example.com/weather?city={city}&key={api_key}"
response = requests.get(url)
return response.json()["forecasts"]
安全提示:生产环境中,API 密钥应通过环境变量或密钥管理服务获取,切勿硬编码在源代码中:
import os
api_key = os.environ.get("WEATHER_API_KEY")
工具函数需要包含类型注解和docstring,MCP 会自动提取这些信息生成函数签名描述,供大模型理解工具的用途和参数规范。
2.3 传输方式配置
MCP 服务器支持两种传输协议:
stdio 模式(本地进程通信):
if __name__ == "__main__":
mcp.run(transport='stdio') # 本地stdio调用
stdio 方式通过标准输入输出进行进程间通信,适用于本地工具集成,延迟最低,不需要网络配置。
SSE 模式(远程 HTTP 通信):
if __name__ == "__main__":
mcp.settings.port = 8001 # 可自定义端口
mcp.run(transport='sse')
SSE(Server-Sent Events)方式通过 HTTP 长连接实现双向通信,适合远程服务部署。服务器在指定端口监听 SSE 连接,客户端通过 URL 访问。
3. 客户端实现详解
3.1 客户端架构
客户端 MCPClient 类管理所有服务器会话和连接资源:
class MCPClient:
def __init__(self):
self.sessions = [] # 存储服务器的会话及其上下文
self.model_name = "deepseek-chat"
self.server_url = "https://your-mcp-server.example.com/sse"
self.client = AsyncOpenAI(
base_url="https://api.example-llm.com",
api_key=os.environ.get("LLM_API_KEY")
)
安全提示:API 密钥和服务器地址等敏感信息应通过环境变量或配置文件注入,避免硬编码。客户端维护三个层级的上下文对象:SSE 流上下文、ClientSession 会话上下文、以及会话实例本身,形成嵌套的异步上下文管理器结构。
3.2 会话初始化
async def init_session(self):
streams_context = sse_client(url=self.server_url)
streams = await streams_context.__aenter__()
session_context = ClientSession(*streams)
session = await session_context.__aenter__()
await session.initialize()
self.sessions = [session, session_context, streams_context]
response = await session.list_tools()
for tool in response.tools:
print(tool)
初始化流程分为四个步骤:首先是创建 SSE 客户端并建立 HTTP 长连接,然后初始化 ClientSession 进行协议握手,接着发送 initialize 消息完成版本协商,最后调用 list_tools 获取可用工具列表。
3.3 工具发现与映射
客户端从服务器获取工具列表后,需要将其转换为符合 OpenAI Function Calling 规范的格式:
for tool in response.tools:
function = {
"type": "function",
"function": {
"name": tool.name,
"description": tool.description,
"parameters": tool.inputSchema,
},
}
available_tools.append(function)
这种转换是 MCP 的关键设计:MCP 工具描述格式与 OpenAI Function Calling 格式之间的映射,使客户端能够将 MCP 工具无缝对接任意支持 Function Calling 的大模型。
3.4 工具调用流程
工具调用遵循"两阶段"模式:
async def process_query(self, query: str):
messages = [{"role": "user", "content": query}]
# 第一阶段:模型决定调用哪些工具
response = await self.client.chat.completions.create(
model=self.model_name,
messages=messages,
tools=available_tools,
)
message = response.choices[0].message
# 第二阶段:执行工具调用
if message.tool_calls:
for tool_call in message.tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
result = await session.call_tool(function_name, function_args)
results.append(result.content)
第一阶段中,大模型分析用户意图并决定调用哪些工具及参数。第二阶段中,客户端通过 MCP 协议向服务器发送 call_tool 请求,执行实际的功能调用。
3.5 结果整合与流式输出
工具执行结果需要再次发送给大模型进行总结:
response = await self.client.chat.completions.create(
model=self.model_name,
messages=messages,
tools=available_tools,
stream=True
)
async for chunk in response:
text = chunk.choices[0].delta.content
if text:
yield text
客户端使用流式响应方式,将大模型的最终回答逐步输出,提供更好的用户体验。
4. 传输协议对比
| 特性 | stdio | SSE |
|---|---|---|
| 通信方式 | 标准输入输出 | HTTP 长连接 |
| 适用场景 | 本地进程集成 | 远程服务部署 |
| 延迟 | 极低 | 较低 |
| 配置复杂度 | 简单 | 需要网络配置 |
| 资源占用 | 低 | 较高 |
对于本地工具调用,推荐使用 stdio 模式。对于需要跨网络访问的工具服务,则应使用 SSE 模式部署 MCP 服务器。
5. 核心设计模式
MCP 的核心设计遵循几个重要原则:职责分离让服务器专注工具实现,客户端处理模型交互;协议适配通过格式转换桥接不同模型提供商;异步优先使用 asyncio 实现高并发处理;上下文管理确保连接资源的正确释放。
这套架构使得工具开发者无需关心大模型的细节,只需实现标准的 MCP 工具函数,即可被任何支持 MCP 客户端的应用使用。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)