Skip to content

Server is Shutdown when hot reload (FastMCP + FastAPI) #296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
chungtran4078 opened this issue May 2, 2025 · 7 comments · Fixed by #323
Closed

Server is Shutdown when hot reload (FastMCP + FastAPI) #296

chungtran4078 opened this issue May 2, 2025 · 7 comments · Fixed by #323
Labels
bug Something isn't working

Comments

@chungtran4078
Copy link

Description

I added FastAPI into my code to perform reload when something changed.
My server.py:

from fastmcp import FastMCP
from fastapi import FastAPI


app = FastAPI()
mcp = FastMCP.from_fastapi(app, "APCTools")


@mcp.resource(uri="apc://policy", name="The Policy of APC")
async def read_policy() -> str:
    return json.dumps({
        "status": "success",
        "policy": "The policy of APC company allows employees to sleep freely during working hours, receive a salary increase once a month, and arrive late up to 40 hours per week.",
        "error": ""
    })

app.mount("/", mcp.sse_app())

Start server command: uvicorn app.server:app --host 0.0.0.0 --port 8000 --reload

Everything fine till I perform save file server.py, this time server will reload and shutdown

postgres-mcp-server-container  | INFO:     Waiting for application startup.
postgres-mcp-server-container  | INFO:     Application startup complete.
postgres-mcp-server-container  | INFO:     192.168.65.1:41967 - "GET /sse HTTP/1.1" 200 OK
postgres-mcp-server-container  | INFO:     192.168.65.1:26200 - "POST /messages/?session_id=a44e28b433964125b93e57f22692fe6a HTTP/1.1" 202 Accepted
postgres-mcp-server-container  | INFO:     192.168.65.1:26200 - "POST /messages/?session_id=a44e28b433964125b93e57f22692fe6a HTTP/1.1" 202 Accepted
postgres-mcp-server-container  | INFO:     192.168.65.1:26200 - "POST /messages/?session_id=a44e28b433964125b93e57f22692fe6a HTTP/1.1" 202 Accepted
postgres-mcp-server-container  | 2025-05-02 01:55:45,368 - INFO - Processing request of type ListResourcesRequest
postgres-mcp-server-container  | WARNING:  StatReload detected changes in 'server.py'. Reloading...
postgres-mcp-server-container  | INFO:     Shutting down
postgres-mcp-server-container  | INFO:     Waiting for connections to close. (CTRL+C to force quit)

Example Code

Version Information

FastMCP version: 2.2.6
MCP version: 1.6.0
Python version: 3.13.3
Platform: macOS-15.1-x86_64-i386-64bit-Mach-O

Additional Context

No response

@chungtran4078 chungtran4078 added the bug Something isn't working label May 2, 2025
@jlowin
Copy link
Owner

jlowin commented May 2, 2025

The low-level MCP server does not have the ability to shut down gracefully, and a new server is started for every SSE connection - that is why it is hanging. I have a branch in flight that will solve this for a different purpose.

@jlowin
Copy link
Owner

jlowin commented May 2, 2025

Actually this is more challenging to fix without modifying the low level server - however unfortunately it is not a FastMCP issue, as much as I would like to solve it as well.

@westonplatter
Copy link

I am seeing the same issue + discussion in the mcp python repo, modelcontextprotocol/python-sdk#514. This pull request was one of the proposed solutions, modelcontextprotocol/python-sdk#586. Cross posting in case it's helpful for others.

@chungtran4078
Copy link
Author

Thanks @jlowin @westonplatter a lot. I think i will wait for next release

@westonplatter
Copy link

Ah ha! Found a work around solution per @mattmess1221's comment. I was able to change the file, see the fastapi mcp app reboot, and reconnect to it using MCP Inspector v0.11.0.

# where my fastapi app is located in app/main.py as app
UVICORN_TIMEOUT_GRACEFUL_SHUTDOWN=0 uvicorn app.main:app --reload 

Using UVICORN_TIMEOUT_GRACEFUL_SHUTDOWN with the fastapi command did not work for me.

@jlowin
Copy link
Owner

jlowin commented May 5, 2025

@westonplatter while we wait for low-level improvements, #323 allows you to pass a graceful timeout shutdown param directly without the env var, and defaults it to 0. Hopefully that helps!

@leavor
Copy link

leavor commented May 7, 2025

downgrade uvicorn

pip install uvicorn==0.21.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants