亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

搭建簡易本地MCP服務器

在我的上一篇博客中,我解释了Model Context Protocol是如何工作的。今天,我们自己动手,从头开始搭建一个MCP服务器。在这次教程里,我打算用两个工具来做个简单的MCP服务器,并在Claude Desktop里试试这两个工具。不过官方教程读起来有点绕,所以我把代码调整了一下,让它更简单易懂。

1. 搭建开发环境

这是本教程的文件结构示例。

以下是一个简单的Python项目的文件结构:
.  
├── 📁 venv (虚拟环境)  
├── 📄 helpers.py (辅助工具)  
├── 📄 server.py (服务器)  
└── 📄 tools.py (工具)

首先,让我们为MCP服务器创建一个虚拟环境。为了简单,我使用默认的`venv`工具。但如果你想的话,也可以使用像Poetry或uv这样的Python包管理器。
# 在 Windows 下  
python -m venv venv  
venv\Scripts\activate  

# 在 Linux 下:  
python3 -m venv venv  
source venv/bin/activate
创建虚拟环境并激活它。

在激活虚拟环境之后,安装所需的依赖。
pip install mcp[cli] httpx
这是一条Python包安装命令

## 2. 创建辅助函数:

我们正在开发一个工具来获取特定位置的天气预报,以及另一个用于获取指定美国州天气警报的工具。为此,我们将会创建两个辅助函数。第一个函数将负责处理API请求,以获取天气数据。第二个函数将负责格式化从API请求中获取的数据。我使用了`httpx`模块来执行API调用,但如果你更喜欢,也可以使用`requests`模块来发起API调用。第二个函数将格式化从API调用中获取的数据。让我们创建一个`helpers.py`文件。

