MCP status panel shows "Auth unsupported" when an OAuth refresh fails and re-login is needed
I have a remote MCP server configured over OAuth in ~/.codex/config.toml. After the access token expired and the refresh got rejected, the composer's MCP status panel started showing it as "Enabled / Auth unsupported".
That label sent me the wrong way for a while. The server supports OAuth fine and had been authenticated minutes earlier. All that actually happened is the stored refresh token stopped being valid and I needed to sign in again. But "Auth unsupported" reads like the server cannot do auth at all, so I went looking at the server instead of just re-running login.
codex mcp list reported the same server as Auth: OAuth at the same moment, so the CLI and the desktop app disagree about the state.
What seems to be happening
McpAuthStatus has five values. From codex app-server generate-json-schema --out DIR, see v2/ListMcpServerStatusResponse.json:
unknown | unsupported | notLoggedIn | bearerToken | oAuth
The desktop label function collapses two of them into one string:
case `unknown`:
case `unsupported`:
return "Auth unsupported" // composer.mcpStatus.authUnsupportedNoAuth
So unknown, which covers "not resolved yet" and the state after a failed refresh, looks identical to a stdio server that genuinely has no auth mechanism. The row is also rendered with disabled: true, so there is no way to re-authenticate from the panel.
The app-server already knows the right answer
It logs the actionable diagnosis, it just never reaches the UI:
WARN MCP OAuth refresh token was rejected; reauthorization required
error=OAuth refresh token was rejected: Server returned error response: invalid_grant
ERROR failed to refresh OAuth tokens for server <server>
codex mcp login <server> fixes it in a few seconds. There is no way to work that out from what is on screen.
Steps to reproduce
- Add a remote MCP server that requires OAuth to
~/.codex/config.toml, then runcodex mcp login <server>. - Let the access token expire, or invalidate the refresh token server side.
- Open the MCP status panel in the composer.
Expected: something like "Not authenticated, sign in".
Actual: "Enabled / Auth unsupported".
You can also see it without the UI by driving codex app-server over stdio: send initialize, then the initialized notification, then mcpServerStatus/list, and read result.data[].authStatus.
One caution if you script that: each mcpServerStatus/list call can trigger a token refresh. If you poll it in a tight loop against a server that rotates refresh tokens, the concurrent requests can look like token replay and get the grant revoked. Poll once and wait.
Suggested fix
Give unknown its own label, something like "Checking...", and surface the reauthorization-required case as an actionable "sign in again" state rather than folding it into unsupported.
Environment
Codex Desktop 26.818.41509, codex-cli 0.149.0-alpha.4.1, macOS 15 (Darwin 25.5.0).
1 Comment
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action