litellm - 💡(How to fix) Fix GET /v1/mcp/server returns delegate_auth_to_upstream: false when database row is true

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

This makes the Admin UI toggle appear off after save/reload, and may cause subsequent updates to write false back to the database because the UI re-syncs from the GET response.

Code Example

SELECT server_name, delegate_auth_to_upstream
FROM "LiteLLM_MCPServerTable";
-- delegate_auth_to_upstream = true

---

curl -s http://localhost:4000/v1/mcp/server \
  -H "Authorization: Bearer <proxy-admin-key>"
RAW_BUFFERClick to expand / collapse

Describe the bug

When an MCP server is created or updated with delegate_auth_to_upstream: true, the value persists in PostgreSQL, but GET /v1/mcp/server consistently returns delegate_auth_to_upstream: false.

This makes the Admin UI toggle appear off after save/reload, and may cause subsequent updates to write false back to the database because the UI re-syncs from the GET response.

To Reproduce

  1. Run LiteLLM proxy with STORE_MODEL_IN_DB=True and a connected Postgres database (migration 20260513120000_add_delegate_auth_to_upstream_to_mcp_servers applied).
  2. Create or update an OAuth2 MCP server with delegate_auth_to_upstream: true via POST /v1/mcp/server or PUT /v1/mcp/server, or via the Admin UI.
  3. Confirm the value in the database:
SELECT server_name, delegate_auth_to_upstream
FROM "LiteLLM_MCPServerTable";
-- delegate_auth_to_upstream = true
  1. Fetch the server via the management API:
curl -s http://localhost:4000/v1/mcp/server \
  -H "Authorization: Bearer <proxy-admin-key>"
  1. Observe that the same server returns "delegate_auth_to_upstream": false.

Expected behavior

GET /v1/mcp/server should return the same delegate_auth_to_upstream value stored in the database.

The Admin UI toggle should remain enabled after save/reload when the field is true in the DB.

Actual behavior

  • Database: delegate_auth_to_upstream = true
  • GET /v1/mcp/server: "delegate_auth_to_upstream": false
  • UI toggle resets to off after reload (likely because MCPPermissionManagement.tsx syncs form state from the GET response)

Impact

  • UI: Toggle state is incorrect; saving again can overwrite the DB value back to false.
  • Runtime: In-memory registry may not honor delegate_auth_to_upstream, affecting OAuth2 delegate-auth behavior for MCP clients.

Environment

  • Image: docker.io/litellm/litellm-non_root:main-stable
  • Digest: sha256:97ce25938fc7f38f14a4036df78ba3d57725706b6183488af9931750e395c673
  • LiteLLM proxy with DB-backed MCP servers (STORE_MODEL_IN_DB=True)
  • Version includes delegate_auth_to_upstream support (migration 20260513120000_add_delegate_auth_to_upstream_to_mcp_servers)
  • OAuth2 MCP server (auth_type: oauth2, HTTP transport)
  • Reproduced on local Docker deployment

Additional context

There is a unit test asserting _build_mcp_server_table() preserves the flag when the in-memory MCPServer object has it set:

tests/test_litellm/proxy/_experimental/mcp_server/auth/test_user_api_key_auth_mcp.py::test_build_mcp_server_table_preserves_delegate_auth_to_upstream

That suggests the list/GET path may be losing the value earlier — when hydrating the in-memory registry from the database — rather than in _build_mcp_server_table() itself.

Relevant code paths to investigate:

  1. GET /v1/mcp/server reads from the in-memory registry via get_all_mcp_servers_unfiltered()_build_mcp_server_table(), not directly from Postgres.
  2. reload_servers_from_database() in mcp_server_manager.py reuses existing registry entries when updated_at matches, skipping build_mcp_server_from_table(). If the cached entry has a stale delegate_auth_to_upstream value, reload will not pick up the DB change.
  3. DB hydration uses LiteLLM_MCPServerTable(**r.model_dump()). If the Prisma model omits the field, Pydantic defaults it to false.

A regression/integration test covering DB write → reload → GET round-trip for delegate_auth_to_upstream would likely catch this.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

GET /v1/mcp/server should return the same delegate_auth_to_upstream value stored in the database.

The Admin UI toggle should remain enabled after save/reload when the field is true in the DB.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

litellm - 💡(How to fix) Fix GET /v1/mcp/server returns delegate_auth_to_upstream: false when database row is true