Skip to content

fix(proxy): share temporary MCP OAuth sessions across instances via Redis - #26318

Merged
ishaan-berri merged 1 commit into
litellm_internal_stagingfrom
litellm_temp_mcp_redis_cache_reapply
Apr 23, 2026
Merged

fix(proxy): share temporary MCP OAuth sessions across instances via Redis#26318
ishaan-berri merged 1 commit into
litellm_internal_stagingfrom
litellm_temp_mcp_redis_cache_reapply

Conversation

@milan-berri

@milan-berri milan-berri commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

Fixes temporary MCP OAuth session lookup failures in multi-instance/LB proxy deployments where /v1/mcp/server/oauth/session is created on one instance and subsequent /server/oauth/{server_id}/... requests may land on another.

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Screenshots / Proof of Fix

Targeted local test runs:

  • poetry run python -m pytest tests/test_litellm/proxy/management_endpoints/test_mcp_management_endpoints.py -v
    • Result: 61 passed

Focused path validation also covered temporary MCP OAuth handlers, Redis fallback logic, and encrypted Redis payload read/write paths in:

  • TestTemporaryMCPSessionEndpoints

Type

🐛 Bug Fix
✅ Test

Changes

  • Fixes multi-instance/LB temporary MCP OAuth flow by sharing temporary MCP session servers in Redis (instead of process-only memory).
  • Keeps current in-memory cache as fallback/L1; Redis is best-effort shared backing store.
  • Encrypts temporary MCP session payloads before Redis write and decrypts on Redis read using existing proxy encryption/decryption helpers.
  • Converts temporary MCP cache lookup helpers to async and updates OAuth endpoints (authorize, token, register) to await them.
  • Adds/updates unit tests for:
    • Redis fallback lookup on local-cache miss
    • Redis write key + TTL behavior
    • encrypted payload write/decrypt read paths
    • async lookup call path assertions

…is (#26162)

Temporary MCP OAuth sessions were kept in process-local memory, so on
multi-instance/LB proxy deployments a session created on instance A could
not be found when the follow-up /server/oauth/{server_id}/... request
landed on instance B.

Persist temporary session records to Redis (encrypted with the existing
proxy encryption helpers) as a best-effort L2 cache alongside the current
in-memory L1. Convert get_cached_temporary_mcp_server to async and await
it from the authorize/token/register OAuth endpoints.

Made-with: Cursor
@veria-ai

veria-ai Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Low: No security issues found

This PR adds Redis-backed caching for temporary MCP OAuth sessions to share them across proxy instances. The implementation properly encrypts MCPServer payloads (which contain OAuth secrets and credentials) before writing to Redis, validates types on the read path to reject non-encrypted payloads, and maintains existing PROXY_ADMIN and user_api_key_auth requirements on all affected endpoints. Error handling is defensive with graceful fallbacks.


Status: 0 open
Risk: 2/10

Posted by Veria AI · 2026-04-23T09:10:23.246Z

@greptile-apps

greptile-apps Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes temporary MCP OAuth session lookup failures in multi-instance/load-balanced proxy deployments by adding a Redis write-through layer alongside the existing process-local cache. New encrypted async_set_cache/async_get_cache helpers (_cache_temporary_mcp_server_in_redis / _get_temporary_mcp_server_from_redis) are added, get_cached_temporary_mcp_server and _get_cached_temporary_mcp_server_or_404 are converted to async, and the three OAuth endpoints (authorize, token, register) are updated to await them. The only finding is a minor style issue where a normal Redis cache miss (None return) triggers the same debug log path as an unexpected non-string payload.

Confidence Score: 5/5

Safe to merge; all remaining findings are P2 style suggestions that do not affect correctness.

The logic is correct: local cache is checked first, Redis is a best-effort fallback, encrypt/decrypt is applied consistently, and error paths all return None without raising. Tests thoroughly cover the new code paths. The single inline comment is a P2 log-message clarity issue.

No files require special attention.

Important Files Changed

Filename Overview
litellm/proxy/management_endpoints/mcp_management_endpoints.py Adds Redis write-through (_cache_temporary_mcp_server_in_redis) and Redis read-fallback (_get_temporary_mcp_server_from_redis) helpers with encrypt/decrypt. Converts get_cached_temporary_mcp_server and _get_cached_temporary_mcp_server_or_404 to async and updates authorize/token/register endpoints to await them. One minor style issue: null-cache-miss and non-string-payload are conflated in a single isinstance check with a misleading log message.
tests/test_litellm/proxy/management_endpoints/test_mcp_management_endpoints.py Adds 8 new async tests covering Redis fallback, TTL/key correctness, encrypt/decrypt paths, and error-handling edge cases. Existing tests correctly updated to async and assert_awaited_once_with. Coverage is thorough.

Sequence Diagram

sequenceDiagram
    participant Client
    participant InstanceA as Proxy Instance A
    participant InstanceB as Proxy Instance B
    participant LocalA as Local Cache (A)
    participant Redis as Redis (shared)

    Client->>InstanceA: POST /v1/mcp/server/oauth/session
    InstanceA->>LocalA: _cache_temporary_mcp_server(server, ttl=300)
    InstanceA->>Redis: _cache_temporary_mcp_server_in_redis(encrypted, ttl=300)
    InstanceA-->>Client: temp session response

    Client->>InstanceB: GET /server/oauth/{server_id}/authorize
    InstanceB->>InstanceB: get_cached_temporary_mcp_server(server_id)
    InstanceB->>LocalA: _prune_expired + local dict lookup → MISS
    InstanceB->>Redis: _get_temporary_mcp_server_from_redis(server_id)
    Redis-->>InstanceB: encrypted payload
    InstanceB->>InstanceB: decrypt_value_helper → MCPServer
    InstanceB-->>Client: OAuth authorize redirect
Loading

Reviews (1): Last reviewed commit: "fix(mcp): share temporary MCP OAuth sess..." | Re-trigger Greptile

Comment thread litellm/proxy/management_endpoints/mcp_management_endpoints.py
@ishaan-berri
ishaan-berri merged commit 2001d91 into litellm_internal_staging Apr 23, 2026
99 of 100 checks passed
@ishaan-berri
ishaan-berri deleted the litellm_temp_mcp_redis_cache_reapply branch April 23, 2026 23:21
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
…is (BerriAI#26162) (BerriAI#26318)

Temporary MCP OAuth sessions were kept in process-local memory, so on
multi-instance/LB proxy deployments a session created on instance A could
not be found when the follow-up /server/oauth/{server_id}/... request
landed on instance B.

Persist temporary session records to Redis (encrypted with the existing
proxy encryption helpers) as a best-effort L2 cache alongside the current
in-memory L1. Convert get_cached_temporary_mcp_server to async and await
it from the authorize/token/register OAuth endpoints.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants