目录

MCP Server 开发教程

快速开始

面向服务端开发者

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

我们将构建什么

许多LLM目前没有获取天气预报和恶劣天气警报的能力。让我们使用MCP来解决这个问题!

我们将构建一个暴露两个工具的服务端:get-alertsget-forecast。然后我们将服务端连接到MCP主机(在本例中为Claude for Desktop):

服务端可以连接到任何客户端。我们在这里选择Claude for Desktop是为了简单起见,但我们也有关于构建自己的客户端的指南,以及其他客户端的列表

为什么选择Claude for Desktop而不是Claude.ai

因为服务端是本地运行的,MCP目前只支持桌面主机。远程主机正在积极开发中。

MCP核心概念

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

  1. 资源:客户端可以读取的文件类数据(如API响应或文件内容)
  2. 工具:LLM可以调用的函数(需用户批准)
  3. 提示:帮助用户完成特定任务的预写模板

本教程将主要关注工具。

Python教程(其他语言看这里)

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

预备知识

本快速入门假设你熟悉:

  • Python
  • 像Claude这样的LLM

系统要求

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

设置你的环境

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

Linux

sh 复制代码
    curl -LsSf https://astral.sh/uv/install.sh | sh

确保之后重新启动终端,以确保uv命令被识别。

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

Liunx

python 复制代码
# 为我们的项目创建一个新目录
uv init weather
cd weather

# 创建虚拟环境并激活它
uv venv
source .venv/bin/activate

# 安装依赖项
uv add "mcp[cli]" httpx

# 创建我们的服务端文件
touch weather.py

现在让我们深入构建你的服务端。

构建你的服务端

导入包并设置实例

将这些添加到weather.py的顶部:

python 复制代码
    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的数据的辅助函数:

python 复制代码
    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:
    """Format an alert feature into a readable string."""
    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')}
"""

实现工具执行

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

python 复制代码
    @mcp.tool()
    async def get_alerts(state: str) -> str:
        """获取美国州的天气警报。
    
        参数:
            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:
        """获取某个位置的天气预报。
    
        参数:
            latitude: 位置的纬度
            longitude: 位置的经度
        """
        # 首先获取预测网格端点
        points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
        points_data = await make_nws_request(points_url)
    
        if not points_data:
            return "无法获取该位置的预测数据。"
    
        # 从points响应中获取预测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]:  # Only show next 5 periods
        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)

运行服务端

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

python 复制代码
    if __name__ == "__main__":
        # 初始化并运行服务端
        mcp.run(transport='stdio')

你的服务端完成了!运行uv run weather.py以确认一切正常。

现在让我们从现有的MCP主机Claude for Desktop测试你的服务端。

使用Claude for Desktop测试你的服务端

Claude for Desktop尚未在Linux上提供。Linux用户可以继续构建客户端教程,以构建一个连接到我们刚刚构建的服务端的MCP客户端。

首先,确保你已经安装了Claude for Desktop。你可以在这里安装最新版本。 如果你已经安装了Claude for Desktop,请确保它已更新到最新版本。

我们需要为你想使用的任何MCP服务端配置Claude for Desktop。为此,请在文本编辑器中打开你的Claude for Desktop应用程序配置~/Library/Application Support/Claude/claude_desktop_config.json。如果文件不存在,请确保创建它。

例如,如果你安装了VS Code

Linux

bash 复制代码
code ~/Library/Application\ Support/Claude/claude_desktop_config.json

然后你将在mcpServers键中添加你的服务端。只有在至少正确配置了一个服务端的情况下,MCP UI元素才会在Claude for Desktop中显示。

在这种情况下,我们将添加我们的单个天气服务端,如下所示:

Linux

json 复制代码
{
    "mcpServers": {
        "weather": {
            "command": "uv",
            "args": [
                "--directory",
                "/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather",
                "run",
                "weather.py"
            ]
        }
    }
}

你可能需要在command字段中输入uv可执行文件的完整路径。你可以通过在MacOS/Linux上运行which uv或在Windows上运行where uv来获取此路径。

