如何构建你的第一个MCP服务器:分步教程

环境准备
开始之前,请确保已准备好以下内容:
- 已安装 Python 3.10 或更高版本。
- 基本熟悉 Python 函数和异步代码。
- uv(快速的 Python 包管理器) – 通过
curl -LsSf https://astral.sh/uv/install.sh | sh安装。 - 一个 MCP 客户端,例如 Claude Desktop(从 claude.ai/download 下载并保持更新)。
- 一个文本编辑器或 IDE。
无需事先具备 MCP 经验。我们将构建一个实用的 天气 MCP 服务器,让 AI 能够通过国家气象局 API 查询美国实时天气警报和预报。
步骤 1:设置环境
创建一个干净的项目目录,并使用 uv 初始化它:
mkdir weather-mcp-server
cd weather-mcp-server
uv init
uv venv
source .venv/bin/activate # Windows 系统: .venv\Scripts\activate
uv add "mcp[cli]" httpx
这将安装官方的 MCP Python SDK (FastMCP) 和用于 API 调用的 httpx。你的项目现在拥有 pyproject.toml 文件和虚拟环境。
预期输出: 一个新的 .venv 文件夹,以及依赖项列在 uv.lock 中。
步骤 2:创建 MCP 服务器代码
创建主文件:
touch weather.py
将这段完整且可直接运行的代码粘贴到 weather.py 中:
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
# 初始化 MCP 服务器
mcp = FastMCP("weather")
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
# 安全调用 NWS API 的辅助函数
async def make_nws_request(url: str) -> dict[str, Any] | None:
headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
# 为 AI 友好地格式化天气警报
def format_alert(feature: dict) -> str:
props = feature["properties"]
return f"""
事件: {props.get("event", "Unknown")}
地区: {props.get("areaDesc", "Unknown")}
严重程度: {props.get("severity", "Unknown")}
描述: {props.get("description", "No description available")}
应对指南: {props.get("instruction", "No specific instructions provided")}
"""
# 工具 1:获取美国某个州的活跃天气警报
@mcp.tool()
async def get_alerts(state: str) -> str:
"""获取美国某个州(例如 "CA" 或 "TX")的当前天气警报。"""
url = f"{NWS_API_BASE}/alerts/active/area/{state.upper()}"
data = await make_nws_request(url)
if not data or "features" not in data:
return "无法获取警报或未找到警报。"
if not data["features"]:
return f"{state.upper()} 没有活跃警报。"
alerts = [format_alert(f) for f in data["features"]]
return "\n---\n".join(alerts)
工具 2:获取任意经纬度的 5 天预报
@mcp.tool() async def get_forecast(latitude: float, longitude: float) -> str: """获取特定经纬度的天气预报。""" points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}" points_data = await make_nws_request(points_url) if not points_data: return "无法获取此位置的预报数据。" forecast_url = points_data["properties"]["forecast"] forecast_data = await make_nws_request(forecast_url) if not forecast_data: return "无法获取详细预报。" periods = forecast_data["properties"]["periods"][:5] forecasts = [] for period in periods: forecast = f""" {period["name"]}: 温度: {period["temperature"]}°{period["temperatureUnit"]} 风速: {period["windSpeed"]} {period["windDirection"]} 预报: {period["detailedForecast"]} """ forecasts.append(forecast) return "\n---\n".join(forecasts)
def main(): mcp.run(transport="stdio")
if name == "main": main()
**关键概念解释:**
- `@mcp.tool()` 装饰器将普通的异步函数转换为 AI 可发现和调用的 MCP 工具。
- 服务器通过 **stdio**(标准输入/输出)运行——这是本地 MCP 服务器的默认设置。
- 所有日志都应输出到 stderr(FastMCP 会自动处理)。
## 步骤 3:本地测试服务器
运行服务器:
```bash
uv run weather.py
预期输出: 终端保持打开且静默(这是 stdio 服务器的正常现象)。只有当 MCP 客户端连接时,你才会看到 JSON-RPC 消息。
保持此终端运行以进行下一步。
步骤 4:将 MCP 服务器连接到 Claude Desktop
- 打开 Claude Desktop。
- 在以下路径创建或编辑配置文件:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
- macOS:
添加以下确切条目(将 /ABSOLUTE/PATH/TO/weather-mcp-server 替换为你的实际文件夹路径):
{
"mcpServers": {
"weather": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/TO/weather-mcp-server",
"run",
"weather.py"
]
}
}
}
- 完全退出 Claude Desktop(macOS 按 Cmd+Q,Windows 从系统托盘关闭)并重新启动。
- 在 Claude 中,点击 “添加文件、连接器等” → 将鼠标悬停在 Connectors 上 → 你应该能看到列表中的 “weather”。
步骤 5:在 AI 中使用你的 MCP 服务器
在 Claude Desktop 中尝试以下提示:
- “德克萨斯州有哪些活跃的天气警报?”
- “给我旧金山的预报(使用纬度 37.77,经度 -122.41)。”
- “检查加利福尼亚州的警报,并告诉我是否需要准备应对任何情况。”
Claude 将自动发现工具,首次使用时会请求你的批准,并返回格式化的结果。
预期行为: AI 会在后台调用你的工具,并以自然语言的形式显示答案。
常见问题与故障排除
-
服务器未在 Claude 中显示:
- 仔细检查 JSON 格式是否有效(无尾部逗号)。
- 在配置中使用绝对路径。
- 完全重启 Claude。
- 检查日志:
~/Library/Logs/Claude/mcp*.log(macOS)或 Windows 中的等效路径。
-
API 错误或无数据:
- NWS API 仅适用于美国地区。
- 使用两个字母的州代码(如 CA、TX 等)。
- 坐标必须是有效的经纬度。
-
“命令未找到”:
- 确保 uv 已在 PATH 环境变量中,且虚拟环境已激活。
- 运行
uv --version以验证安装。
-
超时或响应缓慢:
- 如有需要,可在
make_nws_request中增加超时设置。 - NWS 有速率限制——在生产环境中避免频繁请求。
- 如有需要,可在
-
权限问题:
- 在 macOS 上,前往“系统设置”→“隐私与安全性”,授予 Claude Desktop 完全磁盘访问权限。
后续步骤
- 添加更多工具:使用相同的
@mcp.tool()模式,为数据库、GitHub、Slack 或您自己的 API 创建工具。 - 添加资源和提示:使用
mcp.resource()和mcp.prompt()提供文件类数据和可重用的指令。 - 远程部署:切换到 HTTP/SSE 传输协议,并在 AWS Lambda、Vercel 或任意服务器上托管(FastMCP 支持
stateless_http=True)。 - 支持多语言:尝试使用官方的 TypeScript、Go 或 Rust SDK 以实现相同功能。
- 分享您的服务器:发布代码仓库,以便他人可通过
npx或 Docker 添加使用。
现在,您已拥有一个功能完整的 MCP 服务器,任何兼容的 AI 客户端均可使用。开始实验、扩展工具,即刻构建强大的 AI 集成方案吧!
Continue Reading
More articles connected to the same themes, protocols, and tools.
Referenced Tools
Browse entries that are adjacent to the topics covered in this article.








