Model Context Protocol(MCP) 是由 Anthropic 创建的开放标准,定义了 AI 模型如何与外部工具、数据源和服务进行通信。可以把它想象成"AI 的 USB-C" - - 一个通用连接器,让任何 AI 代理都能通过标准化接口与任何工具进行通信。
自发布以来,MCP 的 SDK 月下载量已超过 9700 万次,并已被所有主要 AI 提供商采用:Anthropic、OpenAI、Google、Microsoft 和 Amazon。在本指南中,我们将探索使用 MCP 构建所需的一切知识。
为什么 MCP 存在
在 MCP 之前,每个 AI 应用程序都必须为其想要使用的每个工具构建自定义集成。想让你的 AI 读取文件?编写自定义代码。查询数据库?更多自定义代码。发送到 Slack?又一个集成。
这造成了一个 N×M 问题:N 个 AI 应用程序各需要 M 个自定义集成,导致重复劳动和碎片化的生态系统。
MCP 通过一个单一协议解决了这个问题,任何 AI 客户端都可以使用它与任何 MCP 服务器进行通信:
核心概念
MCP 有三个基本原语:
1. 工具(Tools)
工具是 AI 可以调用的函数。它们代表诸如"创建文件"、"查询数据库"或"发送消息"等操作。每个工具都有名称、描述和用于其参数的 JSON Schema。
{ name: "create_issue", description: "Create a new GitHub issue", inputSchema: { type: "object", properties: { title: { type: "string", description: "Issue title" }, body: { type: "string", description: "Issue body" }, repo: { type: "string", description: "Repository name" } }, required: ["title", "repo"] } }
2. 资源(Resources)
资源是 AI 可以读取的数据。它们代表文件、数据库记录、API 响应或任何其他数据源。资源通过 URI 标识。
{ uri: "file:///Users/dev/project/README.md", name: "Project README", mimeType: "text/markdown" }
3. 提示词(Prompts)
提示词是可重用的模板,帮助构建交互。它们可以包含动态参数,对于标准化常见工作流程非常有用。
{ name: "code_review", description: "Review code changes for quality and security", arguments: [ { name: "diff", description: "The code diff to review", required: true } ] }
架构
MCP 遵循客户端-服务器架构:
- 宿主:AI 应用程序(Claude Desktop、Cursor、你的自定义应用)
- 客户端:与 MCP 服务器保持 1:1 连接
- 服务器:向客户端公开工具、资源和提示词
- 传输层:通过 stdio(本地)或 Server-Sent Events(远程)的 JSON-RPC 2.0 进行通信
构建 MCP 服务器
让我们构建一个实用的 MCP 服务器,它与存储在 JSON 文件中的待办事项列表进行交互。
设置
mkdir mcp-todo-server && cd mcp-todo-server npm init -y npm install @modelcontextprotocol/sdk zod
服务器实现
// src/index.ts import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import fs from "fs"; const TODO_FILE = "./todos.json"; function readTodos(): { id: number; text: string; done: boolean }[] { if (!fs.existsSync(TODO_FILE)) return []; return JSON.parse(fs.readFileSync(TODO_FILE, "utf-8")); } function writeTodos(todos: { id: number; text: string; done: boolean }[]) { fs.writeFileSync(TODO_FILE, JSON.stringify(todos, null, 2)); } const server = new McpServer({ name: "todo-server", version: "1.0.0", }); // Tool: Add a todo server.tool( "add_todo", "Add a new todo item", { text: z.string().describe("The todo text") }, async ({ text }) => { const todos = readTodos(); const newTodo = { id: Date.now(), text, done: false }; todos.push(newTodo); writeTodos(todos); return { content: [{ type: "text", text: `Added: "${text}"` }] }; } ); // Tool: List todos server.tool( "list_todos", "List all todo items", {}, async () => { const todos = readTodos(); const list = todos .map((t) => `${t.done ? "✅" : "⬜"} [${t.id}] ${t.text}`) .join("\n"); return { content: [{ type: "text", text: list || "No todos yet." }] }; } ); // Tool: Complete a todo server.tool( "complete_todo", "Mark a todo as completed", { id: z.number().describe("The todo ID to complete") }, async ({ id }) => { const todos = readTodos(); const todo = todos.find((t) => t.id === id); if (!todo) return { content: [{ type: "text", text: "Todo not found." }] }; todo.done = true; writeTodos(todos); return { content: [{ type: "text", text: `Completed: "${todo.text}"` }] }; } ); // Resource: Current todos as a readable resource server.resource( "todos://list", "Current todo list", async () => ({ contents: [{ uri: "todos://list", mimeType: "application/json", text: JSON.stringify(readTodos(), null, 2), }], }) ); // Start the server const transport = new StdioServerTransport(); await server.connect(transport);
配置
要在 Claude Desktop 中使用此服务器,请将其添加到你的配置中:
{ "mcpServers": { "todo": { "command": "npx", "args": ["tsx", "/path/to/mcp-todo-server/src/index.ts"] } } }
构建 MCP 客户端
你还可以构建一个自定义客户端,连接到任何 MCP 服务器:
import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; const transport = new StdioClientTransport({ command: "npx", args: ["tsx", "./src/index.ts"], }); const client = new Client({ name: "my-client", version: "1.0.0" }); await client.connect(transport); // List available tools const { tools } = await client.listTools(); console.log("Available tools:", tools.map((t) => t.name)); // Call a tool const result = await client.callTool({ name: "add_todo", arguments: { text: "Write MCP blog post" }, }); console.log(result);
热门 MCP 服务器
MCP 生态系统增长迅速。以下是一些最受欢迎的服务器:
| 服务器 | 描述 | 使用场景 |
|---|---|---|
| GitHub | 创建 issue、PR、管理仓库 | 开发工作流 |
| Slack | 发送消息、管理频道 | 团队沟通 |
| PostgreSQL | 查询和管理数据库 | 数据访问 |
| Filesystem | 读取、写入和搜索文件 | 本地开发 |
| Puppeteer | 浏览器自动化和爬取 | Web 测试 |
| Sentry | 错误监控和调试 | 生产支持 |
| Supabase | 数据库、认证、存储 | 后端操作 |
MCP vs A2A(Agent-to-Agent)
MCP 处理代理到工具的通信,而 Google 的 A2A(Agent-to-Agent) 协议处理代理到代理的通信。它们是互补的:
- MCP:AI 代理如何使用工具(垂直集成)
- A2A:AI 代理如何相互协作(水平集成)
最佳实践
- 保持服务器专注:每个领域一个服务器(GitHub 服务器、Slack 服务器等)。不要构建单体服务器。
- 使用 Zod 验证输入:始终使用正确的 schema 验证工具输入。
- 优雅地处理错误:返回有意义的错误消息,而不是堆栈跟踪。
- 对只读数据使用资源:如果 AI 只需要读取数据,将其作为资源而非工具公开。
- 添加适当的描述:良好的工具和参数描述有助于 AI 理解何时以及如何使用每个工具。
- 使用 MCP Inspector 测试:使用
npx @modelcontextprotocol/inspector交互式地测试你的服务器。
开始使用
# Create a new MCP server from template npx @modelcontextprotocol/create-server my-server # Test with the MCP Inspector npx @modelcontextprotocol/inspector npx tsx ./src/index.ts
结论
MCP 已成为 2026 年 AI 工具使用的事实标准。无论你是在构建自定义 AI 代理、扩展 Claude Code,还是为现有平台创建集成,理解 MCP 都是必不可少的。该协议简单到可以在一个下午学会,但强大到足以构建生产级 AI 工作流。
下一步:
- 探索 MCP 规范
- 浏览现有 MCP 服务器获取灵感
- 使用 TypeScript 或 Python SDK 构建你的第一个服务器
- 使用 Claude Desktop 或 MCP Inspector 进行测试