Skip to content

[Fix] UI - MCP Servers: Make auth value optional for create flow - #22119

Merged
yuneng-jiang merged 1 commit into
mainfrom
litellm_ui_mcp_auth_non_req
Feb 26, 2026
Merged

[Fix] UI - MCP Servers: Make auth value optional for create flow#22119
yuneng-jiang merged 1 commit into
mainfrom
litellm_ui_mcp_auth_non_req

Conversation

@yuneng-jiang

Copy link
Copy Markdown
Contributor

Relevant issues

Summary

Failure Path (Before Fix)

When adding an auth-based MCP server (API Key, Bearer Token, or Basic Auth) from the UI, users were forced to provide the auth value upfront. The frontend form required the field, and the backend NewMCPServerRequest Pydantic validator rejected requests without it. This blocked users who want to configure auth dynamically via per-request headers or OAuth2 flows.

Fix

  • Frontend (create_mcp_server.tsx): Changed auth_value from required: true to an optional validator that only rejects whitespace-only strings (matching the existing edit flow behavior).
  • Backend (_types.py): Removed the validate_credentials_requirements validator on NewMCPServerRequest. All downstream code already treats auth_value as optional — the auth resolution chain falls back to per-request headers and OAuth2 tokens.

Testing

  • Added 15 unit tests for the CreateMCPServer component covering: rendering, transport selection, auth type selection, auth value optional behavior (API Key, Bearer Token), server creation with/without auth value, stdio transport, prefill from discovery, and cancel/back flows.
  • All 26 existing backend MCP management endpoint tests pass (excluding 1 pre-existing unrelated failure).
  • All 17 MCP REST endpoint tests pass.

Type

🐛 Bug Fix
✅ Test

The backend validator and frontend form both enforced auth_value as
required when auth_type is api_key, bearer_token, or basic. Users who
want to provide auth dynamically (via per-request headers or OAuth2
flows) could not skip the field.

- Remove required validation from auth_value in create_mcp_server.tsx
  (keep whitespace-only rejection, matching the edit flow)
- Remove validate_credentials_requirements in NewMCPServerRequest
  (all downstream code already treats auth_value as optional)
- Add tests for the create MCP server component

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Feb 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Building Building Preview, Comment Feb 25, 2026 8:04pm

Request Review

@greptile-apps

greptile-apps Bot commented Feb 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes auth_value optional when creating MCP servers via the UI and backend, aligning the create flow with the existing edit flow. Previously, the backend Pydantic validator on NewMCPServerRequest required auth_value for API Key, Bearer Token, and Basic auth types, and the frontend form enforced it as required — blocking users who configure auth dynamically via per-request headers or OAuth2 flows.

  • Backend (_types.py): Removed the enforcement logic inside validate_credentials_requirements, though the method itself remains as a no-op @model_validator. All downstream code (DB layer, server builder, request execution, auth resolution) already treats auth_value as optional.
  • Frontend (create_mcp_server.tsx): Changed auth_value from required: true to an optional validator that only rejects whitespace-only strings, matching the edit flow's existing behavior.
  • Tests (create_mcp_server.test.tsx): Added 15 unit tests covering rendering, transport selection, auth type selection, optional auth value behavior, server creation with/without auth, stdio transport, prefill data, and cancel/back flows.

Confidence Score: 4/5

  • This PR is safe to merge — the change removes a restriction that was inconsistent with the rest of the codebase, and downstream code already handles optional auth_value gracefully.
  • Score of 4 reflects that the core logic change is correct and well-tested: all downstream backend code (DB, server builder, auth resolution) already treats auth_value as optional, and the frontend now matches the edit flow. One minor style issue: the backend validator is left as a no-op rather than being fully removed. Test coverage is comprehensive.
  • Minor cleanup in litellm/proxy/_types.py — the no-op validate_credentials_requirements validator could be removed entirely.

Important Files Changed

