{"record":{"id":"55329ec14a37002c","repo":"BerriAI/litellm","slug":"user-does-not-have-permission-to-test-mcp-server-t","errorCode":null,"errorMessage":"User does not have permission to test MCP server tools. Only PROXY_ADMIN users can perform this action.","messagePattern":"User does not have permission to test MCP server tools\\. Only PROXY_ADMIN users can perform this action\\.","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"litellm/proxy/_experimental/mcp_server/rest_endpoints.py","lineNumber":1356,"sourceCode":"            return {\"status\": \"ok\"}\n\n        return await _execute_with_mcp_client(\n            new_mcp_server_request,\n            _test_connection_operation,\n            raw_headers=_safe_get_request_headers(request),\n        )\n\n    @router.post(\"/test/tools/list\", dependencies=[Depends(user_api_key_auth)])\n    async def test_tools_list(\n        request: Request,\n        new_mcp_server_request: NewMCPServerRequest,\n        user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),\n    ):\n        \"\"\"\n        Preview tools available from MCP server before adding it\n        \"\"\"\n        if LitellmUserRoles.PROXY_ADMIN != user_api_key_dict.user_role:\n            raise HTTPException(\n                status_code=status.HTTP_403_FORBIDDEN,\n                detail={\n                    \"error\": \"User does not have permission to test MCP server tools. Only PROXY_ADMIN users can perform this action.\"\n                },\n            )\n\n        new_mcp_server_request = _inherit_credentials_from_existing_server(new_mcp_server_request)\n\n        # For OpenAPI spec servers, generate tools from the spec directly\n        if new_mcp_server_request.spec_path:\n            return await _preview_openapi_tools(new_mcp_server_request.spec_path)\n\n        from litellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcp import (\n            MCPRequestHandler,\n        )\n\n        headers: Final = request.headers\n","sourceCodeStart":1338,"sourceCodeEnd":1374,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/_experimental/mcp_server/rest_endpoints.py#L1338-L1374","documentation":"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.","triggerScenarios":"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.","commonSituations":"Same as the connection test: non-admin automation trying to validate MCP server configs; scripts written against admin credentials later run with restricted keys.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async def can_preview_tools(client: httpx.AsyncClient) -> bool:\n    info = (await client.get(f\"{base}/key/info\")).json()\n    return info.get(\"key_info\", {}).get(\"user_role\") == \"proxy_admin\"","typeGuard":"def is_proxy_admin_key(key_info: dict) -> bool:\n    return key_info.get(\"user_role\") == \"proxy_admin\"","tryCatchPattern":"except httpx.HTTPStatusError as e:\n    if e.response.status_code == 403 and \"PROXY_ADMIN\" in e.response.text:\n        raise PermissionError(\"test/tools/list requires a PROXY_ADMIN key\") from e\n    raise","preventionTips":["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."],"tags":["mcp","authorization","http-403","admin-only"],"backgroundTag":"permission-denied-403","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}