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

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-24 21:11:37 +01:00 committed by GitHub
parent 6afd486b1d
commit 7e4e4545c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 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

@ -756,6 +756,31 @@ async def test_concurrent_initialize_session_managers():
@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():
"""
Tests (GH #14536) where an MCP server alias (e.g., "group/id")