{"record":{"id":"52053b3d186dba15","repo":"BerriAI/litellm","slug":"mcp-server-server-server-id-missing-required-o","errorCode":null,"errorMessage":"MCP server '{server.server_id}' missing required OAuth2 fields: client_id={bool(server.client_id)}, client_secret={bool(server.client_secret)}, token_url={bool(server.token_url)}","messagePattern":"MCP server '(.+?)' missing required OAuth2 fields: client_id=(.+?), client_secret=(.+?), token_url=(.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py","lineNumber":123,"sourceCode":"        async with self._get_lock(identity):\n            cached = self.get_cache(identity)\n            if cached is not None:\n                return cached\n\n            token, ttl = await self._fetch_token(server)\n            self.set_cache(identity, token, ttl=ttl)\n            return token\n\n    async def _fetch_token(self, server: \"MCPServer\") -> tuple[str, int]:\n        \"\"\"POST to ``token_url`` with ``grant_type=client_credentials``.\n\n        Returns ``(access_token, ttl_seconds)`` where ttl accounts for the\n        expiry buffer so the cache entry expires before the real token does.\n        \"\"\"\n        client: Final = get_async_httpx_client(llm_provider=httpxSpecialProvider.MCP)\n\n        if not server.client_id or not server.client_secret or not server.token_url:\n            raise ValueError(\n                f\"MCP server '{server.server_id}' missing required OAuth2 fields: \"\n                f\"client_id={bool(server.client_id)}, \"\n                f\"client_secret={bool(server.client_secret)}, \"\n                f\"token_url={bool(server.token_url)}\"\n            )\n\n        token_request: Final = build_upstream_oauth2_token_request(\n            server,\n            auth_method=server.token_endpoint_auth_method,\n            client_id=server.client_id,\n            client_secret=server.client_secret,\n        )\n        data: Final[dict[str, str]] = {\n            \"grant_type\": \"client_credentials\",\n            **token_request.body,\n        }\n        if server.scopes:\n            data[\"scope\"] = \" \".join(server.scopes)","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py#L105-L141","documentation":"Error \"MCP server '{server.server_id}' missing required OAuth2 fields: client_id={bool(server.client_id)}, client_secret={bool(server.client_secret)}, token_url={bool(server.token_url)}\" thrown in BerriAI/litellm.","triggerScenarios":"Thrown at litellm/proxy/_experimental/mcp_server/oauth2_token_cache.py:123 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Set client_id, client_secret, and token_url on the MCP server config."],"exampleFix":"Configure all three OAuth2 fields for the server.","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}