Skip to content

rmcp OAuth tokens never refresh based on expires_at #6572

@LaelLuo

Description

@LaelLuo

Summary

When Codex uses the rmcp streamable HTTP transport against OAuth-enabled MCP servers (e.g. Notion), the cached OAuthTokenResponse keeps the original expires_in duration forever. AuthorizationManager::get_access_token() only refreshes when that duration reaches zero, so tokens that are still considered valid locally never trigger a refresh even after the server rotates them. Eventually every request—including the initialization handshake—fails with Auth required, forcing the user to run codex mcp login ... again.

Expected

The client should derive the remaining lifetime from the stored expires_at (or an equivalent timestamp) and refresh via the refresh_token before the server-side expiry, so long-lived SSE connections continue seamlessly.

Actual

Because expires_in stays at the original value, rmcp never refreshes; once the server-side token rotation happens, all subsequent requests fail immediately with Auth required.

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) servers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions