Spaces:
Running
Running
| 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 | |