Spaces:
Running
Running
File size: 5,168 Bytes
0332908 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | ---
title: FastAPI Integration
sidebarTitle: FastAPI
description: Automatically create FastMCP servers directly from FastAPI applications.
icon: square-bolt
---
If you build your APIs using the popular [FastAPI](https://fastapi.tiangolo.com/) framework, FastMCP offers a seamless way to expose your FastAPI application as an MCP server. This leverages the OpenAPI integration internally but simplifies the setup significantly.
## The Goal: FastAPI App -> MCP Server
FastAPI automatically generates an OpenAPI specification for your application. FastMCP uses this built-in capability to create an MCP server that mirrors your API routes.
- FastAPI path operations (`@app.get`, `@app.post`, etc.) become MCP tools, resources, or templates.
- Pydantic models used in FastAPI for request/response validation are used to generate MCP schemas.
- Communication happens directly in memory, making it very efficient.
## Creating from FastAPI App
Use the `FastMCP.from_fastapi()` class method. You only need your FastAPI `app` instance.
```python
import asyncio
from fastapi import FastAPI
from pydantic import BaseModel
from fastmcp import FastMCP, Client # Import FastMCP and Client
# 1. Define your FastAPI application
api_app = FastAPI(title="MyFastAPIApp")
class Item(BaseModel):
name: str
price: float
is_offer: bool | None = None
@api_app.get("/")
def read_root():
return {"Hello": "World"}
@api_app.get("/items/{item_id}") # -> Resource Template
def read_item(item_id: int, q: str | None = None):
# This will become resource://openapi/read_item_items__item_id__get/{item_id}
return {"item_id": item_id, "q": q, "description": f"Details for item {item_id}"}
@api_app.post("/items/") # -> Tool
def create_item(item: Item):
# This will become the 'create_item_items__post' tool
print(f"Creating item: {item.name}")
return {"item_name": item.name, "status": "created"}
# 2. Create the FastMCP server directly from the FastAPI app
# This is an async class method
async def create_mcp_server_from_fastapi():
mcp_server = await FastMCP.from_fastapi(
app=api_app,
name="FastAPI_MCP_Bridge" # Optional name for the MCP server
)
return mcp_server
# 3. (Example) Run the MCP server and test with an in-memory client
async def run_and_test():
server = await create_mcp_server_from_fastapi()
print(f"Created MCP server '{server.name}' from FastAPI app '{api_app.title}'")
# List discovered components
tools = await server.list_tools()
templates = await server.list_resource_templates()
print("Discovered Tools:", [t.name for t in tools])
print("Discovered Templates:", [t.uriTemplate for t in templates])
# Test using an in-memory client
client = Client(server) # Uses FastMCPTransport
async with client:
# Call the tool derived from POST /items/
create_result = await client.call_tool(
"create_item_items__post",
{"name": "MCP Special", "price": 99.99} # Pydantic model fields become args
)
print("Create Item Tool Result:", create_result[0].text) # JSON string
# Read the resource derived from GET /items/{item_id}
read_result = await client.read_resource(
"resource://openapi/read_item_items__item_id__get/42" # Match template URI
)
print("Read Item Resource Result:", read_result[0].text) # JSON string
# In a real scenario, you might run the MCP server via stdio or sse
# print("Running MCP server via stdio...")
# server.run()
if __name__ == "__main__":
# Requires fastapi, uvicorn, httpx:
# uv pip install "fastapi[all]" httpx
try:
asyncio.run(run_and_test())
except ImportError as e:
print(f"Error: {e}. Please install required packages: uv pip install \"fastapi[all]\" httpx")
# Example Output might include:
# Created MCP server 'FastAPI_MCP_Bridge' from FastAPI app 'MyFastAPIApp'
# Discovered Tools: ['read_root___get', 'create_item_items__post']
# Discovered Templates: ['resource://openapi/read_item_items__item_id__get/{item_id}']
# Create Item Tool Result: {"item_name": "MCP Special", "status": "created"}
# Read Item Resource Result: {"item_id": 42, "q": null, "description": "Details for item 42"}
```
### How it Works Internally
1. **OpenAPI Generation**: `from_fastapi` asks the FastAPI `app` for its OpenAPI schema dictionary (`app.openapi()`).
2. **In-Memory Client**: It creates an `httpx.AsyncClient` configured with an `ASGITransport`. This special transport allows `httpx` to call the FastAPI application directly in memory without needing a running web server process.
3. **OpenAPI Integration**: It calls `FastMCP.from_openapi()`, passing the generated schema and the in-memory `httpx` client.
4. **MCP Server Creation**: The standard OpenAPI integration logic then proceeds to parse the schema and create the `Tool`, `Resource`, and `ResourceTemplate` components that wrap calls to the in-memory FastAPI app.
This provides a highly efficient way to expose your FastAPI logic through the MCP protocol, leveraging FastAPI's routing, dependency injection, and validation features. |