litellm/tests/unit/proxy/_experimental
Pujitha Paladugu d5c9d17d47
fix(mcp): forward caller's extra headers in true_passthrough auth probe
Motivation:
_probe_upstream_auth predicts whether a true_passthrough MCP server will
accept the caller's request before a stateful session opens, so LiteLLM can
return a 401 up front instead of masking the rejection as an empty tool
list. The probe only ever sent Accept and Authorization upstream. When an
upstream identifies the caller through a different header the admin already
configured in server.extra_headers (a gateway-issued platform header, for
example), the probe always looked anonymous to it, so it answered 401 for
every caller including ones with a valid session, and every connect got the
pre-session challenge regardless of whether the caller was actually
authorized.

Approach:
Added _extra_headers_for_probe, which takes the caller's raw request headers
and the server's configured extra_headers list and returns just the values
for those header names (case-insensitively matched), always excluding
authorization since the probe already sets that separately. _probe_upstream_auth
gained an extra_headers parameter that merges into the outgoing probe
request. The is_true_passthrough branch in
_raise_preemptive_401_for_unauthenticated_servers now passes the caller's
configured extra headers into the probe, using the raw_headers parameter
that function already receives. The is_oauth_passthrough /
_check_passthrough_upstream_auth path is untouched, matching the issue's
stated scope.

Validation:
PYTHONPATH=. pytest tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py -v
passes all 240 tests (235 existing + 5 new). Reverting only the server.py
change (git stash) makes the 5 new/changed tests fail, including one that
raises the exact HTTPException: 401 the issue describes, confirming they are
a real regression guard rather than a structural check. ruff check, ruff
format --check, and basedpyright were run on both changed files: no new
basedpyright errors were introduced in server.py (236 before and after), and
the small increase in the test file (reportPrivateUsage / reportAny noise
from calling internal helpers directly, matching this test file's existing
whitebox pattern) stays well under the repo's basedpyright-code-budget.json
limits for those rules.

Disclosure: dependencies were installed into a local virtualenv rather than
through the maturin/editable install this repo normally uses, because of
disk-space limits in this environment; litellm was imported directly from
source with PYTHONPATH, and the Rust bridge already no-ops gracefully when
its compiled extension is absent. No live MCP server was reachable to
reproduce the issue end to end; the fix and its tests are demonstrated at
the unit level described above.

Report: https://github.com/BerriAI/litellm/issues/40099
Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Assisted-by: claude-sonnet-5 (via Claude Code)
2026-10-02 06:48:02 -07:00
..
mcp_server fix(mcp): forward caller's extra headers in true_passthrough auth probe 2026-10-02 06:48:02 -07:00
__init__.py ci: move provider-independent MCP tests into tests/unit and run mcp-integration from litellm-tests (#42904) 2026-09-24 23:07:48 +00:00