BerriAI/litellm · error · HTTPException
Call not allowed to delete MCP server. User is not a proxy a
Error message
Call not allowed to delete MCP server. User is not a proxy admin. route={} What it means
Returned (403) by the delete MCP server endpoint: deletion is restricted to exactly LitellmUserRoles.PROXY_ADMIN, checked after the prisma client is obtained but before any deletion work. The error text helpfully embeds the route ('DELETE /v1/mcp/server') so callers can identify which management call was denied.
Source
Thrown at litellm/proxy/management_endpoints/mcp_management_endpoints.py:1998
),
):
"""
Delete MCP Server from db and associated MCP related server entities.
Parameters:
- server_id: str - Required. The unique identifier of the mcp server to delete.
```
curl -X "DELETE" --location 'http://localhost:4000/v1/mcp/server/server_id' \
--header 'Authorization: Bearer your_api_key_here'
```
"""
prisma_client: Final = get_prisma_client_or_throw(
"Database not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keys"
)
# Authz - restrict only admins to delete mcp servers
if LitellmUserRoles.PROXY_ADMIN != user_api_key_dict.user_role:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail={
"error": "Call not allowed to delete MCP server. User is not a proxy admin. route={}".format(
"DELETE /v1/mcp/server"
)
},
)
# try to delete the mcp server
mcp_server_record_deleted: Final = await delete_mcp_server(prisma_client, server_id)
if mcp_server_record_deleted is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail={"error": f"MCP Server not found, passed server_id={server_id}"},
)
global_mcp_server_manager.remove_server(mcp_server_record_deleted)
View on GitHub (pinned to 77b7c6c40c)
Solutions
- Perform deletions with the proxy master key or a PROXY_ADMIN user's key.
- Gate lifecycle automation on the key's role (check /key/info) before issuing DELETE calls.
- Route deletion requests from non-admins through an admin-owned workflow.
Example fix
# before
requests.delete(f"{PROXY}/v1/mcp/server/{server_id}", headers={"Authorization": f"Bearer {TEAM_KEY}"})
# after
requests.delete(f"{PROXY}/v1/mcp/server/{server_id}", headers={"Authorization": f"Bearer {os.environ['LITELLM_MASTER_KEY']}"}) Defensive patterns
Strategy: validation
Validate before calling
info = requests.get(f"{PROXY}/key/info", headers=AUTH, params={"key": KEY}).json()
if info.get("key_info", info).get("user_role") != "proxy_admin":
raise PermissionError("MCP server deletion requires a PROXY_ADMIN key") Type guard
def can_delete_mcp_server(user_role: str | None) -> bool:
return user_role == "proxy_admin" Try / catch
try:
delete_server(server_id)
except HTTPError as e:
if e.response.status_code == 403:
raise PermissionError("re-run DELETE with the master/admin key")
raise Prevention
- Use an admin key for all MCP lifecycle operations.
- Audit CI jobs that call DELETE endpoints for hard-coded non-admin keys.
When it happens
Trigger: DELETE /v1/mcp/server/{server_id} with an internal-user, team, or org-admin key; cleanup scripts run with a team virtual key; a non-admin attempting to remove a server they can view but not manage.
Common situations: Tearing down test servers with the wrong key in CI; team admins assuming view access implies delete rights; automation that authenticates with a per-team key for lifecycle operations.
Related errors
- User does not have permission to create mcp servers. You can
- User does not have permission to view mcp server with id {se
- User does not have permission to create temporary mcp server
- Access denied to MCP server {server_id}
- MCP Server not found, passed server_id={server_id}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/326ae897e0e98f7c.
Report an issue: GitHub.