Skip to content

Windows MCP OAuth keyring credentials are ignored on restart #28201

Open

Description

@Q1Xuan

What version of Codex CLI is running?

codex-cli 0.139.0

What subscription do you have?

Unknown / not relevant to local MCP OAuth persistence.

Which model were you using?

gpt-5.5 via a custom Responses-compatible provider.

What platform is your computer?

Microsoft Windows NT 10.0.19045.0 x64

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

Windows Terminal / PowerShell.

Codex doctor report

Captured after applying the temporary workaround (mcp_oauth_credentials_store = "file"), so it no longer reflects the failing keyring-mode startup. Relevant details:

codexVersion: 0.139.0
platform: windows-x86_64
install method: npm
mcp configured servers: 1 streamable_http server
config loaded from: C:\Users\Administrator\.codex\config.toml
current workaround: mcp_oauth_credentials_store = "file"

What issue are you seeing?

On Windows with a streamable HTTP MCP server using OAuth (Notion MCP), Codex CLI can complete codex mcp login notion, and Windows Credential Manager may contain a legacy direct keyring entry named like notion|... under service Codex MCP Credentials. However, a fresh Codex startup still fails MCP initialization with:

MCP client for `notion` failed to start
OAuth authorization required, when send initialize request
MCP startup incomplete (failed: notion)

Running codex mcp logout notion && codex mcp login notion does not reliably make keyring-mode persistence usable on later startups. Setting this workaround in config.toml and logging in again fixes startup:

mcp_oauth_credentials_store = "file"

That workaround creates $CODEX_HOME/.credentials.json, which avoids the startup failure but stores OAuth tokens in a plaintext file readable by Codex and other same-user processes. The preferred long-term behavior is for the default/keyring path to persist and reload MCP OAuth credentials reliably on Windows.

What steps can reproduce the bug?

  1. On Windows, configure Notion MCP as a streamable HTTP server:

    [mcp_servers.notion]
    type = "http"
    url = "https://mcp.notion.com/mcp"
  2. Use default MCP OAuth credential storage (auto) or explicitly set:

    mcp_oauth_credentials_store = "keyring"
  3. Run:

    codex mcp logout notion
    codex mcp login notion
  4. Complete OAuth in the browser.

  5. Confirm codex mcp list shows Notion as enabled with OAuth.

  6. Start a fresh Codex CLI process.

Observed result: Codex startup reports OAuth authorization required for the Notion MCP server even though OAuth login completed and a Windows Credential Manager entry may exist.

What is the expected behavior?

After a successful MCP OAuth login, a fresh Codex CLI process should read the persisted OAuth credentials from the Windows keyring-backed store and initialize the Notion MCP server without prompting for OAuth again.

The default auto mode should not require falling back to plaintext $CODEX_HOME/.credentials.json for stable persistence.

Additional information

I investigated current main and found a likely compatibility gap in the keyring backend transition introduced to avoid Windows Credential Manager payload size limits:

In current source, AuthKeyringBackendKind::Secrets reads MCP OAuth credentials from encrypted local secrets. If no encrypted MCP OAuth secret exists, it returns None and does not attempt to read the legacy direct keyring entry (Codex MCP Credentials / server|hash). Existing direct entries are therefore invisible after the secrets backend is selected.

I prepared a small patch that makes the secrets backend fall back to the legacy direct keyring entry when the encrypted MCP OAuth store has no token, then best-effort migrates it into encrypted storage and removes the old direct entry.

Prepared branch:

https://github.com/Q1Xuan/codex/tree/fix/windows-mcp-oauth-keyring-migration

Local patch:

C:\Users\Administrator\codex-mcp-oauth-keyring-migration.patch

Validation performed locally:

rustfmt --edition 2024 --config imports_granularity=Item rmcp-client/src/oauth.rs
git diff --check -- codex-rs/rmcp-client/src/oauth.rs

I could not complete the targeted cargo test -p codex-rmcp-client ... locally because this checkout is a partial/sparse clone and additional workspace object fetches from GitHub repeatedly failed with TLS EOF errors.

Per docs/contributing.md, external code contributions are invitation-only, so I am opening this issue first with reproduction details, root-cause analysis, and the proposed fix branch rather than submitting an unsolicited PR.

Duplicate review

I reviewed the auto-suggested related issues:

So this appears related, but not an exact duplicate.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    windows-osIssues related to Codex on Windows systems
    mcpIssues related to the use of model context protocol (MCP) servers
    authIssues related to authentication and accounts
    on Jun 14, 2026
  2. github-actions commented on Jun 14, 2026

    @github-actions
    Contributor
  3. Q1Xuan commented on Jun 14, 2026

    @Q1Xuan
    Author

    Reviewed the suggested duplicates.

    I updated the issue body with this comparison and cleaned up the Markdown formatting. I think #28201 should stay open as a narrower compatibility/migration bug unless maintainers prefer folding it into one of those broader MCP OAuth startup issues.

  4. Q1Xuan commented on Jun 15, 2026

    @Q1Xuan
    Author

    Local validation update for the proposed minimal fix on Q1Xuan:fix/windows-mcp-oauth-keyring-migration (b9c9820):

    • Installed cargo-nextest 0.9.137 from the official Windows MSVC release asset and verified its SHA-256.
    • just fmt from codex-rs: passed.
    • just fix -p codex-rmcp-client: passed.
    • cargo build -p codex-cli --bin codex: passed. I built this first so the codex-rmcp-client integration test that spawns target/debug/codex.exe can run locally on Windows.
    • just test -p codex-rmcp-client: passed, 84 passed / 2 skipped.

    I did not run full just test: this patch is scoped to codex-rs/rmcp-client/src/oauth.rs and does not touch common/core/protocol. The targeted crate checks now pass locally.

    Per docs/contributing.md, I am not opening a PR unless a Codex maintainer explicitly invites one.

  5. alisterwayne8-web commented on Sep 21, 2026

    @alisterwayne8-web

    Additional confirmation from an n8n MCP setup on Windows:

    Using mcp_oauth_credentials_store = "file" resolved the OAuth persistence problem for Codex Desktop after re-running:

    codex mcp logout n8n
    codex mcp login n8n

    The working config also included the n8n-generated RMCP flag:

    [features]
    experimental_use_rmcp_client = true

    After verifying codex mcp list showed n8n -> enabled -> OAuth, fully quitting Codex Desktop and starting a new thread allowed Desktop to successfully call the remote n8n MCP tools.

    I documented the full Windows + n8n workaround on #32220 as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIauthIssues related to authentication and accountsbugSomething isn't workingmcpIssues related to the use of model context protocol (MCP) serverswindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions