litellm/litellm
Ishaan Jaff 19db79db17
fix(mcp): OAuth2 chat connect - tools fetch, auth, and status fixes (#23406)
* fix(mcp): OAuth2 chat connect - tools fetch, auth flow, and status fixes

- schema.prisma: add missing MCP table fields (approval_status, submitted_by, submitted_at, reviewed_at, review_notes) to prevent destructive migrations
- rest_endpoints.py: inject user OAuth token via extra_headers for OAuth2 servers so tools list is populated; add server name->UUID resolution so MCPConnectPicker name lookups work
- mcp_registry.json: fix Atlassian defaults (transport: http, url: .../v1/mcp)
- ChatPage.tsx: read mcpOauthReturn param to init sidebarView="apps" on OAuth return, clean up param after mount
- MCPAppsPanel.tsx: auto-add OAuth2 servers to selectedServers when credential detected; onConnect also enables server for chat; disconnect removes from selectedServers
- mcp_servers.tsx: sort servers by created_at DESC
- useUserMcpOAuthFlow.tsx: append mcpOauthReturn=apps to return URL so Apps panel is mounted on return

* address greptile review feedback (greploop iteration 1)

* fix(mcp): inject stored OAuth2 token when fetching tools via /responses API

When a user has connected an OAuth2 MCP server (e.g. Atlassian) and then
uses the /responses endpoint with that server, tool listing was failing
because the stored per-user OAuth token was never injected.

Two fixes:
1. server.py: add _get_user_oauth_extra_headers_from_db() helper; call it
   in _get_tools_from_mcp_servers when oauth2_headers is None for an OAuth2
   server, falling back to the user's stored token in LiteLLM_MCPUserCredentials
2. litellm_proxy_mcp_handler.py: also intercept MCP tools whose server_url
   matches */mcp/<server_name> (e.g. http://localhost:4000/mcp/atlassian_test)
   by rewriting them to litellm_proxy/mcp/<server_name> so they go through
   the internal handler (and get the OAuth token injected) instead of being
   forwarded to OpenAI raw where localhost is unreachable

* address greptile review feedback (greploop iteration 2)

* test(mcp): add unit test for OAuth2 token injection in _get_tools_from_mcp_servers

Verifies that when _get_tools_from_mcp_servers is called for an OAuth2 MCP
server without oauth2_headers in the request, the implementation:
- calls _prefetch_oauth_creds_for_user once (not per-server) to avoid N+1 queries
- passes the stored token as extra_headers={"Authorization": "Bearer ..."} to
  _get_tools_from_server so the upstream OAuth2 MCP server authenticates correctly

* address greptile review feedback (greploop iteration 3)

* address greptile review feedback (greploop iteration 4)

* address greptile review feedback (greploop iteration 5)

* redesign credentials table to use Tremor table layout matching Keys page

* fix: /server/oauth authorize 422 - make client_id optional, fall back to real DB server

* fix: mcp_token client_id optional, resolve from server record

* fix: look up real server by UUID (get_mcp_server_by_id) before falling back to name

* Update litellm/responses/mcp/litellm_proxy_mcp_handler.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix: address greptile feedback - client_id guards, dict spread, helper refactor, tests

- mcp_management_endpoints: raise 400 when resolved_client_id is empty in
  mcp_authorize and mcp_token instead of forwarding "" to upstream
- litellm_proxy_mcp_handler: use {**tool, "server_url": ...} spread instead
  of dict(tool) + mutation for shallow copy safety
- rest_endpoints: extract _oauth2_server_ids set comprehension to a named
  _get_oauth2_server_ids() helper for clarity; add Set to typing imports
- test_rest_endpoints: add tests for name→UUID resolution path,
  access-denied when resolved UUID not in allowed list, and OAuth2 user
  token injection for single-server requests; fix fake_get_tools signature
  to accept extra_headers kwarg

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-03-11 22:07:02 -07:00
..
a2a_protocol CircleCI test stability (#23055) 2026-03-07 15:19:39 -08:00
anthropic_interface fix: prompt registry 2026-02-18 00:34:54 +05:30
assistants
batch_completion fix: prompt registry 2026-02-18 00:34:54 +05:30
batches Agents - add max budget + tpm/rpm limiting per agent AND per agent session (#22849) 2026-03-07 19:12:42 -08:00
caching Revert "feat: add model_cost aliases expansion support" 2026-03-10 22:39:19 -03:00
completion_extras Revert "feat: add model_cost aliases expansion support" 2026-03-10 22:39:19 -03:00
containers fix: prompt registry 2026-02-18 00:34:54 +05:30
endpoints/speech/speech_to_completion_bridge
evals fix: prompt registry 2026-02-18 00:34:54 +05:30
experimental_mcp_client fix(mcp): add AWS SigV4 auth for Bedrock AgentCore MCP servers (#22782) 2026-03-10 11:11:20 -07:00
files Merge pull request #22765 from BerriAI/main 2026-03-04 17:40:42 +05:30
fine_tuning Agents - add max budget + tpm/rpm limiting per agent AND per agent session (#22849) 2026-03-07 19:12:42 -08:00
google_genai fix(completion): unify finish_reason mapping to OpenAI-compatible values 2026-02-26 00:12:39 -03:00
images refactor(bfl): separate HTTP logic into dedicated handlers 2026-03-04 18:10:09 -03:00
integrations fix: anthropic prompt caching returns a string instead of an int 2026-03-10 13:51:17 -04:00
interactions fix: prompt registry 2026-02-18 00:34:54 +05:30
litellm_core_utils Fix ruff lint errors: unused imports, undefined names, and statement counts 2026-03-11 14:34:43 -07:00
llms fix(snowflake): transform string tool_choice to object format (#23318) 2026-03-11 21:29:59 -07:00
ocr Enable local file support for OCR (#22133) 2026-02-27 10:50:02 -08:00
passthrough fix(passthrough): propagate Azure 429/5xx errors in async streaming instead of silent HTTP 200 (#22913) 2026-03-05 10:12:43 -08:00
proxy fix(mcp): OAuth2 chat connect - tools fetch, auth, and status fixes (#23406) 2026-03-11 22:07:02 -07:00
proxy_auth fix: prompt registry 2026-02-18 00:34:54 +05:30
rag fix: prompt registry 2026-02-18 00:34:54 +05:30
realtime_api fix(azure): forward realtime_protocol from config and relax api_version check for GA path (#22369) 2026-03-02 19:21:27 +05:30
rerank_api fix(bedrock): pass timeout param to bedrock rerank http client (#22021) 2026-02-24 09:32:11 -08:00
responses fix(mcp): OAuth2 chat connect - tools fetch, auth, and status fixes (#23406) 2026-03-11 22:07:02 -07:00
router_strategy Revert "feat: add model_cost aliases expansion support" 2026-03-10 22:39:19 -03:00
router_utils Fix encrypted content streaming affinity issue 2026-03-03 18:37:22 +05:30
search
secret_managers feat: Hashicorp Vault config override backend endpoints 2026-03-05 16:57:08 -08:00
skills fix: prompt registry 2026-02-18 00:34:54 +05:30
types feat(mcp): add AWS SigV4 auth support in UI and fix credential merge on edit (#23282) 2026-03-11 09:43:28 -07:00
vector_store_files
vector_stores
videos fix(ollama): thread api_base to get_model_info + graceful fallback (#21970) 2026-02-23 21:00:37 -08:00
__init__.py merge: resolve conflicts between main and litellm_oss_staging_03_04_2026 2026-03-10 10:45:04 -03:00
_lazy_imports.py fix: prompt registry 2026-02-18 00:34:54 +05:30
_lazy_imports_registry.py Merge pull request #22866 from mubashir1osmani/feat/bedrock-mantle-provider-clean 2026-03-05 18:24:00 +05:30
_logging.py fix: prompt registry 2026-02-18 00:34:54 +05:30
_redis.py fix: close leaked Redis connection pools on cache eviction and disconnect 2026-02-20 17:09:32 -08:00
_service_logger.py fix: prompt registry 2026-02-18 00:34:54 +05:30
_uuid.py
_version.py
anthropic_beta_headers_config.json fix: enable context-1m-2025-08-07 beta header for vertex_ai provider (#21867) 2026-02-21 20:12:23 -08:00
anthropic_beta_headers_manager.py fix: prompt registry 2026-02-18 00:34:54 +05:30
blog_posts.json fix(ollama): thread api_base to get_model_info + graceful fallback (#21970) 2026-02-23 21:00:37 -08:00
budget_manager.py
constants.py fix: resolve merge conflicts with staging branch 2026-03-10 17:27:57 -03:00
cost.json
cost_calculator.py feat(azure_ai): add router flat cost when response contains actual model 2026-03-06 18:18:06 +05:30
exceptions.py Remove nit 2026-02-26 13:44:06 -08:00
main.py Fix ruff lint errors: unused imports, undefined names, and statement counts 2026-03-11 14:34:43 -07:00
model_prices_and_context_window_backup.json feat(ui): group MCP tools by CRUD risk category in allowlist panels (#23403) 2026-03-11 21:15:25 -07:00
mypy.ini
policy_templates_backup.json feat(add-new-block_code_execution-guardrail): prevent agent from executing code (#22154) 2026-02-25 22:02:14 -08:00
provider_endpoints_support_backup.json feat(search): add Serper (serper.dev) as search provider (#23112) 2026-03-09 08:40:37 -07:00
py.typed
router.py Merge branch 'main' into litellm_oss_staging_03_10_2026 2026-03-11 18:32:17 +05:30
scheduler.py fix: prompt registry 2026-02-18 00:34:54 +05:30
timeout.py
utils.py Merge pull request #23322 from BerriAI/litellm_gemini_embedding_2_support 2026-03-11 19:30:09 +05:30