[Fix] UI - MCP Servers: Make auth value optional for create flow - #22119
Conversation
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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR makes
Confidence Score: 4/5
|
| 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]
Last reviewed commit: a4fd75f
| @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 |
There was a problem hiding this comment.
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.
| @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 | |
| # 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. |
…_req [Fix] UI - MCP Servers: Make auth value optional for create flow
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
NewMCPServerRequestPydantic validator rejected requests without it. This blocked users who want to configure auth dynamically via per-request headers or OAuth2 flows.Fix
create_mcp_server.tsx): Changed auth_value fromrequired: trueto an optional validator that only rejects whitespace-only strings (matching the existing edit flow behavior)._types.py): Removed thevalidate_credentials_requirementsvalidator onNewMCPServerRequest. All downstream code already treatsauth_valueas optional — the auth resolution chain falls back to per-request headers and OAuth2 tokens.Testing
CreateMCPServercomponent 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.Type
🐛 Bug Fix
✅ Test