```python
    # 工具函数

    from textwrap import dedent
    import httpx
    from typing import Any
    import logging

    USER_AGENT = "weather-app/1.0"

    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 as e:
                logging.error(e)
                return None

    def format_alert(feature: dict) -> str:
        """将告警信息格式化为可读的字符串。"""
        props = feature["properties"]
        return dedent(
            f"""
            事件: {props.get('event', '未知')}
            区域: {props.get('areaDesc', '未知')}
            严重程度: {props.get('severity', '未知')}
            描述: {props.get('description', '无可用描述')}
            说明: {props.get('instruction', '无具体说明')}
            """
        )
3. 制作工具

现在我们有了帮助函数,让我们创建一个 tools.py 文件来实现 MCP 工具,把它们整合进工具中。确保每个工具函数都有详细的文档字符串,清楚地说明工具的作用。这些注释对于确定哪个工具适合特定任务非常重要。此外,函数名就是工具的名字。在这种情况下,get_alertsget_forecast 将是我们的工具名称。如果你想的话,你也可以在添加工具到服务器时自定义一个名字和描述。

这些工具基本上在做的是通过一个帮助函数从天气API获取数据,然后用另一个帮助函数来格式化数据,最后返回结果。

    # tools.py  

    from textwrap import dedent  
    from helpers import make_nws_request, format_alert  

    NWS_API_BASE = "https://api.weather.gov"  

    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)  

    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]:  # 仅显示接下来的 5 个周期  
            forecast = dedent(  
                f"""  
                {period['name']}:  
                气温: {period['temperature']}°{period['temperatureUnit']}  
                风向和风速: {period['windSpeed']} {period['windDirection']}  
                天气预报: {period['detailedForecast']}  
                """  
            )  
            forecasts.append(forecast)  

        return "\n---\n".join(forecasts)
4. 创建服务器端

好的。我们已经完成了MCP工具的制作。现在我们来搭建MCP服务器,并把这些工具添加进去。我将为此创建一个server.py文件。在这里,我使用stdio方法来进行通信,因为这是一个本地的服务器。

    # server.py

    from mcp.server.fastmcp import FastMCP
    from tools import get_alerts, get_forecast

    # 启动FastMCP服务器
    mcp = FastMCP("weather")

    # 添加工具
    # mcp.add_tool(get_alerts, name="Get-Weather-Alerts", description="TOOL DESC")
    mcp.add_tool(get_alerts)
    # mcp.add_tool(get_forecast, name="Get-Forecast", description="TOOL DESC")
    mcp.add_tool(get_forecast)

    if __name__ == "__main__":
        # 启动服务器
        mcp.run(transport='stdio')

我们给我们的MCP服务器起名为“weather”。接下来,我们将给服务器添加一些工具功能。你可以为工具自定义名称和描述。不过,工具名称需要遵守一些规则。

  • 它只能包含字母和数字。
  • 允许的特殊字符仅限于下划线 (_) 和破折号 (-)。
  • 它必须至少包含一个字符。
  • 长度不能超过 64 个字符。

最后,我们用stdio方式运行服务器。

5. 连接到 Claude 端

我们已经搭建好了MCP服务器。现在我们可以将这个服务器与Claude Desktop连接起来。为此,我们需要创建一个JSON配置文件。请在以下位置创建该文件:C:\Users\USER\AppData\Roaming\Claude\claude_desktop_config.json

    {  
        "mcpServers": {  
            "weather": {  
                // 在虚拟环境中运行 Python 脚本  
                // 虚拟环境中Python可执行文件的绝对路径  
                "command": "<PATH_TO_ENVIRONMENT>\\venv\\Scripts\\python",  
                "args": [  
                    // 服务器脚本的绝对路径  
                    "<PATH_TO_SERVER>\\server.py"   
                ]  
            }  
        }  
    }

上述配置仅适用于这种特定情况。如果你使用的是 poetry 或类似 uv 的工具来管理虚拟环境,这种配置就不合适了。为了简化上述配置,假设你在一个包含 server.py 文件的文件夹中。你可以使用 venv\Scripts\activate 命令来激活虚拟环境,然后使用 python server.py 命令来运行 server.py 文件。配置所做的事情和上述步骤是一样的。保存文件后,重启 Claude 桌面程序。你无需手动启动服务器。

6: 测试MCP

如果你正确完成了上述所有步骤,你会在Claude Desktop输入部分右下角看到一个锤子形状的图标。点击它就能看到可用工具的详细信息。

这里你就能看到我们工具的列表。正如之前提到的,工具名称对应于函数名称,工具的描述则来自于函数内部的文档字符串。此外,通过服务器的名称,你还能知道这个工具属于哪个服务器。在这个教程里,我只使用了一个服务器,不过Claude Desktop其实支持连接多个服务器。

如果你查询某个州的天气预报,Claude Desktop 会请求运行 MCP 工具的许可。一旦获得许可,它将运行工具并提供结果。

7. 故障解决

如果你没有正确地按照上述步骤来做,你可能会看到类似这样的错误。

点击“打开MCP设置按钮”就会弹出一个新的弹出窗口。

在这里,你可以看到你在JSON配置文件中指定的命令及其参数。试着在终端里用这些参数运行该命令。如果出现错误,可能出现问题的原因有以下两种:

  • JSON 配置错误

如果遇到错误信息显示“系统无法找到指定的路径”或“没有这样的文件或目录”,这通常意味着文件路径可能不对。请检查 server.py 文件或虚拟环境中 python.exe 的路径,然后重启一下 Claude Desktop 应该就可以了。

  • MCP服务端代码中的错误

如果你看到错误信息以“Traceback”开头,这意味着 MCP 服务器的 Python 代码可能出错了。先检查一下 Python 文件中的错误,然后修复它们并重启 Claude Desktop。

第八. 总结一下

我们首先创建了一个辅助函数,它接受一个URL作为参数并返回JSON响应。我们还创建了另一个辅助函数,用于获取JSON字典并返回格式良好的字符串。之后,我们创建了两个工具。第一个工具获取美国州的天气警报信息,此工具接受一个美国州代码作为参数,调用辅助函数以获取天气预报数据,对其进行格式化,并返回结果。第二个工具以经度和纬度作为参数,调用辅助函数以获取天气预报数据,对其进行格式化,并返回结果。接下来,我们创建了MCP服务器,并将这些工具附加到MCP服务器上。然后,我们创建了一个JSON配置来连接我们的MCP服务器和Claude Desktop。当你要求特定地点的天气预报或美国州的天气警报时,Claude将读取工具描述,从你的提示中提取需要的信息,将其转换成工具所需的格式,并传递给MCP工具,获取输出后提供可读的结果。

感谢你加入我们的社区

在你离开之前:

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消