如何在 FastAPI-MCP 中注入自定义 httpx.AsyncClient 让 MCP 工具指向远程 API 地址?
【免费下载链接】fastapi_mcpExpose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi_mcp
当你不想让业务 API 和 MCP 服务跑在同一台机器上时,会碰到一个问题:FastAPI-MCP 默认通过 ASGI 直接在进程内调用你的 FastAPI 应用,根本不发 HTTP 请求,也就没有"指向哪个地址"这一说。如果你的 FastAPI 应用实际部署在远程服务器上,MCP 工具调用就不会到达它。解决办法是向FastApiMCP注入一个自定义的httpx.AsyncClient,并把base_url设为远程 API 地址——这样 MCP 工具执行时就会通过真实 HTTP 请求访问远程端点。
先理解默认行为:为什么需要注入自定义客户端
Transport 说明文档指出:
- FastAPI-MCP 默认使用ASGI 传输,直接与 FastAPI 应用通信,不发出 HTTP 请求,也不需要 base URL,此时 FastAPI 服务甚至不需要真正运行;
- 如果你需要指定自定义 base URL或使用不同的传输方式,就可以提供自己的
httpx.AsyncClient。
从源码 fastapi_mcp/server.py 可以看到:不传http_client时,内部会自建一个使用httpx.ASGITransport(app=...)的客户端,进程内直连你的应用;一旦传入自定义客户端,工具调用就改为按你传入的base_url发起 HTTP 请求。
因此,让 MCP 工具指向远程 API 的关键就是:app对象只作为生成工具定义(OpenAPI 模式)的来源,真正的请求由你注入的客户端发往远程地址。
准备条件
安装 FastAPI-MCP(安装文档):
uv add fastapi-mcp也可以用pip install fastapi-mcp或uv pip install fastapi-mcp。
另外你需要一个可导入的 FastAPIapp对象。它不需要在本机运行,仓库示例 examples/04_separate_server_example.py 中就用注释说明了这一点:"Take the FastAPI app only as a source for MCP server generation"(FastAPI 应用只作为 MCP 服务器的生成来源)。
注入自定义 httpx.AsyncClient
按 docs/advanced/asgi.mdx 给出的方式,创建客户端并传给FastApiMCP:
import httpx from fastapi import FastAPI from fastapi_mcp import FastApiMCP app = FastAPI() custom_client = httpx.AsyncClient( base_url="https://api.example.com", timeout=30.0 ) mcp = FastApiMCP( app, http_client=custom_client ) mcp.mount()其中base_url="https://api.example.com"是文档中的示例值,替换成你的远程 API 实际地址;工具调用时,MCP 服务器会在该 base URL 后拼接各端点路径发起请求。timeout用于控制每次工具调用的超时,如果你的端点响应较慢,可以相应调大(见下文"调整超时"一节)。
如果客户端需要走 MCP 推荐的 Streamable HTTP 传输,也可以按 MCP Transport 文档把mcp.mount()换成mcp.mount_http(),两者支持相同的 FastAPI 集成能力(自定义路由、认证等)。
启动服务
参考 快速开始文档 的运行方式,添加启动入口:
if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)用python fastapi_mcp_server.py(换成你的文件名)运行后,MCP 服务提供在http://localhost:8000/mcp。注意这里启动的是承载 MCP 服务的应用实例,而工具调用会被转发到base_url指向的远程 API——两者是分开的。
验证:工具调用是否真的走了远程 API
FAQ 文档 给出用 MCP Inspector 验证 MCP 服务器是否正常工作的方法:
启动你的 FastAPI 应用;
打开新终端运行 MCP Inspector:
npx @modelcontextprotocol/inspector输入挂载路径 URL 连接你的 MCP 服务器(默认
http://127.0.0.1:8000/mcp);进入
Tools区域点击List Tools,应能看到由app的端点生成的全部工具;选择某个工具、填入参数,点击
Run Tool执行;如有问题,查看服务器日志辅助排查。
如果你的 MCP 客户端支持 SSE/HTTP,也可以直接按 Quickstart 中的配置格式连接,例如 Claude Desktop、Cursor 等客户端使用的配置:
{ "mcpServers": { "fastapi-mcp": { "url": "http://localhost:8000/mcp" } } }Run Tool返回的结果来自远程 API 端点的响应,可以据此判断请求确实到达了远程地址(例如在远程端点加日志观察请求来源)。
可选分支:调整工具调用的超时时间
仓库中的 examples/07_configure_http_timeout_example.py 展示了只改超时的用法——当你的 API 端点响应超过默认时限(该示例注释与 FAQ 均描述默认为 5 秒;源码中默认客户端的timeout值为10.0,两处略有出入,但注入自定义客户端后以你传入的值为准)时:
from examples.shared.apps.items import app # The FastAPI app from examples.shared.setup import setup_logging import httpx from fastapi_mcp import FastApiMCP setup_logging() mcp = FastApiMCP(app, http_client=httpx.AsyncClient(timeout=20)) mcp.mount_http() if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)这个示例没有设置base_url,仍走进程内 ASGI 调用;把它和你前面的base_url用法组合,就能同时指定远程地址与超时。
限制与注意事项
- 工具列表由传入的
app的 OpenAPI 模式生成(源码 中setup_server基于self.fastapi.routes转换),所以远程 API 的路径结构需要与这个app一致;FastApiMCP目前只支持由 FastAPI 端点派生的工具(见 FAQ)。 - 如果在创建并挂载 MCP 服务器之后又给
app新增了端点,新端点不会自动注册为工具,需要调用mcp.setup_server()重新注册(见 Refreshing 文档)。 - 不要把"远程 API 不可用"与"MCP 服务器启动失败"混为一谈:MCP 服务器本身正常启动并列出工具不代表远程端点可达,
Run Tool时才暴露远程连通性问题,可结合服务器日志排查。
【免费下载链接】fastapi_mcpExpose your FastAPI endpoints as Model Context Protocol (MCP) tools, with Auth!项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi_mcp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考