New in version 2.0.0

FastMCP can automatically convert FastAPI applications into MCP servers.

FastMCP does not include FastAPI as a dependency; you must install it separately to run these examples.

from fastapi import FastAPI
from fastmcp import FastMCP


# A FastAPI app
app = FastAPI()

@app.get("/items")
def list_items():
    return [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}]

@app.get("/items/{item_id}")
def get_item(item_id: int):
    return {"id": item_id, "name": f"Item {item_id}"}

@app.post("/items")
def create_item(name: str):
    return {"id": 3, "name": name}


# Create an MCP server from your FastAPI app
mcp = FastMCP.from_fastapi(app=app)

if __name__ == "__main__":
    mcp.run()  # Start the MCP server

Route Mapping

By default, FastMCP will map FastAPI routes to MCP components according to the following rules:

FastAPI Route TypeFastAPI ExampleMCP ComponentNotes
GET without path params@app.get("/stats")ResourceSimple resources for fetching data
GET with path params@app.get("/users/{id}")Resource TemplatePath parameters become template parameters
POST, PUT, DELETE, etc.@app.post("/users")ToolOperations that modify data

For more details on route mapping or custom mapping rules, see the OpenAPI integration documentation; FastMCP uses the same mapping rules for both FastAPI and OpenAPI integrations.

Complete Example

Here’s a more detailed example with a data model:

import asyncio
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from fastmcp import FastMCP, Client

# Define your Pydantic model
class Item(BaseModel):
    name: str
    price: float

# Create your FastAPI app
app = FastAPI()
items = {}  # In-memory database

@app.get("/items")
def list_items():
    """List all items"""
    return list(items.values())

@app.get("/items/{item_id}")
def get_item(item_id: int):
    """Get item by ID"""
    if item_id not in items:
        raise HTTPException(404, "Item not found")
    return items[item_id]

@app.post("/items")
def create_item(item: Item):
    """Create a new item"""
    item_id = len(items) + 1
    items[item_id] = {"id": item_id, **item.model_dump()}
    return items[item_id]

# Test your MCP server with a client
async def test():
    # Create MCP server from FastAPI app
    mcp = await FastMCP.from_fastapi(app=app)
    
    # List the components that were created
    tools = await mcp.list_tools()
    resources = await mcp.list_resources()
    templates = await mcp.list_resource_templates()
    
    print(f"Generated {len(tools)} tools")
    print(f"Generated {len(resources)} resources")
    print(f"Generated {len(templates)} templates")
    
    # In a real scenario, you would run the server:
    # mcp.run()

if __name__ == "__main__":
    asyncio.run(test())

Benefits

  • Leverage existing FastAPI apps - No need to rewrite your API logic
  • Schema reuse - FastAPI’s Pydantic models and validation are inherited
  • Full feature support - Works with FastAPI’s authentication, dependencies, etc.
  • ASGI transport - Direct communication without additional HTTP overhead