从 0 到 1 MCP 工具集实战:写一个能被 Claude Code 调用的工具
发布日期:2026-07-01 | 数据来源:MCP 官方文档、GitHub modelcontextprotocol/servers
MCP(Model Context Protocol,模型上下文协议)是 Anthropic 于 2024 年推出的开源标准,定义了 AI 应用与外部系统之间的标准化连接方式——可以理解为AI 的 USB-C 接口:同一个 MCP Server,写一次,接入 Claude Code、VS Code Copilot、Cursor、ChatGPT 等任意支持 MCP 的客户端,无需为每个工具单独适配。本文从零开始,用 Python FastMCP 写一个可被 Claude Code 实际调用的工具,覆盖架构理解 → 环境搭建 → 工具定义 → 客户端接入的完整链路,并附上 7 个官方开箱即用的 Server 推荐。

先把架构搞清楚:三个角色,两层协议
三个核心参与者(来源:MCP 官方架构文档,2025-06-18):
| 角色 | 是什么 | 举例 |
|---|---|---|
| MCP Host | 运行 AI 应用的宿主,管理所有 Client 连接 | Claude Code、Claude Desktop、VS Code、Cursor |
| MCP Client | Host 为每个 Server 创建的独立连接对象 | Host 内部自动创建,开发者无需关心 |
| MCP Server | 暴露工具、数据、提示词的程序 | 你自己写的 weather.py、官方 Filesystem Server |
两种传输协议:
- Stdio(标准输入输出):本地进程通信,零网络开销,Claude Desktop / Claude Code 接入本地 Server 时使用
- Streamable HTTP:远程服务器通信,支持 SSE 流式推送,适合部署到云端对外提供的 Server
三种 Server 原语(你能提供给 AI 的三类能力):
- Tools(工具):可执行的函数,AI 会调用它完成动作(查数据库、调 API、操作文件)
- Resources(资源):只读数据上下文,AI 用来了解背景信息(文件内容、数据库 Schema)
- Prompts(提示词模板):预定义的 Prompt,用户可直接触发
80% 的场景只用到 Tools,本文以 Tools 为主线。
第一步:5 分钟搭好环境
系统要求:Python 3.10+,推荐用 uv 管理依赖。
# 安装 uv(macOS/Linux)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows PowerShell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# 创建项目
uv init my-mcp-server
cd my-mcp-server
# 激活虚拟环境
uv venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
# 安装 MCP SDK(需 1.2.0+)
uv add "mcp[cli]" httpx
# 创建服务器文件
touch server.py
第二步:写你的第一个 MCP Tool
用 FastMCP,定义一个工具只需要一个装饰器。下面是一个查询天气预警的完整示例(改自官方 Quickstart):
# server.py
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-weather-server") # Server 名称
NWS_API_BASE = "https://api.weather.gov"
@mcp.tool()
async def get_weather_alerts(state: str) -> str:
"""获取美国某州的天气预警信息。
Args:
state: 两字母州代码,如 CA、NY
"""
url = f"{NWS_API_BASE}/alerts/active/area/{state}"
async with httpx.AsyncClient() as client:
try:
resp = await client.get(
url,
headers={"User-Agent": "mcp-demo/1.0"},
timeout=30.0
)
resp.raise_for_status()
data = resp.json()
except Exception as e:
return f"请求失败:{e}"
if not data.get("features"):
return f"{state} 当前无天气预警"
alerts = []
for feat in data["features"][:3]: # 只取前 3 条
p = feat["properties"]
alerts.append(f"- {p.get('event','未知')}:{p.get('areaDesc','')}")
return "\n".join(alerts)
@mcp.tool()
def calculate(expression: str) -> str:
"""计算数学表达式。
Args:
expression: 数学表达式,如 '2 + 3 * 4'
"""
try:
result = eval(expression, {"__builtins__": {}})
return str(result)
except Exception as e:
return f"计算错误:{e}"
if __name__ == "__main__":
mcp.run() # 默认使用 Stdio 传输
关键点:
@mcp.tool()装饰器自动从函数签名和 docstring 生成工具定义(名称、描述、参数 Schema),不需要手写 JSON- 函数的 docstring 就是工具描述,写清楚一点,AI 才能知道什么时候调用它
- STDIO 模式下不能用
print()输出日志,用print(..., file=sys.stderr)或logging代替,否则会污染协议通信
第三步:接入 Claude Code / Claude Desktop
Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"my-weather-server": {
"command": "uv",
"args": [
"--directory",
"/你的项目绝对路径/my-mcp-server",
"run",
"server.py"
]
}
}
}
Claude Code(命令行添加):
claude mcp add my-weather-server \
uv --directory /你的项目绝对路径/my-mcp-server run server.py
保存后重启 Claude Desktop,或在 Claude Code 新会话中,输入 /mcp 确认 Server 已加载。然后直接跟 AI 说"查一下 CA 的天气预警",它会自动调用你刚写的 get_weather_alerts 工具。

