tutorial 12 min read 如何为你的 API 构建 MCP 服务器 将任何 REST API 转换为 MCP 服务器,让 AI 工具直接调用。涵盖端点映射、认证、错误处理和部署。
William Wang · 2026年4月9日 William Wang — TokRepo & GEOScore AI 创始人,专注 AI 开发者工具和搜索可见性。
一句话答案 把 REST API 包装成 MCP Server 的核心原则:无参数的 GET 变成 Resource,带查询参数的 GET 和所有 POST/PUT/DELETE 变成 Tool。用 FastMCP(Python)或 @modelcontextprotocol/sdk(TypeScript),Auth headers 通过环境变量注入,30 分钟就能把任何 REST API 暴露给 Claude Code。 目录 前置条件 REST → MCP 映射 步骤 1 — 规划端点映射 步骤 2 — 构建服务器 步骤 3 — 安全认证 步骤 4 — 错误处理 步骤 5 — 大型 API 拆分 FAQ 下一步 学习如何将任何 REST API 包装为 MCP 服务器,让 Claude Code、Cursor 等 AI 工具通过自然语言与之交互。 前置条件 一个你想暴露给 AI 工具的 REST API Python 3.10+ 或 Node.js 16+ Claude Code 或 Cursor 用于测试 REST → MCP 映射 REST 概念 MCP 等价物 何时使用 GET(无参数) Resource 只读数据 GET(有查询参数) Tool LLM 决定查询什么 POST/PUT/DELETE Tool 有副作用的操作 Auth headers 环境变量 启动时注入 核心原则 :无参数的 GET 变成 Resource,其他一切变成 Tool。 步骤 1 — 规划端点映射
GET /projects → Resource: projects://list
POST /projects → Tool: create_project
GET /projects/{id}/tasks → Tool: list_tasks(有查询参数)
POST /projects/{id}/tasks → Tool: create_task
步骤 2 — 构建服务器
import os
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
API_BASE_URL = os.environ.get("API_BASE_URL", "https://api.example.com/v1")
API_KEY = os.environ.get("API_KEY", "")
mcp = FastMCP("project-api")
async def api_request(method: str, path: str, **kwargs) -> dict[str, Any]:
headers = {"Authorization": f"Bearer {API_KEY}"}
async with httpx.AsyncClient() as client:
r = await client.request(method, f"{API_BASE_URL}{path}", headers=headers, timeout=30.0, **kwargs)
r.raise_for_status()
return r.json()
@mcp.resource("projects://list")
async def list_projects() -> str:
data = await api_request("GET", "/projects")
return "\n".join(f"- [{p['id']}] {p['name']}" for p in data.get("projects", []))
@mcp.tool()
async def create_project(name: str, description: str = "") -> str:
"""创建新项目。"""
data = await api_request("POST", "/projects", json={"name": name, "description": description})
return f"已创建项目 '{data['name']}'(ID: {data['id']})"
if __name__ == "__main__":
mcp.run(transport="stdio")
步骤 3 — 安全认证 绝不硬编码 API Key,使用环境变量:
{
"mcpServers": {
"project-api": {
"command": "uv",
"args": ["--directory", "/path/to/server", "run", "server.py"],
"env": {
"API_BASE_URL": "https://api.example.com/v1",
"API_KEY": "sk-your-key"
}
}
}
}
步骤 4 — 错误处理
@mcp.tool()
async def safe_call(endpoint: str) -> str:
try:
return str(await api_request("GET", endpoint))
except httpx.HTTPStatusError as e:
if e.response.status_code == 404: return f"未找到: {endpoint}"
if e.response.status_code == 429: return "请求过于频繁,稍后再试。"
return f"API 错误 {e.response.status_code}"
except httpx.TimeoutException:
return "请求超时。"
步骤 5 — 大型 API 拆分 50+ 端点的 API 应拆分为多个服务器:
api-users-mcp/ → 用户管理
api-projects-mcp/ → 项目管理
api-billing-mcp/ → 账单支付
每个服务器保持工具数在 30 个以内。Cursor 有 40 工具上限。 FAQ Q: 如何将 REST API 转为 MCP?
A: 无参 GET → Resource,其他 → Tool。用环境变量做认证。 Q: 一个大服务器还是多个小服务器?
A: 多个聚焦的小服务器(每个 30 个以内工具)效果更好。 下一步 用 Python 构建 MCP 服务器 用 TypeScript 构建 MCP 服务器 TokRepo MCP 服务器合集 html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF} 常见问题 REST API 的 GET 应该变成 Resource 还是 Tool? + 无参数的 GET(例如 /projects 列表)变成 Resource,LLM 可以像读文件一样访问。带查询参数的 GET(例如 /projects/{id}/tasks?status=open)变成 Tool,因为 LLM 需要决定传什么参数。这是 MCP 设计的核心规则。 如何处理 API 认证? + 通过环境变量注入,不要硬编码。常见做法:API_BASE_URL 和 API_KEY 放在启动时的 env,MCP Server 内部用 httpx 客户端把 Authorization header 自动加到每个请求。Claude Code 的 .mcp.json 可以配置 env 字段传递这些变量。 MCP Server 的错误处理和 REST 有什么不同? + MCP Server 要把 HTTP 错误翻译成 LLM 能理解的文本。4xx 返回清晰的错误消息(例如 project 123 不存在请检查 ID),5xx 返回可重试提示。不要把 raw JSON 错误原样抛给 LLM,它会反复重试无效请求。 一个 API 该拆成几个 MCP Server? + 按业务域拆分,不按微服务拆。例如项目管理 API 即使后端有 10 个微服务,也只做 1 个 MCP Server,内部封装端点路由。给 LLM 的是一套连贯的工具,而不是 10 个相关但分散的 Server。 MCP Server 做好后如何部署? + 本地开发直接用 stdio 模式,Claude Code 配置 command 启动进程。生产环境可以打包成 Docker 镜像或 PyPI/npm 包发布,让用户 pip install 或 npx 运行。远程 MCP Server 目前还在实验阶段,大部分场景 stdio 本地模式就够。 ← 上一篇 AI 工作流自动化:30+ 即用脚本和 Agent 技能(2026) 下一篇 → 如何用 Python 构建 MCP 服务器(分步教程)