☰
理解MCP | FastMCP开源库应用的学习笔记(一):从FastAPI到MCP Server的迁移实践
2026/10/2 6:45:09 网站建设 项目流程

1. 从 FastAPI 到 MCP Server:一个后端开发者的真实迁移场景

如果你已经用 FastAPI 写了一堆接口,现在想让大模型直接调用这些能力,最省事的路径不是重写一套 Function Call,而是把现有 FastAPI 应用“升级”成 MCP Server。MCP(Model Context Protocol)你可以先粗暴理解成“AI 世界的高级 API”:它把工具、资源、提示词统一暴露给模型客户端,模型侧不用关心你底层是 REST 还是数据库,只要按协议发现并调用即可。

我手头有个商品查询服务,原本是三个 FastAPI 路由:列表、详情、创建。迁移目标很明确——保留原有 HTTP 接口给前端用,同时让 Claude Desktop、Cline 这类 MCP 客户端能直接看到list_items、get_item、create_item三个工具。FastMCP 2.0 提供了FastMCP.from_fastapi(app=app),一行代码把 FastAPI 的 OpenAPI 描述转成 MCP 工具定义,省掉手写 schema 的功夫。

适合谁看:写过 FastAPI、想快速验证 MCP 工具链的 Python 后端;已经在用 Cline / Claude Code、想把自己内部接口接进 Agent 的开发者。前置只需要 Python 3.10+、pip install fastmcp,以及一个能跑 FastAPI 的本地环境。下面所有代码我都实测过,版本是 FastMCP 2.0,1.x 的装饰器行为差异较大,建议直接对齐 2.0。

2. TaoToken 前置:统一 Key 与 API 通道,让模型侧调用不散落

MCP Server 本身只负责“暴露工具”,真正发起模型调用的是客户端侧。问题在于:Claude Code、Cline、Codex 这些客户端各自要配 Base URL、API Key、Model ID,如果每个工具项目都单独申请一套,Key 管理会非常乱。我的做法是用 TaoToken 作为统一入口,把模型调用通道收敛到一个 Key 上。

TaoToken 的定位是模型 API 聚合与统一接入层,官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api (这个地址不加 UTM)。你需要在控制台创建一个 API Key,然后把它填到各个 MCP 客户端的配置里。注意:MCP Server 代码本身不直接调模型,所以 FastMCP 服务端不需要 TaoToken Key;Key 是给“消费 MCP 工具的模型客户端”用的。

具体动作分三步。第一步,打开控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 创建 Key,复制保存。第二步,在 API Keys 页面 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 确认 Key 状态为启用。第三步,如果你用 Claude Code 或 Cline,把 Base URL 填https://taotoken.net/api,Key 填刚创建的,Model ID 按文档里列出的可用模型填。这样模型侧走 TaoToken,MCP 工具侧走本地 FastMCP,两边解耦,换模型不用改工具代码。

注意:TaoToken 是合规的 API 接入通道,不要把它理解成任何形式的网络中转工具。所有配置只涉及 Base URL、Key、Model ID 三件套。

3. 可复制配置:FastMCP 服务端 + 客户端 settings 片段

先装依赖:

pip install fastmcp fastapi uvicorn httpx

服务端完整代码fastapi_mcp_server.py,直接复制可跑:

from fastapi import FastAPI from fastmcp import FastMCP app = FastAPI() @app.get("/items") def list_items(): return [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}] @app.get("/items/{item_id}") def get_item(item_id: int): return {"id": item_id, "name": f"Item {item_id}"} @app.post("/items") def create_item(name: str): return {"id": 3, "name": name} mcp = FastMCP.from_fastapi(app=app) if __name__ == "__main__": mcp.run(transport="streamable-http", host="127.0.0.1", port=4200, path="/mcp")

这里FastMCP.from_fastapi会自动读取 FastAPI 的 OpenAPI schema,把每个路由转成 MCP tool。工具名默认取路由函数名,参数从 Pydantic 模型推断。跑起来后,MCP 端点就是http://127.0.0.1:4200/mcp。

客户端侧,如果你用 Cline 或 Claude Code,配置片段如下(JSON 格式,路径按你本地实际改):

{ "mcpServers": { "fastapi-items": { "url": "http://127.0.0.1:4200/mcp", "transport": "streamable-http" } } }

模型调用通道的 settings 片段(以 Claude Code 为例,写入~/.claude/settings.json):

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "你的TaoTokenKey", "ANTHROPIC_MODEL": "按文档填ModelID" } }

