BerriAI/litellm · error · HTTPException
User does not have permission to test MCP server tools. Only
Error message
User does not have permission to test MCP server tools. Only PROXY_ADMIN users can perform this action.
What it means
POST /mcp-rest/test/tools/list previews the tools an MCP server would expose before registering it (including generating tools from an OpenAPI spec when spec_path is set). Like /test/connection, it is restricted to PROXY_ADMIN callers because it reaches arbitrary hosts; anyone else gets HTTP 403 with this message.
Source
Thrown at litellm/proxy/_experimental/mcp_server/rest_endpoints.py:1356
return {"status": "ok"}
return await _execute_with_mcp_client(
new_mcp_server_request,
_test_connection_operation,
raw_headers=_safe_get_request_headers(request),
)
@router.post("/test/tools/list", dependencies=[Depends(user_api_key_auth)])
async def test_tools_list(
request: Request,
new_mcp_server_request: NewMCPServerRequest,
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
):
"""
Preview tools available from MCP server before adding it
"""
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 test MCP server tools. Only PROXY_ADMIN users can perform this action."
},
)
new_mcp_server_request = _inherit_credentials_from_existing_server(new_mcp_server_request)
# For OpenAPI spec servers, generate tools from the spec directly
if new_mcp_server_request.spec_path:
return await _preview_openapi_tools(new_mcp_server_request.spec_path)
from litellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcp import (
MCPRequestHandler,
)
headers: Final = request.headers
View on GitHub (pinned to 77b7c6c40c)
Solutions
- Use a key whose user has the PROXY_ADMIN role for this preview endpoint.
- Grant the role to the intended user in the admin UI, then retry.
- For non-admin users, register the server via the admin flow and preview tools with GET /mcp-rest/tools/list instead.
Defensive patterns
Strategy: validation
Validate before calling
async def can_preview_tools(client: httpx.AsyncClient) -> bool:
info = (await client.get(f"{base}/key/info")).json()
return info.get("key_info", {}).get("user_role") == "proxy_admin" Type guard
def is_proxy_admin_key(key_info: dict) -> bool:
return key_info.get("user_role") == "proxy_admin" Try / catch
except httpx.HTTPStatusError as e:
if e.response.status_code == 403 and "PROXY_ADMIN" in e.response.text:
raise PermissionError("test/tools/list requires a PROXY_ADMIN key") from e
raise Prevention
- Gate automated onboarding pipelines on an admin key role check before previewing tools.
- Non-admins: after an admin registers the server, use GET /mcp-rest/tools/list to see tools instead of this preview.
When it happens
Trigger: Calling POST /mcp-rest/test/tools/list with a virtual key whose user role is not PROXY_ADMIN; automated onboarding pipelines using team-level keys.
Common situations: Same as the connection test: non-admin automation trying to validate MCP server configs; scripts written against admin credentials later run with restricted keys.
Related errors
- User does not have permission to test MCP server connections
- forbidden
- access_denied
- User not allowed to call this tool.
- MCPJWTSigner: incoming token is missing required claims: {mi
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/55329ec14a37002c.
Report an issue: GitHub.