Skip to content
返回 AI 编程

为 AI 工具构建 MCP 服务器

通过模型上下文协议向 AI 客户端暴露自定义工具和资源。

MCP 开发高级

为什么

MCP 于 2024 年 11 月发布;到 2025 年 12 月已有超过 9700 万月 SDK 下载量,到 2026 年 9 月 npm SDK 单包月下载量达约 2.04 亿(9 个月增长 5 倍),已发布服务器超 1 万个。模型上下文协议(MCP)是一个开放标准,让 AI 助手(Claude、Cursor 等)与外部工具、数据库和 API 交互。

构建 MCP 服务器使你的自定义能力对任何 MCP 兼容客户端可用 — 无需逐客户端集成。这是 AI 推理与现实世界系统之间的桥梁。

何时使用

在以下情况构建 MCP 服务器:你希望 AI 查询你的数据库或 API;需要自定义代码执行(如运行测试、部署);想在 AI 客户端间共享团队特定工具;或将内部服务与 AI 工作流集成。简单的 HTTP API 调用不需要 — 带 curl 示例的提示词更简单。

如何做

1. MCP 架构: - 服务器:暴露"工具"(AI 可调用的函数)和"资源"(AI 可读取的数据) - 传输:stdio(本地)或 SSE(远程) - 协议:基于传输的 JSON-RPC 2.0 2. 用官方 SDK 搭建: npm install @modelcontextprotocol/sdk 3. 定义工具: - name:唯一标识符(如 "query_database") - description:自然语言描述,让 AI 理解何时使用 - inputSchema:参数的 JSON Schema - handler:执行工具的异步函数 4. 定义资源: - uri:标识符(如 "config://app/settings") - handler:返回资源内容 5. 运行服务器: - 本地:stdio 传输,由 AI 客户端启动 - 远程:SSE 传输,作为 HTTP 服务托管 6. 在 AI 客户端注册(如 Claude Desktop 配置): 将你的服务器添加到客户端的 MCP 配置文件。

示例

最小 MCP 服务器,含一个工具(TypeScript): import { Server } from "@modelcontextprotocol/sdk/server/Server.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; const server = new Server( { name: "weather-server", version: "1.0.0" }, { capabilities: { tools: {} } } ); server.setRequestHandler("tools/list", async () => ({ tools: [{ name: "get_weather", description: "获取指定城市的当前天气", inputSchema: { type: "object", properties: { city: { type: "string" } }, required: ["city"], }, }], })); server.setRequestHandler("tools/call", async (req) => { if (req.params.name === "get_weather") { const { city } = req.params.arguments; // ... 获取天气数据 ... return { content: [{ type: "text", text: `${city} 天气:22C,晴` }] }; } }); const transport = new StdioServerTransport(); await server.connect(transport); Claude 现在可以在任何对话中调用 get_weather({ city: "上海" })。

常见问题

  • ⚠Error: Cannot find module '@modelcontextprotocol/sdk' → 运行 `npm install @modelcontextprotocol/sdk zod`;SDK 需 Node.js 18+。
  • ⚠传输错误:stdio 服务器不能写入 stdout(日志用 stderr)— stdout 是协议通道
  • ⚠Schema 验证:无效的 inputSchema 导致静默失败 — 用 MCP Inspector 测试
  • ⚠Error: Cannot find module '@modelcontextprotocol/sdk' → 运行 `npm install @modelcontextprotocol/sdk zod`;SDK 需 Node.js 18+。
  • ⚠"Error: transport closed" / 服务器未被客户端列出 → 确认两侧 stdio/HTTP 传输匹配;检查 `npx @modelcontextprotocol/inspector` 输出。

最佳实践

  • ✓编写清晰的工具描述 — AI 用它决定何时调用你的工具
  • ✓使用带 'required' 字段的严格 JSON Schema — 减少 AI 对可选参数的幻觉
  • ✓返回结构化内容(不仅是字符串)— 帮助 AI 正确解析结果
  • ✓仅日志到 stderr — stdio 传输中 stdout 保留给 MCP 协议
  • ✓部署前用 MCP Inspector(npx @modelcontextprotocol/inspector)测试
  • ✓在描述中为每个工具记录使用示例,提升 AI 利用率

常见问题解答

什么是模型上下文协议(MCP)?

MCP 是一个开放的 JSON-RPC 标准,让 AI 助手调用外部工具和读取资源。服务器暴露工具(函数)和资源(数据);任何 MCP 兼容客户端(Claude、Cursor)都可用,无需逐客户端集成。

stdio 和 SSE 传输该用哪个?

本地服务器由客户端启动用 stdio(最简单,无网络)。远程/共享服务器作为 HTTP 服务用 SSE,供多客户端或团队成员通过网络访问。开发中先用 stdio。

如何向 Claude Desktop 注册 MCP 服务器?

在 claude_desktop_config.json 的 `mcpServers` 下添加条目,含服务器启动命令(stdio)或 URL(SSE),然后重启 Claude Desktop。先用 MCP Inspector(`npx @modelcontextprotocol/inspector`)验证。

为什么 stdio 服务器只能日志到 stderr?

stdio 传输中 stdout 是 JSON-RPC 协议通道。任何 console.log 写入 stdout 都会损坏消息流并破坏客户端。所有日志用 console.error(stderr)。

如何处理 MCP 工具中的错误?

返回 { isError: true, content: [{ type: 'text', text: '...' }] } 而非抛异常。抛异常会崩溃客户端会话;类型化错误结果保持客户端存活,让 AI 可重试或报告失败。