Filename Overview
litellm/proxy/_types.py Removed the validate_credentials_requirements validator logic that required auth_value for api_key/bearer_token/basic auth types. The validator body is now a no-op (just returns values), which works correctly but leaves dead code.
ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.tsx Changed auth_value form field from required: true to an optional validator that only rejects whitespace-only strings. This matches the existing edit flow behavior. Remaining changes are formatting/whitespace cleanup.
ui/litellm-dashboard/src/components/mcp_tools/create_mcp_server.test.tsx New test file with 15 tests covering rendering, transport selection, auth type selection, optional auth value behavior, server creation flows, stdio transport, prefill data, and cancel/back flows. Tests are well-structured and follow most project conventions.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User Creates MCP Server in UI] --> B{Auth Type?}
    B -->|None| C[No credentials in payload]
    B -->|API Key / Bearer / Basic| D{Auth Value Provided?}
    D -->|Yes| E[Include credentials in payload]
    D -->|No / Empty| F[Skip credentials in payload]
    C --> G[Backend: NewMCPServerRequest]
    E --> G
    F --> G
    G --> H[DB: Store server config]
    H --> I{Request-time Auth Resolution}
    I -->|1. Per-request header| J[Use request header]
    I -->|2. OAuth2 client_credentials| K[Fetch & cache OAuth token]
    I -->|3. Static auth_value| L[Use stored token]
    I -->|None available| M[No auth headers added]
Loading

Last reviewed commit: a4fd75f

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread litellm/proxy/_types.py
Comment on lines 1113 to 1122
@model_validator(mode="before")
@classmethod
def validate_credentials_requirements(cls, values):
if not isinstance(values, dict):
return values

auth_type = values.get("auth_type")
if auth_type in {MCPAuth.api_key, MCPAuth.bearer_token, MCPAuth.basic}:
credentials = values.get("credentials")
auth_value = None
if isinstance(credentials, dict):
auth_value = credentials.get("auth_value")
elif hasattr(credentials, "get"):
auth_value = credentials.get("auth_value") # type: ignore[attr-defined]

if not auth_value:
raise ValueError(
"auth_value is required when auth_type is api_key, bearer_token, or basic"
)
"""Validate credentials when provided.

auth_value is optional — users may configure it dynamically
(e.g. via per-request headers or OAuth2 flows) instead of
storing a static value at server creation time.
"""
return values

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No-op validator should be removed

The validate_credentials_requirements method is now a @model_validator that does nothing — it just returns values unchanged. Keeping it as a decorated method adds unnecessary overhead (Pydantic will still invoke it on every instantiation) and may mislead future readers into thinking validation is happening here.

Consider removing the method entirely rather than leaving it as a no-op with a docstring. If preserving the design rationale is important, a class-level comment would be cleaner.

Suggested change
@model_validator(mode="before")
@classmethod
def validate_credentials_requirements(cls, values):
if not isinstance(values, dict):
return values
auth_type = values.get("auth_type")
if auth_type in {MCPAuth.api_key, MCPAuth.bearer_token, MCPAuth.basic}:
credentials = values.get("credentials")
auth_value = None
if isinstance(credentials, dict):
auth_value = credentials.get("auth_value")
elif hasattr(credentials, "get"):
auth_value = credentials.get("auth_value") # type: ignore[attr-defined]
if not auth_value:
raise ValueError(
"auth_value is required when auth_type is api_key, bearer_token, or basic"
)
"""Validate credentials when provided.
auth_value is optionalusers may configure it dynamically
(e.g. via per-request headers or OAuth2 flows) instead of
storing a static value at server creation time.
"""
return values
# Note: auth_value is intentionally optional — users may configure it
# dynamically (e.g. via per-request headers or OAuth2 flows) instead
# of storing a static value at server creation time.

@yuneng-jiang
yuneng-jiang merged commit 88bf8de into main Feb 26, 2026
60 of 93 checks passed
@ishaan-berri
ishaan-berri deleted the litellm_ui_mcp_auth_non_req branch March 26, 2026 22:30
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
…_req

[Fix] UI - MCP Servers: Make auth value optional for create flow
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.

1 participant