{"record":{"id":"f5b434a25fdddb5c","repo":"BerriAI/litellm","slug":"missing-client-id","errorCode":"missing_client_id","errorMessage":"No client_id available for this MCP server. Either configure the server with a client_id or supply one in the request.","messagePattern":"No client_id available for this MCP server\\. Either configure the server with a client_id or supply one in the request\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/management_endpoints/mcp_management_endpoints.py","lineNumber":1856,"sourceCode":"        _raise_if_not_oauth2(mcp_server)\n        # Use the server's stored client_id when the caller doesn't supply one\n        stored_or_supplied_client_id: Final = mcp_server.client_id or client_id or \"\"\n        ephemeral_dcr_client: Final = (\n            await resolve_ephemeral_dcr_client(\n                request=request,\n                mcp_server=mcp_server,\n                code_challenge=code_challenge,\n                code_challenge_method=code_challenge_method,\n                redirect_uri=redirect_uri,\n            )\n            if not stored_or_supplied_client_id\n            else None\n        )\n        resolved_client_id: Final = stored_or_supplied_client_id or (\n            ephemeral_dcr_client.client_id if ephemeral_dcr_client else \"\"\n        )\n        if not resolved_client_id:\n            raise HTTPException(\n                status_code=status.HTTP_400_BAD_REQUEST,\n                detail={\n                    \"error\": \"missing_client_id\",\n                    \"message\": (\n                        \"No client_id available for this MCP server. \"\n                        \"Either configure the server with a client_id or supply one in the request.\"\n                    ),\n                },\n            )\n        return await authorize_with_server(\n            request=request,\n            mcp_server=mcp_server,\n            client_id=resolved_client_id,\n            redirect_uri=redirect_uri,\n            state=state,\n            code_challenge=code_challenge,\n            code_challenge_method=code_challenge_method,\n            response_type=response_type,","sourceCodeStart":1838,"sourceCodeEnd":1874,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/mcp_management_endpoints.py#L1838-L1874","documentation":"Returned (400, error code missing_client_id) by the MCP OAuth authorize endpoint when no client_id can be determined: the server definition has none stored, the request supplied none, and the ephemeral dynamic client registration (DCR) attempt either did not run or returned no client_id. The code resolves stored_or_supplied_client_id first, then the DCR client, and only errors when both are empty.","triggerScenarios":"GET/POST /server/oauth/{server_id}/authorize for an OAuth server created without client_id/client_secret while the request also omits client_id; upstream MCP provider does not support (or fails) dynamic client registration; DCR succeeded but returned an empty client_id.","commonSituations":"Copying an OAuth server template but leaving the credentials out; provider (e.g. internal SSO) has no DCR endpoint; migrating config between environments and dropping the auth fields.","solutions":["Set client_id (and client_secret) on the MCP server definition in the proxy, then retry the authorize call.","Or pass client_id explicitly in the authorize request.","If you expect DCR to work, verify the upstream MCP provider actually supports dynamic client registration and check proxy logs for the DCR attempt failing."],"exampleFix":"# before: server registered without OAuth app credentials\npayload = {\"server_id\": \"gh\", \"server_name\": \"gh\", \"transport\": \"http\", \"url\": \"https://mcp.github.com/mcp\", \"auth_type\": \"oauth\"}\n\n# after: include the OAuth client credentials on the server definition\npayload = {\n    \"server_id\": \"gh\", \"server_name\": \"gh\", \"transport\": \"http\",\n    \"url\": \"https://mcp.github.com/mcp\", \"auth_type\": \"oauth\",\n    \"oauth2_params\": {\"client_id\": os.environ[\"GH_CLIENT_ID\"], \"client_secret\": os.environ[\"GH_CLIENT_SECRET\"]},\n}","handlingStrategy":"validation","validationCode":"server = requests.get(f\"{PROXY}/v1/mcp/server/{server_id}\", headers=AUTH).json()\nhas_client_id = bool((server.get(\"mcp_server\", server) or {}).get(\"client_id\"))\nif not has_client_id and not request_client_id:\n    raise ValueError(\"configure client_id on the server or pass it in the authorize request\")","typeGuard":"def oauth_ready(server: dict, supplied_client_id: str | None) -> bool:\n    return bool(supplied_client_id or server.get(\"client_id\"))","tryCatchPattern":"try:\n    authorize(server_id)\nexcept HTTPError as e:\n    if e.response.status_code == 400 and e.response.json().get(\"error\", {}).get(\"message\", \"\").find(\"client_id\") >= 0:\n        raise ValueError(\"set oauth client_id/client_secret on the MCP server definition\")\n    raise","preventionTips":["Register OAuth MCP servers with their client_id/client_secret from day one.","Confirm the provider supports dynamic client registration before relying on DCR.","Pass client_id in the authorize request when the provider has no DCR."],"tags":["litellm","mcp","oauth","client-id","dcr"],"backgroundTag":"oauth-missing-client-id","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}