fix(mcp): allow view-only admin to use /register; add _validate_mcp_required_fields tests

This commit is contained in:
Ishaan Jaffer 2026-03-10 13:21:35 -07:00
parent 90e256d805
commit 36b2f7bb45
2 changed files with 71 additions and 4 deletions

View file

@ -746,10 +746,7 @@ if MCP_AVAILABLE:
Creates the server with approval_status=pending_review.
Requires a team-scoped API key.
"""
if user_api_key_dict.user_role in (
LitellmUserRoles.PROXY_ADMIN,
LitellmUserRoles.PROXY_ADMIN_VIEW_ONLY,
):
if user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail={

View file

@ -1767,3 +1767,73 @@ class TestMCPApprovalWorkflow:
)
assert result is not None
mock_manager.reload_servers_from_database.assert_awaited_once()
class TestValidateMCPRequiredFields:
"""Tests for _validate_mcp_required_fields."""
def test_missing_required_field_raises_400(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 absent
)
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 == 400
assert "source_url" in str(exc_info.value.detail)
def test_auth_type_sentinel_treated_as_absent(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,
auth_type=MCPAuth.none, # sentinel value — treated as absent
)
with patch_proxy_general_settings({"mcp_required_fields": ["auth_type"]}):
with pytest.raises(HTTPException) as exc_info:
_validate_mcp_required_fields(payload)
assert exc_info.value.status_code == 400
assert "auth_type" in str(exc_info.value.detail)
def test_all_required_fields_present_passes(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="https://github.com/org/repo",
auth_type=MCPAuth.bearer_token,
)
with patch_proxy_general_settings(
{"mcp_required_fields": ["source_url", "auth_type"]}
):
# Should not raise
_validate_mcp_required_fields(payload)
def test_no_required_fields_configured_always_passes(self):
from litellm.proxy.management_endpoints.mcp_management_endpoints import (
_validate_mcp_required_fields,
)
payload = NewMCPServerRequest(
alias="Minimal",
url="https://example.com/mcp",
transport=MCPTransport.sse,
)
with patch_proxy_general_settings({}):
# Should not raise when no required fields are configured
_validate_mcp_required_fields(payload)