Back to Blog
BlogApril 6, 20264

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

如何构建你的第一个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

  1. 打开 Claude Desktop。
  2. 在以下路径创建或编辑配置文件:
    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows: %APPDATA%\Claude\claude_desktop_config.json

添加以下确切条目(将 /ABSOLUTE/PATH/TO/weather-mcp-server 替换为你的实际文件夹路径):

{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/TO/weather-mcp-server",
        "run",
        "weather.py"
      ]
    }
  }
}
  1. 完全退出 Claude Desktop(macOS 按 Cmd+Q,Windows 从系统托盘关闭)并重新启动。
  2. 在 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 集成方案吧!

Share this article