diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index d850b6f0525..7a376380521 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -1625,17 +1625,24 @@ class Member(MemberBase): @field_validator("extra_permissions", mode="before") @classmethod def validate_permission_format(cls, v): - """Validate that all permission strings follow the resource:action format.""" + """Validate that all permission strings are known valid permissions.""" if v is None: return v if not isinstance(v, list): raise ValueError("extra_permissions must be a list of strings") + from litellm.proxy.auth.permissions import VALID_PERMISSIONS + for perm in v: if not isinstance(perm, str) or ":" not in perm: raise ValueError( f"Invalid permission format: '{perm}'. " "Must follow 'resource:action' format (e.g. 'mcp:create')." ) + if perm not in VALID_PERMISSIONS: + raise ValueError( + f"Unknown permission: '{perm}'. " + f"Valid permissions: {sorted(VALID_PERMISSIONS)}" + ) return v diff --git a/litellm/proxy/management_endpoints/mcp_management_endpoints.py b/litellm/proxy/management_endpoints/mcp_management_endpoints.py index ac1f7c833d7..38628a460eb 100644 --- a/litellm/proxy/management_endpoints/mcp_management_endpoints.py +++ b/litellm/proxy/management_endpoints/mcp_management_endpoints.py @@ -1854,7 +1854,7 @@ if MCP_AVAILABLE: description="Allows updating mcp servers in the db", dependencies=[Depends(user_api_key_auth)], response_model=LiteLLM_MCPServerTable, - status_code=status.HTTP_200_OK, + status_code=status.HTTP_202_ACCEPTED, ) @management_endpoint_wrapper async def edit_mcp_server( diff --git a/litellm/proxy/management_helpers/object_permission_utils.py b/litellm/proxy/management_helpers/object_permission_utils.py index 1f2bef0d191..a4b52962332 100644 --- a/litellm/proxy/management_helpers/object_permission_utils.py +++ b/litellm/proxy/management_helpers/object_permission_utils.py @@ -366,6 +366,13 @@ async def validate_key_mcp_servers_against_team( ) +def _invalidate_team_cache(team_id: str) -> None: + """Invalidate the cached team object so subsequent reads see updated data.""" + from litellm.proxy.proxy_server import user_api_key_cache + + user_api_key_cache.delete_cache(key="team_id:{}".format(team_id)) + + async def add_mcp_server_to_team( prisma_client: PrismaClient, team_id: str, server_id: str ) -> None: @@ -421,6 +428,9 @@ async def add_mcp_server_to_team( data={"object_permission_id": object_permission_id}, ) + # Invalidate team cache so the updated mcp_servers list is visible immediately + _invalidate_team_cache(team_id) + async def remove_mcp_server_from_team( prisma_client: PrismaClient, team_id: str, server_id: str @@ -452,3 +462,6 @@ async def remove_mcp_server_from_team( where={"object_permission_id": team.object_permission_id}, data={"mcp_servers": updated_servers}, ) + + # Invalidate team cache so the updated mcp_servers list is visible immediately + _invalidate_team_cache(team_id)