Expose Your FastAPI Endpoints as MCP Tools—With Built‑In Auth and Almost No Config
If you’re building AI features today, you’ve probably felt the friction. You already have a clean FastAPI app, but turning those endpoints into tools an AI agent can call—securely, reliably, and with real schema guarantees—can feel like rebuilding your house just to add a door.
What if you could point a helper at your FastAPI app and instantly expose your endpoints as Model Context Protocol (MCP) tools? And what if authentication, schema preservation, and docs came along for the ride?
That’s exactly what FastAPI-MCP does. It’s a FastAPI‑native bridge to MCP that respects your models, reuses your auth dependencies, and speaks ASGI directly—no HTTP hop, no brittle converters, almost no config.
In this guide, I’ll show you how it works, why it’s different, and how to wire it up in minutes.
Quick primer: What is the Model Context Protocol (MCP)?
MCP is an open protocol that lets AI models discover and call tools in a structured, predictable way. Think of MCP as the “USB standard” for AI tools: a shared interface for functions and data sources that models can depend on—across vendors, runtimes, and deployments.
- Learn more: Model Context Protocol
- Background: Anthropic’s announcement of MCP
In practice, MCP unblocks a lot of teams: you can make your existing services available to AI agents with well-defined schemas, strict auth, and clean documentation—without re-platforming.
Why FastAPI-MCP? FastAPI‑native, secure, and zero‑to‑one in minutes
FastAPI-MCP is not “just another OpenAPI → MCP converter.” It’s a FastAPI‑first extension that connects your existing app to MCP, with the benefits you actually want:
- Built‑in authentication using your existing FastAPI dependencies (Depends)
- Native FastAPI integration—no fragile conversion step
- Zero/minimal configuration: point it at your app and it works
- Schema‑true: preserves request and response models as JSON Schema
- Documentation‑true: carries over your summaries, descriptions, and examples
- Flexible deployment: mount to the same app or deploy separately
- ASGI transport: talks to your app directly—no HTTP loopback, no extra hops
Here’s why that matters. A lot of “glue” solutions generate new tool definitions from OpenAPI and sit next to your app. That introduces drift (docs vs reality), adds runtime latency (HTTP proxying), and bypasses your actual auth logic. FastAPI-MCP takes the opposite route: it stays inside your FastAPI universe and leverages what you already built.
If you prefer a managed path, there’s also a hosted option: tadata.com.
Installation in seconds
We recommend uv, a very fast Python package installer:
uv add fastapi-mcp
Prefer pip? That works too:
pip install fastapi-mcp
Requirements: Python 3.10+ (we recommend 3.12 for performance and typing).
The 60‑second setup: turn your app into an MCP server
The simplest way to use FastAPI-MCP is to add an MCP server directly to your FastAPI application:
from fastapi import FastAPI
from fastapi_mcp import FastApiMCP
app = FastAPI()
mcp = FastApiMCP(app)
# Mount the MCP server directly to your FastAPI app
mcp.mount()
That’s it. Your auto‑generated MCP server is now available at https://app.base.url/mcp.
No extra routers. No Schema voodoo. Just a native ASGI component that your FastAPI app recognizes.
How it works under the hood (without the hand‑waving)
Let’s make this concrete.
- FastAPI knows your schemas. You likely rely on Pydantic models to define request bodies and response shapes. FastAPI-MCP reads those models and exposes them as MCP tool parameters and result schemas—faithfully.
- FastAPI knows your docs. Summaries, descriptions, and examples you’ve already written for your endpoints are preserved. What your team sees in Swagger is what the AI agent sees in MCP.
- FastAPI knows your security. You use
Depends(...)
for authentication/authorization. FastAPI-MCP reuses those dependencies at tool call time. If a user can’t hit the endpoint, they can’t call the tool. - ASGI all the way down. FastAPI-MCP uses your app’s ASGI interface directly. That means no HTTP loopback, lower latency, and a simpler mental model. One process, one runtime, one set of middlewares.
Because the tool definitions derive from your actual FastAPI routes, there’s no “generator drift.” Update a schema, add a field, or tweak your docs and your MCP surface updates naturally.
FastAPI authentication—applied to MCP tools
Security is often where tool bridges crumble. FastAPI-MCP leans into FastAPI’s native dependency injection so you can keep your exact auth logic.
Here’s a simple example with an API token:
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi import APIRouter
router = APIRouter()
auth_scheme = HTTPBearer()
async def require_token(
creds: HTTPAuthorizationCredentials = Depends(auth_scheme),
):
if creds.credentials != "super-secret-token":
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
@router.get("/reports/summary", summary="Get account summary")
async def get_summary(_: None = Depends(require_token)):
return {"accounts": 3, "balance": 4200.50}
- You’re using
Depends(require_token)
exactly as you would for any endpoint. - FastAPI-MCP respects this. Calls to the MCP tool representing
/reports/summary
must pass the same auth check. - You’re not maintaining two parallel auth systems, and there’s no “bypass” path through MCP.
Need OAuth2, scopes, or role checks? You can follow FastAPI’s standard security patterns: – FastAPI Security: OAuth2, JWT, and scopes
If it works for your REST endpoints, it works for your MCP tools.
Zero/minimal config—what “just works” out of the box
By default, FastAPI-MCP will:
- Discover routes from your FastAPI app
- Extract request and response models from your endpoint signatures
- Convert those Pydantic models into JSON Schema for MCP
- Carry over endpoint metadata (summary, description, examples)
- Create an MCP server mounted at
/mcp
(customizable) - Use your app’s middleware, dependencies, and error handlers
In other words, if you’re already using FastAPI “the FastAPI way,” you get a clean MCP interface with very little ceremony.
FastAPI-MCP vs. OpenAPI converters: what you avoid
A lot of teams try the “OpenAPI to tools” route first. It works—until it doesn’t.
Here are the biggest pitfalls that FastAPI-MCP avoids:
- Divergence. Generated tools can lag behind your actual code. Documentation lies, and models drift. FastAPI-MCP derives from your real runtime, not a static file.
- Duplicate auth. Converters often require new API keys or proxy layers. With FastAPI-MCP, your existing
Depends(...)
apply directly. - Extra latency. HTTP loopback (MCP → reverse proxy → REST) adds overhead and fails in tricky ways under load. ASGI transport keeps the call in‑process.
- Narrow features. Converters don’t always preserve examples, descriptions, or fine-grained model semantics. FastAPI-MCP keeps what you authored.
To be fair, OpenAPI is excellent for many things—client SDK generation, docs, spec‑driven development. It’s just not a perfect substrate for AI tools without the rest of your FastAPI behavior. If you’re curious, see OpenAPI and FastAPI’s docs.
Flexible deployment: same app or separate process
You have options for where the MCP server runs:
- Same app, same process. This is the simplest path. Call
mcp.mount()
on your app and you’re done. Pros: lowest latency, shared infra, fewer moving pieces. - Separate deployment. If you want to isolate the MCP surface (for scaling, security zones, or traffic shaping), you can deploy it as its own service. FastAPI-MCP supports pointing the MCP server at your existing FastAPI app while running in a separate process. Consult the project docs for the exact setup and best practices.
Both approaches are enabled by the library’s ASGI‑first design. You’re free to pick the topology that fits your environment and compliance posture.
Real‑world example: turning a service into MCP tools
Let’s imagine a normal FastAPI service that manages users and invoices.
from typing import List
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
app = FastAPI(title="Billing API", description="Manage users and invoices")
class InvoiceCreate(BaseModel):
user_id: str
amount_cents: int
description: str | None = None
class Invoice(BaseModel):
id: str
user_id: str
amount_cents: int
status: str
async def require_staff():
# Pretend we checked a token, a DB, etc.
...
@app.post("/invoices", response_model=Invoice, summary="Create an invoice")
async def create_invoice(
payload: InvoiceCreate,
_auth: None = Depends(require_staff),
):
return Invoice(id="inv_123", user_id=payload.user_id, amount_cents=payload.amount_cents, status="open")
@app.get("/invoices/{invoice_id}", response_model=Invoice, summary="Get invoice by ID")
async def get_invoice(invoice_id: str, _auth: None = Depends(require_staff)):
# Fetch from DB; mocked here
if invoice_id != "inv_123":
raise HTTPException(status_code=404, detail="Not found")
return Invoice(id=invoice_id, user_id="usr_88", amount_cents=9999, status="paid")
Now add FastAPI-MCP:
from fastapi_mcp import FastApiMCP
mcp = FastApiMCP(app)
mcp.mount()
What you get:
- An MCP tool to create invoices that accepts the
InvoiceCreate
schema and returns theInvoice
schema - An MCP tool to fetch an invoice by ID (with the path parameter correctly typed)
- Your
require_staff
auth applied to both tools - The summaries (“Create an invoice”, “Get invoice by ID”) shown in the tool registry for easier discoverability by models
No duplicate validation, no proxy, no hand‑made tool wrappers.
Performance: ASGI transport means less overhead
Because FastAPI-MCP uses your app’s ASGI interface, you avoid the double serialization and network tax of “MCP proxy calls your REST API.”
Practically, that means: – Lower latency per tool call – Fewer sockets and TLS handshakes – Shared event loop and worker pool (e.g., Uvicorn + Starlette) – One set of observability, rate limiting, and logging middleware
If performance and simplicity matter, removing a hop is a big deal. If you’re curious about the underlying stack, check out ASGI and Starlette.
Documentation that AI can actually use
Schema is half the story. Good prompts begin with good human‑authored docs: – Endpoint summaries set purpose (“Create an invoice” vs. “Create record”) – Descriptions add nuance (“amount in cents to avoid floating point issues”) – Examples reduce guesswork (payload and response samples)
FastAPI-MCP preserves your FastAPI docs so agents see the same truth you show in Swagger. For a deeper dive on how FastAPI structures docs, see the FastAPI docs.
Here’s a tip: keep endpoint summaries short and action‑oriented. Use descriptions for constraints and business rules. Include at least one example in your request models for tricky fields.
Hosted option: let someone else run it
Not every team wants to host their MCP layer. If you prefer a managed service, take a look at tadata.com. You get the benefits of FastAPI-MCP without owning the uptime and scaling story yourself.
Advanced patterns and tips
As your usage grows, a few patterns will help you stay organized and safe.
- Curate your tool surface
- Only expose endpoints that are safe and useful for agents. Consider a “tools” router or tag.
- Keep destructive operations behind stronger auth and explicit allow‑lists.
- Validate human intent where it matters
- Use idempotency keys and confirmation flows for high‑risk actions (e.g., payments, deletes).
- Leverage FastAPI’s middleware
- Apply observability, rate limiting, or request logging globally so both REST and MCP paths benefit.
- Design with schema clarity
- Prefer structured enums and constrained types over free‑form strings. Models are more reliable when the schema is explicit.
- Treat errors as part of your API
- Return informative error bodies. Clear, typed errors help models learn how to retry or escalate.
Because FastAPI-MCP is FastAPI‑native, most of these are just “good FastAPI hygiene” that carry over to MCP.
Development, community, and contributions
FastAPI-MCP is community‑friendly. Contributions are welcome—bug fixes, docs, and examples all help the ecosystem. Before you dive in: – Read the project’s Contribution Guide in the repository – Open Issues for questions and feature requests – Join the wider MCP conversation in the MCParty Slack (community for MCP enthusiasts)
For MCP itself, you’ll find specs, examples, and reference clients here: – Model Context Protocol
End‑to‑end checklist: from “hello” to production
Use this quick checklist when you’re ready to ship:
- Install with uv or pip.
- Initialize the MCP server with
FastApiMCP(app)
and callmcp.mount()
. - Confirm the MCP endpoint is reachable at
/mcp
. - Audit which routes you want to expose; tag or isolate if needed.
- Add or verify auth dependencies (
Depends(...)
) for every route you expose. - Tighten schemas: enums, min/max, formats—make ambiguity impossible.
- Add concise summaries and meaningful descriptions; include examples for complex models.
- Run load tests to verify latency (ASGI path) and error handling.
- Wire up logging and rate limiting middleware if you haven’t already.
- Deploy—either alongside your app or as a separate service depending on your infra.
- Connect your MCP‑aware client/agent and test real workflows end‑to‑end.
Frequently Asked Questions (FAQ)
- What is MCP in simple terms?
- MCP (Model Context Protocol) is a standard way for AI models to discover and call tools. It defines how tools describe their inputs/outputs and how clients connect and invoke them. See the official site: modelcontextprotocol.dev.
- How is FastAPI-MCP different from an OpenAPI → tools converter?
- It’s FastAPI‑native. It reads your actual routes, models, docs, and dependencies at runtime. There’s no separate generator step, less drift, and no extra HTTP proxy layer.
- Does it preserve my Pydantic models and Swagger docs?
- Yes. Request/response models become MCP schemas, and your summaries/descriptions carry over. What you see in Swagger is what the AI sees in MCP.
- How does authentication work?
- FastAPI-MCP uses your existing FastAPI dependencies (
Depends(...)
). If an endpoint requires a token or a role, the corresponding MCP tool will enforce the same logic. - Can I choose which endpoints become MCP tools?
- Yes. You can curate your surface by limiting which routes you include. Organize endpoints in routers or use include/exclude strategies as documented in FastAPI-MCP. Keep destructive actions behind stronger checks.
- Is performance good enough for production?
- Yes. Calls travel over your app’s ASGI interface—no extra network hop—so latency is low and predictable. You also share middleware and infrastructure between REST and MCP paths.
- Can I mount the MCP server to a different app or deploy it separately?
- You can mount the MCP server to the same FastAPI app (simplest) or run it as a separate service for isolation. FastAPI-MCP was designed for both.
- What about WebSockets or streaming endpoints?
- MCP tools are typically request/response with structured JSON. For streaming or sessions, consult the MCP spec and FastAPI-MCP docs to see current support and recommended patterns.
- Which Python versions are supported?
- Python 3.10+ (3.12 recommended).
- Do I need to change my code to support MCP?
- Usually not. If your endpoints already declare request/response models and use FastAPI dependencies for auth, you can add FastAPI-MCP and be productive immediately.
- Where can I learn more about FastAPI and the underlying stack?
- FastAPI: fastapi.tiangolo.com
- ASGI: asgi.readthedocs.io
- Pydantic: docs.pydantic.dev
The takeaway
FastAPI-MCP lets you turn your FastAPI endpoints into MCP tools with almost no friction—and without abandoning the things you’ve already done right: schemas, docs, and auth. Because it’s FastAPI‑native and ASGI‑first, you get reliability, performance, and a single source of truth for your API and your AI tools.
If you’ve been waiting for a clean way to expose your services to AI agents, this is it. Install the package, mount the server, and start experimenting. Then, when you’re ready, harden your auth and schemas and roll it into production—or explore the hosted path with tadata.com.
Want more deep dives like this? Stick around, keep exploring, and consider subscribing so you don’t miss the next guide.
Discover more at InnoVirtuoso.com
I would love some feedback on my writing so if you have any, please don’t hesitate to leave a comment around here or in any platforms that is convenient for you.
For more on tech and other topics, explore InnoVirtuoso.com anytime. Subscribe to my newsletter and join our growing community—we’ll create something magical together. I promise, it’ll never be boring!
Stay updated with the latest news—subscribe to our newsletter today!
Thank you all—wishing you an amazing day ahead!
Read more related Articles at InnoVirtuoso
- How to Completely Turn Off Google AI on Your Android Phone
- The Best AI Jokes of the Month: February Edition
- Introducing SpoofDPI: Bypassing Deep Packet Inspection
- Getting Started with shadps4: Your Guide to the PlayStation 4 Emulator
- Sophos Pricing in 2025: A Guide to Intercept X Endpoint Protection
- The Essential Requirements for Augmented Reality: A Comprehensive Guide
- Harvard: A Legacy of Achievements and a Path Towards the Future
- Unlocking the Secrets of Prompt Engineering: 5 Must-Read Books That Will Revolutionize You