不想自己写?7 个官方 Server 开箱即用
官方 Reference Server 仓库提供了以下可直接使用的实现(来源:GitHub modelcontextprotocol/servers,2026-07-01):
| Server | 功能 | 适合场景 |
|---|---|---|
| Filesystem | 安全文件读写,可配置访问范围 | 让 AI 读写本地文件 |
| Git | 读取、搜索、操作 Git 仓库 | 代码库分析、commit 查询 |
| Memory | 基于知识图谱的持久化记忆 | 跨会话保存上下文 |
| Fetch | 抓取网页并转为 LLM 可读格式 | 让 AI 读任意网页 |
| Sequential Thinking | 结构化思维链推理工具 | 复杂问题分步推理 |
| Time | 时间查询与时区转换 | 时间相关任务 |
| PostgreSQL | 只读数据库访问 + Schema 查询 | 数据库问答 |
以 Filesystem Server 为例,claude_desktop_config.json 中添加:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/你的用户名/Documents"
]
}
}
}
进阶:用 MCP Inspector 调试工具
官方提供了可视化调试工具 MCP Inspector,不需要启动 Claude Desktop 就能测试你的 Server:
# 安装并启动
npx @modelcontextprotocol/inspector uv --directory . run server.py
打开浏览器的调试界面,可以手动触发 tools/list 和 tools/call,实时看到请求响应的 JSON,比直接在 Claude 里测试效率高得多。
不想本地部署?云端 MCP 服务
如果不想在本地维护 MCP Server 进程,七牛云提供了云端 MCP 服务——标准化模型能力编排平台,无需本地部署即可构建 Agent 应用,直接通过 Streamable HTTP 接入,适合需要对外提供服务或团队共享 MCP 能力的场景。
常见问题
Q:MCP Tool 和直接 Function Calling 有什么区别?
Function Calling 是模型厂商私有的工具调用格式,每家不一样,代码无法复用。MCP 是开放协议,同一个 Server 写一次,接入任意支持 MCP 的 Host(Claude、ChatGPT、VS Code 等)无需修改。MCP 的底层依然走 JSON-RPC,可以理解为"标准化的 Function Calling 注册中心"(来源:MCP 官方文档)。
Q:本地 Stdio Server 和远程 Streamable HTTP Server 怎么选?
本地 Server 用 Stdio:零延迟,可访问本地文件系统和数据库,Claude Desktop / Claude Code 接入最简单。远程 Server 用 Streamable HTTP:可以部署到服务器供团队共用,支持 OAuth 鉴权,一个 Server 同时服务多个 Client。开发和测试阶段用 Stdio,需要对外提供服务时迁移到 HTTP。
Q:@mcp.tool() 的 docstring 重要吗?
非常重要。AI 依赖工具的 description 字段来决定"要不要调这个工具"——描述模糊,AI 要么不调用,要么调错。最佳实践:首句说明工具做什么,Args 说明每个参数的含义和格式,必要时加使用示例。可以把 docstring 当成写给 AI 看的函数文档。
Q:MCP Server 能同时暴露 Tools 和 Resources 吗?
可以。同一个 Server 可以同时定义 @mcp.tool()、@mcp.resource() 和 @mcp.prompt(),Client 通过 tools/list、resources/list、prompts/list 分别发现。实际项目中,通常用 Resources 提供数据库 Schema 作为背景上下文,用 Tools 执行具体查询操作,两者配合使用效果最好。
权威来源:
- MCP Build Server 教程
- GitHub: modelcontextprotocol/servers(官方 Reference Servers)
- 云端 MCP 服务:七牛云 MCP 使用手册
本文代码基于 MCP Python SDK 1.2.0+,官方 API 以最新版本为准。
更多推荐


所有评论(0)