Skip to content

MCP startup_timeout_sec does not cover pre-initialize OAuth bootstrap with saved tokens #22072

@josh-omio

Description

@josh-omio

What version of Codex CLI is running?

codex-cli 0.130.0

What platform is your computer?

Darwin 24.6.0 arm64

What issue are you seeing?

For Streamable HTTP MCP servers with saved OAuth credentials, Codex can hang before sending initialize when the OAuth metadata/bootstrap path is unreachable or hanging. startup_timeout_sec does not appear to apply to this pre-initialize OAuth path.

This is especially visible for VPN-only MCP servers:

  • When the MCP is auth_status: not_logged_in, Codex uses plain HTTP startup (initialize, tools/list) and fails fast if the VPN-only endpoint is unreachable.
  • When the same MCP is auth_status: o_auth because saved OAuth credentials exist, Codex performs OAuth bootstrap before initialize. If VPN is off, it can hang before the normal MCP startup timeout applies.

Repro

Use a Streamable HTTP MCP config with a low startup timeout:

mcp_oauth_credentials_store = "file"

[mcp_servers.local_timeout_config_test]
url = "http://127.0.0.1:<port>/mcp"
startup_timeout_sec = 3

Run a local test server that:

  1. Accepts OAuth metadata requests like GET /.well-known/oauth-authorization-server/mcp but never responds, simulating a VPN-off / unreachable OAuth bootstrap path.
  2. Allows unauthenticated MCP startup requests on /mcp (initialize, tools/list) if Codex reaches them.

Compare two cases:

  1. No saved MCP OAuth token for this server.
  2. A saved MCP OAuth token exists in the configured MCP credentials store for this server.

Observed behavior

No saved token:

GET  /.well-known/oauth-authorization-server/mcp
GET  /mcp/.well-known/oauth-authorization-server
GET  /.well-known/oauth-authorization-server
POST /mcp initialize                 no Authorization
POST /mcp notifications/initialized  no Authorization
POST /mcp tools/list                 no Authorization
DELETE /mcp                          no Authorization

Codex eventually reaches plain MCP startup.

Saved OAuth token:

GET /.well-known/oauth-authorization-server/mcp

Codex never sends initialize or tools/list. In my controlled test, the process was still stuck after 12 seconds even though startup_timeout_sec = 3.

Expected behavior

Either:

  • startup_timeout_sec should cover pre-initialize OAuth transport/bootstrap work, or
  • the OAuth bootstrap path should have its own bounded timeout and return an actionable MCP startup error.

With startup_timeout_sec = 3, Codex should not remain stuck indefinitely before initialize.

Why this matters

A user who has previously run codex mcp login <server> can get worse startup behavior than a first-time/not-logged-in user. For VPN-only MCP servers, saved OAuth credentials cause Codex to enter a pre-initialize OAuth path that can hang when the VPN is off. The workaround is to run codex mcp logout <server> before starting Codex off VPN, which restores the plain startup/fail-fast path, but that is surprising and easy to miss.

Additional context

From reading the current open-source Codex code, the timeout seems to wrap the MCP handshake after the client/transport is created. In the saved-token case, Codex loads OAuth tokens and creates the OAuth-wrapped transport before the normal initialize/handshake timeout is applied. That appears to be the timeout boundary causing this behavior.

Related but not exact issues I found:

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIauthIssues related to authentication and accountsbugSomething isn't workingconnectivityIssues involving networking or endpoint connectivity problems (disconnections)mcpIssues related to the use of model context protocol (MCP) servers

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions