{"record":{"id":"e8ec820ec47f8c51","repo":"BerriAI/litellm","slug":"access-denied","errorCode":"access_denied","errorMessage":"The key is not allowed to access server {server_id}","messagePattern":"The key is not allowed to access server (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"litellm/proxy/_experimental/mcp_server/rest_endpoints.py","lineNumber":487,"sourceCode":"                    detail={\n                        \"error\": \"ip_filtering\",\n                        \"message\": (\n                            f\"MCP server '{server_id}' is not accessible from your IP address \"\n                            f\"({_rest_client_ip}). This server is restricted to internal \"\n                            \"networks only. To make it externally accessible, set \"\n                            \"'available_on_public_internet: true' in the server configuration.\"\n                        ),\n                    },\n                )\n            if _server is None:\n                raise HTTPException(\n                    status_code=404,\n                    detail={\n                        \"error\": \"server_not_found\",\n                        \"message\": f\"MCP server '{server_id}' was not found\",\n                    },\n                )\n            raise HTTPException(\n                status_code=403,\n                detail={\n                    \"error\": \"access_denied\",\n                    \"message\": f\"The key is not allowed to access server {server_id}\",\n                },\n            )\n\n        # Build allowed_mcp_servers list (only include allowed servers)\n        allowed_mcp_servers: Final[list[MCPServer]] = []\n        for allowed_server_id in allowed_server_ids_set:\n            server = global_mcp_server_manager.get_mcp_server_by_id(allowed_server_id)\n            if server is not None:\n                allowed_mcp_servers.append(server)\n\n        return allowed_mcp_servers, canonical_server_id\n\n    async def _get_tools_for_single_server(\n        server,","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/_experimental/mcp_server/rest_endpoints.py#L469-L505","documentation":"On the REST tool-call route, the server exists and is IP-accessible, but server_id is not in the union of MCP servers the caller's key is allowed to use, so the proxy returns 403 error=access_denied. Allowlists are inclusive: an explicit mcp_servers list on the key or team excludes everything not on it.","triggerScenarios":"Key or team carries an mcp_servers allowlist that omits this server_id; a personal key used against a server granted only to a team; a server rolled out after the key's allowlist was frozen.","commonSituations":"New MCP server added to general settings but keys keep old explicit allowlists; least-privilege keys scoped for one integration then reused for another; team grants vs key grants confusion.","solutions":["Add the server_id to the key's mcp_servers list (/key/update or dashboard), or add it to the team's allowlist.","Or remove the per-key mcp_servers restriction so the key inherits the general-settings server set.","Verify with the key info endpoint (/key/info) that the server now appears in the key's allowed mcp_servers."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async def key_allows_server(key_info: dict, server_id: str) -> bool:\n    allowed = key_info.get(\"mcp_servers\")\n    return allowed is None or server_id in allowed  # None = inherits general settings","typeGuard":null,"tryCatchPattern":"resp = await client.post(f\"{proxy}/mcp/tool-call\", json=payload, headers=headers)\nif resp.status_code == 403 and resp.json().get(\"detail\", {}).get(\"error\") == \"access_denied\":\n    raise PermissionError(f\"key not granted {payload['server_id']}; update key/team mcp_servers\") from None\nresp.raise_for_status()","preventionTips":["When rolling out a new MCP server, update every key/team allowlist that names servers explicitly.","Check /key/info for the effective mcp_servers set before wiring new integrations.","Prefer inheriting general settings over per-key allowlists unless least-privilege demands it."],"tags":["mcp","authorization","http-403","api-key","permissions"],"backgroundTag":"api-key-permission-denied","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}