[BUG] Uvicorn reload hangs when FastAPI-MCP has active SSE connections
Describe the bug When using FastAPI-MCP with SSE connections active, Uvicorn's reload functionality gets stuck during shutdown phase, requiring manual process termination. This severely impacts development workflow.
To Reproduce
- Create minimal FastAPI app
main.pywith MCP mounted:
from fastapi import FastAPI
from fastapi_mcp import FastApiMCP
app = FastAPI()
mcp = FastApiMCP(app)
# Mount the MCP server directly to your FastAPI app
mcp.mount()
- Start server with reload:
uvicorn --reload --port 9000 main:app
Open browser to SSE endpoint: http://localhost:9000/mcp and hold on:
- Modify any file (e.g. main.py) to trigger reload
Expected Behavior:
Server should:
- Detect file changes
- Gracefully close existing connections
- Restart with new code
Actual Behavior:
Server hangs at shutdown phase:
INFO: Shutting down
INFO: Waiting for connections to close. (CTRL+C to force quit)
System Information: fastapi==0.115.12 fastapi-mcp==0.3.6 uvicorn==0.34.2 Python==3.12.10 OS: Linux
Proposed Solutions:
- Add proper SSE connection tracking in FastAPI-MCP
- Implement graceful shutdown handler for SSE
- Provide API to manually close connections before reload
Hi, I replicated and didn't face any issue, can you pls elaborate ?
@sqrt676
Docker Reproduction Environment
1. File Structure
fastapi-mcp-reload-issue/
├── main.py # FastAPI + MCP entrypoint
└── Dockerfile # Image build
2. File Contents
-
main.py
from fastapi import FastAPI
from fastapi_mcp import FastApiMCP
app = FastAPI()
mcp = FastApiMCP(app)
# Mount the MCP server directly to your FastAPI app
mcp.mount()
-
Dockerfile
FROM python:3.12
WORKDIR /app
RUN pip install --no-cache-dir fastapi fastapi-mcp
EXPOSE 9000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "9000", "--reload"]
3. Build Docker image
cd fastapi-mcp-reload-issue
docker build -t test-fastapi-mcp-reload
4. Start Docker Container
docker run --rm -ti -v "$(pwd):/app" -p 9000:9000 test-fastapi-mcp-reload
5. Reproduction Steps
Initiate SSE connection (new terminal):
curl -v -N http://localhost:9000/mcp
Modify main.py (new terminal; e.g., add a comment):
cd fastapi-mcp-reload-issue
echo "# Trigger reload" >> main.py
Active SSE connection:
Hanging reload process and can not stop with ctrl+c:
Reload proceeds normally ONLY AFTER terminating the curl request - stopping the SSE client connection allows the shutdown sequence to complete.
I'm experiencing the same issue. It does not want to shutdown.
Running uvicorn with --timeout-graceful-shutdown seems to do the trick.
uvicorn main:app --port 8000 --reload --timeout-graceful-shutdown=0
I've also had this problem and can confirm @tomsquest solution seems to work.