三件套齐了:Base URL 是https://taotoken.net/api,Key 是控制台创建的,Model ID 按文档选。如果你用 Codex,对应写auth.json:

{ "base_url": "https://taotoken.net/api", "api_key": "你的TaoTokenKey", "model": "按文档填ModelID" }

提示:MCP Server 的url和模型 API 的base_url是两个不同东西,别混。前者指向你本地 FastMCP,后者指向 TaoToken。

4. 验证请求:用 MCP Inspector 看工具列表与调用结果

服务端跑起来后,第一件事是确认工具真的被暴露了。FastMCP 自带一个内存客户端,可以写个脚本快速验证:

import asyncio from fastmcp import Client async def main(): async with Client("http://127.0.0.1:4200/mcp") as client: tools = await client.list_tools() for t in tools: print(t.name, t.description) result = await client.call_tool("list_items", {}) print("list_items result:", result) result2 = await client.call_tool("get_item", {"item_id": 2}) print("get_item result:", result2) asyncio.run(main())

实测输出会列出list_items、get_item、create_item三个工具,list_items返回两个 item 的列表,get_item返回{"id": 2, "name": "Item 2"}。如果工具列表为空,说明from_fastapi没解析到路由,检查 FastAPI 的app是否在from_fastapi之前已经注册完所有路由。

更直观的方式是用 MCP Inspector。官方推荐npx @modelcontextprotocol/inspector,启动后填http://127.0.0.1:4200/mcp,点 Connect,左侧会显示 Tools 列表,点进去能看到每个工具的 input schema,直接填参数点 Run 就能看到返回。我试过用 Inspector 调create_item,传name=Test,返回{"id": 3, "name": "Test"},和 FastAPI 原始行为一致。

如果你在 Claude Code 里验证,先确认 MCP 配置已加载,然后对话里问“列出所有 items”,模型会调用list_items工具并返回结果。这一步能跑通,说明 FastAPI → FastMCP → 模型客户端整条链路通了。

5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth

报错一:401 Unauthorized。出现在模型客户端侧,说明 TaoToken Key 没填对或没生效。检查ANTHROPIC_API_KEY是否和 API Keys 页面里的一致,注意不要有多余空格。如果 Key 刚创建,等几秒再试。MCP Server 侧不会报 401,因为它不调模型。

报错二:local proxy failed。通常出现在客户端连 MCP Server 时,url写错或服务没启动。确认mcp.run的host和port与客户端url一致,path是/mcp不是/。如果用了streamable-http,客户端transport也要写streamable-http,写成sse会连不上。

报错三:reading choices 相关错误。这是模型返回格式解析失败,常见于 Model ID 填错或模型不支持工具调用。回到 TaoToken 文档确认该 Model ID 是否支持 function calling / tool use。如果模型不支持,MCP 工具列表能列出但调用会失败。

报错四:OAuth 相关报错。如果你在 Claude Code 里看到 OAuth 提示,说明它走了默认的 Anthropic 登录流程,没走你的 Base URL。检查settings.json里ANTHROPIC_BASE_URL是否被其他配置覆盖,环境变量优先级要确认。Codex 的auth.json同理,base_url必须显式写 TaoToken 地址。

报错五:工具列表为空。from_fastapi依赖 OpenAPI schema,如果 FastAPI 路由用了自定义 response_model 或复杂依赖,可能解析失败。先用app.openapi()打印 schema,确认路由都在paths里。实在不行,退回手动@mcp.tool()注册,把 FastAPI 函数包一层。

6. 语义一致 CTA:把工具接进模型侧,从统一 Key 开始

整条链路里,FastMCP 负责把 FastAPI 变成 MCP Server,TaoToken 负责把模型调用收敛到一个 Key。你接下来要做的,是去控制台创建 Key,然后按文档把 Base URL、Key、Model ID 填进你用的客户端。

  • 创建和管理 Key:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
  • 接入文档(含各客户端配置示例):https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
  • 想先验证模型对话是否通:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
  • 长期跑编码 Agent、需要稳定额度:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=

我自己的习惯是:FastMCP 服务端用streamable-http跑在本地 4200,客户端配置里 MCP 指向本地,模型 Base URL 指向 TaoToken。这样换模型只改一个 Model ID,工具代码一行不动。下一步你可以试试把@mcp.resource加进来,把配置文件也暴露给模型读,那又是另一个坑了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询