FastMCP 实战:一个 .py 文件,给 Claude Code 装上 3 个超实用工具

最近掘金热榜被 MCP 和 Skill 刷屏了,什么「写 Skill 行业就死了」「Prompt、Agent、Function Call、Skill、MCP 傻傻分不清楚」,看得我一愣一愣的。

说实话,MCP 这东西没大家想的那么玄乎。我花了一个下午,用 FastMCP 3.0 写了个「开发者工具箱」MCP Server------一个 Python 文件,三个工具,直接接到 Claude Code 里用,效率提升肉眼可见。

今天把过程和踩的坑都写出来,保证你照着做 30 分钟内能跑起来。

先说结论

工具 功能 代码量 实用指数
search_pypi 查 Python 包最新版本和信息 15 行 ⭐⭐⭐⭐⭐
github_trending 抓 GitHub 当日热门仓库 20 行 ⭐⭐⭐⭐
port_check 检查本地端口占用情况 10 行 ⭐⭐⭐⭐

三个工具加起来不到 80 行 Python,FastMCP 帮你处理了所有 MCP 协议的脏活。

MCP 是啥?30 秒版本

MCP(Model Context Protocol)是 Anthropic 搞的一个开放协议,简单说就是给 AI 装外挂的标准接口。

以前你想让 Claude 查个天气,得自己写一堆胶水代码。现在有了 MCP,你只要:

  1. 写一个 Python 函数
  2. 加个 @mcp.tool 装饰器
  3. 完事了

Claude Code、Cursor、Windsurf 这些 AI 编辑器都支持 MCP,装上就能用。

环境准备

bash 复制代码
# 装 FastMCP 3.0(需要 Python 3.10+)
pip install fastmcp httpx

# 验证安装
python -c "import fastmcp; print(fastmcp.__version__)"

我用的是 FastMCP 3.1.0,3.0 以上版本都行。如果你还在用 2.x,强烈建议升级,3.0 的 API 简洁太多了。

开搓:dev_toolbox_server.py

工具一:PyPI 包信息查询

写代码时经常要查某个包的最新版本、依赖关系,以前得开浏览器搜。现在直接让 Claude 帮你查:

python 复制代码
from fastmcp import FastMCP
import httpx

mcp = FastMCP("DevToolbox 🔧")

@mcp.tool
async def search_pypi(package_name: str) -> dict:
    """查询 Python 包的最新版本、简介和依赖信息。

    Args:
        package_name: PyPI 上的包名,如 'requests'、'fastapi'
    """
    async with httpx.AsyncClient() as client:
        resp = await client.get(
            f"https://pypi.org/pypi/{package_name}/json",
            timeout=10
        )
        if resp.status_code == 404:
            return {"error": f"包 '{package_name}' 不存在"}

        data = resp.json()
        info = data["info"]
        return {
            "name": info["name"],
            "version": info["version"],
            "summary": info["summary"],
            "author": info["author"],
            "license": info["license"],
            "python_requires": info["requires_python"],
            "homepage": info["home_page"] or info["project_urls"].get("Homepage", ""),
            "dependencies": info.get("requires_dist", [])[:10],  # 只取前 10 个
        }

注意几个点:

  • async 函数。FastMCP 原生支持异步,网络请求用异步性能好很多
  • docstring 很重要。FastMCP 会把它作为工具描述传给 AI,写清楚了 AI 才知道什么时候该调用这个工具
  • 类型注解不能省package_name: str 这个注解是 FastMCP 生成 JSON Schema 的依据

每天上班第一件事看 GitHub 热榜?让 AI 帮你看:

python 复制代码
@mcp.tool
async def github_trending(language: str = "", since: str = "daily") -> list[dict]:
    """获取 GitHub 今日热门仓库列表。

    Args:
        language: 编程语言筛选,如 'python'、'javascript',留空表示所有语言
        since: 时间范围,可选 'daily'、'weekly'、'monthly'
    """
    url = "https://api.gitterapp.com/repositories"
    params = {"since": since}
    if language:
        params["language"] = language.lower()

    async with httpx.AsyncClient() as client:
        resp = await client.get(url, params=params, timeout=15)
        repos = resp.json()

    return [
        {
            "name": f"{repo['author']}/{repo['name']}",
            "description": repo.get("description", ""),
            "stars": repo.get("stars", 0),
            "today_stars": repo.get("currentPeriodStars", 0),
            "language": repo.get("language", "Unknown"),
            "url": repo.get("url", ""),
        }
        for repo in repos[:15]  # 取前 15 个
    ]

这里用的是 gitterapp.com 的非官方 API,不需要 token,够用了。如果你需要更稳定的数据源,可以用 GitHub 官方 API(需要 Personal Access Token)。

工具三:端口占用检查

开发时端口冲突是家常便饭,lsof -i :8080 记不住?交给 AI:

python 复制代码
import subprocess

@mcp.tool
def port_check(port: int) -> dict:
    """检查指定端口是否被占用,如果被占用则显示占用进程信息。

    Args:
        port: 要检查的端口号,如 8080、3000、5432
    """
    try:
        result = subprocess.run(
            ["lsof", "-i", f":{port}", "-P", "-n"],
            capture_output=True, text=True, timeout=5
        )
        if result.returncode != 0 or not result.stdout.strip():
            return {"port": port, "status": "available", "message": f"端口 {port} 空闲,可以使用"}

        lines = result.stdout.strip().split("\n")
        processes = []
        for line in lines[1:]:  # 跳过 header
            parts = line.split()
            if len(parts) >= 9:
                processes.append({
                    "command": parts[0],
                    "pid": parts[1],
                    "user": parts[2],
                    "name": parts[8] if len(parts) > 8 else "",
                })

        return {
            "port": port,
            "status": "in_use",
            "process_count": len(processes),
            "processes": processes,
        }
    except subprocess.TimeoutExpired:
        return {"port": port, "status": "timeout", "message": "检查超时"}

