Skip to content

Commit 7e4e454

Browse files
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
1 parent 6afd486 commit 7e4e454

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

litellm/proxy/_experimental/mcp_server/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class ListMCPToolsRestAPIResponseObject(MCPTool):
149149
app=server,
150150
event_store=None,
151151
json_response=False, # enables SSE streaming
152-
stateless=False, # enables session state
152+
stateless=True,
153153
)
154154

155155
# Create SSE session manager

tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,31 @@ async def init_task():
756756

757757

758758
@pytest.mark.asyncio
759+
async def test_streamable_http_session_manager_is_stateless():
760+
"""
761+
Test that the StreamableHTTPSessionManager is initialized with stateless=True.
762+
763+
Regression test for GitHub issue #20242 / PR #19809.
764+
When stateless=False, the mcp library rejects non-initialize requests
765+
that lack an mcp-session-id header, breaking clients like MCP Inspector,
766+
curl, and any HTTP client without automatic session management.
767+
"""
768+
try:
769+
from litellm.proxy._experimental.mcp_server.server import session_manager
770+
except ImportError:
771+
pytest.skip("MCP server not available")
772+
773+
# The session manager must be stateless to avoid requiring mcp-session-id
774+
# on every request. This was regressed by PR #19809 (stateless=True -> False).
775+
assert session_manager.stateless is True, (
776+
"StreamableHTTPSessionManager must be initialized with stateless=True. "
777+
"stateless=False breaks MCP clients that don't manage session IDs. "
778+
"See: https://github.com/BerriAI/litellm/issues/20242"
779+
)
780+
781+
782+
@pytest.mark.asyncio
783+
@pytest.mark.no_parallel
759784
async def test_mcp_routing_with_conflicting_alias_and_group_name():
760785
"""
761786
Tests (GH #14536) where an MCP server alias (e.g., "group/id")

0 commit comments

Comments
 (0)