BerriAI/litellm · error · HTTPException
User does not have permission to create mcp servers. You can
Error message
User does not have permission to create mcp servers. You can only create mcp servers if you are a PROXY_ADMIN.
What it means
Returned (403) by the create MCP server endpoint because it restricts creation to exactly LitellmUserRoles.PROXY_ADMIN — the check is strict role equality on user_api_key_dict.user_role, so internal users, team admins, and org admins are all rejected. The guard runs after payload validation but before any uniqueness or reserved-id checks.
Source
Thrown at litellm/proxy/management_endpoints/mcp_management_endpoints.py:1543
payload: NewMCPServerRequest,
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
litellm_changed_by: str | None = Header(
None,
description="The litellm-changed-by header enables tracking of actions performed by authorized users on behalf of other users, providing an audit trail for accountability",
),
):
"""
Allow users to add a new external mcp server.
"""
prisma_client: Final = get_prisma_client_or_throw("Database not connected. Connect a database to your proxy")
# Validate and normalize payload fields
validate_and_normalize_mcp_server_payload(payload)
stamp_omitted_oauth2_flow(payload)
# AuthZ - restrict only proxy admins to create mcp servers
if LitellmUserRoles.PROXY_ADMIN != user_api_key_dict.user_role:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail={
"error": "User does not have permission to create mcp servers. You can only create mcp servers if you are a PROXY_ADMIN."
},
)
# Block reserved special server IDs
if (
SpecialMCPServerName.all_team_servers == payload.server_id
or SpecialMCPServerName.all_proxy_servers == payload.server_id
):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail={"error": f"MCP Server with id {payload.server_id} is special and cannot be used."},
)
if payload.server_id is not None:
# fail if the mcp server with id already existsView on GitHub (pinned to 77b7c6c40c)
Solutions
- Re-run the call with the proxy master key or a key belonging to a PROXY_ADMIN user.
- Check the calling key's role first via /key/info (or user info) and only attempt creation when user_role is proxy_admin.
- Have a proxy admin pre-create the server and grant it to the team.
Example fix
# before: team admin key
requests.post(f"{PROXY}/v1/mcp/server", headers={"Authorization": f"Bearer {TEAM_ADMIN_KEY}"}, json=payload)
# after: proxy master key (role == proxy_admin)
requests.post(f"{PROXY}/v1/mcp/server", headers={"Authorization": f"Bearer {os.environ['LITELLM_MASTER_KEY']}"}, json=payload) Defensive patterns
Strategy: validation
Validate before calling
info = requests.get(f"{PROXY}/key/info", headers=AUTH, params={"key": KEY}).json()
role = info.get("key_info", info).get("user_role")
if role != "proxy_admin":
raise PermissionError("MCP server creation requires a PROXY_ADMIN key") Type guard
def is_proxy_admin(key_info: dict) -> bool:
return key_info.get("user_role") == "proxy_admin" Try / catch
try:
create_server(payload)
except HTTPError as e:
if e.response.status_code == 403:
raise PermissionError("re-run with the proxy master key or a proxy-admin user's key")
raise Prevention
- Keep a dedicated PROXY_ADMIN key for provisioning scripts.
- Check user_role via /key/info before management calls.
- Never assume team-admin rank grants MCP create rights.
When it happens
Trigger: POST to the mcp server create endpoint with an internal-user or team virtual key; a team admin trying to self-serve an MCP server; any key whose user_role is not PROXY_ADMIN (note the master key authenticates as proxy admin and passes).
Common situations: Teams trying to register their own MCP servers without proxy-admin involvement; scripts run with a user-level key instead of the master key; assuming team-admin rank implies MCP create rights.
Related errors
- Call not allowed to delete MCP server. User is not a proxy a
- 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}
- User {user_api_key_dict.user_id} does not have access to vec
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/cf99bb90f2b383b8.
Report an issue: GitHub.