MCP Logo

服务器开发

了解如何构建自己的服务器,以便在 Claude 桌面版及其他客户端中使用。

在本教程中,我们将构建一个简单的 MCP 天气服务器,并将其连接到 Claude 桌面版主机。我们将从基本设置开始,然后逐步过渡到更复杂的用例。

我们将构建什么

目前,大多数大语言模型还不具备直接获取实时天气预报和严重天气警报的能力。通过 MCP 技术,我们可以轻松解决这一问题!

我们将创建一个服务器,提供两个核心工具:get-alerts (获取警报) 和 get-forecast (获取预报)。随后,我们会将这个服务器连接到 MCP 主机,本教程中我们选择使用 Claude 桌面版作为示例:

该服务器实际上可以连接到任何支持MCP的客户端。我们选择Claude桌面版仅是为了演示的简便性。此外,我们还提供了如何构建自己的客户端的指南和其他可用客户端的列表

MCP 核心概念

MCP 服务器可以提供三种主要类型的功能:

  1. 资源 (Resources):客户端可读取的类文件数据,例如 API 响应结果或文件内容等
  2. 工具 (Tools):可由大语言模型调用的函数,这些调用会先获取用户批准
  3. 提示 (Prompts):帮助用户高效完成特定任务的预设模板

本教程将主要聚焦于如何实现和使用工具功能。

让我们开始构建我们的天气服务器吧!您可以在这里找到我们将要构建的完整代码。

前提知识

本快速入门假设您熟悉:

  • Python
  • 像 Claude 这样的大语言模型

系统要求

  • 已安装 Python 3.10 或更高版本。
  • 您必须使用 Python MCP SDK 1.2.0 或更高版本。

设置您的环境

首先,让我们安装 uv 并设置 Python 项目和环境:

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

安装完成后请确保重启终端,以确保 uv 命令能被正确识别。

现在,让我们创建并设置我们的项目:

# 为我们的项目创建一个新目录
uv init weather
cd weather
 
# 创建虚拟环境并激活它
uv venv
source .venv/bin/activate
 
# 安装依赖项
uv add "mcp[cli]" httpx
 
# 创建我们的服务器文件
touch weather.py

现在让我们开始构建您的服务器。

构建您的服务器

导入包和设置实例

将以下代码添加到您的 weather.py 文件顶部:

from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
 
# 初始化FastMCP服务器
mcp = FastMCP("weather")
 
# 常量
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"

FastMCP 类使用 Python 类型提示和文档字符串自动生成工具定义,这使得创建和维护 MCP 工具变得简单。

辅助函数

接下来,让我们添加辅助函数,用于查询和格式化来自国家气象服务 API 的数据:

async def make_nws_request(url: str) -> dict[str, Any] | None:
    """向NWS API发送请求并进行适当的错误处理。"""
    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')}  # 安全指南
"""

实现工具执行

工具执行处理程序负责实际执行每个工具的逻辑。让我们添加它:

@mcp.tool()
async def get_alerts(state: str) -> str:
    """获取美国各州的天气警报。
    
    Args:
        state: 美国州的两字母代码(例如CA代表加利福尼亚州, NY代表纽约州)
    """
    url = f"{NWS_API_BASE}/alerts/active/area/{state}"
    data = await make_nws_request(url)
 
    if not data or "features" not in data:
        return "无法获取警报信息或未找到相关警报。"
 
    if not data["features"]:
        return "该州目前没有活跃的天气警报。"
 
    alerts = [format_alert(feature) for feature in data["features"]]
    return "\n---\n".join(alerts)
 
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
    """获取指定位置的天气预报。
    
    Args:
        latitude: 位置的纬度
        longitude: 位置的经度
    """
    # 首先获取预报网格端点
    points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
    points_data = await make_nws_request(points_url)
 
    if not points_data:
        return "无法为该位置获取预报数据。"
 
    # 从点响应中获取预报URL
    forecast_url = points_data["properties"]["forecast"]
    forecast_data = await make_nws_request(forecast_url)
 
    if not forecast_data:
        return "无法获取详细预报。"
 
    # 将时段格式化为可读的预报
    periods = forecast_data["properties"]["periods"]
    forecasts = []
    for period in periods[:5]:  # 只显示接下来的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)

运行服务器

最后,让我们初始化并运行服务器:

if __name__ == "__main__":
    # 初始化并运行服务器
    mcp.run(transport='stdio')

您的服务器已经完成!运行 uv run weather.py 来确认一切正常工作。

现在让我们从一个现有的 MCP 主机 (Claude 桌面版) 测试您的服务器。

使用 Claude 桌面版测试您的服务器

Claude桌面版目前尚未支持Linux系统。如果您使用的是Linux,可以参考构建客户端教程,构建一个可连接到我们刚刚创建的服务器的MCP客户端。

首先,请确保您已经安装了 Claude 桌面版。您可以在这里下载最新版本。如果您已经安装了 Claude 桌面版,请务必确保它已更新至最新版本

接下来,我们需要为您的 MCP 服务器配置 Claude 桌面版。要完成这一步,请在文本编辑器中打开 Claude 桌面版的配置文件,路径为 ~/Library/Application Support/Claude/claude_desktop_config.json。如果该文件不存在,您需要创建它。

例如,如果您已安装 VS Code 编辑器:

然后,您需要在 mcpServers 键下添加您的服务器配置。请注意,只有当至少配置了一个服务器时,Claude 桌面版中的 MCP 相关界面元素才会显示。

在本例中,我们将添加一个天气服务器,配置如下:

您可能需要在command字段中使用uv可执行文件的完整路径。您可以通过在MacOS/Linux系统上运行which uv命令或在Windows系统上运行where uv命令来获取这个路径。

务必使用服务器的绝对路径,而不是相对路径。请将示例中的"/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather"替换为您实际项目的完整路径。

这段配置向 Claude 桌面版说明: 1。有一个名为 "weather" 的 MCP 服务器 2。需要通过运行 uv --directory /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather run weather.py 命令来启动它

完成配置后,保存文件并重新启动 Claude 桌面版应用程序。

功能测试

首先,让我们确认 Claude 桌面版能够识别我们在 weather 服务器中提供的两个工具。您可以通过界面中的锤子图标来确认:

点击锤子图标后,您应该能看到可用工具列表:

如果您的服务器没有被 Claude 桌面版识别,请查看下方故障排除部分获取调试建议。

如果锤子图标已正常显示,您可以通过在 Claude 桌面版中输入以下问题来测试服务器功能:

  • 萨克拉门托的天气如何?
  • 德克萨斯州有哪些活跃的天气警报?

请注意,由于使用的是美国国家气象服务API,此服务仅支持查询美国地区的天气信息。

工作原理解析

当您向 Claude 提问时,背后发生了以下过程:

  1. 客户端将您的问题发送给 Claude
  2. Claude 分析可用工具并决定使用哪个工具来回答您的问题
  3. 客户端通过 MCP 协议调用服务器上的相应工具
  4. 工具执行结果返回给 Claude
  5. Claude 根据工具返回的数据生成自然语言回答
  6. 最终答案显示给您!

故障排除

需更高级的故障排除技巧,请参考我们的MCP调试指南

下一步

在 GitHub 上编辑

最后更新于