MCP OAuth refresh regression after upgrade to rmcp 1.7.0

Resolved 💬 1 comment Opened Jun 2, 2026 by Savlar Closed Jun 5, 2026

What version of Codex CLI is running?

0.136.0

What subscription do you have?

Plus

Which model were you using?

gpt-5.5

What platform is your computer?

Windows 11

What issue are you seeing?

After logging in to an OAuth streamable HTTP MCP server with:

codex mcp login <server-name>

Codex logs in and stores OAuth credentials successfully. The identity provider is Keycloak, and the login creates a Keycloak regular SSO session and also stores a refresh token with offline_access.

In Codex CLI 0.136.0, once the regular SSO OAuth access token expires, running:

/mcp

causes Codex to show no available tools for that MCP server. The FastMCP server shows HTTP 401.

This used to work in 0.135.0.

What steps can reproduce the bug?

  1. Configure a streamable HTTP MCP server using OAuth.
  2. Use Keycloak as the OAuth provider.
  3. Ensure the OAuth login grants offline_access and returns a refresh token.
  4. Run:

codex mcp login <server-name>

  1. Start Codex CLI 0.136.0.
  2. Confirm /mcp initially lists the MCP tools.
  3. Wait until the access token expires, without letting the refresh token expire.
  4. Run /mcp again.
  5. Observe that Codex lists no tools for the MCP server.
  6. Check the MCP server logs.

What is the expected behavior?

If Codex has a valid OAuth refresh token for an MCP server, it should refresh the expired token before MCP initialization or tool listing, then continue using tools without requiring new login.

Additional information

This appears to be a regression related to rmcp bump between 0.135.0 and 0.136.0.

  • 0.135.0 used rmcp 0.15.0.
  • 0.136.0 uses rmcp 1.7.0.

The likely cause is how RMCP handles OAuth token expiry.

  • In rmcp 0.15.0, AuthorizationManager::get_access_token() refreshed if refresh_token().is_some() and the token was expired.
  • In rmcp 1.7.0, refresh depends on both expires_in and RMCP token_received_at.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