[BUG] MCP OAuth Dynamic Client Registration: client_id is not persisted and strict RFC 9207 iss check breaks authorization

#29620 · open · 3 comments

View on GitHub ↗

rahatHSL

### What happened? When authenticating with an MCP server using OAuth 2.0 / 2.1 via `/mcp auth <server>`, Dynamic Client Registration (RFC 7591) and the callback handling encounter two interrelated issues: 1. **Dynamic Client Registration credentials are not persisted across sessions:** When connecting to an MCP server without a pre-configured `clientId`, Gemini CLI successfully performs Dynamic Client Registration against the server's `registration_endpoint` using an ephemeral loopback redirect URI (e.g. `http://localhost:<random-port>/oauth/callback`). However, the resulting `client_id` and registration details are kept in memory only (`config.clientId = clientRegistration.client_id`) and are never saved to configuration (`settings.json`) or persistent token/client storage. Consequently, every subsequent `/mcp auth` invocation or reconnection triggers a brand new DCR call, registering duplicate client records on the authorization server. 2. **Unconditional RFC 9207 `iss` check causes dynamic registration to fail:** During the authorization callback, Gemini CLI strictly rejects responses without an `iss` parameter: ```text ✕ Failed to authenticate with MCP server '<server>': Missing "iss" parameter in authorization response per RFC 9207 ``` In `packages/core/src/utils/oauth-flow.ts`, `startCallbackServer` validates `expectedIssuer` which is populated from discovery metadata. Gemini CLI unconditionally rejects missing `iss` even when the Authorization Server metadata does not advertise `authorization_response_iss_parameter_supported: true`. Per RFC 9207 §2.4 and MCP Specification (2026-07-28), clients should proceed when `authorization_response_iss_parameter_supported` is absent or false. ### What did you expect to happen? 1. When Dynamic Client Registration succeeds, the registered client information (`client_id`, `client_secret` if applicable, registration URI) should be cached or persisted so the client is reused rather than re-registering on every authentication attempt. 2. The RFC 9207 `iss` parameter check should respect `authorization_response_iss_parameter_supported: true` in the authorization server metadata. If absent or false, the client should not abort with `Missing "iss" parameter in authorization response per RFC 9207`. ### Steps to Reproduce 1. Configure an MCP server in `~/.gemini/settings.json` that uses dynamic discovery with an RFC 7591 registration endpoint: ```json "mcpServers": { "my-server": { "url": "https://staging.mcp.example.com/mcp", "type": "http" } } ``` 2. Run `/mcp auth my-server`. 3. Observe: - DCR executes and creates a new client. - If the callback does not carry `iss`, it fails with `Missing "iss" parameter in authorization response per RFC 9207`. - Re-running `/mcp auth my-server` creates another new client via DCR rather than reusing the previous registration. ### Client Information <details> <summary>Client Information</summary> - **CLI Version:** 0.62.0 - **OS:** macOS (darwin arm64) - **Node.js:** v26.3.0 - **Package:** `@google/[email protected]` </details> ### Additional Context - Related to RFC 9207 issuer enforcement discussed in #29477. - Related to DCR support requests in #29109 and #20990.

Comments

adityasharmaaaaa

/assign

gemini-cli[bot]

👋 @adityasharmaaaaa, thanks for your interest in this issue! We're reserving self-assignment for issues that have been marked with the `help wanted` label. Feel free to check out our list of [issues that need attention](https://github.com/google-gemini/gemini-cli/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22).

swapnil1222589

Hi, I’d like to help with this issue. I think we could handle the client registration persistence and the missing issuer parameter as two separate fixes. I’d be happy to start with the persistence part and add tests to make sure the registered client is reused across authentication attempts. Could you please let me know if this would be a good place to start?