借助MCP尝试创建自己的Agent(二)

关于模型上下文协议(model context protocol, MCP)的相关概念可以参考上一篇博客:借助MCP尝试创建自己的Agent(一)

Python SDK构建个性化天气查询服务器

尝试在claude客户端获取天气信息

目前,很多未联网的大模型是不能获取某地当天的天气信息的,例如,当我询问claude桌面版Q: 深圳今天的天气怎么样?却得到了下面的回复?
在这里插入图片描述

如何使本地agent具有天气查询能力呢?MCP文档1给出了详细的实例,我在这里复现一遍。

1. 环境配置

在获取天气信息之前,需要先配置uv环境, uv是一个类似于conda的python包或项目管理工具2

# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# MacOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

我用的是windows系统,在PowerShell 安装完成后如图所示。
在这里插入图片描述
安装完成后,重启Powershell,并通过下面的命令创建访问天气的项目。

# windows
# Create a new directory for our project
uv init weather
cd weather
# Create virtual environment and activate it
uv venv
.venv\Scripts\activate
# Install dependencies
uv add mcp[cli] httpx
# Create our server file
new-item weather.py

# MacOS/Linux
# Create a new directory for our project
uv init weather
cd weather
# Create virtual environment and activate it
uv venv
source .venv/bin/activate
# Install dependencies
uv add "mcp[cli]" httpx
# Create our server file
touch weather.py

这里需要在当前目录下创建一个名为weather的文件,如果不想在当前目录下创建,可以先进入到其他目录中再进行操作,我的操作结果如下图所示:
在这里插入图片描述
到这里已经完成了基本环境的配置,下一步可以开始配置服务器了

2. 构建天气服务器

打开之前创建的weather.py文件,导入相应的包,并且设置天气查询服务的MCP服务器设置

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

# Initialize FastMCP server
mcp = FastMCP("weather")

# Constants
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"

The FastMCP class uses Python type hints and docstrings to automatically generate tool definitions, making it easy to create and maintain MCP tools.

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

接着,添加帮助函数,来从国家天气服务(National Weather Service)API查询天气数据

async def make_nws_request(url: str) -> dict[str, Any] | None:
    """Make a request to the NWS API with proper error handling."""
    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')}
"""

其次,添加工具执行处理模块来负责执行每个工具:

@mcp.tool()
async def get_alerts(state: str) -> str:
    """Get weather alerts for a US state.

    Args:
        state: Two-letter US state code (e.g. 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 "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)

@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
    """Get weather forecast for a location.

    Args:
        latitude: Latitude of the location
        longitude: Longitude of the location
    """
    # First get the forecast grid endpoint
    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."

    # Get the forecast URL from the points response
    forecast_url = points_data["properties"]["forecast"]
    forecast_data = await make_nws_request(forecast_url)

    if not forecast_data:
        return "Unable to fetch detailed forecast."

    # Format the periods into a readable forecast
    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)

最后,实现运行该服务器,在创建的weather文件夹下通过uv run weather.py运行天气查询服务

if __name__ == "__main__":
    # Initialize and run the server
    mcp.run(transport='stdio')

3. 在Claude桌面版中配置天气查询服务器

找到并打开claude_desktop_config.json文件,将添加的weather服务加入到mcpServers

{
    "mcpServers": {
        "weather": {
            "command": "uv",
            "args": [
                "--directory",
                "C:\\ABSOLUTE\\PATH\\TO\\PARENT\\FOLDER\\weather",
                "run",
                "weather.py"
            ]
        }
    }
}

重启claude 客户端

!!! 然而,重启之后出现了问题,发现配置失败。原因是访问位置不在美国,导致了天气访问的API出现了问题。挂美国的梯子也不行,所以对weather.py的代码进行改进
在这里插入图片描述

4. 改进weather服务器代码

第二天我重新按官方文档设置了一遍,目前可以查看美国各州的天气警告信息,但访问其他地方的天气时还会出现问题,估计是API的原因
在这里插入图片描述
这里的改进用了和风天气的API3,想尝试的小伙伴可以看一看,可以免费使用1000个token。根据和风天气返回数据的特点,删除了预测和警告信息查看功能,只保留了查询目前天气情况的功能,该变代码如下:

from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
import asyncio
# Initialize FastMCP server
mcp = FastMCP("weather")
# Constants
NWS_API_BASE = "https://devapi.qweather.com/v7/weather"
USER_AGENT = "weather-app/1.0"
key = "xxxx" # 输入你自己的key
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
@mcp.tool()
async def get_now(latitude: float, longitude: float) -> str:
    """Get weather forecast for a location.

    Args:
        latitude: Latitude of the location
        longitude: Longitude of the location
    """
    # First get the forecast grid endpoint
    points_url =  f"{NWS_API_BASE}/now?location={longitude},{latitude}&key={key}"
    points_data = await make_nws_request(points_url)

    if not points_data:
        return "Unable to fetch detailed forecast"
    now = points_data['now']
    weather_info = (
        f"观测时间: {now['obsTime']}\n"
        f"温度: {now['temp']}°C\n"
        f"体感温度: {now['feelsLike']}°C\n"
        f"天气: {now['text']}\n"
        f"风向: {now['windDir']}\n"
        f"风力等级: {now['windScale']}\n"
        f"风速: {now['windSpeed']}km/h\n"
        f"湿度: {now['humidity']}%\n"
        f"降水量: {now['precip']}mm\n"
        f"气压: {now['pressure']}hPa\n"
        f"能见度: {now['vis']}km"
    )
    return weather_info
