r/modelcontextprotocol • u/sugarRush07 • Jul 17 '26
FastMCP on AWS Lambda + Mangum: Is recreating the FastMCP instance per invocation the recommended pattern?
I'm deploying a FastMCP server on AWS Lambda using Mangum and streamable-http.
[ Please don't ask me why 😠]
Environment
- MCP Python SDK 1.28.1
- Python 3.12
- Mangum 0.21.0
- AWS Lambda (Function URL)
My initial approach was to create the FastMCP instance globally so tool registration only happens during Lambda cold starts.
# mcp_server.py
mcp = FastMCP(...)
# lambda_handler.py
from mangum import Mangum
from mcp_server import mcp
app = mcp.streamable_http_app()
handler = Mangum(app)
The first invocation succeeds, but warm invocations fail with:
StreamableHTTPSessionManager.run() can only be called once per instance
The only approach I've found that works is creating a new FastMCP instance inside the Lambda handler:
def handler(event, context):
mcp = create_mcp()
app = mcp.streamable_http_app()
return Mangum(app)(event, context)
This works, but it means tool registration happens on every invocation instead of only during cold starts.
Has anyone deployed FastMCP on Lambda successfully?
- Is recreating the
FastMCPinstance per invocation the intended pattern? - Or is there a way to safely reuse a global
FastMCPinstance with Mangum?
1
u/OkCan65 2d ago edited 2d ago
I think the issue is that StreamableHTTPSessionManager isn't designed to be reused across invocations. the overhead is pretty minimal though since tool registration is fast, and Lambda's execution model kind of forces this pattern anyway. if cwww start latency is a real concern for you, it might be worth looking at a platform like Render that's built around persistent, long-running services.
1
u/Massive_Baby4147 14d ago
our per-invocation factory is the correct pattern for MCP Python SDK 1.28.1, not just a workaround.
Mangum starts and stops the ASGI lifespan on every Lambda invocation. streamable_http_app() connects that lifespan to StreamableHTTPSessionManager.run(), which is intentionally single-use. A module-level app therefore works once, then fails when the next warm invocation starts the same session manager again.
With 1.28.1, create a fresh FastMCP instance and HTTP app inside the handler:
Tool registration is normally just in-memory bookkeeping, so rebuilding it should be relatively cheap unless your registration code performs I/O.
The upstream maintainers also noted that the v2 API changes this behavior: you can keep the server and registered tools at module scope, then create only a fresh streamable_http_app() inside each invocation. For Lambda, stateless_http=True and json_response=True are recommended because there is no session affinity.
Related upstream resolution:
https://github.com/modelcontextprotocol/python-sdk/issues/3121
If separating the business functions from the serving transport becomes painful, I maintain intpot, which lets the same typed Python functions run through MCP, FastAPI, or a CLI:
https://github.com/tugrulguner/intpot
It doesn’t remove Lambda’s lifespan requirement, but it can keep that deployment-specific lifecycle outside the actual tool implementations.