{"record":{"id":"ca0d53aa102a71f7","repo":"BerriAI/litellm","slug":"unsupported-grant-type","errorCode":null,"errorMessage":"Unsupported grant_type","messagePattern":"Unsupported grant_type","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py","lineNumber":882,"sourceCode":"    return \"gateway_stored\" if mcp_server.client_id else \"caller_supplied\"\n\n\nasync def exchange_token_with_server(\n    request: Request,\n    mcp_server: MCPServer,\n    grant_type: str,\n    code: str | None,\n    redirect_uri: str | None,\n    client_id: str,\n    client_secret: str | None,\n    code_verifier: str | None,\n    refresh_token: str | None = None,\n    scope: str | None = None,\n    client_token_endpoint_auth_method: MCPTokenEndpointAuthMethod | None = None,\n):\n    _raise_if_not_oauth2(mcp_server)\n    if grant_type not in (\"authorization_code\", \"refresh_token\"):\n        raise HTTPException(status_code=400, detail=\"Unsupported grant_type\")\n\n    if mcp_server.token_url is None:\n        raise HTTPException(\n            status_code=400,\n            detail=_endpoint_not_configured_detail(\n                mcp_server,\n                \"token url\",\n                \"set Token URL manually\",\n                \"set Issuer to discover it from the identity provider (RFC 8414)\",\n            ),\n        )\n\n    # The id, secret, and token-endpoint auth method must come from the same source. When the\n    # server-side client_id wins, falling back to the caller's secret pairs the persisted client\n    # with a foreign secret; the register short-circuit hands clients a placeholder secret\n    # (\"dummy\"), so a re-auth against a persisted public PKCE client (no stored secret) would send\n    # that placeholder and the IdP 401s. Symmetrically, a caller-side client (an ephemeral mint\n    # recovered from a sealed code) must authenticate the way its own registration was granted,","sourceCodeStart":864,"sourceCodeEnd":900,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py#L864-L900","documentation":"Token-exchange endpoint guard in exchange_token_with_server: the caller posted a grant_type other than authorization_code or refresh_token. It is a generic input-validation 400 raised before any upstream call.","triggerScenarios":"Thrown at litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py:882 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Use a supported grant_type (authorization_code or refresh_token)."],"exampleFix":"grant_type=authorization_code","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"}