Codex Desktop MCP OAuth DCR registers fewer scopes than it later requests
Description
Codex Desktop fails OAuth login for a remote Streamable HTTP MCP server that supports Dynamic Client Registration (DCR).
The authorization server metadata advertises DCR and the following scopes:
{
"issuer": "https://clerk.actionbook.dev",
"authorization_endpoint": "https://clerk.actionbook.dev/oauth/authorize",
"token_endpoint": "https://clerk.actionbook.dev/oauth/token",
"registration_endpoint": "https://clerk.actionbook.dev/oauth/register",
"scopes_supported": [
"openid",
"profile",
"email",
"public_metadata",
"private_metadata",
"offline_access"
],
"code_challenge_methods_supported": ["S256"]
}
Codex Desktop appears to dynamically register an OAuth client without registering the same scopes that it later requests during the authorization step. The flow reaches the browser callback, but authorization fails with:
OAuth provider returned `invalid_scope`: The requested scope is invalid, unknown, or malformed. The OAuth 2.0 Client is not allowed to request scope `openid`.
The callback URL contains:
error=invalid_scope&error_description=The requested scope is invalid, unknown, or malformed. The OAuth 2.0 Client is not allowed to request scope `openid`.
Expected behavior
Codex Desktop should keep the DCR registration request and the subsequent authorization request consistent.
If Codex Desktop later requests:
scope=openid profile email ...
at /oauth/authorize, then it should register the dynamic client with the same requested/allowed scopes at /oauth/register, or only request scopes that were successfully registered/allowed for that dynamic client.
Actual behavior
DCR succeeds far enough for Codex Desktop to proceed to authorization, but the dynamically registered OAuth client is not allowed to request openid. Codex Desktop then requests openid during authorization, causing the authorization server to reject the flow with invalid_scope.
Why this appears client-side
The same MCP server works with Claude against the same authorization server. In that flow, the DCR registration scopes and authorization request scopes are consistent.
This does not appear to be a case where the MCP server lacks DCR support. The problem is that Codex Desktop registration and authorization use inconsistent scope sets.
Environment
- Product: Codex Desktop
- MCP transport: Streamable HTTP
- OAuth provider: Clerk OAuth with Dynamic Client Registration enabled
- MCP URL:
https://edge.actionbook.dev/mcp
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