痛点
你在搭建 AI Agent 系统时,是否遇到过这些问题:
- 每接一个新工具(数据库查询、API 调用、文件操作),都要写一套 adapter 代码
- 不同 LLM 的 function calling 格式不统一,换模型就得改接入层
- Agent 调用工具的输入/输出没有标准约束,调试困难,容易出现幻觉调用
2024 年底 Anthropic 发布了 MCP(Model Context Protocol) 开放协议,2025 年已被 OpenAI、Google、AWS 等主流厂商跟进支持。MCP 为 AI Agent 调用外部工具提供了统一的「USB-C 接口」——一次实现,处处接入。
方案
MCP 的核心思想是 Server/Client 分离:
- MCP Server:封装具体工具能力(如查询 PostgreSQL、读取文件、调用 API),暴露标准化接口
- MCP Client:嵌入 AI Agent 侧,负责发现 Server、调用 Tool、传递上下文
- 传输层:支持 stdio(本地进程)和 HTTP+SSE(远程服务)两种模式
┌──────────────┐ MCP Protocol ┌──────────────────┐
│ AI Agent │ ◄──────────────────► │ MCP Server │
│ (Client) │ JSON-RPC over │ (PostgreSQL) │
│ │ stdio / HTTP+SSE │ │
└──────────────┘ └──────────────────┘
一个 MCP Server 可以同时暴露 Tools(工具)、Resources(资源)、Prompts(提示模板) 三类能力。
实操步骤
第 1 步:安装 MCP SDK 并创建 Server
以 Python 为例,用官方 mcp SDK 创建一个查询服务器负载的 MCP Server:
pip install mcp[cli]
# server_sysinfo.py
from mcp.server.fastmcp import FastMCP
import psutil
mcp = FastMCP("sysinfo")
@mcp.tool()
def get_cpu_usage() -> dict:
"""获取当前 CPU 使用率"""
return {
"cpu_percent": psutil.cpu_percent(interval=1),
"cpu_count": psutil.cpu_count(),
"load_avg": list(psutil.getloadavg())
}
@mcp.tool()
def get_memory_usage() -> dict:
"""获取内存使用情况"""
mem = psutil.virtual_memory()
return {
"total_gb": round(mem.total / (1024**3), 2),
"used_gb": round(mem.used / (1024**3), 2),
"percent": mem.percent
}
@mcp.tool()
def get_disk_usage(path: str = "/") -> dict:
"""获取指定路径磁盘使用情况"""
disk = psutil.disk_usage(path)
return {
"total_gb": round(disk.total / (1024**3), 2),
"used_gb": round(disk.used / (1024**3), 2),
"percent": disk.percent
}
if __name__ == "__main__":
mcp.run(transport="stdio")
第 2 步:配置 Client 连接 MCP Server
在 Claude Desktop、Cursor 或自研 Agent 中配置 mcp.json:
{
"mcpServers": {
"sysinfo": {
"command": "python",
"args": ["server_sysinfo.py"],
"transport": "stdio"
}
}
}
如果是远程部署,改用 HTTP+SSE 传输:
# 启动远程 Server
if __name__ == "__main__":
mcp.run(transport="sse", host="0.0.0.0", port=8080)
Client 配置改为:
{
"mcpServers": {
"sysinfo": {
"url": "http://your-server:8080/sse",
"transport": "sse"
}
}
}
第 3 步:Agent 自动发现并调用工具
MCP Client 连接 Server 后,会自动获取工具清单(tools/list)。Agent 在推理过程中可直接调用:
# 用 mcp SDK 的 Client 演示手动调用流程
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import asyncio
async def main():
server_params = StdioServerParameters(
command="python",
args=["server_sysinfo.py"]
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# 列出可用工具
tools = await session.list_tools()
print(f"可用工具: {[t.name for t in tools.tools]}")
# 调用工具
result = await session.call_tool("get_cpu_usage", {})
print(f"CPU: {result.content[0].text}")
asyncio.run(main())
输出示例:
可用工具: ['get_cpu_usage', 'get_memory_usage', 'get_disk_usage']
CPU: {"cpu_percent": 23.5, "cpu_count": 8, "load_avg": [1.2, 0.9, 0.7]}
避坑
坑 1:stdio 模式下 Server 输出污染
MCP 的 stdio 传输用 stdin/stdout 传递 JSON-RPC 消息。如果 Server 代码中有 print() 调试输出,会破坏协议通信。
解决:所有日志输出走 stderr 或用 logging 模块配置 stream=sys.stderr。
坑 2:工具返回值过大导致上下文溢出
如果 MCP Tool 返回几十 KB 的数据(如整张表的查询结果),会吃掉 Agent 的上下文窗口。
解决:在 Server 端做数据截断或分页,限制单次返回 ≤ 4KB。对大数据集,返回摘要 + 分页 token,让 Agent 按需取后续数据。
坑 3:远程 SSE 模式缺乏认证
MCP 官方协议未内置认证机制,裸跑 HTTP+SSE 相当于开放了工具调用权限。
解决:生产环境务必在前面加一层 Nginx 反代 + API Key 验证,或使用 OAuth2 Bearer Token。示例 Nginx 配置:
location /sse {
if ($http_authorization != "Bearer YOUR_SECRET_KEY") {
return 401;
}
proxy_pass http://127.0.0.1:8080;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
}
总结
MCP 协议解决了 AI Agent 工具接入的三大痛点:
| 对比维度 | 传统方式 | MCP 方式 |
|---|---|---|
| 接入成本 | 每个工具写一套 adapter | 实现一次 Server,所有 Client 通用 |
| 模型绑定 | function calling 格式各异 | 协议层标准化,与模型解耦 |
| 可复用性 | 几乎不可复用 | Server 可跨项目、跨团队共享 |
落地建议:
- 优先用 stdio 模式做本地开发验证,稳定后再部署 HTTP+SSE 远程服务
- 关注 MCP Server 生态,常见工具(PostgreSQL、Redis、GitHub、Slack)已有官方/社区 Server
- 生产环境一定要加认证 + 限流 + 工具白名单,避免 Agent 越权调用
MCP 正在成为 AI Agent 生态的事实标准,现在落地正当时。