litellm/litellm
Mateo Wang 1b0ae3af83
fix(mcp-oauth): PROXY_BASE_URL escape hatch + diagnostic logging for {"detail":"invalid_request"} (#28086)
* fix(mcp-oauth): add PROXY_BASE_URL escape hatch + diagnostic logging for invalid_request

Customers hitting "{"detail":"invalid_request"}" on the MCP /authorize
endpoint had no way to recover when their ingress mangles X-Forwarded-*
headers (the same-origin check in validate_trusted_redirect_uri compares
the browser-supplied redirect_uri against get_request_base_url, which is
reconstructed from those headers).

Two contained changes:

  1. get_request_base_url now honours PROXY_BASE_URL as the canonical
     public origin when set, bypassing the X-Forwarded-* trust gate
     entirely. Operators who know their public URL can set it once
     instead of debugging ingress header rewrites.

  2. The rejection path in validate_trusted_redirect_uri emits a WARN
     log carrying the redirect_uri, computed proxy base, and the
     X-Forwarded-* / Host headers seen. A bare 400 was undiagnosable;
     this turns it into a one-line root-cause.

* test(mcp-oauth): capture warnings from correct logger ("LiteLLM")

Co-authored-by: Yassin Kortam <yassin@berri.ai>

* fix(mcp-oauth): reject malformed PROXY_BASE_URL with one-shot diagnostic

A scheme-less PROXY_BASE_URL (e.g. "litellm.example.com" instead of
"https://litellm.example.com") would sail through urlparse with empty
scheme + netloc, silently breaking every same-origin compare in
validate_trusted_redirect_uri and leaving the operator staring at the
same opaque 400 the env var was meant to fix.

Validate it once at read time: only honour values that parse as
http(s) URLs with a non-empty netloc; otherwise log a one-shot WARN
naming the bad value and fall through to the request-derived origin
so the proxy still serves traffic.

* fix(mcp/oauth): normalize PROXY_BASE_URL to strip query/fragment

Match the X-Forwarded-* path's normalization so a configured
PROXY_BASE_URL containing a query string or fragment does not break
downstream f-string concatenation like f"{base_url}/callback".

Co-authored-by: Yassin Kortam <yassin@berri.ai>

* refactor(mcp-oauth): drop non-essential comments from PROXY_BASE_URL changes

Strip narrative comments and verbose docstrings added in this PR; the
code is intuitive enough on its own and the log messages already carry
their own diagnostic context. Pre-existing comments are left untouched.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Yassin Kortam <yassin@berri.ai>
2026-05-16 17:48:03 -07:00
..
a2a_protocol
anthropic_interface
assistants
batch_completion
batches fix(vertex-ai): fix zero cost/usage on completed Vertex AI batch jobs (#27912) 2026-05-15 04:47:02 -07:00
caching chore(caching): remove allow_legacy_unscoped_cache_hits opt-in 2026-05-04 22:16:30 +00:00
completion_extras fix(responses): normalize chat tool_choice for completions→responses bridge (#27634) 2026-05-11 10:24:34 -07:00
compression
containers
endpoints/speech/speech_to_completion_bridge
evals
experimental_mcp_client feat(mcp): add OBO MCP Auth (#27421) 2026-05-07 15:35:21 -07:00
files thread trusted params through vertex file content 2026-05-01 18:24:22 -07:00
fine_tuning
google_genai
images
integrations feat(otel): set http.response.status_code on the success SERVER span (#28090) 2026-05-16 15:29:56 -07:00
interactions
litellm_core_utils feat(otel): OTel-standard attributes on the proxy SERVER span (status code, route/path, preprocessing latency) (#28040) 2026-05-16 13:45:08 -07:00
llms fix(bedrock-mantle): use /anthropic/v1/messages path for Mantle endpo… (#27976) 2026-05-15 13:31:59 -07:00
ocr chore: reject bare str at file-input sinks to prevent local-file read (#27762) 2026-05-12 16:40:07 -07:00
passthrough
proxy fix(mcp-oauth): PROXY_BASE_URL escape hatch + diagnostic logging for {"detail":"invalid_request"} (#28086) 2026-05-16 17:48:03 -07:00
proxy_auth
rag
realtime_api
rerank_api
responses fix(responses): preserve cache_control in Responses API -> Chat Completion transformation (#27727) 2026-05-13 12:17:06 -07:00
router_strategy feat: add weighted-routing failover (#27980) 2026-05-15 17:28:54 +00:00
router_utils fix(responses): register cooldowns on failure + fail fast on stale encrypted_content (#27820) 2026-05-13 09:03:13 -07:00
search
secret_managers Implement normalize_nonempty_secret_str function to trim whitespace from secrets and treat empty values as unset. Update proxy_server to use this function for Grafana credentials. Enhance tests to validate the new normalization behavior. 2026-05-04 18:17:31 +00:00
skills chore(proxy): scope skills and container resources 2026-04-30 18:23:58 -07:00
types feat(mcp): add delegate_auth_to_upstream flag for PKCE passthrough (#27834) 2026-05-13 12:06:13 -07:00
vector_store_files
vector_stores
videos
__init__.py Add Bedrock Claude Platform route (#27678) 2026-05-11 15:50:54 -07:00
_internal_context.py
_lazy_imports.py
_lazy_imports_registry.py fix(utils): import get_secret at runtime (#28014) 2026-05-15 14:01:18 -07:00
_logging.py fix(bedrock-mantle): use /anthropic/v1/messages path for Mantle endpo… (#27976) 2026-05-15 13:31:59 -07:00
_redis.py fix: Fix Redis Sentinel client handling to solve authentication error… (#26302) 2026-05-13 14:06:58 -07:00
_redis_credential_provider.py feat: add ability to auth to azure with token (#27556) 2026-05-09 22:34:09 +00:00
_service_logger.py
_uuid.py
_version.py
anthropic_beta_headers_config.json fix(anthropic,bedrock,databricks): four reasoning_effort follow-ups 2026-05-03 10:03:53 -07:00
anthropic_beta_headers_manager.py
blog_posts.json
budget_manager.py docs(budget_manager): add docstring to BudgetManager.reset_cost (#27867) 2026-05-13 13:28:22 -07:00
constants.py feat(mcp): support MCP access group names in URL-based namespacing (#27726) 2026-05-13 20:20:38 -07:00
cost.json
cost_calculator.py fix(vertex-ai): fix zero cost/usage on completed Vertex AI batch jobs (#27912) 2026-05-15 04:47:02 -07:00
exceptions.py
main.py Match litellm.completion supported model parameters with proxy model info (#27720) 2026-05-12 08:25:01 -07:00
model_prices_and_context_window_backup.json feat(model_catalog): add Azure AI Foundry GPT-5.4 model metadata (#28030) 2026-05-16 15:08:10 -07:00
mypy.ini
policy_templates_backup.json
provider_endpoints_support_backup.json
py.typed
router.py feat: add weighted-routing failover (#27980) 2026-05-15 17:28:54 +00:00
scheduler.py
setup_wizard.py
timeout.py docs: add class docstring to _LoopWrapper (#27870) 2026-05-13 13:54:00 -07:00
utils.py fix(utils): import get_secret at runtime (#28014) 2026-05-15 14:01:18 -07:00