Summary
The session_idle_timeout feature currently has two linked problems:
- it is implemented on
StreamableHTTPSessionManager but not exposed through the canonical streamable_http_app() API surface
- it can terminate a session while a request is actively in flight
Why this looks like a bug
PR #1994 / #2022 describe session_idle_timeout as a way to reap sessions that receive no HTTP requests for the configured duration.
That implies two things:
- users of the high-level StreamableHTTP API should be able to configure it without dropping down to manual session-manager wiring
- a request that is currently being processed should not count as an idle session
Today neither of those expectations holds.
Problem 1: not exposed by streamable_http_app()
StreamableHTTPSessionManager(...) accepts session_idle_timeout, but:
mcp.server.lowlevel.server.Server.streamable_http_app(...) does not
mcp.server.mcpserver.server.MCPServer.streamable_http_app(...) does not
So the recommended high-level API cannot configure a supported session-manager feature.
Reproduction
from mcp.server import Server
app = Server("demo")
app.streamable_http_app(session_idle_timeout=30)
Observed behavior
TypeError: Server.streamable_http_app() got an unexpected keyword argument 'session_idle_timeout'
Problem 2: active requests can be cancelled by the idle timeout
With a short idle timeout and a handler that takes longer than that timeout, the session can be reaped mid-request and the client waits until timeout / session termination rather than receiving the tool result.
Reproduction outline
- configure
StreamableHTTPSessionManager(app=..., session_idle_timeout=...)
- make a tool handler sleep longer than the timeout
- call the tool over StreamableHTTP
Observed behavior
On current main, the active request can be terminated before the handler finishes, and the client fails instead of receiving the result.
Expected behavior
streamable_http_app() should expose session_idle_timeout
- idle reaping should only happen when the session has no in-flight requests
- once the last active request finishes, the idle deadline can resume normally
Validation
I reproduced both behaviors locally against current main.
I also verified that a minimal patch can fix both together by:
- threading
session_idle_timeout through the low-level + MCPServer streamable_http_app() wrappers
- suspending idle reaping while at least one request is in flight
- restoring the idle deadline after the last active request completes
A focused regression suite in tests/server/test_streamable_http_manager.py can cover:
- passthrough from
streamable_http_app(session_idle_timeout=...)
- active request longer than the timeout still completes successfully
- existing idle-session reaping still works once requests are finished
Summary
The
session_idle_timeoutfeature currently has two linked problems:StreamableHTTPSessionManagerbut not exposed through the canonicalstreamable_http_app()API surfaceWhy this looks like a bug
PR #1994 / #2022 describe
session_idle_timeoutas a way to reap sessions that receive no HTTP requests for the configured duration.That implies two things:
Today neither of those expectations holds.
Problem 1: not exposed by
streamable_http_app()StreamableHTTPSessionManager(...)acceptssession_idle_timeout, but:mcp.server.lowlevel.server.Server.streamable_http_app(...)does notmcp.server.mcpserver.server.MCPServer.streamable_http_app(...)does notSo the recommended high-level API cannot configure a supported session-manager feature.
Reproduction
Observed behavior
Problem 2: active requests can be cancelled by the idle timeout
With a short idle timeout and a handler that takes longer than that timeout, the session can be reaped mid-request and the client waits until timeout / session termination rather than receiving the tool result.
Reproduction outline
StreamableHTTPSessionManager(app=..., session_idle_timeout=...)Observed behavior
On current
main, the active request can be terminated before the handler finishes, and the client fails instead of receiving the result.Expected behavior
streamable_http_app()should exposesession_idle_timeoutValidation
I reproduced both behaviors locally against current
main.I also verified that a minimal patch can fix both together by:
session_idle_timeoutthrough the low-level + MCPServerstreamable_http_app()wrappersA focused regression suite in
tests/server/test_streamable_http_manager.pycan cover:streamable_http_app(session_idle_timeout=...)