本篇属于「AI Agent 开发实战系列」第 3 篇
前言
在上一篇文章中,我们介绍了 ReAct 模式——让 Agent 学会「边想边做」。
但有一个关键问题没有解决:Agent 如何标准化地连接外部工具和数据源?
每个 AI 厂商都在做自己的 Agent SDK:OpenAI 有 Tools,Anthropic 有 Tools,Google 有 Agent Space...它们互不兼容。如果你想让 Claude Agent 访问 GitHub,同时让 GPT Agent 也能访问,那就要写两套代码。
MCP(Model Context Protocol) 就是为了解决这个问题而生的——一个开放、标准化的 Agent 通信协议。
前置知识
阅读本文前,建议:
核心概念
一、为什么需要 MCP?
先看一个实际场景:
你的 AI Agent 需要做什么?
- 读取 GitHub 仓库的代码
- 查询数据库获取业务数据
- 搜索文件系统中的文档
- 调用企业内部 API
- 操作浏览器/桌面应用
- ...(可能有几十种工具)
传统方式的问题:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Claude App │ │ GPT App │ │ Gemini App │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│GitHub 工具│ │GitHub 工具│ │GitHub 工具│
│写一套代码│ │另写一套代码│ │再写一套代码│
└─────────┘ └─────────┘ └─────────┘
问题:每换一个大模型,就要重新实现一遍工具!
MCP 的解决思路:
┌─────────────────┐
│ MCP Host │
│ (Claude/GPT/...)│
└────────┬────────┘
│ 标准化协议
▼
┌──────────────────────────┐
│ MCP Protocol (统一) │
└──────────────────────────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│GitHub MCP│ │ DB MCP │ │FS MCP │
│ Server │ │ Server │ │Server │
└─────────┘ └─────────┘ └─────────┘
优势:一次实现,所有大模型都能用!
二、MCP 协议架构
MCP 采用客户端-服务器(Client-Server) 架构:
┌─────────────────────────────────────────────────────────────┐
│ MCP 架构图 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ MCP Host │ │ MCP Server │ │
│ │ │◀─────────▶│ │ │
│ │ - Claude App │ stdio / │ - GitHub │ │
│ │ - Cursor │ HTTP │ - Database │ │
│ │ - Claude Code │ │ - Filesystem │ │
│ │ - 自定义 Agent │ │ - Slack │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ │ MCP Client │ MCP Resources │
│ │ │ MCP Tools │
│ │ │ MCP Prompts │
│ └──────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
核心组件:
-
MCP Host(宿主应用)
- Claude Desktop、Cursor、Claude Code 等
- 运行 AI 模型的地方
- 通过 MCP Client 与 Server 通信
-
MCP Client(客户端)
- 内嵌在 Host 中
- 负责与 Server 建立连接
- 处理协议层面的通信
-
MCP Server(服务器)
- 提供具体的工具、数据、提示词
- 可以是任何语言实现(Python、TypeScript、Go...)
- 通过标准协议与 Client 通信
三、MCP 的核心能力
MCP 定义了三类核心能力:
| 能力类型 | 描述 | 类比 |
|---|---|---|
| Resources | 提供数据/文件访问 | 读操作 |
| Tools | 提供可执行的操作 | 读写操作 |
| Prompts | 预定义的提示词模板 | 快捷指令 |
// MCP Server 定义的 capabilities
{
"capabilities": {
"resources": {
"github_repos": {
"description": "访问用户的 GitHub 仓库",
"uriTemplate": "github://{owner}/{repo}/..."
},
"user_files": {
"description": "访问用户的本地文件",
"uriTemplate": "file://{path}"
}
},
"tools": {
"search_code": {
"description": "在代码库中搜索",
"inputSchema": {
"type": "object",
"properties": {
"query": {"type": "string"},
"repo": {"type": "string"}
}
}
}
},
"prompts": {
"code_review": {
"description": "代码评审提示词",
"arguments": [
{"name": "language", "required": true}
]
}
}
}
}
四、MCP vs Function Calling vs Tools API
| 维度 | Function Calling | MCP |
|---|---|---|
| 标准化 | 各厂商私有 | 开放统一 |
| 可发现性 | 无 | 自动发现 |
| 复用性 | 不可复用 | 一次实现,多处使用 |
| 生态 | 封闭 | 开放(已有 100+ Server) |
| 适用场景 | 简单工具 | 复杂系统 |
一句话总结:Function Calling 是"私有API",MCP 是"开放生态"。
实践指南
环境准备
方式一:使用 Claude Desktop(推荐新手)
Claude Desktop 内置了 MCP 支持,可以直接配置使用。
1. 安装 Claude Desktop
# macOS
brew install --cask claude
# 或从官网下载:https://claude.ai/desktop
2. 配置 MCP Server
编辑配置文件 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"],
"env": {}
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "your-token-here"
}
}
}
}
3. 重启 Claude Desktop
现在 Claude 就能直接访问你的文件系统和 GitHub 了!
方式二:使用 Python 自行实现 MCP Server
下面我们从头实现一个 MCP Server,体验协议的细节。
1. 安装依赖
pip install mcp uvicon
2. 创建 MCP Server
# server.py
from mcp.server.fastmcp import FastMCP
# 创建 MCP Server
mcp = FastMCP("我的工具服务器")
# ========== 定义 Resources ==========
@mcp.resource("user://profile")
def get_user_profile() -> str:
"""返回用户资料"""
return """
{
"name": "张三",
"role": "全栈工程师",
"skills": ["Python", "TypeScript", "AI"]
}
"""
@mcp.resource("greeting://{name}")
def greet(name: str) -> str:
"""动态资源:根据名字生成问候语"""
return f"你好,{name}!欢迎来到 AI Agent 世界。"
# ========== 定义 Tools ==========
@mcp.tool()
def calculator(expression: str) -> str:
"""
数学计算工具
Args:
expression: 数学表达式,如 "25 * 3 + 10"
Returns:
计算结果
"""
try:
result = eval(expression)
return f"计算结果:{result}"
except Exception as e:
return f"计算错误:{str(e)}"
@mcp.tool()
def weather(city: str) -> str:
"""
天气查询工具(模拟)
Args:
city: 城市名称
Returns:
天气信息
"""
# 实际项目中这里会调用真实天气 API
weather_data = {
"北京": "晴,25°C",
"上海": "多云,22°C",
"深圳": "小雨,28°C"
}
return weather_data.get(city, f"未找到 {city} 的天气数据")
@mcp.tool()
def search_files(directory: str, pattern: str) -> str:
"""
文件搜索工具
Args:
directory: 要搜索的目录
pattern: 文件名匹配模式
Returns:
匹配的文件列表
"""
import glob
import os
search_path = os.path.join(directory, f"*{pattern}*")
files = glob.glob(search_path)
if not files:
return f"在 {directory} 中未找到匹配 {pattern} 的文件"
result = "\n".join([f"- {f}" for f in files])
return f"找到 {len(files)} 个文件:\n{result}"
# ========== 定义 Prompts ==========
@mcp.prompt()
def code_review_prompt(repo_path: str, language: str = "Python") -> str:
"""
代码评审提示词
Args:
repo_path: 仓库路径
language: 编程语言
Returns:
完整的评审提示词
"""
return f"""请帮我评审 {repo_path} 中的 {language} 代码:
1. 检查代码质量和风格
2. 识别潜在 bug 和安全问题
3. 提出改进建议
4. 评估是否遵循最佳实践
重点关注:
- 错误处理是否完善
- 是否有安全漏洞
- 性能是否需要优化
"""
# ========== 启动 Server ==========
if __name__ == "__main__":
mcp.run()
3. 配置到 Claude Desktop
在 claude_desktop_config.json 中添加:
{
"mcpServers": {
"my-tools": {
"command": "python",
"args": ["/path/to/your/server.py"]
}
}
}
4. 测试
重启 Claude Desktop,然后尝试:
- "用计算器算一下 (25 + 10) * 2"
- "帮我搜索 /Users/you/projects 目录下包含 'agent' 的文件"
- "生成一个 Python 代码评审提示词"
MCP Server 生态
目前已有大量开源 MCP Server:
| 分类 | Server | 功能 |
|---|---|---|
| 数据 | @modelcontextprotocol/server-sqlite | SQLite 数据库 |
| 数据 | @modelcontextprotocol/server-postgres | PostgreSQL |
| 数据 | @modelcontextprotocol/server-google-maps | 地图服务 |
| 代码 | @modelcontextprotocol/server-github | GitHub API |
| 代码 | @modelcontextprotocol/server-git | Git 操作 |
| 文件 | @modelcontextprotocol/server-filesystem | 文件系统 |
| 通信 | @modelcontextprotocol/server-slack | Slack 消息 |
| 通信 | @modelcontextprotocol/server-sentry | 错误监控 |
| 搜索 | @modelcontextprotocol/server-everything | 全局搜索 |
| AI | @modelcontextprotocol/server-puppeteer | 浏览器控制 |
进阶拓展
MCP 协议通信机制
MCP 支持两种通信方式:
1. stdio(标准输入输出)
{
"command": "python",
"args": ["server.py"]
}
// 通过 stdin/stdout 通信,适合本地进程
2. HTTP + SSE(服务器发送事件)
{
"command": "node",
"args": ["server.js"],
"env": {
"PORT": "3000"
}
}
// 通过 HTTP 请求通信,适合远程服务
开发 MCP Server 的最佳实践
1. 使用 FastMCP 框架
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("服务名")
# 装饰器自动处理类型转换和错误
@mcp.tool()
async def async_tool(param: str) -> str:
# 支持 async 函数
result = await do_something(param)
return result
2. 添加详细描述
@mcp.tool(
name="specific_name", # 显式命名
description="详细描述这个工具做什么", # LLM 会看到
annotations={
"readOnlyHint": True, # 提示这是只读操作
"destructiveHint": False # 提示是否有副作用
}
)
def my_tool(param: str) -> str:
...
3. 处理错误和边界情况
@mcp.tool()
def risky_operation(param: str) -> str:
try:
result = do_risky_thing(param)
return json.dumps(result)
except ValueError as e:
raise UserError(f"参数错误: {e}")
except PermissionError:
raise UserError("没有权限执行此操作")
总结
本文介绍了 MCP 协议:
- MCP = Model Context Protocol,解决大模型与外部工具的标准化连接问题
- 核心架构:Host + Client + Server,清晰的分层设计
- 三大能力:Resources(数据)、Tools(操作)、Prompts(模板)
- 生态优势:一次实现,Claude、GPT、Gemini... 所有支持 MCP 的应用都能用
MCP 是 AI Agent 工具生态的未来,随着更多 Server 的出现,Agent 将能连接一切数据源和工具。
下篇预告: 在下一篇文章中,我们将从零构建一个完整的 AI Agent 应用。你将综合运用前几篇学到的知识:
- 设计 Agent 架构
- 实现 ReAct 推理循环
- 集成 MCP 工具
- 构建对话界面
参考资料
本文是「AI Agent 开发实战系列」第 3 篇,系列共 10 篇。