注意这个工具是同步函数 (没有 async),FastMCP 同步异步都支持,混着写完全没问题。

启动入口

python 复制代码
if __name__ == "__main__":
    mcp.run()

就这一行。

完整代码

把上面的片段合在一起,完整的 dev_toolbox_server.py 大概 75 行。保存好后先测试一下:

bash 复制代码
# 用 FastMCP 自带的检查工具验证
fastmcp inspect dev_toolbox_server.py

# 或者直接运行看看有没有语法错误
python dev_toolbox_server.py

接入 Claude Code

在你的项目根目录创建或编辑 .claude/settings.json

json 复制代码
{
  "mcpServers": {
    "dev-toolbox": {
      "command": "python",
      "args": ["/你的路径/dev_toolbox_server.py"],
      "env": {}
    }
  }
}

重启 Claude Code,输入 /mcp 应该能看到你的三个工具了。

试着问 Claude:「帮我查一下 fastapi 最新版本是多少」,它会自动调用 search_pypi 工具返回结果。

踩坑记录

坑 1:httpx 超时默认太短

httpx 默认超时 5 秒,GitHub API 有时候响应慢会挂掉。我一开始没设 timeout 参数,动不动就 ReadTimeout解决 :所有网络请求都显式设 timeout=10 或更长。

坑 2:docstring 写得烂,AI 就不调用

一开始我的 port_check 工具 docstring 只写了「检查端口」三个字。结果 Claude 遇到端口相关的问题压根不调用这个工具,因为它不确定这个工具具体能干啥。

改成详细描述之后,调用率直接翻倍。经验:把 docstring 当作给 AI 看的说明书来写,参数说明越具体越好。

坑 3:subprocess 在 Windows 上翻车

lsof 是 macOS/Linux 的命令,Windows 上跑不了。如果你要跨平台,得用 netstat 做兼容:

python 复制代码
import platform

if platform.system() == "Windows":
    result = subprocess.run(
        ["netstat", "-ano", "-p", "TCP"],
        capture_output=True, text=True
    )
    # 自己解析 netstat 输出...

我没做这个兼容,因为我只在 Mac 上开发。但如果你要分享给团队用,记得处理。

坑 4:FastMCP 2.x 升 3.0 的 breaking change

如果你之前用的 FastMCP 2.x,升级 3.0 要注意:

  • @mcp.resource 的 URI 格式变了,现在必须是 "protocol://path" 形式
  • Contextfastmcp.server.context 导入,不是以前的 fastmcp.context
  • mcp.run() 默认用 stdio 传输,要用 SSE 得手动指定 mcp.run(transport="sse")

进阶:加个 Resource

除了 Tool,MCP 还有 Resource 的概念------提供只读数据给 AI 参考。比如加一个展示所有工具说明的 Resource:

python 复制代码
@mcp.resource("docs://toolbox/readme")
def toolbox_readme() -> str:
    """开发者工具箱使用说明"""
    return """
    # DevToolbox MCP Server

    可用工具:
    - search_pypi: 查询 Python 包信息
    - github_trending: 获取 GitHub 热门仓库
    - port_check: 检查端口占用

    使用示例:
    - "查一下 requests 包最新版本"
    - "今天 Python 圈有什么热门项目"
    - "8080 端口被谁占了"
    """

小结

MCP 和 Skill 被热榜吹得挺玄乎,但实际上手发现就是「给函数套个装饰器」的事。FastMCP 3.0 把协议层的复杂度全吃了,你只需要关心业务逻辑。

今天这三个工具是抛砖引玉,你可以按同样的模式扩展更多:

  • 接数据库查询
  • 接 Jira/飞书 API 查任务状态
  • 接 Docker API 管理容器

一个 Python 文件能塞不少东西,我目前自己用的 MCP Server 已经有十几个工具了,日常开发基本不用离开编辑器。

热榜说「写 Skill 越多行业死越快」,我倒觉得恰恰相反------会写工具的开发者,才是这轮 AI 浪潮里最难被替代的。毕竟 AI 再强,也得有人告诉它怎么跟外部世界交互。


本文代码已在 Python 3.12 + FastMCP 3.1.0 环境下测试通过。有问题评论区见。

相关推荐
FE_C_P小麦2 小时前
别再被炒作裹挟:理性拆解OpenClaw,警惕AI工具背后的资本陷阱与劳动异化
ai编程
小虎AI生活2 小时前
用微信指挥你的 AI 员工:QClaw 给普通人发了一张超级个体的入场券
ai编程
狼爷3 小时前
AI编程狂飙时代:别被Vibe Coding毁了系统,DDD+SDD才是下一代稳健开发范式
ai编程·领域驱动设计
洛小豆3 小时前
我用 AI 当主力,三天撸了一个跨平台的所见即所得 Markdown 编辑器
openai·ai编程
踩着两条虫3 小时前
AI 驱动的 Vue3 应用开发平台 入门指南(五):创建 H5 移动应用
前端·vue.js·ai编程
chaors3 小时前
从零学RAG0x03第一个实战应用:医疗知识混合检索实战
人工智能·aigc·ai编程
踩着两条虫3 小时前
AI 驱动的 Vue3 应用开发平台 入门指南(二):快速入门
前端·vue.js·ai编程
dev派4 小时前
AI Agent 系统中的常用 Workflow 模式(2) Evaluator-Optimizer模式
python·langchain
昵称为空C4 小时前
spring-ai mcp-server(ssh工具)
后端·ai编程