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 exists

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Re-run the call with the proxy master key or a key belonging to a PROXY_ADMIN user.
  2. Check the calling key's role first via /key/info (or user info) and only attempt creation when user_role is proxy_admin.
  3. 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

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


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/cf99bb90f2b383b8. Report an issue: GitHub.