if __name__ == "__main__":
    # Initialize and run the server
    mcp.run(transport='stdio')
    # weather_data = asyncio.run(get_now(22.5,114))
    # if weather_data:
    #     print(weather_data)

最后,成功通过claude获取了某个城市天气信息,这里不仅仅是添加了天气服务,而且窥探了通过python自定义服务的功能,这里需要仔细阅读官方给出了Python SDK网页内容,才能实现自己后续的开发。
在这里插入图片描述


今天的分享就到这里,欢迎各位大佬批评指正。我是会编程的加缪,目前正在学习LLMs相关知识,有问题欢迎与我讨论!


  1. MPC document ↩︎

  2. An extremely fast Python package and project manager, written in Rust. ↩︎

  3. 和风天气开发服务 ↩︎

<think>好的,我需要帮助用户了解如何配置和使用fastmcp服务器。根据用户提供的引用内容,特别是引用[1]和引用[2],我需要整理出配置步骤和使用指南。 首先,用户提到了fastmcp的安装和项目地址,应该从安装开始。根据引用[1],安装可能通过pip进行,所以第一步应该是安装fastmcp包。然后,用户需要启用MCP服务器,这涉及到Roo Code菜单栏的设置,如引用[2]所述。需要指导用户如何启用相关选项,比如“Enable MCP Servers”和“Enable MCP Server Creation”。 接下来,配置cline_mcp_settings.json文件是关键步骤。用户可能需要编辑这个文件来设置服务器参数,比如端口、协议和日志路径。需要详细说明每个配置项的作用,例如port、protocol和log_path,并给出示例配置,这样用户可以直接参考。 然后,用户可能需要创建一个基本的MCP服务器实例。这里需要提供Python代码示例,展示如何继承BaseMCPServer类并定义handle_request方法。代码示例应该简洁明了,让用户能够快速上手。 此外,启动服务器和测试连接也是必要的步骤。需要指导用户如何运行服务器,以及如何使用telnet或Python客户端进行测试,确保服务器正常运行。 最后,根据用户的问题,生成相关问题,帮助用户进一步探索高级配置和优化方法。这些问题可以包括自定义协议解析、性能优化以及错误处理等内容,参考引用中的进阶篇信息。 在整理过程中,要注意使用正确的LaTeX格式,比如行内公式用$...$,独立公式用$$...$$,但在这个配置指南中可能用不上数学公式,所以主要关注代码块和配置示例的正确格式。同时,引用标识要自然地添加在相关步骤的末尾,比如在提到编辑配置文件时引用[^2],在安装步骤引用[^1]。 需要确保回答结构清晰,分步骤说明,每个步骤都有对应的操作和示例,帮助用户逐步完成配置和使用。同时,检查是否有遗漏的信息,比如是否需要安装其他依赖,或者是否有常见问题需要注意,但根据提供的引用内容,可能没有这些细节,所以暂时不添加。 总结下来,回答的结构应该是:安装fastmcp → 启用MCP服务器 → 编辑配置文件 → 创建服务器实例 → 启动与测试 → 相关问题。每个步骤都提供具体的命令或代码,并引用对应的来源。</think>### fastmcp服务器配置与使用指南 #### 一、环境准备 1. 安装fastmcp包 ```bash pip install fastmcp ``` 安装完成后可访问项目地址查看文档更新[^1]。 #### 、基础配置 1. **启用MCP服务** - 在IDE菜单栏选择 Roo Code → MCP Servers - 勾选以下选项: - ✅ Enable MCP Servers - ✅ Enable MCP Server Creation[^2] 2. **编辑配置文件** 打开`cline_mcp_settings.json`文件,基础配置示例: ```json { "server_config": { "port": 8888, "protocol": "tcp", "log_path": "/var/log/mcp_server.log" } } ``` - `port`: 服务监听端口 - `protocol`: 支持tcp/udp协议 - `log_path`: 日志存储路径[^2] #### 三、创建MCP服务实例 ```python from fastmcp import BaseMCPServer class MyMCPServer(BaseMCPServer): async def handle_request(self, raw_data: bytes): # 实现自定义协议解析逻辑 processed_data = raw_data.decode().upper() return processed_data.encode() ``` #### 四、启动与测试 1. **启动服务器** ```python server = MyMCPServer() server.run() ``` 2. **客户端测试** 使用telnet测试连接: ```bash telnet localhost 8888 ``` 或Python客户端: ```python import socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect(("localhost", 8888)) s.send(b"test message") ``` 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会编程的加缪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值