fix(mcp): revert StreamableHTTPSessionManager to stateless mode (#21323)

PR #19809 changed stateless=True to stateless=False to enable progress
notifications for MCP tool calls. This caused the mcp library to enforce
mcp-session-id headers on all non-initialize requests, breaking MCP
Inspector, curl, and any client without automatic session management.

Revert to stateless=True to restore compatibility with all MCP clients.
The progress notification code already handles missing sessions gracefully
(defensive checks + try/except), so no other changes are needed.

Fixes #20242
This commit is contained in:
michelligabriele 2026-02-16 18:08:44 +01:00 • committed by GitHub
parent 0dcc744f7e
commit 035f0916ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 1 deletions

View file

@ -149,7 +149,7 @@ if MCP_AVAILABLE:
app=server,
event_store=None,
json_response=False, # enables SSE streaming
stateless=False, # enables session state
stateless=True,
)
# Create SSE session manager

View file

@ -779,6 +779,30 @@ async def test_concurrent_initialize_session_managers():
mcp_server._sse_session_manager_cm = original_sse_session_cm
@pytest.mark.asyncio
async def test_streamable_http_session_manager_is_stateless():
"""
Test that the StreamableHTTPSessionManager is initialized with stateless=True.
Regression test for GitHub issue #20242 / PR #19809.
When stateless=False, the mcp library rejects non-initialize requests
that lack an mcp-session-id header, breaking clients like MCP Inspector,
curl, and any HTTP client without automatic session management.
"""
try:
from litellm.proxy._experimental.mcp_server.server import session_manager
except ImportError:
pytest.skip("MCP server not available")
# The session manager must be stateless to avoid requiring mcp-session-id
# on every request. This was regressed by PR #19809 (stateless=True -> False).
assert session_manager.stateless is True, (
"StreamableHTTPSessionManager must be initialized with stateless=True. "
"stateless=False breaks MCP clients that don't manage session IDs. "
"See: https://github.com/BerriAI/litellm/issues/20242"
)
@pytest.mark.asyncio
@pytest.mark.no_parallel
async def test_mcp_routing_with_conflicting_alias_and_group_name():