从 0 开发一个 MCP Server:手把手教你构建 AI 工具调用能力
大模型再聪明,也无法直接查你的数据库、调用内部 API 或读取本地文件——这不是模型「不够聪明」,而是缺少标准化的工具调用通道。Model Context Protocol(MCP) 正是 Anthropic 开源的解决方案:让 Claude、Cursor、GPT 通过统一协议访问外部能力。读完本文,你将能独立开发、调试并部署一个生产可用的 MCP Server,涵盖 Tools、Resources、Prompts 三大核心能力与 HTTP 远程传输。
1. 三大痛点:为什么 AI 需要 MCP Server
在写第一行代码前,先对齐你要解决的实际问题:
- 工具孤岛:Function Calling、Plugins、LangChain Tools 各写各的格式,换一个模型供应商就要重写集成层——典型的 N×M 困境。
- 数据不可达:模型训练数据有截止日期,无法读取你的实时配置、内部文档或数据库状态。
- 动作不可执行:纯对话 AI 不能替你发 HTTP 请求、写文件或跑 SQL——除非通过标准化工具层暴露这些能力。
若你已读过《MCP 为什么会成为 AI 时代的 HTTP 协议》,本文不再重复协议选型论证,而是直接进入代码实现。适合人群:有 Python 或 TypeScript 基础的后端 / AI 开发者。
2. 什么是 MCP:协议原理与架构概览
2.1 MCP 的诞生背景
大模型工具调用能力经历了三代演进:Function Calling(OpenAI 私有格式)→ Plugins(ChatGPT 生态封闭)→ MCP(2024 年 11 月 Anthropic 开源的开放协议)。MCP 解决的核心问题是:标准化 AI 与外部工具之间的通信,一次实现、多客户端复用。
2.2 协议架构:Client ↔ Server ↔ 三大能力
┌────────────────────┐ ┌─────────────────────┐
│ MCP Client │ ◄─────► │ MCP Server │
│ (Claude / Cursor) │ JSON │ (你要开发的部分) │
│ │ -RPC │ │
└────────────────────┘ └─────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
Tools Resources Prompts
(工具调用) (资源读取) (提示词模板)
- Client:AI 模型侧——Claude Desktop、Cursor、VS Code、自定义 Agent。
- Server:你开发的能力提供方,暴露 Tools / Resources / Prompts。
- Tools:AI 可调用的函数(搜索、计算、数据库查询、写文件)。
- Resources:AI 可读取的资源(文件、URL、配置流),通过 URI 寻址。
- Prompts:预定义的提示词模板,支持动态参数注入。
2.3 通信机制
MCP 基于 JSON-RPC 2.0。传输方式有两种:
- stdio:本地子进程,Client 启动 Server 并通过标准输入/输出通信,延迟极低。
- HTTP + SSE / Streamable HTTP:远程服务,支持多客户端并发连接。
生命周期:初始化握手 → 能力协商(tools/list、resources/list)→ 请求/响应(tools/call)→ 关闭。
2.4 MCP 与其他方案对比
| 对比维度 | MCP | OpenAI Function Calling | LangChain Tools |
|---|---|---|---|
| 标准化程度 | 开放协议标准 | 厂商私有 | 框架绑定 |
| 传输方式 | stdio / HTTP | HTTP | HTTP |
| 跨模型支持 | 是(Claude、GPT、Gemini 等) | 否 | 部分 |
| Resources / Prompts | 原生支持 | 不支持 | 不支持 |
| 生态规模(2026) | 10,000+ Server,AAIF 治理 | 成熟但封闭 | 成熟但绑定 Python |
3. 开发环境准备与项目结构
3.1 选择开发语言
- Python(本文主语言):官方 SDK
mcp,FastMCP装饰器简洁易上手。 - TypeScript(对照):官方 SDK
@modelcontextprotocol/sdk,适合 Node/全栈开发者。
3.2 环境搭建
# Python 环境
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install mcp httpx pydantic
# TypeScript 环境(对照)
npm init -y
npm install @modelcontextprotocol/sdk
3.3 推荐项目结构
my-mcp-server/
├── server.py # 主服务入口
├── tools/
│ ├── __init__.py
│ ├── calculator.py
│ └── web_search.py
├── resources/
│ └── file_reader.py
├── prompts/
│ └── templates.py
├── tests/
│ └── test_tools.py
├── pyproject.toml
└── README.md
3.4 调试工具
- MCP Inspector:官方调试 UI,可视化测试 Tools / Resources / Prompts。
- Claude Desktop:编辑
claude_desktop_config.json联调。 - Cursor:在 Settings → MCP 或项目
.cursor/mcp.json中配置。
4. 第一个 MCP Server:Hello World
4.1 最简 Server 代码
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-first-server")
@mcp.tool()
def say_hello(name: str) -> str:
"""向指定的人打招呼"""
return f"Hello, {name}! 这是你的第一个 MCP 工具。"
if __name__ == "__main__":
mcp.run()
4.2 运行与验证
python server.py
# 或使用 MCP Inspector 调试
npx @modelcontextprotocol/inspector python server.py
Inspector 启动后,在浏览器中查看 tools/list 是否返回 say_hello,并用 tools/call 传入 {"name": "开发者"} 验证返回。
4.3 在 Cursor / Claude Desktop 中接入
Cursor(.cursor/mcp.json):
{
"mcpServers": {
"my-first-server": {
"command": "python",
"args": ["/absolute/path/to/server.py"]
}
}
}
Claude Desktop(macOS ~/Library/Application Support/Claude/claude_desktop_config.json):结构相同。重启客户端后,在 Agent 对话中应能看到 say_hello 工具出现在上下文中。
5. Tools:开发可被 AI 调用的工具
5.1 工具基本结构
函数签名即文档:参数类型、返回类型、docstring 会被自动转为 JSON Schema 供 AI 理解。命名建议用 snake_case,动词开头(search_web、read_file)。
5.2 输入参数类型(Pydantic)
from pydantic import BaseModel, Field
class SearchInput(BaseModel):
query: str = Field(description="搜索关键词")
max_results: int = Field(default=5, description="最多返回结果数")
language: str = Field(default="zh", description="结果语言")
@mcp.tool()
def web_search(input: SearchInput) -> list[dict]:
"""执行网络搜索,返回相关结果列表"""
# 实现搜索逻辑
...
5.3 五个实用工具实战
- 计算器:
eval安全子集或ast.literal_eval,处理数学表达式。 - 文件读写:限定白名单目录,防止路径穿越。
- HTTP 请求:用
httpx调用外部 API,返回 JSON 或文本。 - 数据库查询:只读 SQL + 参数化查询,禁止 DDL。
- 时间工具:
datetime.now(timezone.utc)与时区转换。
5.4 异步工具
import httpx
@mcp.tool()
async def fetch_url(url: str) -> str:
"""获取指定 URL 的内容"""
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url)
response.raise_for_status()
return response.text
5.5 错误处理最佳实践
- 业务错误返回结构化 JSON(
{"error": "...", "code": 404}),而非裸抛异常。 - 所有外部调用设置超时(建议 30s 以内)。
- 文件/数据库操作做权限校验,最小权限原则。
6. Resources:让 AI 读取动态内容
6.1 Resource 与 Tool 的区别
Resource 是数据提供者,Tool 是动作执行者。 AI 通过 URI 读取 Resource 内容,不会触发副作用。
6.2 静态与动态资源
import json
@mcp.resource("config://app-settings")
def get_app_settings() -> str:
"""返回应用配置"""
return json.dumps({"version": "1.0", "env": "production"})
@mcp.resource("user://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
"""根据用户 ID 返回用户资料"""
user = db.query_user(user_id)
return json.dumps(user)
URI 方案支持 file://、http://、custom:// 等自定义前缀。
6.3 资源类型
- 文本:
text/plain、application/json - 二进制:图片、PDF(Base64 或 Blob URI)
- 流式:实时数据推送(SSE 订阅)
6.4 文件系统资源服务器
实战模式:列出目录 → 读取文件内容 → 可选监听文件变化(watchfiles)触发资源更新通知。务必配置允许访问的根目录白名单,避免 AI 读取敏感路径。
7. Prompts:定义可复用的提示词模板
7.1 什么是 MCP Prompt
预定义的提示词片段,AI 客户端可直接复用,支持动态参数注入,提升团队一致性与可维护性。
7.2 创建提示词模板
from mcp.types import PromptMessage, TextContent
@mcp.prompt()
def code_review_prompt(language: str, code: str) -> list[PromptMessage]:
"""代码审查提示词模板"""
return [
PromptMessage(
role="user",
content=TextContent(
type="text",
text=f"""请对以下 {language} 代码进行审查,重点关注:
1. 代码质量和可读性
2. 潜在的 Bug 和安全隐患
3. 性能优化建议
代码内容:
```{language}
{code}
```"""
)
)
]
7.3 多轮对话提示词
可定义包含 user 和 assistant 的多轮模板,适用于面试模拟、代码调试助手等场景。每条 PromptMessage 指定 role 与 content,Client 按序注入对话上下文。
8. HTTP 传输模式:远程 MCP Server
8.1 stdio vs HTTP + SSE
| 特性 | stdio | HTTP + SSE |
|---|---|---|
| 部署方式 | 本地子进程 | 远程服务器 |
| 延迟 | 极低(<1ms) | 依赖网络(10–200ms) |
| 多客户端 | 不支持 | 支持 |
| 适用场景 | 本地开发、个人工具 | SaaS、团队共享、7×24 服务 |
8.2 实现 HTTP 传输
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("remote-server", transport="streamable-http")
if __name__ == "__main__":
mcp.run(host="0.0.0.0", port=8000)
8.3 认证与安全
- Bearer Token:Client 请求头携带
Authorization: Bearer <token>。 - API Key 中间件:校验密钥 + IP 白名单。
- CORS:仅允许可信 Origin。
- 频率限制:防止工具被滥用(如每秒 10 次 tools/call)。
9. 调试、测试与常见错误
9.1 MCP Inspector 调试流程
- 启动:
npx @modelcontextprotocol/inspector python server.py - 在 UI 中查看 Tools / Resources / Prompts 列表。
- 手动触发
tools/call,检查请求/响应 JSON。 - 模拟错误场景(超时、非法参数)验证错误处理。
9.2 单元测试示例
import pytest
from mcp.client.session import ClientSession
from mcp.client.stdio import StdioServerParameters, stdio_client
@pytest.mark.asyncio
async def test_calculator_tool():
server_params = StdioServerParameters(
command="python",
args=["server.py"]
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("calculate", {"expression": "2 + 2"})
assert result.content[0].text == "4"
9.3 常见错误排查
| 错误现象 | 常见原因 | 解决方案 |
|---|---|---|
| 工具未出现在 AI 中 | 配置路径错误、Client 未重启 | 检查 config.json 绝对路径,重启 Cursor/Claude |
| JSON 序列化失败 | 返回类型不支持(如 datetime 对象) | 转为字符串或 dict |
| 超时断开 | 工具执行超过 Client 默认超时 | 改用 async + 设置 timeout,或拆分长任务 |
| 权限拒绝 | 文件路径超出白名单 | 配置允许访问的目录根路径 |
10. 生产部署:Docker、云服务与监控
10.1 Docker 容器化
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "server.py"]
10.2 云服务选型(2026 参考)
- Railway / Render:一键部署,适合个人项目(月费约 $5–20)。
- AWS Lambda / Google Cloud Run:Serverless,按调用计费。
- 自建 VPS / 远程 Mac:配合 Nginx 反向代理 + launchd 守护,适合需要 Apple 生态或长期 7×24 运行的 Agent 工具链。
10.3 监控与可观测性
- 结构化日志:每次 tools/call 记录 tool 名、耗时、状态码。
- Prometheus 指标:调用次数、P99 延迟、错误率。
- Sentry:未捕获异常告警。
- 健康检查:
GET /health返回 200 + 协议版本号。
10.4 版本管理与兼容性
在初始化握手时声明 MCP 协议版本;工具升级采用向后兼容策略——新增可选参数而非删除必填字段。重大变更时并行运行 v1/v2 Server,Client 通过能力协商选择。
11. 实战项目:个人知识库 MCP Server
11.1 项目需求
- 让 AI 能搜索你的本地 Markdown 笔记。
- 支持语义搜索(向量检索,而非纯关键词)。
- 支持创建和更新笔记。
11.2 技术选型
- 向量数据库:ChromaDB 或 Qdrant(本地嵌入式,零运维)。
- 嵌入模型:
text-embedding-3-small(OpenAI)或本地nomic-embed-text。 - 文件监听:
watchfiles自动重建索引。
11.3 核心工具设计
- index_notes:扫描笔记目录,分块嵌入并写入向量库。
- search_notes:语义搜索,返回 Top-K 片段 + 源文件路径。
- write_note:创建或追加 Markdown 文件(白名单目录内)。
- notes://{path} Resource:直接读取指定笔记全文。
11.4 效果演示
在 Cursor 中直接问:「我上周记录了什么关于 MCP 的笔记?」—— AI 调用 search_notes 工具,返回相关片段并引用源文件。这比把整库笔记塞进 Context Window 节省 90%+ Token,且支持实时更新。
12. MCP 生态与未来展望
12.1 优质 MCP Server 推荐
- mcp-server-filesystem:文件系统读写与目录列表。
- mcp-server-github:GitHub 仓库操作、Issue、PR。
- mcp-server-brave-search:网络搜索。
- mcp-server-postgres:PostgreSQL 只读查询。
- mcp-server-slack:Slack 消息发送与读取。
官方文档:modelcontextprotocol.io;Python SDK:github.com/modelcontextprotocol/python-sdk;TypeScript SDK:github.com/modelcontextprotocol/typescript-sdk。
12.2 2026 生态趋势
- 主流 AI 客户端(Cursor、Claude Desktop、VS Code Copilot、Gemini CLI)均已原生支持 MCP。
- MCP Marketplace 与 AAIF 治理推动 Server 质量认证。
- 企业级安全标准:OAuth 2.1、细粒度 Tool 权限、审计日志。
12.3 下一步学习路径
- 深入学习 MCP 协议规范全文。
- 开发并发布你的第一个公开 MCP Server 到 GitHub。
- 探索 MCP + Agent 组合(参考《Cursor Agent Skill》与 OpenClaw MCP 集成)。
- 向开源生态贡献 Tools 或 Resources 实现。
13. 总结:从本机实验到 7×24 生产节点的决策
本文覆盖了 MCP Server 开发的完整链路:协议原理 → 环境搭建 → Hello World → Tools / Resources / Prompts → HTTP 远程传输 → Inspector 调试 → Docker 部署 → 个人知识库实战。MCP 是 AI 工具化的标准协议,掌握它是 2026 年 AI 工程师的核心竞争力之一。
然而,本机 stdio 模式有明确边界:笔记本合盖即断链、向量库与嵌入模型占用本地内存、多 Server 并发时 CPU 争抢。个人知识库 MCP、HTTP 远程 Server、以及需要 ChromaDB + 嵌入 API 的长时会话,在常在线 Apple Silicon 节点上运行更稳定——统一内存架构对向量检索友好,macOS 原生支持 launchd 守护与 Cursor/Claude 同构工具链。
SFTPMAC 远程 Mac 租赁提供面向 MCP Server 与 AI Agent 工作流的 7×24 Apple Silicon 环境:低延迟 HTTP+SSE 回调、原生 Python/Node 运行时、SFTP/rsync 同步笔记目录与配置,比「家用电脑兼 MCP 宿主」更适合把个人知识库或团队工具层当生产入口。你打算用 MCP 开发什么工具?从 Hello World 开始,今天就能跑起来。