mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
fix(mcp): validate field names in mcp_required_fields; surface backend error in submit UI
This commit is contained in:
parent
36b2f7bb45
commit
31f6568bad
3 changed files with 38 additions and 2 deletions
|
|
@ -161,6 +161,10 @@ if MCP_AVAILABLE:
|
|||
_base_validate_and_normalize_mcp_server_payload(payload)
|
||||
_validate_mcp_server_name_fields(payload)
|
||||
|
||||
_VALID_MCP_REQUIRED_FIELDS: frozenset = frozenset(
|
||||
NewMCPServerRequest.model_fields
|
||||
)
|
||||
|
||||
def _validate_mcp_required_fields(payload: Any) -> None:
|
||||
"""Validate submission payload against admin-configured mcp_required_fields."""
|
||||
from litellm.proxy.proxy_server import (
|
||||
|
|
@ -173,6 +177,18 @@ if MCP_AVAILABLE:
|
|||
if not required_fields:
|
||||
return
|
||||
|
||||
# Fail fast on unknown field names — a typo in the config would silently
|
||||
# block every submission with a confusing "missing fields" error.
|
||||
unknown = [f for f in required_fields if f not in _VALID_MCP_REQUIRED_FIELDS]
|
||||
if unknown:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail={
|
||||
"error": f"mcp_required_fields contains unknown field names: {unknown}. "
|
||||
"Check general_settings.mcp_required_fields in your proxy config."
|
||||
},
|
||||
)
|
||||
|
||||
# Mirror the UI's compliance checks (MCPStandardsSettings.tsx FIELD_GROUPS):
|
||||
# auth_type requires a real value — "none" is treated as absent.
|
||||
_AUTH_TYPE_SENTINEL = "none"
|
||||
|
|
@ -750,7 +766,7 @@ if MCP_AVAILABLE:
|
|||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail={
|
||||
"error": "Admin users should use POST /v1/mcp/server to create servers directly instead of the submission workflow."
|
||||
"error": "PROXY_ADMIN users should use POST /v1/mcp/server to create servers directly instead of the submission workflow."
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1837,3 +1837,20 @@ class TestValidateMCPRequiredFields:
|
|||
with patch_proxy_general_settings({}):
|
||||
# Should not raise when no required fields are configured
|
||||
_validate_mcp_required_fields(payload)
|
||||
|
||||
def test_unknown_field_name_in_config_raises_500(self):
|
||||
from litellm.proxy.management_endpoints.mcp_management_endpoints import (
|
||||
_validate_mcp_required_fields,
|
||||
)
|
||||
|
||||
payload = NewMCPServerRequest(
|
||||
alias="My Server",
|
||||
url="https://example.com/mcp",
|
||||
transport=MCPTransport.sse,
|
||||
)
|
||||
# "source_Url" is a typo — not a real field on NewMCPServerRequest
|
||||
with patch_proxy_general_settings({"mcp_required_fields": ["source_Url"]}):
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
_validate_mcp_required_fields(payload)
|
||||
assert exc_info.value.status_code == 500
|
||||
assert "source_Url" in str(exc_info.value.detail)
|
||||
|
|
|
|||
|
|
@ -391,7 +391,10 @@ const CreateMCPServer: React.FC<CreateMCPServerProps> = ({
|
|||
onCreateSuccess(response);
|
||||
}
|
||||
} catch (error) {
|
||||
NotificationsManager.fromBackend("Error creating MCP Server: " + error);
|
||||
const reason = error instanceof Error ? error.message : String(error);
|
||||
NotificationsManager.fromBackend(
|
||||
isAdmin ? `Error creating MCP Server: ${reason}` : `Error submitting MCP Server: ${reason}`
|
||||
);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue