fastmcp入门教程:5行Python代码搭建你的第一个MCP服务器

MCP(Model Context Protocol)让AI Agent能调用外部工具,但原生的协议实现复杂。fastmcp将这个过程简化到了极致。本文带你从零搭建一个可用的MCP天气查询服务。

fastmcp入门教程:5行Python代码搭建你的第一个MCP服务器封面

什么是MCP?

简单理解,MCP就是”AI Agent的USB-C接口”。它定义了一套标准协议,让任何工具(天气查询、数据库操作、文件读写)都能被Claude、GPT等AI模型统一调用。

fastmcp是PrefectHQ推出的Python框架,目标是让MCP开发像写Flask API一样简单。

Step 1:安装

pip install fastmcp

Step 2:创建第一个MCP工具

新建文件 `weather_server.py`:

from fastmcp import FastMCP
from typing import Optional

# 创建MCP服务器实例
mcp = FastMCP("Weather Service")

@mcp.tool()
def get_weather(city: str, unit: str = "celsius") -> dict:
    """查询指定城市的天气信息。

    Args:
        city: 城市名称,如"北京"
        unit: 温度单位,celsius或fahrenheit
    """
    # 模拟天气数据(实际项目中替换为真实API调用)
    weather_data = {
        "北京": {"temp": 28, "humidity": 65, "condition": "晴"},
        "上海": {"temp": 32, "humidity": 80, "condition": "多云"},
        "深圳": {"temp": 30, "humidity": 75, "condition": "阵雨"},
    }

    data = weather_data.get(city, {"temp": 25, "humidity": 60, "condition": "未知"})

    if unit == "fahrenheit":
        data["temp"] = data["temp"] * 9/5 + 32
        data["unit"] = "fahrenheit"
    else:
        data["unit"] = "celsius"

    return {"city": city, **data}

@mcp.tool()
def get_forecast(city: str, days: int = 3) -> dict:
    """查询未来天气预报。

    Args:
        city: 城市名称
        days: 预报天数,1-7
    """
    forecast = []
    for i in range(min(days, 7)):
        forecast.append({
            "day": f"第{i+1}天",
            "temp_high": 28 + i,
            "temp_low": 20 + i,
            "condition": "晴转多云"
        })
    return {"city": city, "forecast": forecast}

if __name__ == "__main__":
    # 启动服务器,默认stdio传输
    mcp.run()

Step 3:测试服务器

fastmcp内置了一个Web调试面板,极大简化了测试流程:

# 启动调试面板
python3 weather_server.py --transport http --port 8000

打开浏览器访问 `http://localhost:8000`,你会看到一个交互式界面,可以直接选择工具、填写参数、查看响应。这个调试面板还会记录每次调用的耗时和错误日志。

Step 4:接入Claude Desktop

在Claude Desktop的配置文件中添加你的MCP服务器:

{
  "mcpServers": {
    "weather": {
      "command": "python3",
      "args": ["/path/to/weather_server.py"]
    }
  }
}

重启Claude Desktop后,你就可以在对话中直接让Claude查询天气了:”帮我查一下北京明天天气怎么样?”

Step 5:添加资源端点

除了工具(tool),MCP还支持资源(resource)和提示词(prompt):

@mcp.resource("weather://cities")
def list_cities() -> str:
    """返回支持查询的城市列表"""
    return "北京, 上海, 深圳, 广州, 杭州, 成都"

@mcp.prompt()
def weather_analyst_prompt() -> str:
    """返回一个天气预报分析的系统提示词"""
    return "你是一个专业的天气预报分析师。回答时请包括温度、湿度、穿衣建议和出行提示。"

进阶:连接真实API

将模拟数据替换为真实的天气API(以OpenWeatherMap为例):

import httpx
import os

@mcp.tool()
async def get_weather(city: str) -> dict:
    api_key = os.environ["OPENWEATHER_API_KEY"]
    async with httpx.AsyncClient() as client:
        resp = await client.get(
            "https://api.openweathermap.org/data/2.5/weather",
            params={"q": city, "appid": api_key, "units": "metric"}
        )
        data = resp.json()
        return {
            "city": city,
            "temp": data["main"]["temp"],
            "humidity": data["main"]["humidity"],
            "condition": data["weather"][0]["description"]
        }

生产环境最佳实践

1. 错误处理:为每个工具添加异常捕获和回退逻辑,避免Agent卡死

2. 日志监控:fastmcp集成了结构化日志,建议接入ELK或Datadog

3. 认证鉴权:生产环境务必添加API Key验证,防止未授权调用

4. 速率限制:工具函数内部实现`asyncio.Semaphore`防止API被刷爆

总结

fastmcp将MCP开发的复杂度从”需要理解整个协议规范”降到了”知道怎么写Python函数”。对于正在构建AI Agent应用的团队来说,它是一个价值巨大的生产力工具。

进阶玩法:组合多个MCP工具

fastmcp的真正威力在于工具编排。看一个更复杂的例子——结合天气API和位置服务:

@mcp.tool()
async def plan_outdoor_activity(city: str, activity: str) -> dict:
    """判断某城市是否适合进行指定户外活动"""
    weather = await get_weather(city)
    suggestions = {
        "跑步": weather["temp"] < 30 and weather["humidity"] < 80,
        "野餐": weather["condition"] not in ["雨", "暴雨"] and weather["temp"] < 33,
        "骑行": weather["humidity"] < 75 and weather["temp"] < 32,
    }
    return {
        "city": city,
        "activity": activity,
        "suitable": suggestions.get(activity, True),
        "weather": weather,
        "tip": "记得带水!" if weather["temp"] > 28 else "注意防晒"
    }

常见踩坑与解决方案

问题1:Claude Desktop找不到MCP服务器

检查配置JSON的路径是否使用绝对路径,以及Python环境是否包含fastmcp。建议先用`–transport http`模式在浏览器中验证服务器正常运行。

问题2:异步工具函数报错

fastmcp原生支持async/await,但混用同步和异步函数可能导致事件循环冲突。建议统一使用`async def`定义工具函数。

问题3:调试面板打不开

确认启动命令中的`–port`端口未被占用,且防火墙未拦截。可以用`lsof -i :8000`检查端口状态。

🔥 关注LC智趣厅,获取更多AI开发实战教程。

👇 关注不错过,技术干货每日更新。


— END —
LC 智趣厅 · 科技与生活的交点
ihygg.cn

滚动至顶部
微信公众号:LC智趣厅

扫码关注微信公众号
LC智趣厅