litellm - 💡(How to fix) Fix [Bug]: MCP HTTP proxy client does not forward mcp-session-id to upstream stateful servers - tools never load [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#25128Fetched 2026-04-08 02:45:01
View on GitHub
Comments
2
Participants
2
Timeline
9
Reactions
0
Author
Participants
Timeline (top)
commented ×2labeled ×2mentioned ×2subscribed ×2

Error Message

This error fires because LiteLLM sends a second initialize (without a session ID, so the server treats it as a new connection) while the first session's transport is still active. The shared McpServer instance rejects the second connection.

Root Cause

This error fires because LiteLLM sends a second initialize (without a session ID, so the server treats it as a new connection) while the first session's transport is still active. The shared McpServer instance rejects the second connection.

Code Example

# Step 1 — initialize → server returns mcp-session-id
curl -X POST http://<host>:<port>/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' \
  -D -
# → response header: mcp-session-id: <uuid>

# Step 2 — tools/list WITH session ID → tools returned ✅
curl -X POST http://<host>:<port>/mcp \
  -H "Content-Type: application/json" \
  -H "mcp-session-id: <uuid>" \
  -d '[{"jsonrpc":"2.0","method":"notifications/initialized"},{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}]'

# Step 3 — tools/list WITHOUT session ID → server rejects / hangs ❌
# (This is what LiteLLM sends)
curl -X POST http://<host>:<port>/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

---

Server-side (`mcp-searxng` in HTTP mode) when LiteLLM connects:


Already connected to a transport


This error fires because LiteLLM sends a second `initialize` (without a session ID, so the server treats it as a new connection) while the first session's transport is still active. The shared `McpServer` instance rejects the second connection.

LiteLLM UI: tools list remains empty / spinner with "unable to load tools".
RAW_BUFFERClick to expand / collapse

Check for existing issues

  • I have searched the existing issues and checked that my issue is not a duplicate.

What happened?

When LiteLLM's proxy connects to an upstream MCP server via Streamable HTTP, it receives a mcp-session-id header in the initialize response but does not include that header in subsequent requests (tools/list, tools/call). Each follow-up request arrives at the upstream server without a session ID - the server treats it as a brand-new uninitialised session, and tools never load.

Expected: after receiving mcp-session-id: <uuid> in the initialize response, LiteLLM should echo that header back on all subsequent requests to the same upstream server, as required by the MCP Streamable HTTP spec.

This is the outbound MCP HTTP client behaviour (LiteLLM connecting to upstream servers), distinct from #20242 which concerned LiteLLM's own server-side session manager.

Steps to Reproduce

  1. Start any stateful Streamable HTTP MCP server - e.g. isokoliuk/mcp-searxng with MCP_HTTP_PORT set, or Supergateway in --stateful mode.
  2. Add it in the LiteLLM UI: MCP Servers → Add New MCP Server, Transport = HTTP, URL = http://<host>:<port>/mcp.
  3. Observe: UI shows "unable to load tools" / zero tools appear.
  4. Confirm the server itself works when the session ID is forwarded manually:
# Step 1 — initialize → server returns mcp-session-id
curl -X POST http://<host>:<port>/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' \
  -D -
# → response header: mcp-session-id: <uuid>

# Step 2 — tools/list WITH session ID → tools returned ✅
curl -X POST http://<host>:<port>/mcp \
  -H "Content-Type: application/json" \
  -H "mcp-session-id: <uuid>" \
  -d '[{"jsonrpc":"2.0","method":"notifications/initialized"},{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}]'

# Step 3 — tools/list WITHOUT session ID → server rejects / hangs ❌
# (This is what LiteLLM sends)
curl -X POST http://<host>:<port>/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

Relevant log output

Server-side (`mcp-searxng` in HTTP mode) when LiteLLM connects:


Already connected to a transport


This error fires because LiteLLM sends a second `initialize` (without a session ID, so the server treats it as a new connection) while the first session's transport is still active. The shared `McpServer` instance rejects the second connection.

LiteLLM UI: tools list remains empty / spinner with "unable to load tools".

What part of LiteLLM is this about?

Proxy

What LiteLLM version are you on ?

v.1.81.4

Twitter / LinkedIn details

@axelquack

extent analysis

TL;DR

The issue can be fixed by modifying the LiteLLM proxy to include the mcp-session-id header in subsequent requests after receiving it in the initialize response.

Guidance

  • Verify that the mcp-session-id header is being received correctly in the initialize response by checking the response headers.
  • Modify the LiteLLM proxy to store the mcp-session-id header and include it in subsequent requests to the same upstream server.
  • Check the MCP Streamable HTTP spec to ensure that the implementation is correct and aligns with the expected behavior.
  • Test the fix by repeating the steps to reproduce and verifying that the tools list is loaded correctly.

Example

No code snippet is provided as the issue does not include specific code details, but the fix would involve modifying the LiteLLM proxy to handle the mcp-session-id header correctly.

Notes

The issue seems to be specific to the LiteLLM proxy and its handling of the mcp-session-id header. The fix would require modifying the proxy to correctly handle this header and include it in subsequent requests.

Recommendation

Apply a workaround by modifying the LiteLLM proxy to include the mcp-session-id header in subsequent requests, as this is the most direct way to address the issue and align with the MCP Streamable HTTP spec.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

litellm - 💡(How to fix) Fix [Bug]: MCP HTTP proxy client does not forward mcp-session-id to upstream stateful servers - tools never load [2 comments, 2 participants]