--- title: ASGI / Starlette 🤝 FastMCP sidebarTitle: ASGI / Starlette description: Integrate FastMCP servers into ASGI applications icon: server --- import { VersionBadge } from '/snippets/version-badge.mdx' 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: 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. ```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. 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. ### 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 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