从 0 开发一个 MCP Server: 手把手教你构建 AI 工具调用能力
大模型再聪明,也无法直接查数据库、调 API、读写文件——AI 工具调用能力决定了 Agent 能否触达真实世界。MCP(Model Context Protocol) 是 Anthropic 开源的标准协议,让 Claude、Cursor 等客户端以统一方式发现与调用你编写的 Server。本文面向有 Python 或 TypeScript 基础的后端 / AI 开发者,从零带你走完协议原理、环境搭建、Tools / Resources / Prompts 三大能力、远程 HTTP 部署、调试测试到生产上线的完整链路。
读完你将能回答三件事:① MCP 与 Function Calling、LangChain Tools 的本质差异;② 如何用官方 SDK 注册工具、资源和提示词模板;③ 如何把个人知识库封装成生产可用的 MCP Server,并在 Cursor 中直接提问「我上周关于 MCP 的笔记是什么」。
01 MCP 是什么?协议原理、通信机制与方案对比
工具调用能力经历了三代演进:Function Calling(厂商私有格式)→ Plugins(平台绑定)→ MCP(开放协议标准)。Anthropic 设计 MCP 的核心动机,是用一套 JSON-RPC 规范统一「AI 客户端如何发现、描述并调用外部能力」,终结 N 个模型 × M 个工具的定制集成噩梦。
- 痛点切入:模型缺乏访问外部工具与实时数据的能力,无法查库、调 API、操作文件。
- 场景描述:你希望 Claude / GPT 能查数据库、调 REST API、读写本地 Markdown——这正是 MCP Server 要暴露的能力。
- 价值承诺:读完本文,你能独立开发并部署一个生产可用的 MCP Server。
架构上,MCP Client(Claude Desktop、Cursor 等)与 MCP Server(你开发的部分)通过 JSON-RPC 双向通信,Server 再对接外部系统:
- Tools:AI 可调用的函数(搜索、计算、数据库查询)
- Resources:AI 可读取的资源(文件、URL、数据流)
- Prompts:预定义的提示词模板,支持参数注入
通信基于 JSON-RPC 2.0,传输方式分两种:stdio(本地子进程,延迟极低)与 HTTP + SSE / Streamable HTTP(远程服务,支持多客户端)。生命周期为:初始化握手 → 能力协商 → 请求/响应 → 关闭。
| 对比维度 | MCP | OpenAI Function Calling | LangChain Tools |
|---|---|---|---|
| 标准化程度 | 开放协议标准 | 厂商私有 | 框架绑定 |
| 传输方式 | stdio / HTTP | HTTP | HTTP |
| 跨模型支持 | 是 | 否 | 部分 |
| 资源 / 提示词 | 原生支持 | 不支持 | 不支持 |
| 生态工具 | 快速增长(10,000+ Server) | 成熟 | 成熟 |
延伸阅读:MCP 为何成为 AI 时代的 HTTP 协议;官方规范见 modelcontextprotocol.io。
02 开发环境准备:语言选型、依赖安装与项目结构
Python(推荐新手):官方 SDK mcp,FastMCP 装饰器简洁易上手。TypeScript(推荐前端 / 全栈):官方 SDK @modelcontextprotocol/sdk。本文以 Python 为主,TypeScript 做对照说明。
# Python 环境
python -m venv .venv
source .venv/bin/activate
pip install mcp
# TypeScript 环境(对照)
npm init -y
npm install @modelcontextprotocol/sdk
推荐项目结构:
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
调试工具三件套:
- MCP Inspector:官方调试 UI,可视化测试 Tools / Resources / Prompts
- Claude Desktop:编辑
claude_desktop_config.json做本地联调 - Cursor MCP 配置:Settings → MCP → 添加 stdio 命令行启动项
03 Hello World:最简单的 MCP Server 与 Cursor 接入
用 FastMCP 十行代码即可跑通第一个 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()
运行与验证:
python server.py
# 或使用 MCP Inspector 调试
npx @modelcontextprotocol/inspector python server.py
Cursor 接入六步:
- 确认 Python 路径:虚拟环境中
which python记下绝对路径。 - 打开 Cursor MCP 设置:Settings → Features → MCP Servers。
- 添加 stdio Server:command 填 Python 路径,args 填
server.py绝对路径。 - 重启 Cursor:使 MCP 配置生效。
- 验证工具列表:在 Agent 模式查看是否出现
say_hello。 - 触发调用:对话中让 AI「用 say_hello 向 JEXCLOUD 打招呼」,确认返回正确。
Claude Desktop 同理:编辑 ~/Library/Application Support/Claude/claude_desktop_config.json,在 mcpServers 节点注册同名配置。
04 Tools 开发:参数类型、五大实战工具与异步模式
工具的基本契约:函数签名即文档——参数类型、返回类型、docstring 会被 MCP 转为 JSON Schema 供 AI 理解。命名用 snake_case,错误优先返回结构化信息而非裸异常。
复杂参数用 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]:
"""执行网络搜索,返回相关结果列表"""
...
五大实用工具建议作为练手清单:
- 计算器:安全求值数学表达式(
ast.literal_eval防注入) - 文件读写:限定白名单目录内的 read / write
- HTTP 请求:封装 GET / POST,统一超时与重试
- 数据库查询:只读 SQL + 参数化防注入
- 时间工具:当前时间、时区转换、ISO 8601 格式化
IO 密集型工具用异步:
import httpx
@mcp.tool()
async def fetch_url(url: str) -> str:
"""获取指定 URL 的内容"""
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=30.0)
return response.text
错误处理最佳实践:设置超时、权限校验(路径白名单 / API Key)、返回 {"error": "...", "code": "..."} 结构体便于 AI 自我修正。
05 Resources:URI 寻址、静态与动态资源、文件系统实战
Resource 与 Tool 的区别:Resource 是数据提供者(只读),Tool 是动作执行者(可写、可副作用)。寻址用 URI 方案:file://、http://、custom://。
# 静态资源
@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:
user = db.query_user(user_id)
return json.dumps(user)
资源类型覆盖:
- 文本:
text/plain、application/json - 二进制:图片、PDF(Base64 或 blob URI)
- 流式:实时日志、行情推送(资源订阅)
文件系统资源服务器实战:列出目录 → 按路径读取文件 → 可选 watchfiles 监听变更并推送资源更新通知。
06 Prompts:可复用提示词模板与多轮对话场景
MCP Prompt 是预定义的提示词片段,AI 客户端可直接复用,支持动态参数注入,提升团队提示词的一致性与可维护性。
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} 代码进行审查..."
)
)
]
多轮对话模板可混合 user 与 assistant 角色,典型场景:面试模拟(先 assistant 提问、再 user 作答)、代码调试助手(assistant 引导排障步骤)。
07 HTTP 传输模式:远程 MCP Server 与安全加固
| 特性 | stdio | HTTP + SSE |
|---|---|---|
| 部署方式 | 本地进程 | 远程服务器 |
| 延迟 | 极低 | 依赖网络 |
| 多客户端 | 不支持 | 支持 |
| 适用场景 | 本地工具 | SaaS / 团队共享 |
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)
生产环境须叠加:Bearer Token 认证、API Key 中间件、CORS 白名单、请求频率限制(如 slowapi)。远程 Server 适合团队共享数据库查询、内部 API 网关等能力。
08 调试与测试:MCP Inspector、单元测试与常见错误
MCP Inspector 工作流:启动 Inspector → 连接 stdio 命令 → 在 UI 中测试 tools/call → 查看 JSON-RPC 请求/响应日志 → 模拟超时与权限拒绝场景。
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"
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 工具未出现在 AI 中 | 配置路径错误 | 检查 config.json 中 command / args 绝对路径 |
| JSON 序列化失败 | 返回类型不支持 | 转为字符串或 dict |
| 超时断开 | 工具执行太慢 | 改异步 + 超时控制 |
| 权限拒绝 | 文件路径受限 | 配置允许访问的目录白名单 |
09 生产部署:Docker、云服务与可观测性
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "server.py"]
部署选型:
- Railway / Render:一键部署,适合个人项目
- AWS Lambda / Google Cloud Run:Serverless,按调用计费
- 自建 VPS:Nginx 反向代理 + TLS,配合 Bearer Token
可观测性三件套:结构化请求日志、Prometheus 工具调用指标、Sentry 错误告警;暴露 /health 健康检查。版本管理须声明 MCP 协议版本,工具升级保持向后兼容,利用能力协商避免客户端崩溃。
- MCP Python SDK:github.com/modelcontextprotocol/python-sdk
- MCP TypeScript SDK:github.com/modelcontextprotocol/typescript-sdk
- MCP Inspector:github.com/modelcontextprotocol/inspector
10 实战项目:构建个人知识库 MCP Server
需求:让 AI 能搜索本地 Markdown 笔记、语义检索、创建与更新笔记。
技术选型:
- 向量数据库:ChromaDB 或 Qdrant(本地轻量)
- 嵌入模型:
text-embedding-3-small(OpenAI)或本地nomic-embed-text - 文件监听:
watchfiles增量重建索引
核心模块:
index_notes工具:扫描笔记目录,切块嵌入写入向量库semantic_search工具:query → top-k 相关片段write_note工具:创建 / 追加 Markdown 文件notes://{path}资源:按 URI 读取单篇笔记全文
效果演示:在 Cursor 中问「我上周记录了什么关于 MCP 的笔记?」→ AI 调用 semantic_search → 返回相关片段并综合回答。这是把私有知识接入 Agent 工作流的最短路径。
11 MCP 生态展望、学习路径与生产宿主选型
优质社区 Server 推荐:
mcp-server-filesystem:文件系统操作mcp-server-github:GitHub 仓库操作mcp-server-brave-search:网络搜索mcp-server-postgres:数据库查询mcp-server-slack:Slack 消息
2026 生态趋势:Cursor、Claude Desktop、VS Code、OpenAI、Google Gemini 均已原生或计划支持 MCP;MCP Marketplace 加速 Server 分发;企业级安全标准(OAuth 2.1、审计日志)进入路线图。
下一步学习路径:精读 MCP 协议规范 → 发布第一个公开 Server → 探索 MCP + Agent 编排 → 向开源生态贡献 PR。
- 协议版本:2024-11-05 首发,2025 起 Streamable HTTP 替代纯 SSE 成为远程传输推荐方案
- 生态规模:截至 2026 年,社区 MCP Server 已超过 10,000 个
- SDK 维护方:Anthropic 开源 + Linux Foundation AAIF 治理,Python / TypeScript 双官方 SDK 周更
MCP 是 AI 工具化的标准协议——掌握 Server 开发,等于掌握了让任意 LLM 调用你业务系统的能力。你打算用 MCP 封装什么工具?欢迎在评论区分享场景。
生产级 MCP Server 的隐性成本在宿主稳定性:笔记本合盖 STDIO 子进程即死、家用宽带抖动打断 HTTP 长连接、共享 VPS 无 macOS 沙箱与 TCC 权限。若你需要 7×24 运行知识库索引、远程 HTTP MCP 或配合 Cursor Agent 做 CI,JEXCLOUD 多区域裸金属 Mac 提供独占 Apple Silicon、固定公网 IP、120 秒交付与按月弹性租期——比「本地凑合 + 频繁重连」更适合生产 Agent 工作流。节点与价格见 JEXCLOUD 定价页,部署问题见 帮助中心。