codex - 💡(How to fix) Fix MCP OAuth: Google-backed servers never get a refresh token; session breaks after ~1h [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

Root cause (from reading codex-rs/rmcp-client/src/perform_oauth_login.rs): Google OAuth issues a refresh token only when the authorization request includes access_type=offline (typically with prompt=consent). This is a Google-specific query parameter, not part of OAuth scope negotiation. Google does not honor offline_access as a scope, so requesting it via the existing scopes config has no effect. Codex's authorize-URL builder appends only one parameter on top of what rmcp generates (resource=), so access_type=offline is never sent and Google therefore omits the refresh token.

Fix Action

Fix / Workaround

A draft change on a fork (https://github.com/forketyfork/codex/pull/1) explores one possible mitigation for reference (adding extra_authorize_params to the MCP auth configuration).

Code Example



---

{
  "server_name": "<name>",
  "access_token": "<JWT, ~1h lifetime>",
  "expires_at": <approx now + 3600s>,
  "scope": "openid email profile"
  // no `refresh_token` field
}

---

[mcp_servers.example]
   url = "https://example.com/mcp"
RAW_BUFFERClick to expand / collapse

What version of Codex CLI is running?

codex-cli 0.134.0

What subscription do you have?

ChatGPT Enterprise

Which model were you using?

No response

What platform is your computer?

macOS Darwin 25.5.0 arm64 arm

What terminal emulator and version are you using (if applicable)?

No response

Codex doctor report

What issue are you seeing?

Logging into an MCP server that uses Google as its OAuth identity provider succeeds initially, but the stored credentials contain only an access token, with no refresh_token. After the ~1h access token expires, MCP tool calls fail with auth errors and the only recovery is to run codex mcp login <server> again and walk through the full browser flow.

Inspecting the stored credentials confirms the symptom:

{
  "server_name": "<name>",
  "access_token": "<JWT, ~1h lifetime>",
  "expires_at": <approx now + 3600s>,
  "scope": "openid email profile"
  // no `refresh_token` field
}

The credential blob lives in the macOS Keychain under service Codex MCP Credentials, or in $CODEX_HOME/.credentials.json when keyring writes fall back to file.

What steps can reproduce the bug?

  1. Configure any MCP server that uses Google as its OAuth provider, e.g.:

    [mcp_servers.example]
    url = "https://example.com/mcp"
  2. Run codex mcp login example and complete the Google sign-in in the browser.

  3. Inspect the stored credentials (Keychain entry for Codex MCP Credentials with account example|<hash>, or $CODEX_HOME/.credentials.json). No refresh_token field is present.

  4. Wait until the access token expires, or make an MCP tool call shortly after the 1h mark. The session fails to refresh and requires manual relogin.

What is the expected behavior?

After codex mcp login against a Google-backed MCP server, the stored credentials should contain a refresh_token so the session can survive past access-token expiry without forcing the user back through the browser flow. This is how Claude Code's MCP client behaves against the same servers.

Additional information

Root cause (from reading codex-rs/rmcp-client/src/perform_oauth_login.rs): Google OAuth issues a refresh token only when the authorization request includes access_type=offline (typically with prompt=consent). This is a Google-specific query parameter, not part of OAuth scope negotiation. Google does not honor offline_access as a scope, so requesting it via the existing scopes config has no effect. Codex's authorize-URL builder appends only one parameter on top of what rmcp generates (resource=), so access_type=offline is never sent and Google therefore omits the refresh token.

A draft change on a fork (https://github.com/forketyfork/codex/pull/1) explores one possible mitigation for reference (adding extra_authorize_params to the MCP auth configuration).

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING