MCP协议核心概念与通信机制
🎯 MCP协议简介
MCP (Model Context Protocol) 是一个开放标准协议,为AI应用与外部工具和数据源之间提供标准化的通信接口。
🏗️ 核心架构
┌─────────────────┐ MCP协议 ┌─────────────────┐
│ MCP Client │ ◄──────────► │ MCP Server │
│ (AI应用) │ JSON-RPC │ (工具提供者) │
└─────────────────┘ └─────────────────┘
📋 核心组件详解
1. MCP Server (服务器端)
定义: MCP服务器是提供具体工具和资源的独立进程
核心职责:
- 定义和实现工具(Tools)
- 管理资源(Resources)
- 处理客户端请求
- 返回执行结果
基本结构:
python
from mcp.server import Server
from mcp.types import Tool, TextContent
# 1. 创建服务器实例
server = Server("my-server")
# 2. 定义工具列表
@server.list_tools()
async def handle_list_tools():
return [
Tool(
name="calculator",
description="执行数学计算",
inputSchema={
"type": "object",
"properties": {
"expression": {"type": "string"}
},
"required": ["expression"]
}
)
]
# 3. 处理工具调用
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict):
if name == "calculator":
result = eval(arguments["expression"]) # 简化示例
return [TextContent(type="text", text=str(result))]
# 4. 启动服务器
async def main():
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream)
2. MCP Client (客户端)
定义: MCP客户端是连接和使用MCP服务器的应用程序
核心职责:
- 连接MCP服务器
- 发现可用工具
- 调用工具执行任务
- 处理执行结果
基本结构:
python
from mcp.client.stdio import stdio_client
class MCPClient:
def __init__(self, server_path: str):
self.server_path = server_path
self.session = None
# 1. 建立连接
async def connect(self):
server_params = {
"command": "python",
"args": [self.server_path]
}
self.session = await stdio_client(server_params)
await self.session.initialize()
# 2. 发现工具
async def list_tools(self):
tools = await self.session.list_tools()
return [tool.name for tool in tools.tools]
# 3. 调用工具
async def call_tool(self, tool_name: str, arguments: dict):
result = await self.session.call_tool(tool_name, arguments)
return result.content[0].text if result.content else None
# 4. 断开连接
async def disconnect(self):
if self.session:
await self.session.close()
3. MCP协议通信机制
3.1 通信协议栈
应用层 │ MCP协议消息 (Tools, Resources)
传输层 │ JSON-RPC 2.0 (请求/响应格式)
连接层 │ stdio/SSE/WebSocket (数据传输)
3.2 消息流程
1. 初始化阶段
json
// 客户端 -> 服务器: 初始化请求
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": {"listChanged": true}
}
}
}
// 服务器 -> 客户端: 初始化响应
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {"listChanged": true}
}
}
}
2. 工具发现阶段
json
// 客户端 -> 服务器: 获取工具列表
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}
// 服务器 -> 客户端: 返回工具列表
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "calculator",
"description": "执行数学计算",
"inputSchema": {
"type": "object",
"properties": {
"expression": {"type": "string"}
}
}
}
]
}
}
3. 工具调用阶段
json
// 客户端 -> 服务器: 调用工具
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "calculator",
"arguments": {
"expression": "2 + 3 * 4"
}
}
}
// 服务器 -> 客户端: 返回结果
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "14"
}
]
}
}
3.3 传输方式
1. Stdio (标准输入输出)
python
# 服务器端
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream)
# 客户端
server_params = {
"command": "python",
"args": ["server.py"]
}
session = await stdio_client(server_params)
2. SSE (Server-Sent Events)
python
# 服务器端
app = FastAPI()
await sse_server(app, server)
# 客户端
session = await sse_client("http://localhost:8000/sse")
3. WebSocket
python
# 服务器端
await websocket_server(websocket, server)
# 客户端
session = await websocket_client("ws://localhost:8000/ws")
🔧 简化实例
计算器MCP服务器
python
#!/usr/bin/env python3
"""简化的计算器MCP服务器"""
import asyncio
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
# 创建服务器
server = Server("calculator-server")
@server.list_tools()
async def handle_list_tools():
"""定义可用工具"""
return [
Tool(
name="add",
description="两数相加",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"}
},
"required": ["a", "b"]
}
),
Tool(
name="multiply",
description="两数相乘",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"}
},
"required": ["a", "b"]
}
)
]
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict):
"""处理工具调用"""
if name == "add":
result = arguments["a"] + arguments["b"]
return [TextContent(type="text", text=f"结果: {result}")]
elif name == "multiply":
result = arguments["a"] * arguments["b"]
return [TextContent(type="text", text=f"结果: {result}")]
else:
return [TextContent(type="text", text="未知工具")]
async def main():
"""启动服务器"""
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream)
if __name__ == "__main__":
asyncio.run(main())
计算器MCP客户端
python
#!/usr/bin/env python3
"""简化的计算器MCP客户端"""
import asyncio
from mcp.client.stdio import stdio_client
class CalculatorClient:
def __init__(self):
self.session = None
async def connect(self):
"""连接到服务器"""
server_params = {
"command": "python",
"args": ["calculator_server.py"]
}
self.session = await stdio_client(server_params)
await self.session.initialize()
print("✅ 已连接到计算器服务器")
async def add(self, a: float, b: float):
"""调用加法工具"""
result = await self.session.call_tool("add", {"a": a, "b": b})
return result.content[0].text
async def multiply(self, a: float, b: float):
"""调用乘法工具"""
result = await self.session.call_tool("multiply", {"a": a, "b": b})
return result.content[0].text
async def disconnect(self):
"""断开连接"""
if self.session:
await self.session.close()
print("🔌 已断开连接")
async def main():
"""演示客户端使用"""
client = CalculatorClient()
try:
# 连接服务器
await client.connect()
# 执行计算
result1 = await client.add(5, 3)
print(f"5 + 3 = {result1}")
result2 = await client.multiply(4, 7)
print(f"4 × 7 = {result2}")
finally:
await client.disconnect()
if __name__ == "__main__":
asyncio.run(main())
🚀 运行示例
bash
# 1. 安装依赖
pip install mcp
# 2. 启动服务器 (在一个终端)
python calculator_server.py
# 3. 运行客户端 (在另一个终端)
python calculator_client.py
输出结果:
✅ 已连接到计算器服务器
5 + 3 = 结果: 8
4 × 7 = 结果: 28
🔌 已断开连接
🔑 关键概念总结
MCP Server 核心要素
- 工具定义 (
@server.list_tools()): 声明提供哪些功能 - 工具实现 (
@server.call_tool()): 具体的功能逻辑 - 服务启动 (
server.run()): 启动服务监听
MCP Client 核心要素
- 连接建立 (
stdio_client()): 连接到服务器 - 会话初始化 (
session.initialize()): 协议握手 - 工具调用 (
session.call_tool()): 执行远程功能
MCP 通信机制
- 协议层: JSON-RPC 2.0 标准格式
- 传输层: stdio/SSE/WebSocket 多种方式
- 消息流: 初始化 → 发现 → 调用 → 响应
📦 Python MCP框架详解
核心依赖包
MCP协议的Python实现基于以下核心框架和库:
bash
# 核心MCP框架
pip install mcp>=1.0.0
# 可选的异步HTTP支持 (用于SSE/WebSocket传输)
pip install aiohttp>=3.8.0
pip install fastapi>=0.104.0
pip install uvicorn>=0.24.0
# 类型检查支持
pip install typing-extensions>=4.8.0
Import模块详解
1. MCP Server 相关导入
python
# 核心服务器框架
from mcp.server import Server # MCP服务器主类
from mcp.server.models import InitializationOptions # 初始化配置
from mcp.server.stdio import stdio_server # 标准输入输出服务器
# 传输协议支持
from mcp.server.sse import sse_server # Server-Sent Events服务器
from mcp.server.websocket import websocket_server # WebSocket服务器
# 数据类型定义
from mcp.types import (
Tool, # 工具定义类型
Resource, # 资源定义类型
TextContent, # 文本内容类型
ImageContent, # 图片内容类型
EmbeddedResource # 嵌入式资源类型
)
各模块作用:
Server: MCP服务器的核心类,负责注册和管理工具stdio_server: 提供基于标准输入输出的服务器实现Tool: 定义工具的结构,包括名称、描述和参数schemaTextContent: 定义文本类型的返回内容
2. MCP Client 相关导入
python
# 核心客户端框架
from mcp.client import ClientSession # 客户端会话管理
from mcp.client.session import ClientSession # 会话基类
# 传输协议客户端
from mcp.client.stdio import stdio_client # 标准输入输出客户端
from mcp.client.sse import sse_client # Server-Sent Events客户端
from mcp.client.websocket import websocket_client # WebSocket客户端
# 异常处理
from mcp.client.exceptions import (
MCPError, # MCP基础异常
ConnectionError, # 连接异常
TimeoutError, # 超时异常
ProtocolError # 协议异常
)
各模块作用:
ClientSession: 管理与MCP服务器的会话和通信stdio_client: 通过标准输入输出连接服务器MCPError: MCP相关的异常处理基类
3. 类型系统导入
python
# Python标准库类型支持
from typing import (
Any, # 任意类型
Dict, # 字典类型
List, # 列表类型
Optional, # 可选类型
Union, # 联合类型
Callable, # 可调用类型
Awaitable # 可等待类型
)
# 异步编程支持
import asyncio # 异步I/O框架
from asyncio import StreamReader, StreamWriter # 异步流处理
# JSON处理
import json # JSON序列化/反序列化
from pydantic import BaseModel # 数据验证框架 (MCP内部使用)
框架架构详解
1. 异步框架基础
MCP协议基于asyncio异步框架构建:
python
import asyncio
# MCP使用asyncio的核心特性
async def async_function():
"""所有MCP操作都是异步的"""
pass
# 事件循环管理
if __name__ == "__main__":
asyncio.run(main()) # Python 3.7+ 推荐方式
为什么使用asyncio:
- 高并发: 支持同时处理多个客户端连接
- 非阻塞I/O: 避免因网络延迟导致的阻塞
- 资源效率: 单线程处理多个连接,减少资源消耗
2. JSON-RPC 2.0 框架
MCP协议底层使用JSON-RPC 2.0标准:
python
# MCP内部使用的JSON-RPC消息格式
class JSONRPCRequest:
def __init__(self, method: str, params: dict, id: int):
self.jsonrpc = "2.0"
self.method = method
self.params = params
self.id = id
class JSONRPCResponse:
def __init__(self, result: Any, id: int):
self.jsonrpc = "2.0"
self.result = result
self.id = id
3. 数据验证框架
MCP使用Pydantic进行数据验证:
python
from pydantic import BaseModel, Field
from typing import Dict, Any
class ToolSchema(BaseModel):
"""工具定义的数据模型"""
name: str = Field(..., description="工具名称")
description: str = Field(..., description="工具描述")
inputSchema: Dict[str, Any] = Field(..., description="输入参数schema")
# 自动验证和类型转换
tool = ToolSchema(
name="calculator",
description="数学计算工具",
inputSchema={"type": "object", "properties": {...}}
)
完整的依赖配置
requirements.txt
txt
# MCP核心框架
mcp>=1.0.0
# 异步HTTP支持 (用于SSE/WebSocket)
aiohttp>=3.8.0
fastapi>=0.104.0
uvicorn>=0.24.0
# 数据处理
pydantic>=2.0.0
typing-extensions>=4.8.0
# 可选:日志和调试
loguru>=0.7.0
rich>=13.0.0
# 可选:配置管理
python-dotenv>=1.0.0
pyyaml>=6.0
pyproject.toml (现代Python项目配置)
toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-mcp-project"
version = "1.0.0"
description = "MCP协议示例项目"
dependencies = [
"mcp>=1.0.0",
"aiohttp>=3.8.0",
"pydantic>=2.0.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0.0",
"pytest-asyncio>=0.21.0",
"black>=23.0.0",
"ruff>=0.1.0",
]
框架特性详解
1. 装饰器模式
MCP使用装饰器简化服务器开发:
python
from mcp.server import Server
server = Server("my-server")
# 工具列表装饰器
@server.list_tools()
async def handle_list_tools():
"""使用装饰器注册工具列表处理器"""
return [...]
# 工具调用装饰器
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict):
"""使用装饰器注册工具调用处理器"""
return [...]
# 资源管理装饰器
@server.list_resources()
async def handle_list_resources():
"""使用装饰器注册资源列表处理器"""
return [...]
2. 上下文管理器
MCP支持Python的上下文管理器模式:
python
# 服务器端上下文管理
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream)
# 客户端上下文管理
async with stdio_client(server_params) as session:
await session.initialize()
result = await session.call_tool("tool_name", {})
3. 类型提示支持
MCP框架完全支持Python类型提示:
python
from typing import List, Dict, Any, Optional
from mcp.types import Tool, TextContent
async def handle_list_tools() -> List[Tool]:
"""完整的类型提示支持"""
return []
async def handle_call_tool(
name: str,
arguments: Dict[str, Any]
) -> List[TextContent]:
"""参数和返回值都有类型提示"""
return []
开发环境配置
1. 虚拟环境设置
bash
# 创建虚拟环境
python -m venv mcp_env
# 激活虚拟环境 (Linux/Mac)
source mcp_env/bin/activate
# 激活虚拟环境 (Windows)
mcp_env\Scripts\activate
# 安装依赖
pip install -r requirements.txt
2. IDE配置 (VS Code)
json
// .vscode/settings.json
{
"python.defaultInterpreterPath": "./mcp_env/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"python.linting.ruffEnabled": true,
"python.formatting.provider": "black"
}
3. 调试配置
json
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "MCP Server",
"type": "python",
"request": "launch",
"program": "server.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}"
}
]
}
性能优化建议
1. 异步最佳实践
python
# 推荐:使用异步上下文管理器
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
data = await response.json()
# 避免:阻塞式操作
import time
time.sleep(1) # ❌ 会阻塞事件循环
# 推荐:异步等待
await asyncio.sleep(1) # ✅ 不会阻塞其他任务
2. 连接池管理
python
# 使用连接池提高性能
import aiohttp
class OptimizedMCPClient:
def __init__(self):
self.session = aiohttp.ClientSession(
connector=aiohttp.TCPConnector(
limit=100, # 总连接池大小
limit_per_host=30, # 每个主机的连接数
ttl_dns_cache=300, # DNS缓存时间
use_dns_cache=True
)
)
🎉 MCP协议优势
✅ 标准化 : 统一的接口规范,易于集成
✅ 类型安全 : JSON Schema 参数验证
✅ 异步支持 : 高性能的异步I/O模型
✅ 多传输 : 支持多种通信方式
✅ 扩展性: 插件式架构,易于扩展功能
通过MCP协议,AI应用可以安全、高效地调用外部工具和服务,实现能力的无限扩展!