litellm/litellm/proxy
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
..
_experimental fix(mcp-oauth): PROXY_BASE_URL escape hatch + diagnostic logging for {"detail":"invalid_request"} (#28086) 2026-05-16 17:48:03 -07:00
agent_endpoints fix(proxy): use set lookup for permitted agent filters 2026-05-01 21:47:18 -07:00
analytics_endpoints fix(spend): session-TZ-independent date filtering for spend/error log queries 2026-04-10 17:04:52 -07:00
anthropic_endpoints style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
auth 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
batches_endpoints fix(proxy/batches): forward model to retrieve_batch for bedrock 2026-04-29 22:48:03 +02:00
client fix: scope CLI stored token to base_url to prevent cross-domain credential leakage (#26945) 2026-05-01 12:11:32 -07:00
common_utils feat: litellm shin agent oss staging 05 10 2026 (#27631) 2026-05-11 20:31:43 -07:00
config_management_endpoints
container_endpoints chore(container): use delete_cache, json-encode scope key, clean test 2026-05-05 00:43:47 +00:00
credential_endpoints style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
custom_hooks style: run black formatter on entire codebase 2026-03-11 17:07:57 -03:00
db feat: add componentized proxy deployment with gateway, backend, ui, and migrations (#27557) 2026-05-16 09:25:17 -07:00
discovery_endpoints feat: add control plane for multi-proxy worker management 2026-03-19 22:50:19 -07:00
example_config_yaml chore(ci): modernize model references in tests and configs (#27856) 2026-05-15 15:44:28 -07:00
fine_tuning_endpoints style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
google_endpoints run pre_call_hook on Google generateContent endpoints 2026-04-30 16:43:42 -07:00
guardrails feat(lasso): add tool-calling support to LassoGuardrail (#27648) 2026-05-14 08:35:24 -07:00
health_check_utils feat(proxy): skip disable_background_health_check models on GET /health when flag set (#27716) 2026-05-13 09:49:05 -07:00
health_endpoints fix(proxy): expose db status on public /health/readiness 2026-05-13 13:02:38 -07:00
hooks fix(rate-limit): stop v3 limiter from leaking internal stash to provider body (#27913) 2026-05-14 10:53:04 -07:00
image_endpoints fix: tighten file input handling in image edit endpoints 2026-04-22 18:04:39 -07:00
management_endpoints fix(mcp): allow delegate PKCE bypass for internal MCP servers 2026-05-15 08:32:09 +05:30
management_helpers decouple S3 audit-log config via s3_audit_callback_params 2026-05-05 13:23:32 -07:00
memory Litellm memory improvements v2 (#26541) 2026-04-25 19:03:43 -07:00
middleware fix(proxy): point /metrics 401 at the opt-out flag 2026-05-08 18:09:14 -07:00
ocr_endpoints style: run black formatter on entire codebase 2026-03-11 17:07:57 -03:00
openai_evals_endpoints style: run black formatter on entire codebase 2026-03-11 17:07:57 -03:00
openai_files_endpoints harden cloud file compatibility path 2026-05-01 18:14:36 -07:00
pass_through_endpoints fix(proxy): thread config_file_path into pass-through and MCP-tool YAML loaders 2026-05-13 03:15:59 +00:00
policy_engine Fix runtime policy attachment initialization 2026-05-01 17:11:57 -07:00
prompts fix: harden /key/update authorization checks (#27878) 2026-05-14 04:16:04 +00:00
public_endpoints chore(proxy): keep public AI hub unauthenticated 2026-05-01 19:07:21 -07:00
rag_endpoints fix: harden /key/update authorization checks (#27878) 2026-05-14 04:16:04 +00:00
realtime_endpoints [Fix] Use type:ignore instead of Union return type for realtime endpoint 2026-03-13 11:42:26 -07:00
rerank_endpoints
response_api_endpoints fix: address Greptile review comments 2026-03-19 14:10:58 +05:30
response_polling style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
search_endpoints feat(proxy): move search tool access to object permissions 2026-04-29 12:29:20 +05:30
spend_tracking fix(spend-logs): redact echoed prompts in error_information (LIT-2992) (#27689) 2026-05-13 22:11:24 -07:00
swagger
test_prompts
types_utils fix(types_utils): drop opt-in env from remote-module runtime gate 2026-05-13 02:52:14 +00:00
ui_crud_endpoints fix(proxy): preserve public ai hub ui setting 2026-05-01 19:46:27 -07:00
vector_store_endpoints fix(vector_store): cache use-time embedding-config resolution 2026-05-03 10:27:53 +00:00
vector_store_files_endpoints chore(vector stores): address access review followups 2026-04-30 16:09:26 -07:00
vertex_ai_endpoints chore(callbacks): guard dynamic integration hosts 2026-04-30 14:27:19 -07:00
video_endpoints [Staging] - Ishaan March 17th (#23903) 2026-03-18 15:09:01 -07:00
workflows feat(proxy): durable agent workflow run tracking via /v1/workflows/runs (#26793) 2026-04-29 17:12:18 -07:00
.gitignore
__init__.py
_lazy_features.py Cache normalized SERVER_ROOT_PATH at middleware init 2026-05-12 21:00:31 -07:00
_lazy_openapi_snapshot.json Merge upstream/litellm_internal_staging into HEAD 2026-05-02 02:24:39 +00:00
_lazy_openapi_snapshot.py [Fix] Proxy: Repair Stale HTTP_METHODS Reference In Lazy OpenAPI Snapshot 2026-05-01 15:11:56 -07:00
_logging.py
_new_new_secret_config.yaml
_new_secret_config.yaml Litellm krrish staging 04 20 2026 (#26138) 2026-04-20 16:22:12 -07:00
_super_secret_config.yaml
_types.py Merge pull request #27801 from stuxf/chore/get-instance-fn-runtime-s3-gate 2026-05-13 20:53:54 -07:00
cached_logo.jpg
caching_routes.py
common_request_processing.py Preserve LiteLLM headers for passthrough responses (#27412) 2026-05-07 12:59:36 -07:00
compliance_checks.py
custom_auth_auto.py
custom_prompt_management.py
custom_sso.py style: run black formatter on entire codebase 2026-03-11 17:07:57 -03:00
custom_validate.py
dd_span_tagger.py style: run black formatter on entire codebase 2026-03-11 17:07:57 -03:00
enterprise
health_check.py Litellm agent oss staging 05 11 2026 (#27733) 2026-05-13 14:09:12 -07:00
lambda.py
litellm_pre_call_utils.py 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
llamaguard_prompt.txt
logo.jpg
mcp_registry.json feat(ui): group MCP tools by CRUD risk category in allowlist panels (#23403) 2026-03-11 21:15:25 -07:00
mcp_tools.py
model_config.yaml
openapi.json
openapi_registry.json feat(ui): OpenAPI MCP server support with popular API quick-picker (#23200) 2026-03-10 13:59:52 -07:00
post_call_rules.py
prisma_migration.py
prometheus_cleanup.py Add Prometheus child_exit cleanup for gunicorn workers 2026-02-27 16:11:15 -08:00
proxy_cli.py [litellm-agent] Staging → litellm_internal_staging (5/11/2026) (#27677) 2026-05-11 14:49:38 -07:00
proxy_config.yaml
proxy_server.py fix(proxy): sort BYOK models by their displayed name in /v2/model/info (#28079) 2026-05-16 15:46:21 -07:00
README.md build: migrate packaging, CI, and Docker from Poetry to uv (#25007) 2026-04-09 11:46:23 -07:00
route_llm_request.py feat(proxy): fix vector store retrieve/list/update/delete without model (#27929) 2026-05-15 04:37:59 -07:00
schema.prisma feat(mcp): add delegate_auth_to_upstream flag for PKCE passthrough (#27834) 2026-05-13 12:06:13 -07:00
start.sh
utils.py 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

litellm-proxy

A local, fast, and lightweight OpenAI-compatible server to call 100+ LLM APIs.

usage

$ uv tool install litellm
$ litellm --model ollama/codellama 

#INFO: Ollama running on http://0.0.0.0:8000

replace openai base

import openai # openai v1.0.0+
client = openai.OpenAI(api_key="anything",base_url="http://0.0.0.0:8000") # set proxy to base_url
# request sent to model set on litellm proxy, `litellm --model`
response = client.chat.completions.create(model="gpt-3.5-turbo", messages = [
    {
        "role": "user",
        "content": "this is a test request, write a short poem"
    }
])

print(response)

See how to call Huggingface,Bedrock,TogetherAI,Anthropic, etc.


Folder Structure

Routes

  • proxy_server.py - all openai-compatible routes - /v1/chat/completion, /v1/embedding + model info routes - /v1/models, /v1/model/info, /v1/model_group_info routes.
  • health_endpoints/ - /health, /health/liveliness, /health/readiness
  • management_endpoints/key_management_endpoints.py - all /key/* routes
  • management_endpoints/team_endpoints.py - all /team/* routes
  • management_endpoints/internal_user_endpoints.py - all /user/* routes
  • management_endpoints/ui_sso.py - all /sso/* routes