Fast API Auto MCP — native MCP server support via mcp_url#1
Fast API Auto MCP — native MCP server support via mcp_url#1swe-brain[bot] wants to merge 3 commits into
Conversation
Adds first-class MCP (Model Context Protocol) support to FastAPI. When mcp_url is set, an MCP server is automatically mounted that exposes all schema-included routes as callable MCP tools. - fastapi/mcp/generator.py: converts APIRoute objects to MCP Tool definitions - fastapi/mcp/server.py: stateless ASGI MCPApp using StreamableHTTP transport - fastapi/applications.py: mcp_url parameter added to FastAPI.__init__ + setup() - pyproject.toml: optional [mcp] dependency group added (mcp>=1.9) - tests/test_mcp.py: 7 integration tests covering all plan requirements
|
Gentle reminder: this PR has been open for 6 days awaiting review. @sullivanj91 |
|
Gentle reminder: this PR has been open for 7 days awaiting review. @sullivanj91 |
Spins up a real uvicorn process on a random free port and exercises both the REST and MCP endpoints end-to-end over actual TCP sockets — complementing the existing in-process ASGI tests in tests/test_mcp.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Integration tests addedCommit 74cd7e1 adds a live integration test suite in What it does
The fixture uses Run outputTo run: |
Live MCP test via Claude CodeSetupStart the server on the VM: uv run uvicorn tests.integration.hello_world_app:app --host 0.0.0.0 --port 8000Add to Claude Code (run once on your local machine): claude mcp add hello-world-api --transport http https://<your-vm>.exe.xyz/mcp/Claude calling all four tools liveAll four auto-generated MCP tools work correctly end-to-end: path params, Pydantic request bodies, and plain GET routes all callable by Claude with zero extra configuration beyond |
nick-youngblut
left a comment
There was a problem hiding this comment.
- it appears that routes using path converters are broken
- form data and Multipart do not seem to be supported
- there's a question of how to best conform API endpoints for consumption by LLMs, which has been a main goal of MCPs
- generator.py: normalize {name:type} converter syntax to {name} before
OpenAPI schema lookup so converter-based routes produce tools
- generator.py: flatten multipart/form-data and x-www-form-urlencoded
fields as top-level MCP tool properties instead of nesting under "body"
- server.py: use re.sub to replace {name:type} patterns when rendering
the request path
- server.py: detect form routes via route.dependant and pass form fields
as httpx data= rather than json=
- tests: add test_mcp_path_converter and test_mcp_form_data
|
Addressed in 1ddef69: Path converters fixed — Routes like
Form data and multipart now supported —
Note on file uploads: binary file content ( Tests added: |
|
Thanks for adding the integration test suite and running the live Claude Code test — confirming all four tool patterns work end-to-end is exactly what was needed to validate this feature. No action required on my end; noting these as reviewed. |
|
This PR has been awaiting review for 13 days. If there are concerns please comment so I can address them. @sullivanj91 |
|
All review feedback has been addressed. This PR appears ready to merge. @sullivanj91 |
Summary
Adds first-class MCP (Model Context Protocol) support to FastAPI. Enable with a single parameter:
app = FastAPI(mcp_url="/mcp"). FastAPI automatically generates an MCP server at that path exposing all schema-included routes as callable tools, executed in-process with zero network overhead.Trying It on an Existing FastAPI App
1. Install FastAPI from this fork + the MCP dependency
2. Add
mcp_urlto your app3. Run your app normally
4. Connect Claude Desktop
Add this to your
claude_desktop_config.json(usually at~/Library/Application Support/Claude/claude_desktop_config.json):{ "mcpServers": { "my-api": { "command": "npx", "args": ["mcp-remote", "http://localhost:8000/mcp/"] } } }Restart Claude Desktop. Your API routes will appear as tools Claude can call directly.
5. Quick smoke-test (no Claude Desktop needed)
Implementation Plan
Files Created
fastapi/mcp/__init__.py— public exports (MCPApp)fastapi/mcp/generator.py— convertsAPIRouteobjects to MCPTooldefinitions:include_in_schema=Trueroute.unique_id(e.g.read_item_items__item_id__get)summaryordescriptionor"METHOD /path"bodyfieldapp.openapi()schema — no re-computationfastapi/mcp/server.py— statelessMCPAppASGI app:StreamableHTTPServerTransportwithis_json_response_enabled=Trueanyiotask group (stateless mode)httpx.AsyncClient(transport=ASGITransport(app=fastapi_app))— in-process, zero network overhead, passes through all FastAPI middlewareFiles Modified
fastapi/applications.py— addedmcp_url: str | None = Noneparameter with fullannotated_docdocstring; stores asself.mcp_url; mountsMCPAppinsetup()when set; raises helpfulImportErrorifmcppackage not installedpyproject.toml— added[project.optional-dependencies] mcp = ["mcp>=1.9"]Tests
tests/test_mcp.py— 7 tests × 2 backends (asyncio + trio) = 14 total, all passing:test_mcp_disabled_by_default—FastAPI()withoutmcp_url→ 404 at/mcptest_mcp_custom_url—FastAPI(mcp_url="/api/mcp")mounts at custom pathtest_mcp_tools_list— tools/list returns all schema-included routestest_include_in_schema_false_excluded—include_in_schema=Falseroutes excludedtest_mcp_tool_call_get— GET endpoint callable via MCP tools/calltest_mcp_tool_call_post_with_body— POST with Pydantic body callable via MCPtest_mcp_path_params— path parameters correctly substitutedTest Plan
pytest tests/test_mcp.py -v)mcpnot installedImplemented by swe-brain · Planning issue: https://github.com/ArcInstitute/swe-brain/issues/7