## The Problem FastAPI services often need to expose their endpoints to external tooling that follows the Model Context Protocol (MCP). Building a custom bridge requires manual OpenAPI conversion, authentication wiring, and an additional transport layer, which is error‑prone and duplicates effort across projects.
## What This Does fastapi_mcp turns a regular FastAPI app into an MCP‑compatible server with built‑in authentication. The core package lives under fastapi_mcp/:
fastapi_mcp/__init__.py– defines the publicFastApiMCPclass and re‑exports helpers; 16 other modules import it, making it the primary entry point.fastapi_mcp/server.py– implementsmount(),mount_http(),mount_sse(), and the request handlershandle_call_tool,handle_post_message, etc.fastapi_mcp/openapi/convert.pyandutils.py– translate FastAPI’s OpenAPI schema into MCP tool definitions while preserving request/response models.fastapi_mcp/transport/http.pyandsse.py– provide ASGI‑based transports; the HTTP path makes an outbound request viaclient.get(network call).
Example applications in examples/ show zero‑configuration usage (examples/01_basic_usage_example.py) and more advanced scenarios such as custom authentication (examples/09_auth_example_auth0.py).
## How It Is Wired Execution normally starts in examples/shared/setup.py:
from fastapi import FastAPI
from fastapi_mcp import FastApiMCP
app = FastAPI()
mcp = FastApiMCP(app)
mcp.mount() # → fastapi_mcp/server.py:mount
mount() (line 426) registers the MCP endpoint routes and then calls a chain of eleven internal functions, most notably handle_call_tool (line 151) and handle_mcp_streamable_http (line 245). These handlers are the only functions not referenced elsewhere, meaning they form the public API surface.
The internal call graph shows:
FastApiMCPis invoked from 24 places (tests, examples, docs).convert_openapi_to_mcp_toolsis called 10 times, driving the OpenAPI‑to‑MCP conversion._execute_api_tool(used byhandle_call_tool) reaches_request, which triggers an outbound HTTP call (client.get) – the sole network‑leaving operation.
fastapi_mcp/__init__.py acts as a hub (16 dependents, instability 0.11). Any change here has a wide blast radius. Conversely, examples/shared/apps/items.py and the OpenAPI utilities have high branching density and deep nesting (max indentation depth 11), which complicates future modifications.
## How To Use It
- Install – the project uses a
pyproject.toml; the README recommends the fast installer uv:
uv add fastapi-mcp
or the classic pip alternative:
pip install fastapi-mcp
- Add to a FastAPI app – see
examples/shared/setup.pyfor the minimal pattern:
from fastapi import FastAPI
from fastapi_mcp import FastApiMCP
app = FastAPI()
FastApiMCP(app).mount()
- Optional authentication – the
fastapi_mcp/auth/package supplies OAuth proxy helpers. Exampleexamples/09_auth_example_auth0.pydemonstrates configuring JWKS and OAuth metadata URLs; no extra env‑var handling is baked into the core library.
- Run – start the FastAPI app as usual (
uvicorn examples.shared.setup:app). The MCP endpoint will be reachable at<base>/mcp.
## Real‑World Use A microservice exposing a product catalog can be wrapped with FastApiMCP. The service continues to serve its REST API, while an MCP client can invoke list_items or read_item through the MCP tool set without additional HTTP round‑trips, because the transport uses FastAPI’s ASGI interface directly.
## Code Health & Issues
- High – Pin GitHub Actions –
.github/workflows/*.ymluses tags (astral-sh/setup-uv@v5,codecov/codecov-action@v5). Replace with commit SHAs to avoid supply‑chain drift. - Medium – Least‑privilege GITHUB_TOKEN –
.github/workflows/ci.ymldeclares no permissions; addpermissions: contents: read(and tighten per job). - Medium – Dependency‑vulnerability gate – No scan step in CI; integrate
dependency-review-actionorosv-scanner. - Medium – Checkout persist‑credentials –
.github/workflows/release.ymlshould setpersist-credentials: falseand supply a token only to the push step. - Low – Job timeouts –
.github/workflows/ci.ymllackstimeout-minutes; set a reasonable bound to prevent overlapping runs.
Additional static findings:
- Broad
except:blocks infastapi_mcp/__init__.py,transport/http.py, and a test file – replace with specific exception handling. - High branching density in
examples/shared/apps/items.pyand OpenAPI utilities – consider extracting strategy tables. - Deep nesting (up to 11 levels) in
openapi/convert.py,server.py, andtransport/http.py– refactor with guard clauses. - Duplicated 6‑line code snippets across auth proxy, types, and several tests – centralise in a helper module.
- Six
TODO/FIXMEmarkers remain infastapi_mcp/server.py– triage or resolve.
No lockfile is present (pyproject.toml only), which makes reproducible builds non‑deterministic.
## The Bottom Line fastapi_mcp provides a pragmatic, FastAPI‑native way to expose MCP tools with minimal configuration and built‑in auth support. The core wiring is clear, but the hub module and several deeply nested files raise maintenance risk. The repo ships a solid test suite and CI, yet it lacks a lockfile and has several high‑severity hygiene gaps in its GitHub Actions setup. It is suitable for teams already using FastAPI that need MCP integration, provided they address the listed security and maintainability concerns.