## 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 public FastApiMCP class and re‑exports helpers; 16 other modules import it, making it the primary entry point.
  • fastapi_mcp/server.py – implements mount(), mount_http(), mount_sse(), and the request handlers handle_call_tool, handle_post_message, etc.
  • fastapi_mcp/openapi/convert.py and utils.py – translate FastAPI’s OpenAPI schema into MCP tool definitions while preserving request/response models.
  • fastapi_mcp/transport/http.py and sse.py – provide ASGI‑based transports; the HTTP path makes an outbound request via client.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:

  • FastApiMCP is invoked from 24 places (tests, examples, docs).
  • convert_openapi_to_mcp_tools is called 10 times, driving the OpenAPI‑to‑MCP conversion.
  • _execute_api_tool (used by handle_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

  1. 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
  1. Add to a FastAPI app – see examples/shared/setup.py for the minimal pattern:
   from fastapi import FastAPI
   from fastapi_mcp import FastApiMCP

   app = FastAPI()
   FastApiMCP(app).mount()
  1. Optional authentication – the fastapi_mcp/auth/ package supplies OAuth proxy helpers. Example examples/09_auth_example_auth0.py demonstrates configuring JWKS and OAuth metadata URLs; no extra env‑var handling is baked into the core library.
  1. 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/*.yml uses 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.yml declares no permissions; add permissions: contents: read (and tighten per job).
  • Medium – Dependency‑vulnerability gate – No scan step in CI; integrate dependency-review-action or osv-scanner.
  • Medium – Checkout persist‑credentials – .github/workflows/release.yml should set persist-credentials: false and supply a token only to the push step.
  • Low – Job timeouts – .github/workflows/ci.yml lacks timeout-minutes; set a reasonable bound to prevent overlapping runs.

Additional static findings:

  • Broad except: blocks in fastapi_mcp/__init__.py, transport/http.py, and a test file – replace with specific exception handling.
  • High branching density in examples/shared/apps/items.py and OpenAPI utilities – consider extracting strategy tables.
  • Deep nesting (up to 11 levels) in openapi/convert.py, server.py, and transport/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/FIXME markers remain in fastapi_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.