确保你传入服务端的绝对路径。

这告诉Claude for Desktop:

  1. 有一个名为"weather"的MCP服务端
  2. 通过运行uv --directory /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather run weather.py来启动它

保存文件,并重新启动Claude for Desktop

这告诉Claude for Desktop:

  1. 有一个名为"weather"的MCP服务端
  2. 通过运行java -jar /ABSOLUTE/PATH/TO/PARENT/FOLDER/weather/build/libs/weather-0.1.0-all.jar来启动它

保存文件,并重新启动Claude for Desktop。 </Tabs.Tab>

使用命令测试

让我们确保Claude for Desktop能够识别我们在weather服务端中暴露的两个工具。你可以通过查找锤子图标来做到这一点:

点击锤子图标后,你应该看到列出的两个工具:

如果你的服务端没有被Claude for Desktop识别,请继续故障排除部分以获取调试提示。

如果锤子图标已经显示,你现在可以通过在Claude for Desktop中运行以下命令来测试你的服务端:

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

由于这是美国国家气象局服务,查询仅适用于美国位置。

幕后发生了什么

当你提出问题时:

  1. 客户端将你的问题发送给Claude
  2. Claude分析可用的工具并决定使用哪个工具
  3. 客户端通过MCP服务端执行所选工具
  4. 结果被发送回Claude
  5. Claude制定自然语言响应
  6. 响应显示给你!

故障排除

Claude for Desktop集成问题

从Claude for Desktop获取日志

与MCP相关的Claude.app日志写入~/Library/Logs/Claude中的日志文件:

  • mcp.log将包含有关MCP连接和连接失败的一般日志。
  • 名为mcp-server-SERVERNAME.log的文件将包含来自命名服务端的错误(stderr)日志。

你可以运行以下命令列出最近的日志并跟随任何新的日志:

sh 复制代码
    # 检查Claude的日志以查找错误
    tail -n 20 -f ~/Library/Logs/Claude/mcp*.log

服务端未在Claude中显示

  1. 检查你的claude_desktop_config.json文件语法
  2. 确保你的项目路径是绝对的而不是相对的
  3. 完全重新启动Claude for Desktop

工具调用静默失败

如果Claude尝试使用工具但它们失败:

  1. 检查Claude的日志以查找错误
  2. 验证你的服务端构建和运行没有错误
  3. 尝试重新启动Claude for Desktop

这些都不起作用。我该怎么办?

请参阅我们的调试指南以获取更好的调试工具和更详细的指导。

天气API问题

错误:无法检索网格点数据

这通常意味着:

  1. 坐标在美国以外
  2. NWS API出现问题
  3. 你被限速

修复:

  • 验证你使用的是美国坐标
  • 在请求之间添加小延迟
  • 检查NWS API状态页面

错误:没有活跃的警报用于[STATE]

这不是错误 - 这只是意味着该州当前没有天气警报。尝试不同的州或在恶劣天气期间检查。

有关更高级的故障排除,请查看我们的调试MCP指南

下一步

构建客户端

服务端示例

调试指南

使用LLM构建MCP

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
哥不是小萝莉3 小时前
如何使用 OpenAI Agents SDK 构建 MCP
mcp
movee4 小时前
十分钟从零开始开发一个自己的MCP server(二)
后端·llm·mcp
movee5 小时前
十分钟从零开始开发一个自己的MCP server(一)
后端·llm·mcp
AI产品黄叔6 小时前
10分钟搞定高德地图MCP!我用AI解决了约会地点选择难题
前端·ai编程·mcp
Martian小小10 小时前
MCP探索
llm·mcp
阿洲48212 小时前
Spring AI通过MCP支持大语言模型调用工具
mcp
go4it16 小时前
spring-ai-starter-mcp-client小试牛刀
mcp
MobotStone18 小时前
MCP协议:AI界的"万能插槽"革命
mcp
dmy1 天前
十分钟搞懂mcp
ai编程·cursor·mcp
聪明的一休丶1 天前
MCP Server 实现一个 天气查询
python·llm·aigc·mcp