1. 为什么 FastMCP 对接 OpenAPI 总在配置这一步卡住
FastMCP 是 Python 生态里把普通函数、REST 接口快速包装成 MCP 服务的轻量框架,OpenAPI 则是描述 REST 接口的标准规范。把两者接起来,理论上只要FastMCP.from_openapi()一行就能把几十个接口变成 MCP 工具,但真正落地时,卡人的往往不是这行代码,而是它周围的配置文件:config.toml里模型通道怎么填、settings.json里 MCP Server 怎么注册、统一 Key 怎么让 FastMCP 生成的工具在调用外部 API 时不用每个接口单独配密钥。
这篇是「快速手搓一个 MCP 服务指南」系列的第八篇,聚焦 FastMCP 与 OpenAPI 集成时的配置文件落地。适合已经写过一两个 MCP Server、想让现有 REST API 快速变成 MCP 工具、并且希望用一套统一 Key 打通「API 到 MCP 链路」的开发者。下面从目录结构开始,给出可直接复制的config.toml、settings.json骨架,再演示如何用 TaoToken 的统一 Key 接入 AI 工具,最后跑一次真实请求验证整条链路。
2. TaoToken 前置:统一 Key 与 API 通道准备
FastMCP 生成的 MCP 工具在调用后端 OpenAPI 时,需要携带认证信息。如果每个接口都单独配 Key,配置文件会迅速膨胀。TaoToken 提供统一 Key 和统一 API 通道,让 FastMCP 侧只认一个地址、一个 Key,后端具体路由由通道层处理。
先到官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册并进入控制台,在 API Keys 页面创建一个 Key。这个 Key 就是后面config.toml里api_key字段的值。控制台地址:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
创建完成后,API 基础地址统一用 https://taotoken.net/api(不加 UTM)。这个地址会作为 FastMCP 里httpx.AsyncClient的base_url,也是config.toml中base_url的值。如果你后续要接 Claude Code 这类编码工具,可以在 Coding Plan 页面查看套餐:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite
注意:Key 只创建一次,复制后妥善保存。控制台不会再次完整显示,丢失只能重新生成。
3. 可复制配置:config.toml 与 settings.json 骨架
先建目录结构,保持配置和代码分离:
fastmcp-openapi-demo/ ├── config.toml ├── settings.json ├── server.py └── openapi.json3.1 config.toml 骨架
config.toml负责模型通道和统一 Key,FastMCP 侧读取后用于构造带认证的 HTTP 客户端。
[api] base_url = "https://taotoken.net/api" api_key = "sk-你的TaoTokenKey" timeout = 30.0 [mcp] server_name = "openapi-bridge" transport = "stdio" [openapi] spec_path = "./openapi.json" route_prefix = "/v1"base_url和api_key是核心。timeout控制所有请求的超时,避免某个慢接口拖垮整个 MCP Server。spec_path指向本地 OpenAPI 规范文件,也可以换成远程 URL。
3.2 settings.json 骨架
settings.json负责把 MCP Server 注册到 AI 工具里,不同客户端字段名略有差异,下面以通用结构为例:
{ "mcpServers": { "openapi-bridge": { "command": "python", "args": ["server.py"], "env": { "TAOTOKEN_API_KEY": "sk-你的TaoTokenKey", "TAOTOKEN_BASE_URL": "https://taotoken.net/api" } } } }这里把 Key 通过环境变量注入,避免硬编码进server.py。command和args根据你实际运行方式调整,用uv的话可以换成uv run server.py。
3.3 server.py 读取配置并生成 MCP
import json import tomllib import httpx from fastmcp import FastMCP with open("config.toml", "rb") as f: cfg = tomllib.load(f) api_cfg = cfg["api"] mcp_cfg = cfg["mcp"] client = httpx.AsyncClient( base_url=api_cfg["base_url"], headers={"Authorization": f"Bearer {api_cfg['api_key']}"}, timeout=api_cfg["timeout"], ) with open(cfg["openapi"]["spec_path"], "r", encoding="utf-8") as f: openapi_spec = json.load(f) mcp = FastMCP.from_openapi( openapi_spec=openapi_spec, client=client, name=mcp_cfg["server_name"], ) if __name__ == "__main__": mcp.run(transport=mcp_cfg["transport"])这段代码把配置读取、客户端构造、MCP 生成串起来。Authorization头统一带上 TaoToken Key,后端 OpenAPI 接口不需要再各自处理认证。
4. 验证请求:从 OpenAPI 规范到 MCP 工具调用
配置写完后,先确认 OpenAPI 规范能被正确解析。准备一个最小openapi.json:
{ "openapi": "3.0.0", "info": {"title": "Demo API", "version": "1.0.0"}, "paths": { "/v1/items": { "get": { "operationId": "list_items", "summary": "列出条目", "responses": {"200": {"description": "OK"}} } } } }启动 MCP Server:
python server.py如果走 stdio 传输,进程会等待客户端连接。用 MCP 客户端或支持 MCP 的 AI 工具连接后,应该能看到list_items这个工具。调用它:
result = await client.call_tool("list_items", {}) print(result)请求实际发往https://taotoken.net/api/v1/items,带上Authorization: Bearer sk-...。返回结果与直接调 REST 接口一致,说明「OpenAPI 规范 → MCP 工具 → 统一 Key 通道」这条链路已经打通。
想先在对话里验证模型通道是否正常,可以打开模型对话页面:https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite
5. 本篇常见错排查
5.1 config.toml 解析报错
tomllib是 Python 3.11 才内置的,低版本会ModuleNotFoundError。要么升级 Python,要么装tomli并改导入:
try: import tomllib except ModuleNotFoundError: import tomli as tomllib5.2 401 或 403
先检查config.toml里api_key是否有多余空格,再确认base_url是https://taotoken.net/api而不是带路径的地址。环境变量注入时,settings.json的env字段名要和server.py读取的一致。
5.3 工具列表为空
多半是openapi.json里paths为空,或者operationId缺失。FastMCP 默认用operationId生成工具名,没有它可能跳过该接口。补上operationId后重启。
5.4 超时
timeout设太小,慢接口会直接失败。先在config.toml里调到 30 秒以上,再针对单个接口做超时覆盖。如果后端确实慢,考虑在 OpenAPI 规范里给该接口加x-timeout扩展,FastMCP 侧读取后单独处理。
5.5 路径前缀重复
base_url已经带了/api,OpenAPI 里路径又写/api/v1/items,会拼成/api/api/v1/items。统一在base_url里保留到域名,路径前缀交给 OpenAPI 规范管理。
6. 继续把链路用起来
配置骨架跑通后,下一步是把更多 OpenAPI 规范接进来,用route_maps排除敏感端点、用mcp_names把operationId改成更友好的工具名。需要长期跑编码或 Agent 任务的话,Coding Plan 页面有更完整的通道说明:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite
接入文档里有 FastMCP、OpenAPI、MCP 客户端注册的完整字段说明,遇到配置字段对不上时直接查:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
Key 管理和重新生成在 API Keys 页面:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite
我自己的习惯是:每加一个 OpenAPI 规范,先在config.toml里单独开一个[openapi.xxx]段,跑通一个再合并,避免一次性接太多接口导致排查困难。