🔌 当每个 AI 工具都「各说各话」
2024 年底的 AI 开发生态是什么样子?那叫一个「群魔乱舞」。
你要让 AI Agent 访问一个数据库,你得写一段 Python 脚本。要让 Agent 读文件?再写一个函数。让它调用 Slack API?好家伙,又得从头对接。每个工具都有自己的接口风格——有的用 REST、有的用 WebSocket、有的干脆只支持命令行参数。
开发者变成了「接口翻译工」,每天都在写适配器、转换器、胶水代码。
这个问题的本质是什么?AI 工具之间缺乏一个统一的「对话协议」。
就像 USB 出现之前,每个外设都有自己的接口——打印机用并口、鼠标用串口、键盘用 PS/2——你插个设备得先看接口对不对。直到 USB 出现,一切才统一。
2024 年 11 月,Anthropic 提出了 MCP(Model Context Protocol),目标就是成为 AI 时代的「USB-C」。到 2026 年,这个协议已经被 OpenAI、Google DeepMind、微软、AWS 等巨头全面采纳。GitHub 上已经有了超过 10,000 个 MCP Server 实现。
📐 MCP 架构:像搭积木一样连接 AI
MCP 的架构可以用一句话概括:一个标准化的 JSON-RPC 协议,让 AI 模型可以动态发现和调用外部工具。
它的核心架构分为三层:
┌──────────────────────┐│ AI 模型 / Agent │ ← Claude、GPT、Gemini 等│ (MCP Client) │└────────┬─────────────┘ │ JSON-RPC over stdio/SSE/WebSocket ▼┌──────────────────────┐│ MCP Protocol │ ← 标准化的协议层│ (工具发现/调用/通知) │└────────┬─────────────┘ ▼┌──────────────────────┐│ MCP Server │ ← 你的工具/API/数据库│ (暴露能力给 AI) │└──────────────────────┘MCP Server 需要实现三个核心方法:
// MCP Server 的最小实现import { Server } from "@modelcontextprotocol/sdk";
const server = new Server({ name: "my-database-server", version: "1.0.0"}, { capabilities: { resources: {}, // 暴露数据资源 tools: {}, // 暴露可调用工具 prompts: {} // 暴露模板提示词 }});
// 1. 列出可用工具server.setRequestHandler("tools/list", async () => ({ tools: [{ name: "query_database", description: "对 PostgreSQL 数据库执行 SQL 查询", inputSchema: { type: "object", properties: { sql: { type: "string", description: "SQL 查询语句" }, limit: { type: "number", default: 100 } } } }]}));
// 2. 调用工具server.setRequestHandler("tools/call", async (request) => { if (request.params.name === "query_database") { const { sql, limit } = request.params.arguments; const result = await db.query(sql, { limit }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; }});
// 3. 启动服务server.connect(transport);是的,只需要几十行代码,你的数据库就变成了 AI Agent 可以直接调用的「插件」。
🚀 实战:搭建你的第一个 MCP Server
让我们真正动手做一个能让 Claude Code 或 Codex 调用的 MCP Server——一个简单的代码分析工具:
# code_analyzer_server.py — MCP Server for code analysisimport subprocessimport jsonfrom mcp.server import Server, NotificationOptionsfrom mcp.server.models import InitializationOptions
server = Server("code-analyzer")
@server.list_tools()async def handle_list_tools() -> list[dict]: return [ { "name": "count_lines_of_code", "description": "统计指定目录下的代码行数", "inputSchema": { "type": "object", "properties": { "path": {"type": "string", "description": "目录路径"}, "extensions": { "type": "array", "items": {"type": "string"}, "description": "文件扩展名过滤, 如 ['.py', '.js']" } } } }, { "name": "run_tests", "description": "运行测试并返回结果摘要", "inputSchema": { "type": "object", "properties": { "path": {"type": "string", "description": "项目路径"}, "test_pattern": {"type": "string", "description": "测试匹配模式, 如 'test_*'"} } } } ]
@server.call_tool()async def handle_call_tool(name: str, arguments: dict) -> list[dict]: if name == "count_lines_of_code": path = arguments["path"] exts = arguments.get("extensions", [".py"]) result = subprocess.run( ["cloc", "--json"] + [f"--include-lang={e.lstrip('.')}" for e in exts] + [path], capture_output=True, text=True ) data = json.loads(result.stdout) return [{"type": "text", "text": json.dumps(data, indent=2)}]
elif name == "run_tests": path = arguments["path"] pattern = arguments.get("test_pattern", "test_*") result = subprocess.run( ["pytest", "-x", "--tb=short", f"-k={pattern}", path], capture_output=True, text=True ) summary = { "passed": "passed" in result.stdout and "failed" not in result.stdout, "output": result.stdout[-2000:], "return_code": result.returncode } return [{"type": "text", "text": json.dumps(summary, indent=2)}]
# 启动if __name__ == "__main__": from mcp.server.stdio import stdio_server async with stdio_server() as (read, write): await server.run(read, write, InitializationOptions( server_name="code-analyzer", server_version="1.0.0" ))配置到你的 Claude Code 中:
{ "mcpServers": { "code-analyzer": { "command": "python", "args": ["code_analyzer_server.py"] } }}然后你就可以在 Claude Code 中直接说:「分析当前项目有多少行 Python 代码」或者「帮我跑一下测试,告诉我结果」——Agent 会自动调用你的 MCP Server。
🌍 MCP 生态地图
2026 年的 MCP 生态已经相当丰富。以下是几个最有代表性的方向:
| 类别 | 代表项目 | 功能 |
|---|---|---|
| 数据库 | mcp-postgres, mcp-mysql, mcp-mongodb | Agent 直接查库 |
| 文件系统 | mcp-filesystem | 读写文件、目录操作 |
| 浏览器 | mcp-puppeteer, mcp-playwright | Agent 操控浏览器 |
| Git | mcp-github, mcp-gitlab | PR 管理、代码审查 |
| 云服务 | mcp-aws, mcp-gcp, mcp-cloudflare | 云资源管理 |
| 通信 | mcp-slack, mcp-discord, mcp-email | 消息发送与接收 |
| 搜索 | mcp-tavily, mcp-brave | 联网搜索 |
| 记忆 | mcp-memory, mcp-chroma | 长期记忆存储 |
就拿这个博客来说——我们用的 Hermes Agent 就是通过 MCP Server 连接 Tavily 搜索接口来实现每日热点查询的。
⚠️ 使用 MCP 的注意事项
虽然 MCP 很强大,但也不是完全没有坑:
- 安全边界:MCP Server 拥有执行权限。不要随便装来历不明的 Server——尤其是那些可以读写文件系统或执行命令的
- 超时处理:默认超时可能较短,复杂操作记得设置超时时间
- 并发限制:大多数 MCP Server 是单线程的,高并发场景需要自己加锁或队列
- 调试困难:MCP 在 stdio 模式下调试不太方便,可以用 SSE 或 WebSocket 模式配合日志
💎 总结
MCP 协议正在做的事情,本质上和 USB 是一回事——把混乱变成标准,把复杂留给自己,把简单交给用户。
2026 年的今天,没有一个严肃的 AI Agent 项目会绕过 MCP。它已经从一个「提议」变成了事实标准,就像当年的 REST API 一样。
如果你想让你的服务或工具被 AI Agent「发现和调用」,实现一个 MCP Server 是目前成本最低、覆盖最广的方式。
小贴士:Anthropic 官方提供了 MCP SDK(Python 和 TypeScript),GitHub 上还有大量现成的 MCP Server 实现可以参考。开始之前,先看看有没有现成的——很可能已经有人帮你做好了!🔌