fix(proxy): share temporary MCP OAuth sessions across instances via Redis - #26318
Conversation
…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
Low: No security issues foundThis 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 Posted by Veria AI · 2026-04-23T09:10:23.246Z |
Greptile SummaryThis 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 Confidence Score: 5/5Safe 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.
|
| 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
Reviews (1): Last reviewed commit: "fix(mcp): share temporary MCP OAuth sess..." | Re-trigger Greptile
2001d91
into
litellm_internal_staging
…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
Relevant issues
Fixes temporary MCP OAuth session lookup failures in multi-instance/LB proxy deployments where
/v1/mcp/server/oauth/sessionis 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
tests/test_litellm/directory, Adding at least 1 test is a hard requirement - see detailsmake test-unit@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewCI (LiteLLM team)
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 -v61 passedFocused path validation also covered temporary MCP OAuth handlers, Redis fallback logic, and encrypted Redis payload read/write paths in:
TestTemporaryMCPSessionEndpointsType
🐛 Bug Fix
✅ Test
Changes
authorize,token,register) to await them.