fix(fastmcp): add session_idle_timeout parameter to prevent unbounded session memory growth#3443
fix(fastmcp): add session_idle_timeout parameter to prevent unbounded session memory growth#3443abhijeethp wants to merge 3 commits intoPrefectHQ:mainfrom
Conversation
… session memory growth
jlowin
left a comment
There was a problem hiding this comment.
Thanks - with no 1.27 in sight yet, I've added a dont merge label to prevent accidental conflicts.
I recommend the following:
- remove the conditional test skip; when you add this we should bump
mcp>=1.27, so add that to pyproject.toml - relatedly, I would expect CI to fail here until 1.27 exists. right now CI is protected if it runs on a lower version but users would experience an error if they tried to pass this I think
|
Thanks @jlowin for reviewing. Plan sounds good 👍 |
Test Failure AnalysisSummary: All CI jobs fail at the Root Cause: The latest commit ("Require mcp>=1.27.0 and remove runtime SDK detection") bumped the Suggested Solution: Revert the Detailed AnalysisFailing log excerpt (all 5 jobs): File causing the issue: - "mcp>=1.24.0,<2.0",
+ "mcp>=1.27.0,<2.0",The previous version of this PR used runtime inspection ( Related Files
|
| fastmcp.settings.session_idle_timeout = 60.0 | ||
| server = create_test_server() | ||
| # Should not raise - the setting is picked up | ||
| app = server.http_app() |
There was a problem hiding this comment.
this is a little weak of an assertion -- is there a way for us to verify this was applied to the server?
| fastmcp.settings.session_idle_timeout = 60.0 | ||
| server = create_test_server() | ||
| # Explicit value should override settings | ||
| app = server.http_app(session_idle_timeout=120.0) |
There was a problem hiding this comment.
this one is probably fine due to type checking?
Description
Add
session_idle_timeoutparameter to prevent unbounded session memory growthIn stateful HTTP mode (the default),
StreamableHTTPSessionManageraccumulates sessions in an in-memory dict without any TTL, cleanup, or max session limit. Disconnected clients leave orphaned sessions with live tasks and memory streams. Terminated sessions persist as zombie entries. Over time this causes unbounded memory growth, eventually leading to OOM on long-running servers.The MCP Python SDK has merged support for
session_idle_timeout([modelcontextprotocol/python-sdk#2022](modelcontextprotocol/python-sdk#2022), [modelcontextprotocol/python-sdk#1994](modelcontextprotocol/python-sdk#1994)) but has not yet released it. This PR threads the parameter through FastMCP so it is ready to use once the SDK releases.Changes
settings.py: Addsession_idle_timeout: float | None = None(configurable viaFASTMCP_SESSION_IDLE_TIMEOUTenv var)server/http.py: Acceptsession_idle_timeoutincreate_streamable_http_app(), pass it toStreamableHTTPSessionManagerwith runtime detection — logs a warning if the installed MCP SDK doesn't support it yetserver/mixins/transport.py: Threadsession_idle_timeoutthroughhttp_app()andrun_http_async()with settings fallbacktests/client/test_streamable_http.py: 6 new tests covering parameter threading, settings defaults, settings override, SDK compatibility warning, and end-to-end idle session cleanup (auto-skipped until SDK releases)Usage (once MCP SDK >= 1.27.0 is released)
Or via environment variable:
export FASTMCP_SESSION_IDLE_TIMEOUT=1800This PR was authored with the help of Claude Code.
Contributors Checklist
Review Checklist