tutorial12 min read
如何为你的 API 构建 MCP 服务器
将任何 REST API 转换为 MCP 服务器,让 AI 工具直接调用。涵盖端点映射、认证、错误处理和部署。
WI
William Wang · Apr 9, 2026
William Wang — TokRepo & GEOScore AI 创始人,专注 AI 开发者工具和搜索可见性。
学习如何将任何 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 个以内工具)效果更好。