Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion litellm/proxy/_experimental/mcp_server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class ListMCPToolsRestAPIResponseObject(MCPTool):
app=server,
event_store=None,
json_response=False, # enables SSE streaming
stateless=False, # enables session state
stateless=True,
)

# Create SSE session manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,30 @@ async def init_task():
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():
Expand Down
Loading