2026年,MCP(Model Context Protocol)已经成为 AI Agent 开发的事实标准。本文手把手教你用MCP协议开发一个能调用外部工具的AI Agent,附完整代码和踩坑记录。
为什么2026年的AI Agent必须掌握MCP?
如果你还在用"function calling + 手写adapter"的方式开发Agent,那你正在重复造轮子。
MCP是Anthropic在2024年底推出的开放协议,经过一年多的生态演进,2026年已经被主流框架全部支持。它解决的核心问题是:让AI Agent用统一的方式调用任意外部工具,不用为每个API写一套适配代码。
简单类比:MCP之于AI Agent,就像USB之于电脑外设。你不需要为每个鼠标键盘写驱动,插上就能用。
2026年的Agent开发现状:
- Google A2A(Agent-to-Agent)协议让Agent之间可以协作
- Anthropic MCP让Agent连接外部工具
- OpenAI Function Calling仍然是最底层的能力
- 三者不是竞争关系,而是不同层级的标准
MCP协议核心概念(5分钟搞懂)
架构三角
┌──────────┐ MCP协议 ┌──────────┐
│ AI Agent │ ◄──────────► │ MCP Server│
│ (Client) │ │ (Tools) │
└──────────┘ └──────────┘
│
┌────┴────┐
│外部系统 │
│数据库/API│
└─────────┘
三个角色:
- Host:你的应用,负责发起Agent会话
- Client:Agent本体,理解用户意图并决定调用哪些工具
- Server:工具提供方,暴露能力给Agent
核心能力
| 能力 | 说明 | 典型场景 |
|---|---|---|
| Tools | Agent可调用的函数 | 查数据库、发邮件、调API |
| Resources | Agent可读取的数据 | 文件系统、知识库 |
| Prompts | 预定义的提示模板 | 代码审查、文档生成 |
传输方式
MCP支持两种传输:
- stdio:适合本地工具,通过标准输入输出通信
- HTTP SSE:适合远程服务,通过HTTP Server-Sent Events
实战:从零搭建MCP Agent
环境准备
# Python 3.10+
pip install mcp anthropic
# 或者用Node.js
npm install @modelcontextprotocol/sdk
我在腾讯云轻量服务器上开发(2核4G配置,跑Agent绰绰有余),推荐开发阶段用这个配置:
- 腾讯云轻量应用服务器,新用户首年很便宜
第一步:写一个MCP Server
先写一个最简单的天气查询工具:
# weather_server.py
from mcp.server import Server
from mcp.types import Tool, TextContent
import httpx
app = Server("weather-tool")
@app.list_tools()
async def list_tools():
return [
Tool(
name="get_weather",
description="查询指定城市的天气",
inputSchema={
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名"}
},
"required": ["city"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_weather":
city = arguments["city"]
# 调用真实天气API
async with httpx.AsyncClient() as client:
resp = await client.get(
f"https://wttr.in/{city}?format=j1"
)
data = resp.json()
current = data["current_condition"][0]
return [TextContent(
type="text",
text=f"{city}天气:{current['weatherDesc'][0]['value']},"
f"温度{current['temp_C']}°C,"
f"湿度{current['humidity']}%"
)]
if __name__ == "__main__":
import asyncio
from mcp.server.stdio import stdio_server
asyncio.run(stdio_server(app))
第二步:配置MCP Client
{
"mcpServers": {
"weather": {
"command": "python",
"args": ["weather_server.py"],
"transport": "stdio"
}
}
}
第三步:Agent调用逻辑
# agent.py
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from anthropic import Anthropic
async def run_agent():
# 连接MCP Server
server = StdioServerParameters(
command="python",
args=["weather_server.py"]
)
async with stdio_client(server) 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]}")
# Agent决策:是否需要调用工具
client = Anthropic()
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "北京今天天气怎么样?"}],
tools=[{
"name": t.name,
"description": t.description,
"input_schema": t.inputSchema
} for t in tools.tools]
)
# 处理工具调用
for block in response.content:
if block.type == "tool_use":
result = await session.call_tool(
block.name, block.input
)
print(f"工具返回: {result.content[0].text}")
进阶:连接10个常用外部工具
基础跑通之后,实际项目中一个Agent通常需要连接多个工具。以下是我在生产环境中验证过的10个MCP Server配置:
| 工具 | 用途 | 传输方式 | 复杂度 |
|---|---|---|---|
| 文件系统 | 读写本地文件 | stdio | ⭐ |
| 数据库 | 查询MySQL/PG | stdio | ⭐⭐ |
| 飞书/钉钉 | 发消息、读文档 | HTTP SSE | ⭐⭐⭐ |
| GitHub | PR审查、Issue管理 | stdio | ⭐⭐ |
| 搜索引擎 | 实时信息检索 | stdio | ⭐ |
| 邮件 | 收发邮件 | stdio | ⭐⭐ |
| 日历 | 会议调度 | HTTP SSE | ⭐⭐ |
| 监控 | Prometheus/Grafana | HTTP SSE | ⭐⭐⭐ |
| 知识库 | RAG检索 | stdio | ⭐⭐ |
| 部署 | CI/CD触发 | HTTP SSE | ⭐⭐⭐ |
多工具配置示例:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "ghp_xxx" }
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://..."]
}
}
}
关键经验:工具数量控制在10-15个以内。超过15个工具,LLM选择工具的准确率会明显下降。
生产部署注意事项
1. 安全隔离
MCP Server运行在你的服务器上,对外部系统有真实的读写权限。务必做到:
# 白名单机制示例
ALLOWED_PATHS = ["/data/", "/tmp/agent-workspace/"]
@app.call_tool()
async def call_tool(name, arguments):
if name == "read_file":
path = arguments["path"]
if not any(path.startswith(p) for p in ALLOWED_PATHS):
raise ValueError(f"路径不在白名单内: {path}")
2. 超时和重试
import asyncio
async def safe_call_tool(session, name, args, timeout=30):
try:
return await asyncio.wait_for(
session.call_tool(name, args),
timeout=timeout
)
except asyncio.TimeoutError:
return {"error": f"工具 {name} 调用超时({timeout}s)"}
3. 成本控制
Agent每次调用LLM都消耗token。在生产环境中,我建议:
- 简单任务用Claude Haiku(便宜10倍),复杂推理用Sonnet
- 工具调用结果做缓存(相同参数5分钟内不重复调用)
- 设置每个session的最大tool call次数
如果需要部署到生产环境,推荐使用阿里云ECS,稳定性好,国内访问延迟低。
踩坑记录(真实经历)
坑1:stdio传输的进程管理
MCP的stdio模式下,Server是一个子进程。如果Agent崩溃,子进程不会自动清理,导致僵尸进程。
解决:用进程组管理,Agent退出时signal整个进程组。
坑2:并发工具调用的顺序问题
当Agent同时调用3个工具时,返回顺序不确定。如果工具之间有依赖(先查数据库,再发邮件),需要在Agent层面做编排。
解决:在system prompt中明确告诉Agent调用顺序,或者用chain-of-thought拆解步骤。
坑3:大模型的"幻觉工具调用"
LLM有时候会调用不存在的工具,或者给工具传错误的参数。
解决:在Client层做严格校验,参数不匹配直接返回错误信息让LLM重试。
FAQ
Q1:MCP和LangChain的Tool有什么区别?
MCP是协议层标准,LangChain的Tool是框架层封装。你可以在LangChain中使用MCP Server,两者是互补关系。LangChain 0.3+ 已经内置了MCP adapter。
Q2:MCP Server可以用什么语言写?
官方SDK支持Python和TypeScript。社区也有Go、Rust、Java的实现。选你团队最熟悉的语言。
Q3:一个Agent最多能连多少个MCP Server?
技术上没有限制,但实测超过15个工具后,LLM的工具选择准确率下降明显。建议按场景分组,每个场景5-8个工具。
Q4:MCP和Google A2A协议的关系?
MCP解决"Agent↔工具"的连接问题,A2A解决"Agent↔Agent"的协作问题。生产级系统两个都需要。
Q5:开发MCP Server需要什么级别的服务器?
开发阶段2核4G足够(腾讯云轻量服务器或阿里云ECS入门款)。生产环境取决于并发量,中等负载4核8G起步。
总结
MCP协议让AI Agent开发从"每个API写一遍adapter"变成了"统一协议、即插即用"。2026年入坑Agent开发,MCP是必修课。
完整项目代码我已整理成可运行的模板,包含上面提到的10个工具Server配置,可以直接clone到你的服务器上跑起来。
如果你对AI Agent开发感兴趣,推荐看看我整理的AI Agent开发实战手册,从架构设计到生产部署的完整路径。
作者:TechFind | AI产品架构师 | 专注AI Agent开发与落地