For Server Developers

环境设置

  • 安装 uv:运行 curl -LsSf https://astral.sh/uv/install.sh | sh,重启终端。

  • 初始化项目:uv init weather,进入目录,设置虚拟环境:uv venv 并激活 source .venv/bin/activate

  • 安装依赖:uv add "mcp[cli]" httpx,创建服务器文件:touch weather.py

服务器构建

  • 导入必要的包,初始化 FastMCP("weather"),设置 NWS API 常量。

  • 实现辅助函数如 make_nws_requestformat_alert,处理 API 请求和数据格式化。

  • 定义工具:get_alerts 根据州代码获取警报,get_forecast 根据经纬度获取5期预测。

  • 运行服务器:添加 if __name__ == "__main__": mcp.run(transport='stdio'),用 uv run weather.py 启动。

测试与配置

  • Mac 用户:安装 Claude for Desktop (下载链接),在 ~/Library/Application Support/Claude/claude_desktop_config.json 配置服务器,测试命令如“萨克拉门托的天气如何?”。

  • Linux 用户:Claude for Desktop 不可用,请参考 客户端构建指南

  • 意外细节:配置需使用绝对路径,Linux 用户需额外构建客户端,增加了跨平台复杂性。


详细报告

引言

Model Context Protocol (MCP) 是一个框架,允许构建服务器以提供工具和资源,供 AI 模型如 Claude 使用。本指南详细介绍了如何构建一个天气服务器,专注于提供 get-alertsget-forecast 工具,通过 National Weather Service (NWS) API 获取天气警报和预测数据。指南适合有 Python 和 LLM(如 Claude)基础的用户,需满足 Python 3.10 或更高版本,以及 Python MCP SDK 1.2.0 或更高版本的要求。

前提条件与系统需求

  • 熟悉 Python 和 LLM(如 Claude):用户需具备基础编程知识,了解 LLM 的工作原理。

  • 系统需求

    • Python 3.10 或更高版本

    • Python MCP SDK 1.2.0 或更高版本

以下是详细的设置和实现步骤:

环境设置

为了确保环境正确配置,我们需要安装 uv 工具(用于项目管理和虚拟环境),并初始化项目。以下是具体步骤:

步骤
命令/详情

安装 uv

`curl -LsSf https://astral.sh/uv/install.sh

创建并设置项目

uv init weathercd weatheruv venv,激活虚拟环境 source .venv/bin/activate

安装依赖

uv add "mcp[cli]" httpx

创建服务器文件

touch weather.py

uv 是一个现代化工具,简化了 Python 项目的初始化和依赖管理。虚拟环境确保项目依赖隔离,避免冲突。

服务器构建

服务器使用 FastMCP 类构建,需实现辅助函数和工具。以下是详细代码和说明:

导入与设置

首先,导入必要的包并初始化服务器:

from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("weather")
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
  • FastMCP 是 MCP SDK 提供的高效服务器类,weather 是服务器名称。

  • NWS_API_BASEUSER_AGENT 用于后续 API 请求。

辅助函数

实现两个辅助函数,处理 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

def format_alert(feature: dict) -> str:
    props = feature["properties"]
    return f"""
    Event: {props.get('event', 'Unknown')}
    Area: {props.get('areaDesc', 'Unknown')}
    Severity: {props.get('severity', 'Unknown')}
    Description: {props.get('description', 'No description available')}
    Instructions: {props.get('instruction', 'No specific instructions provided')}
    """
  • make_nws_request 异步请求 NWS API,设置超时为30秒,处理异常返回 None。

  • format_alert 将警报数据格式化为易读的字符串,包括事件、区域、严重程度等。

工具实现

定义两个工具,分别处理天气警报和预测:

  • get_alerts:根据州代码获取活跃天气警报。

    @mcp.tool()
    async def get_alerts(state: str) -> str:
        url = f"{NWS_API_BASE}/alerts/active/area/{state}"
        data = await make_nws_request(url)
        if not data or "features" not in data:
            return "Unable to fetch alerts or no alerts found."
        if not data["features"]:
            return "No active alerts for this state."
        alerts = [format_alert(feature) for feature in data["features"]]
        return "\n---\n".join(alerts)
    • 接受州代码(如 CA, NY),请求 NWS API 获取活跃警报,格式化后返回。

  • get_forecast:根据经纬度获取天气预测,显示未来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 "Unable to fetch forecast data for this location."
        forecast_url = points_data["properties"]["forecast"]
        forecast_data = await make_nws_request(forecast_url)
        if not forecast_data:
            return "Unable to fetch detailed forecast."
        periods = forecast_data["properties"]["periods"]
        forecasts = []
        for period in periods[:5]:
            forecast = f"""
            {period['name']}:
            Temperature: {period['temperature']}°{period['temperatureUnit']}
            Wind: {period['windSpeed']} {period['windDirection']}
            Forecast: {period['detailedForecast']}
            """
            forecasts.append(forecast)
        return "\n---\n".join(forecasts)
    • 接受经纬度,获取预测网格点,显示温度、风速和详细预测。

运行服务器

weather.py 文件末尾添加:

if __name__ == "__main__":
    mcp.run(transport='stdio')

运行服务器命令:

uv run weather.py

这将启动服务器,使用标准输入输出传输协议。

测试与 Claude for Desktop 配置

为了测试服务器,我们需要与 Claude for Desktop 集成。以下是具体步骤:

  • 安装

    • 下载链接 安装最新版本,确保更新到最新。

  • 配置(Mac 用户):

    • 找到配置文件 ~/Library/Application Support/Claude/claude_desktop_config.json,如果不存在则创建。

    • mcpServers 下添加服务器配置,例如:

      "mcpServers": {
          "weather": {
              "command": "uv",
              "args": ["--directory", "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather", "run", "weather.py"]
          }
      }
    • 替换路径为实际项目目录,使用 which uv 获取 uv 的完整路径。

  • 测试

    • 启动 Claude for Desktop,寻找锤子图标查看可用工具。

    • 测试命令如“萨克拉门托的天气如何?”或“德州当前天气警报是什么?”(仅限美国地点)。

  • Linux 用户注意事项

故障排除

如果服务器未被 Claude for Desktop 识别,检查以下内容:

  • 确保配置文件路径正确,mcpServers 配置无误。

  • 运行 uv run weather.py 检查服务器输出。

  • 保存配置文件后重启 Claude for Desktop。

  • 更多高级调试,请参考 故障排除部分调试 MCP 指南

附加资源

本指南提供了从环境设置到测试的详细步骤,确保用户能够成功构建和使用 MCP 天气服务器,特别注意了跨平台差异和配置细节。

关键引用

最后更新于