{"record":{"id":"b659fea219dc9f9f","repo":"BerriAI/litellm","slug":"access-denied-to-mcp-server-server-id","errorCode":null,"errorMessage":"Access denied to MCP server {server_id}","messagePattern":"Access denied to MCP server (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"litellm/proxy/management_endpoints/mcp_management_endpoints.py","lineNumber":1806,"sourceCode":"\n            client_ip: Final = IPAddressUtils.get_mcp_client_ip(request) if request else None\n            server = global_mcp_server_manager.get_mcp_server_by_id(\n                server_id\n            ) or global_mcp_server_manager.get_mcp_server_by_name(server_id, client_ip=client_ip)\n        if server is None:\n            raise HTTPException(\n                status_code=status.HTTP_404_NOT_FOUND,\n                detail={\"error\": f\"MCP server {server_id} not found\"},\n            )\n\n        # Per-server access policy mirrors `fetch_mcp_server`: admin-view\n        # callers are unrestricted; non-admins must have the server in their\n        # allowed-servers set. Temporary cached servers come from the\n        # admin-only `/server/oauth/session` setup flow and are not exposed\n        # to non-admins.\n        if not _user_has_admin_view(user_api_key_dict):\n            if resolved_from_temp_cache:\n                raise HTTPException(\n                    status_code=status.HTTP_403_FORBIDDEN,\n                    detail={\"error\": f\"Access denied to MCP server {server_id}\"},\n                )\n            allowed_server_ids: Final[set[str]] = set()\n            for auth_context in await build_effective_auth_contexts(user_api_key_dict):\n                allowed_server_ids.update(await global_mcp_server_manager.get_allowed_mcp_servers(auth_context))\n            if server.server_id not in allowed_server_ids:\n                raise HTTPException(\n                    status_code=status.HTTP_403_FORBIDDEN,\n                    detail={\"error\": f\"Access denied to MCP server {server_id}\"},\n                )\n        return server\n\n    @router.get(\n        \"/server/oauth/{server_id}/authorize\",\n        include_in_schema=False,\n        dependencies=[Depends(_mcp_oauth_user_api_key_auth)],\n    )","sourceCodeStart":1788,"sourceCodeEnd":1824,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/mcp_management_endpoints.py#L1788-L1824","documentation":"Returned (403) by the OAuth server-resolution helper when a non-admin-view caller references a server that was resolved from the temporary cache. Temporary servers come from the admin-only /server/oauth/session setup flow and are intentionally never exposed to non-admins, so any non-admin hitting them gets this blanket denial regardless of grants.","triggerScenarios":"Calling /server/oauth/{temp_session_id}/authorize (or /token) with a non-admin virtual key; a bookmarked OAuth URL containing a temp session id being opened by a regular user; sharing setup links with team members.","commonSituations":"Admin copies the OAuth setup URL and a teammate opens it with their own (non-admin) key; automation for the OAuth flow accidentally configured with a user-level key.","solutions":["Complete OAuth setup flows with the proxy admin/master key.","For end users, register a permanent server first and run the user-side OAuth flow against its real server_id.","Regenerate the temp session (it may also have expired) using an admin key."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"info = requests.get(f\"{PROXY}/key/info\", headers=AUTH, params={\"key\": KEY}).json()\nrole = info.get(\"key_info\", info).get(\"user_role\")\nif role != \"proxy_admin\" and is_temp_session_id(server_id):\n    raise PermissionError(\"temp session servers are admin-only; use an admin key\")","typeGuard":"def is_temp_session_id(server_id: str) -> bool:\n    return server_id.startswith(\"mcp-oauth-session-\")  # match your deployment's temp id prefix","tryCatchPattern":"try:\n    authorize(server_id)\nexcept HTTPError as e:\n    if e.response.status_code == 403:\n        raise PermissionError(\"temp OAuth setup requires the admin key\")\n    raise","preventionTips":["Never share OAuth setup URLs containing temp session ids with non-admins.","Run setup flows with the admin key; run user flows against permanent server ids."],"tags":["litellm","mcp","oauth","forbidden","authorization"],"backgroundTag":"authorization-forbidden","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}