Update integration docs

This commit is contained in:
Jeremiah Lowin 2025-07-09 16:50:16 -04:00
commit 9cbfcab94c
6 changed files with 561 additions and 428 deletions

View file

@ -1,220 +0,0 @@
---
title: Integrating FastMCP in ASGI Applications
sidebarTitle: ASGI Integration
description: Integrate FastMCP servers into existing Starlette, FastAPI, or other ASGI applications
icon: plug
---
import { VersionBadge } from '/snippets/version-badge.mdx'
While FastMCP provides standalone server capabilities, you can also integrate your FastMCP server into existing web applications. This approach is useful for:
- Adding MCP functionality to an existing website or API
- Mounting MCP servers under specific URL paths
- Combining multiple services in a single application
- Leveraging existing authentication and middleware
Please note that all FastMCP servers have a `run()` method that can be used to start the server. This guide focuses on integration with broader ASGI frameworks.
## ASGI Server
FastMCP servers can be created as [Starlette](https://www.starlette.io/) ASGI apps for straightforward hosting or integration into existing applications.
The first step is to obtain a Starlette application instance from your FastMCP server using the `http_app()` method:
<Tip>
The `http_app()` method is new in FastMCP 2.3.2. In older versions, use `sse_app()` for SSE transport or `streamable_http_app()` for Streamable HTTP transport.
</Tip>
```python
from fastmcp import FastMCP
mcp = FastMCP("MyServer")
@mcp.tool
def hello(name: str) -> str:
return f"Hello, {name}!"
# Get a Starlette app instance for Streamable HTTP transport (recommended)
http_app = mcp.http_app()
# For legacy SSE transport (deprecated)
sse_app = mcp.http_app(transport="sse")
```
Both approaches return a Starlette application that can be integrated with other ASGI-compatible web frameworks.
The returned app stores the `FastMCP` instance on `app.state.fastmcp_server`, so you
can access it from custom middleware or routes via `request.app.state.fastmcp_server`.
The MCP server's endpoint is mounted at the root path `/mcp/` for Streamable HTTP transport, and `/sse/` for SSE transport, though you can change these paths by passing a `path` argument to the `http_app()` method:
```python
# For Streamable HTTP transport
http_app = mcp.http_app(path="/custom-mcp-path")
# For SSE transport (deprecated)
sse_app = mcp.http_app(path="/custom-sse-path", transport="sse")
```
### Running the Server
To run the FastMCP server, you can use the `uvicorn` ASGI server:
```python
from fastmcp import FastMCP
import uvicorn
mcp = FastMCP("MyServer")
http_app = mcp.http_app()
if __name__ == "__main__":
uvicorn.run(http_app, host="0.0.0.0", port=8000)
```
Or, from the command line:
```bash
uvicorn path.to.your.app:http_app --host 0.0.0.0 --port 8000
```
### Custom Middleware
<VersionBadge version="2.3.2" />
You can add custom Starlette middleware to your FastMCP ASGI apps by passing a list of middleware instances to the app creation methods:
```python
from fastmcp import FastMCP
from starlette.middleware import Middleware
from starlette.middleware.cors import CORSMiddleware
# Create your FastMCP server
mcp = FastMCP("MyServer")
# Define custom middleware
custom_middleware = [
Middleware(
CORSMiddleware,
allow_origins=["https://example.com", "https://app.example.com"],
allow_credentials=True,
allow_methods=["GET", "POST", "OPTIONS"],
allow_headers=["Content-Type", "Authorization"],
),
]
# Create ASGI app with custom middleware
http_app = mcp.http_app(middleware=custom_middleware)
```
## Starlette Integration
<VersionBadge version="2.3.1" />
You can mount your FastMCP server in another Starlette application:
```python
from fastmcp import FastMCP
from starlette.applications import Starlette
from starlette.routing import Mount
# Create your FastMCP server as well as any tools, resources, etc.
mcp = FastMCP("MyServer")
# Create the ASGI app
mcp_app = mcp.http_app(path='/mcp')
# Create a Starlette app and mount the MCP server
app = Starlette(
routes=[
Mount("/mcp-server", app=mcp_app),
# Add other routes as needed
],
lifespan=mcp_app.lifespan,
)
```
The MCP endpoint will be available at `/mcp-server/mcp/` of the resulting Starlette app.
<Warning>
For Streamable HTTP transport, you **must** pass the lifespan context from the FastMCP app to the resulting Starlette app, as nested lifespans are not recognized. Otherwise, the FastMCP server's session manager will not be properly initialized.
</Warning>
### Nested Mounts
You can create complex routing structures by nesting mounts:
```python
from fastmcp import FastMCP
from starlette.applications import Starlette
from starlette.routing import Mount
# Create your FastMCP server as well as any tools, resources, etc.
mcp = FastMCP("MyServer")
# Create the ASGI app
mcp_app = mcp.http_app(path='/mcp')
# Create nested application structure
inner_app = Starlette(routes=[Mount("/inner", app=mcp_app)])
app = Starlette(
routes=[Mount("/outer", app=inner_app)],
lifespan=mcp_app.lifespan,
)
```
In this setup, the MCP server is accessible at the `/outer/inner/mcp/` path of the resulting Starlette app.
<Warning>
For Streamable HTTP transport, you **must** pass the lifespan context from the FastMCP app to the *outer* Starlette app, as nested lifespans are not recognized. Otherwise, the FastMCP server's session manager will not be properly initialized.
</Warning>
## FastAPI Integration
<VersionBadge version="2.3.1" />
FastAPI is built on Starlette, so you can mount your FastMCP server in a similar way:
```python
from fastmcp import FastMCP
from fastapi import FastAPI
from starlette.routing import Mount
# Create your FastMCP server as well as any tools, resources, etc.
mcp = FastMCP("MyServer")
# Create the ASGI app
mcp_app = mcp.http_app(path='/mcp')
# Create a FastAPI app and mount the MCP server
app = FastAPI(lifespan=mcp_app.lifespan)
app.mount("/mcp-server", mcp_app)
```
The MCP endpoint will be available at `/mcp-server/mcp/` of the resulting FastAPI app.
<Warning>
For Streamable HTTP transport, you **must** pass the lifespan context from the FastMCP app to the resulting FastAPI app, as nested lifespans are not recognized. Otherwise, the FastMCP server's session manager will not be properly initialized.
</Warning>
## Custom Routes
In addition to adding your FastMCP server to an existing ASGI app, you can also add custom web routes to your FastMCP server, which will be exposed alongside the MCP endpoint. To do so, use the `@custom_route` decorator. Note that this is less flexible than using a full ASGI framework, but can be useful for adding simple endpoints like health checks to your standalone server.
```python
from fastmcp import FastMCP
from starlette.requests import Request
from starlette.responses import PlainTextResponse
mcp = FastMCP("MyServer")
@mcp.custom_route("/health", methods=["GET"])
async def health_check(request: Request) -> PlainTextResponse:
return PlainTextResponse("OK")
```
These routes will be included in the FastMCP app when mounted in your web application.

View file

@ -65,10 +65,7 @@
{
"group": "Essentials",
"icon": "cube",
"pages": [
"servers/server",
"deployment/running-server"
]
"pages": ["servers/server", "deployment/running-server"]
},
{
"group": "Core Components",
@ -97,11 +94,6 @@
"group": "Authentication",
"icon": "shield-check",
"pages": ["servers/auth/bearer"]
},
{
"group": "Deployment",
"icon": "upload",
"pages": ["deployment/asgi"]
}
]
},
@ -111,10 +103,7 @@
{
"group": "Essentials",
"icon": "cube",
"pages": [
"clients/client",
"clients/transports"
]
"pages": ["clients/client", "clients/transports"]
},
{
"group": "Core Operations",
@ -153,15 +142,17 @@
"integrations/claude-desktop",
"integrations/cursor",
"integrations/eunomia-authorization",
"integrations/fastapi",
"integrations/gemini",
"integrations/mcp-json-configuration",
"integrations/openai"
"integrations/openai",
"integrations/openapi",
"integrations/starlette"
]
},
{
"group": "Patterns",
"pages": [
"servers/openapi",
"patterns/tool-transformation",
"patterns/decorating-methods",
"patterns/http-requests",

View file

@ -0,0 +1,229 @@
---
title: FastAPI 🤝 FastMCP
sidebarTitle: FastAPI
description: Integrate FastMCP with FastAPI applications
icon: bolt
---
import { VersionBadge } from '/snippets/version-badge.mdx'
FastMCP provides two powerful ways to integrate with FastAPI applications, both of which are documented below.
1. You can [generate an MCP server FROM your FastAPI app](#generating-an-mcp-server) by converting existing API endpoints into MCP tools. This is useful for bootstrapping and quickly attaching LLMs to your API.
2. You can [mount an MCP server INTO your FastAPI app](#mounting-an-mcp-server) by adding MCP functionality to your web application. This is useful for exposing your MCP tools alongside regular API endpoints.
You can even combine both approaches to create a single FastAPI app that serves both regular API endpoints and MCP tools!
<Tip>
Generating MCP servers from FastAPI apps is a great way to get started with FastMCP, but in practice LLMs achieve **significantly better performance** with well-designed and curated MCP servers than with auto-converted FastAPI servers. This is especially true for complex APIs with many endpoints and parameters.
</Tip>
<Note>
FastMCP does *not* include FastAPI as a dependency; you must install it separately to use this integration.
</Note>
## Generating an MCP Server
<VersionBadge version="2.0.0" />
FastMCP can directly convert your existing FastAPI applications into MCP servers, allowing AI models to interact with your API endpoints through the MCP protocol.
<Tip>
Under the hood, the FastAPI integration is built on top of FastMCP's OpenAPI integration. See the [OpenAPI docs](/integrations/openapi) for more details.
</Tip>
### Create a Server
The simplest way to convert a FastAPI app is using the `FastMCP.from_fastapi()` method:
```python server.py
from fastapi import FastAPI
from fastmcp import FastMCP
# Your existing FastAPI app
app = FastAPI(title="My API", version="1.0.0")
@app.get("/items", tags=["items"], operation_id="list_items")
def list_items():
return [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}]
@app.get("/items/{item_id}", tags=["items", "detail"], operation_id="get_item")
def get_item(item_id: int):
return {"id": item_id, "name": f"Item {item_id}"}
@app.post("/items", tags=["items", "create"], operation_id="create_item")
def create_item(name: str):
return {"id": 3, "name": name}
# Convert FastAPI app to MCP server
mcp = FastMCP.from_fastapi(app=app)
if __name__ == "__main__":
mcp.run() # Run as MCP server
```
### Component Mapping
By default, FastMCP converts **every endpoint** in your FastAPI app into an MCP **Tool**. This provides maximum compatibility with LLM clients that primarily support MCP tools.
You can customize this behavior using route maps to control which endpoints become tools, resources, or resource templates:
```python
from fastmcp.server.openapi import RouteMap, MCPType
# Custom route mapping
mcp = FastMCP.from_fastapi(
app=app,
route_maps=[
# GET requests with path parameters become ResourceTemplates
RouteMap(methods=["GET"], pattern=r".*\{.*\}.*", mcp_type=MCPType.RESOURCE_TEMPLATE),
# All other GET requests become Resources
RouteMap(methods=["GET"], pattern=r".*", mcp_type=MCPType.RESOURCE),
# POST/PUT/DELETE become Tools (handled by default rule)
],
)
```
The `FastMCP.from_fastapi()` method accepts all the same configuration options as `FastMCP.from_openapi()`, including route maps, custom tags, component naming, timeouts, and component customization functions. For comprehensive configuration details, see the [OpenAPI Integration guide](/integrations/openapi).
### Key Considerations
#### Operation IDs
FastMCP uses your FastAPI operation IDs to name MCP components. Ensure your endpoints have meaningful operation IDs:
```python
@app.get("/users/{user_id}", operation_id="get_user_detail") # ✅ Good
@app.get("/users/{user_id}") # ❌ Auto-generated name might be unclear
```
#### Pydantic Models
Your Pydantic models are automatically converted to JSON schema for MCP tool parameters:
```python
from pydantic import BaseModel
class CreateItemRequest(BaseModel):
name: str
description: str | None = None
price: float
@app.post("/items")
def create_item(item: CreateItemRequest):
return {"id": 123, **item.dict()}
```
The MCP tool will have properly typed parameters matching your Pydantic model.
#### Error Handling
FastAPI error handling carries over to the MCP server. HTTPExceptions are automatically converted to appropriate MCP errors.
Since FastAPI integration is built on OpenAPI, all the same configuration options are available including authentication setup, timeout configuration, and request parameter handling. For detailed information on these features, see the [OpenAPI Integration guide](/integrations/openapi).
## Mounting an MCP Server
<VersionBadge version="2.3.1" />
You can also mount an existing FastMCP server into your FastAPI application, adding MCP functionality to your web application. This is useful for exposing your MCP tools alongside regular API endpoints.
### Basic Integration
```python
from fastmcp import FastMCP
from fastapi import FastAPI
from starlette.routing import Mount
# Create your FastMCP server
mcp = FastMCP("MyServer")
@mcp.tool
def analyze_data(query: str) -> dict:
"""Analyze data based on the query."""
return {"result": f"Analysis for: {query}"}
# Create the ASGI app from your MCP server
mcp_app = mcp.http_app(path='/mcp')
# Create a FastAPI app and mount the MCP server
app = FastAPI(lifespan=mcp_app.lifespan)
app.mount("/mcp-server", mcp_app)
# Add regular FastAPI routes
@app.get("/health")
def health_check():
return {"status": "healthy"}
```
The MCP endpoint will be available at `/mcp-server/mcp/` of your FastAPI application.
<Warning>
For Streamable HTTP transport, you **must** pass the lifespan context from the FastMCP app to the FastAPI app. Otherwise, the FastMCP server's session manager will not be properly initialized.
</Warning>
### Advanced Integration
You can combine both approaches - generate an MCP server from your FastAPI app AND mount additional MCP servers:
```python
from fastmcp import FastMCP
from fastapi import FastAPI
# Your existing FastAPI app
app = FastAPI()
@app.get("/items")
def list_items():
return [{"id": 1, "name": "Item 1"}]
# Generate MCP server from FastAPI app
api_mcp = FastMCP.from_fastapi(app=app, name="API Server")
# Create additional purpose-built MCP server
tools_mcp = FastMCP("Tools Server")
@tools_mcp.tool
def advanced_analysis(data: dict) -> dict:
"""Perform advanced analysis not available via API."""
return {"analysis": "complex results"}
# Mount the tools server into the same FastAPI app
tools_app = tools_mcp.http_app(path='/mcp')
app.mount("/tools", tools_app, lifespan=tools_app.lifespan)
```
Now you have:
- API endpoints converted to MCP tools (via `api_mcp`)
- Additional MCP tools available at `/tools/mcp/`
- Regular FastAPI endpoints at their original paths
### Authentication and Middleware
When mounting MCP servers into FastAPI, you can leverage FastAPI's authentication and middleware:
```python
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
security = HTTPBearer()
def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
if credentials.credentials != "secret-token":
raise HTTPException(status_code=401, detail="Invalid token")
return credentials
app = FastAPI()
# Mount MCP server with authentication
@app.get("/secure")
def secure_endpoint(auth=Depends(verify_token)):
return {"message": "Authenticated"}
# The mounted MCP server inherits the app's security
mcp_app = mcp.http_app()
app.mount("/mcp", mcp_app, lifespan=mcp_app.lifespan)
```
For more advanced ASGI integration patterns, see the [ASGI Integration guide](/integrations/asgi).

View file

@ -1,21 +1,25 @@
---
title: OpenAPI Integration
sidebarTitle: OpenAPI Integration
description: Generate MCP servers from OpenAPI specs and FastAPI apps
icon: code-branch
title: OpenAPI 🤝 FastMCP
sidebarTitle: OpenAPI
description: Generate MCP servers from any OpenAPI specification
icon: list-tree
---
import { VersionBadge } from '/snippets/version-badge.mdx'
<VersionBadge version="2.0.0" />
FastMCP can automatically generate an MCP server from an OpenAPI specification or FastAPI app. Instead of manually creating tools and resources, you provide an OpenAPI spec and FastMCP intelligently converts your API endpoints into the appropriate MCP components.
FastMCP can automatically generate an MCP server from any OpenAPI specification, allowing AI models to interact with existing APIs through the MCP protocol. Instead of manually creating tools and resources, you provide an OpenAPI spec and FastMCP intelligently converts API endpoints into the appropriate MCP components.
## Quick Start
<Tip>
Generating MCP servers from OpenAPI is a great way to get started with FastMCP, but in practice LLMs achieve **significantly better performance** with well-designed and curated MCP servers than with auto-converted OpenAPI servers. This is especially true for complex APIs with many endpoints and parameters.
</Tip>
To convert an OpenAPI specification to an MCP server, you can use the `FastMCP.from_openapi` class method. This method takes an OpenAPI specification and an async HTTPX client that can be used to make requests to the API, and returns an MCP server.
## Create a Server
Here's an example:
```python {11-15}
To convert an OpenAPI specification to an MCP server, use the `FastMCP.from_openapi()` class method:
```python server.py
import httpx
from fastmcp import FastMCP
@ -36,8 +40,27 @@ if __name__ == "__main__":
mcp.run()
```
That's it! Your entire API is now available as an MCP server. Clients can discover and interact with your API endpoints through the MCP protocol, with full schema validation and type safety.
### Authentication
If your API requires authentication, configure it on the HTTP client:
```python
import httpx
from fastmcp import FastMCP
# Bearer token authentication
api_client = httpx.AsyncClient(
base_url="https://api.example.com",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
# Create MCP server with authenticated client
mcp = FastMCP.from_openapi(
openapi_spec=spec,
client=api_client,
timeout=30.0 # 30 second timeout for all requests
)
```
## Route Mapping
@ -51,7 +74,7 @@ Each `RouteMap` specifies a combination of methods, patterns, and tags, as well
- **Pattern**: Regex pattern to match the route path (e.g. `r"^/users/.*"` or `r".*"` for all)
- **Tags**: A set of OpenAPI tags that must all be present. An empty set (`{}`) means no tag filtering, so the route matches regardless of its tags.
- **MCP type**: What MCP component type to create (`TOOL`, `RESOURCE`, `RESOURCE_TEMPLATE`, or `EXCLUDE`)
- **MCP tags** A set of custom tags to add to components created from matching routes
- **MCP tags**: A set of custom tags to add to components created from matching routes
Here is FastMCP's default rule:
@ -70,7 +93,7 @@ When creating your FastMCP server, you can customize routing behavior by providi
For example, prior to FastMCP 2.8.0, GET requests were automatically mapped to `Resource` and `ResourceTemplate` components based on whether they had path parameters. (This was changed solely for client compatibility reasons.) You can restore this behavior by providing custom route maps:
```python {2, 5-10}
```python
from fastmcp import FastMCP
from fastmcp.server.openapi import RouteMap, MCPType
@ -83,7 +106,8 @@ semantic_maps = [
]
mcp = FastMCP.from_openapi(
...,
openapi_spec=spec,
client=client,
route_maps=semantic_maps,
)
```
@ -97,9 +121,9 @@ from fastmcp import FastMCP
from fastmcp.server.openapi import RouteMap, MCPType
mcp = FastMCP.from_openapi(
...,
openapi_spec=spec,
client=client,
route_maps=[
# Analytics `GET` endpoints are tools
RouteMap(
methods=["GET"],
@ -132,12 +156,13 @@ To exclude routes from the MCP server, use a route map to assign them to `MCPTyp
You can use this to remove sensitive or internal routes by targeting them specifically:
```python {7,8}
```python
from fastmcp import FastMCP
from fastmcp.server.openapi import RouteMap, MCPType
mcp = FastMCP.from_openapi(
...,
openapi_spec=spec,
client=client,
route_maps=[
RouteMap(pattern=r"^/admin/.*", mcp_type=MCPType.EXCLUDE),
RouteMap(tags={"internal"}, mcp_type=MCPType.EXCLUDE),
@ -146,15 +171,17 @@ mcp = FastMCP.from_openapi(
```
Or you can use a catch-all rule to exclude everything that your maps don't handle explicitly:
```python {10}
```python
from fastmcp import FastMCP
from fastmcp.server.openapi import RouteMap, MCPType
mcp = FastMCP.from_openapi(
...,
openapi_spec=spec,
client=client,
route_maps=[
# custom mapping logic goes here
...,
# ... your specific route maps ...
# exclude all remaining routes
RouteMap(mcp_type=MCPType.EXCLUDE),
],
@ -165,7 +192,6 @@ mcp = FastMCP.from_openapi(
Using a catch-all exclusion rule will prevent the default route mappings from being applied, since it will match every remaining route. This is useful if you want to explicitly allow-list certain routes.
</Tip>
### Advanced Route Mapping
<VersionBadge version="2.5.0" />
@ -178,7 +204,6 @@ In addition to more precise targeting of methods, patterns, and tags, this funct
The `route_map_fn` **is** called on routes that matched `MCPType.EXCLUDE` in your custom maps, giving you an opportunity to override the exclusion.
</Tip>
```python
from fastmcp import FastMCP
from fastmcp.server.openapi import RouteMap, MCPType, HTTPRoute
@ -200,12 +225,40 @@ def custom_route_mapper(route: HTTPRoute, mcp_type: MCPType) -> MCPType | None:
return None
mcp = FastMCP.from_openapi(
...,
openapi_spec=spec,
client=client,
route_map_fn=custom_route_mapper,
)
```
## Customizing MCP Components
## Customization
### Component Names
<VersionBadge version="2.5.0" />
FastMCP automatically generates names for MCP components based on the OpenAPI specification. By default, it uses the `operationId` from your OpenAPI spec, up to the first double underscore (`__`).
All component names are automatically:
- **Slugified**: Spaces and special characters are converted to underscores or removed
- **Truncated**: Limited to 56 characters maximum to ensure compatibility
- **Unique**: If multiple components have the same name, a number is automatically appended to make them unique
For more control over component names, you can provide an `mcp_names` dictionary that maps `operationId` values to your desired names. The `operationId` must be exactly as it appears in the OpenAPI spec. The provided name will always be slugified and truncated.
```python
mcp = FastMCP.from_openapi(
openapi_spec=spec,
client=client,
mcp_names={
"list_users__with_pagination": "user_list",
"create_user__admin_required": "create_user",
"get_user_details__admin_required": "user_detail",
}
)
```
Any `operationId` not found in `mcp_names` will use the default strategy (operationId up to the first `__`).
### Tags
@ -217,12 +270,12 @@ FastMCP provides several ways to add tags to your MCP components, allowing you t
You can add custom tags to components created from specific routes using the `mcp_tags` parameter in `RouteMap`. These tags will be applied to all components created from routes that match that particular route map.
```python {12, 20, 28}
from fastmcp import FastMCP
```python
from fastmcp.server.openapi import RouteMap, MCPType
mcp = FastMCP.from_openapi(
...,
openapi_spec=spec,
client=client,
route_maps=[
# Add custom tags to all POST endpoints
RouteMap(
@ -253,59 +306,18 @@ mcp = FastMCP.from_openapi(
#### Global Tags
You can add tags to **all** components by providing a `tags` parameter when creating your FastMCP server with `from_openapi` or `from_fastapi`. These global tags will be applied to every component created from your OpenAPI specification.
<CodeGroup>
```python {6} from_openapi()
from fastmcp import FastMCP
You can add tags to **all** components by providing a `tags` parameter when creating your MCP server. These global tags will be applied to every component created from your OpenAPI specification.
```python
mcp = FastMCP.from_openapi(
openapi_spec=spec,
client=client,
tags={"api-v2", "production", "external"}
)
```
```python {5} from_fastapi()
from fastmcp import FastMCP
mcp = FastMCP.from_fastapi(
app=app,
tags={"internal-api", "microservice"}
)
```
</CodeGroup>
### Names
<VersionBadge version="2.5.0" />
FastMCP automatically generates names for MCP components based on the OpenAPI specification. By default, it uses the `operationId` from your OpenAPI spec, up to the first double underscore (`__`).
All component names are automatically:
- **Slugified**: Spaces and special characters are converted to underscores or removed
- **Truncated**: Limited to 56 characters maximum to ensure compatibility
- **Unique**: If multiple components have the same name, a number is automatically appended to make them unique
For more control over component names, you can provide an `mcp_names` dictionary that maps `operationId` values to your desired names. The `operationId` must be exactly as it appears in the OpenAPI spec. The provided name will always be slugified and truncated.
```python {5-9}
from fastmcp import FastMCP
mcp = FastMCP.from_openapi(
...
mcp_names={
"list_users__with_pagination": "user_list",
"create_user__admin_required": "create_user",
"get_user_details__admin_required": "user_detail",
}
)
```
Any `operationId` not found in `mcp_names` will use the default strategy (operationId up to the first `__`).
### Advanced Customization
<VersionBadge version="2.5.0" />
By default, FastMCP creates MCP components using a variety of metadata from the OpenAPI spec, such as incorporating the OpenAPI description into the MCP component description.
@ -316,8 +328,7 @@ At times you may want to modify those MCP components in a variety of ways, such
Your `mcp_component_fn` is expected to modify the component in-place, not to return a new component. The result of the function is ignored.
</Tip>
```python {27}
from fastmcp import FastMCP
```python
from fastmcp.server.openapi import (
HTTPRoute,
OpenAPITool,
@ -329,7 +340,6 @@ def customize_components(
route: HTTPRoute,
component: OpenAPITool | OpenAPIResource | OpenAPIResourceTemplate,
) -> None:
# Add custom tags to all components
component.tags.add("openapi")
@ -342,10 +352,12 @@ def customize_components(
component.tags.add("data")
mcp = FastMCP.from_openapi(
...,
openapi_spec=spec,
client=client,
mcp_component_fn=customize_components,
)
```
## Request Parameter Handling
FastMCP intelligently handles different types of parameters in OpenAPI requests:
@ -401,118 +413,4 @@ FastMCP handles array parameters according to OpenAPI specifications:
### Headers
Header parameters are automatically converted to strings and included in the HTTP request.
## Auth
If your API requires authentication, configure it on the HTTP client before creating the MCP server:
```python
import httpx
from fastmcp import FastMCP
# Bearer token authentication
api_client = httpx.AsyncClient(
base_url="https://api.example.com",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
# Create MCP server with authenticated client
mcp = FastMCP.from_openapi(..., client=api_client)
```
## Timeouts
Set a timeout for all API requests:
```python
mcp = FastMCP.from_openapi(
openapi_spec=spec,
client=api_client,
timeout=30.0 # 30 second timeout for all requests
)
```
## FastAPI Integration
<VersionBadge version="2.0.0" />
FastMCP can directly convert FastAPI applications into MCP servers by extracting their OpenAPI specifications:
<Tip>
FastMCP does *not* include FastAPI as a dependency; you must install it separately to use this integration.
</Tip>
```python
from fastapi import FastAPI
from fastmcp import FastMCP
# Your FastAPI app
app = FastAPI(title="My API", version="1.0.0")
@app.get("/items", tags=["items"], operation_id="list_items")
def list_items():
return [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}]
@app.get("/items/{item_id}", tags=["items", "detail"], operation_id="get_item")
def get_item(item_id: int):
return {"id": item_id, "name": f"Item {item_id}"}
@app.post("/items", tags=["items", "create"], operation_id="create_item")
def create_item(name: str):
return {"id": 3, "name": name}
# Convert FastAPI app to MCP server
mcp = FastMCP.from_fastapi(app=app)
if __name__ == "__main__":
mcp.run() # Run as MCP server
```
Note that operation ids are optional, but are used to create component names. You can also provide custom names, just like with OpenAPI specs.
<Warning>
FastMCP servers are not FastAPI apps, even when created from one. To learn how to deploy them as an ASGI app, see the [ASGI Integration](/deployment/asgi) documentation.
</Warning>
### FastAPI Configuration
All OpenAPI integration features work with FastAPI apps:
```python
from fastmcp.server.openapi import RouteMap, MCPType
# Custom route mapping with FastAPI
mcp = FastMCP.from_fastapi(
app=app,
name="My Custom Server",
timeout=5.0,
tags={"api-v1", "fastapi"}, # Global tags for all components
mcp_names={"operationId": "friendly_name"}, # Custom component names
route_maps=[
# Admin endpoints become tools with custom tags
RouteMap(
methods="*",
pattern=r"^/admin/.*",
mcp_type=MCPType.TOOL,
mcp_tags={"admin", "privileged"}
),
# Internal endpoints are excluded
RouteMap(methods="*", pattern=r".*", mcp_type=MCPType.EXCLUDE, tags={"internal"}),
],
route_map_fn=my_route_mapper,
mcp_component_fn=my_component_customizer,
mcp_names={
"get_user_details_users__user_id__get": "get_user_details",
}
)
```
### FastAPI Benefits
- **Zero code duplication**: Reuse existing FastAPI endpoints
- **Schema inheritance**: Pydantic models and validation are preserved
- **ASGI transport**: Direct in-memory communication (no HTTP overhead)
- **Full FastAPI features**: Dependencies, middleware, authentication all work
Header parameters are automatically converted to strings and included in the HTTP request.

View file

@ -0,0 +1,213 @@
---
title: Starlette / ASGI 🤝 FastMCP
sidebarTitle: Starlette / ASGI
description: Integrate FastMCP servers into ASGI applications
icon: server
---
import { VersionBadge } from '/snippets/version-badge.mdx'
<VersionBadge version="2.3.1" />
FastMCP servers can be integrated into existing ASGI applications, allowing you to add MCP functionality to your web applications. This is useful for:
- Adding MCP functionality to an existing website or API
- Mounting MCP servers under specific URL paths
- Combining multiple services in a single application
- Leveraging existing authentication and middleware
## Basic Usage
To integrate a FastMCP server into an ASGI application, use the `http_app()` method to obtain a Starlette application instance:
<Tip>
The `http_app()` method is new in FastMCP 2.3.2. In older versions, use `sse_app()` for SSE transport or `streamable_http_app()` for Streamable HTTP transport.
</Tip>
```python
from fastmcp import FastMCP
mcp = FastMCP("MyServer")
@mcp.tool
def hello(name: str) -> str:
return f"Hello, {name}!"
# Get a Starlette app instance for Streamable HTTP transport (recommended)
http_app = mcp.http_app()
# For legacy SSE transport (deprecated)
sse_app = mcp.http_app(transport="sse")
```
The returned Starlette application can be integrated with other ASGI-compatible web frameworks. The MCP server's endpoint is mounted at `/mcp/` for Streamable HTTP transport and `/sse/` for SSE transport.
### Configuration Options
You can customize the endpoint path and access the FastMCP server instance:
```python
# Custom endpoint path
http_app = mcp.http_app(path="/custom-mcp-path")
# Access the FastMCP server from middleware/routes
# The server is available at: request.app.state.fastmcp_server
```
### Adding Custom Routes
You can add custom web routes directly to your FastMCP server using the `@custom_route` decorator:
```python
from fastmcp import FastMCP
from starlette.requests import Request
from starlette.responses import JSONResponse
mcp = FastMCP("MyServer")
@mcp.custom_route("/api/status", methods=["GET"])
async def get_status(request: Request):
return JSONResponse({"server": "running"})
http_app = mcp.http_app()
```
#### Health Check Endpoints
Health checks are commonly needed for monitoring and load balancing:
```python
from fastmcp import FastMCP
from starlette.requests import Request
from starlette.responses import JSONResponse
mcp = FastMCP("MyServer")
@mcp.custom_route("/health", methods=["GET"])
async def health_check(request: Request):
return JSONResponse({"status": "healthy"})
http_app = mcp.http_app()
```
The health endpoint will be available at `/health` alongside your MCP endpoint at `/mcp/`.
## Starlette Integration
Mount your FastMCP server in another Starlette application:
```python
from fastmcp import FastMCP
from starlette.applications import Starlette
from starlette.routing import Mount
# Create your FastMCP server
mcp = FastMCP("MyServer")
@mcp.tool
def analyze(data: str) -> dict:
return {"result": f"Analyzed: {data}"}
# Create the ASGI app
mcp_app = mcp.http_app(path='/mcp')
# Create a Starlette app and mount the MCP server
app = Starlette(
routes=[
Mount("/mcp-server", app=mcp_app),
# Add other routes as needed
],
lifespan=mcp_app.lifespan,
)
```
The MCP endpoint will be available at `/mcp-server/mcp/` of the resulting Starlette app.
<Warning>
For Streamable HTTP transport, you **must** pass the lifespan context from the FastMCP app to the resulting Starlette app, as nested lifespans are not recognized. Otherwise, the FastMCP server's session manager will not be properly initialized.
</Warning>
### Nested Mounts
You can create complex routing structures by nesting mounts:
```python
from fastmcp import FastMCP
from starlette.applications import Starlette
from starlette.routing import Mount
# Create your FastMCP server
mcp = FastMCP("MyServer")
# Create the ASGI app
mcp_app = mcp.http_app(path='/mcp')
# Create nested application structure
inner_app = Starlette(routes=[Mount("/inner", app=mcp_app)])
app = Starlette(
routes=[Mount("/outer", app=inner_app)],
lifespan=mcp_app.lifespan,
)
```
In this setup, the MCP server is accessible at the `/outer/inner/mcp/` path.
## Custom Middleware
<VersionBadge version="2.3.2" />
Add custom Starlette middleware to your FastMCP ASGI apps by passing a list of middleware instances:
```python
from fastmcp import FastMCP
from starlette.middleware import Middleware
from starlette.middleware.cors import CORSMiddleware
# Create your FastMCP server
mcp = FastMCP("MyServer")
# Define custom middleware
custom_middleware = [
Middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
]
# Create ASGI app with middleware
http_app = mcp.http_app(custom_middleware=custom_middleware)
```
## Running the Server
To run your ASGI application, use an ASGI server like `uvicorn`:
```python
import uvicorn
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
```
Or from the command line:
```bash
uvicorn path.to.your.app:app --host 0.0.0.0 --port 8000
```
## Framework-Specific Integration
### FastAPI
For FastAPI-specific integration patterns including both mounting MCP servers into FastAPI apps and generating MCP servers from FastAPI apps, see the [FastAPI Integration guide](/integrations/fastapi).
### Other ASGI Frameworks
The patterns shown here work with any ASGI-compatible framework. The key requirements are:
1. Mount the FastMCP ASGI app at your desired path
2. Pass the lifespan context to your root application
3. Configure any necessary middleware or authentication

View file

@ -232,6 +232,28 @@ proxy = FastMCP.as_proxy(backend, name="ProxyServer")
# Now use the proxy like any FastMCP server
```
## OpenAPI Integration
<VersionBadge version="2.0.0" />
FastMCP can automatically generate servers from OpenAPI specifications or existing FastAPI applications using `FastMCP.from_openapi()` and `FastMCP.from_fastapi()`. This allows you to instantly convert existing APIs into MCP servers without manual tool creation.
See the [FastAPI Integration](/integrations/fastapi) and [OpenAPI Integration](/integrations/openapi) guides for detailed examples and configuration options.
```python
import httpx
from fastmcp import FastMCP
# From OpenAPI spec
spec = httpx.get("https://api.example.com/openapi.json").json()
mcp = FastMCP.from_openapi(openapi_spec=spec, client=httpx.AsyncClient())
# From FastAPI app
from fastapi import FastAPI
app = FastAPI()
mcp = FastMCP.from_fastapi(app=app)
```
## Server Configuration
Servers can be configured using a combination of initialization arguments, global settings, and transport-specific settings.
@ -322,12 +344,12 @@ await mcp.run_async(
)
```
### Environment Variables
### Setting Global Configuration
Settings can be configured via environment variables:
Global FastMCP settings can be configured via environment variables (prefixed with `FASTMCP_`):
```bash
# Global settings
# Configure global FastMCP behavior
export FASTMCP_LOG_LEVEL=DEBUG
export FASTMCP_MASK_ERROR_DETAILS=True
export FASTMCP_RESOURCE_PREFIX_FORMAT=protocol