CLI 0.147.0 reports “MCP startup interrupted” even though all servers initialize successfully

Open 💬 8 comments Opened Aug 7, 2026 by pheisiph
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of Codex CLI is running?

codex-cli 0.147.0

What subscription do you have?

paid company account

Which model were you using?

gpt-5.6-sol

What platform is your computer?

Darwin 25.5.0 arm64 arm

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

iTerm2 3.7.0beta9, without a terminal multiplexer.

Codex doctor report

{
  "schemaVersion": 1,
  "generatedAt": "<REDACT>",
  "overallStatus": "ok",
  "codexVersion": "0.147.0",
  "checks": {
    "app_server.status": {
      "id": "app_server.status",
      "category": "app-server",
      "status": "ok",
      "summary": "background server is not running",
      "details": {
        "control socket": "/Users/<REDACT>/.codex/app-server-control/app-server-control.sock",
        "daemon state dir": "/Users/<REDACT>/.codex/app-server-daemon",
        "mode": "ephemeral",
        "pid file": "/Users/<REDACT>/.codex/app-server-daemon/app-server.pid (missing)",
        "settings": "/Users/<REDACT>/.codex/app-server-daemon/settings.json (missing)",
        "status": "not running",
        "update-loop pid file": "/Users/<REDACT>/.codex/app-server-daemon/app-server-updater.pid (missing)"
      },
      "remediation": null,
      "durationMs": 0
    },
    "auth.credentials": {
      "id": "auth.credentials",
      "category": "auth",
      "status": "ok",
      "summary": "auth is configured",
      "details": {
        "auth file": "/Users/<REDACT>/.codex/auth.json",
        "auth storage mode": "File",
        "stored API key": "false",
        "stored ChatGPT tokens": "true",
        "stored agent identity": "false",
        "stored auth mode": "chatgpt"
      },
      "remediation": null,
      "durationMs": 0
    },
    "config.load": {
      "id": "config.load",
      "category": "config",
      "status": "ok",
      "summary": "config loaded",
      "details": {
        "CODEX_HOME": "/Users/<REDACT>/.codex",
        "config.toml": "/Users/<REDACT>/.codex/config.toml",
        "config.toml parse": "ok",
        "cwd": "<REDACT>",
        "enabled feature flags": "shell_tool, view_image, unified_exec, shell_snapshot, code_mode_host, terminal_resize_reflow, sqlite, hooks, enable_request_compression, multi_agent, apps, tool_search_always_defer_mcp_tools, tool_suggest, plugins, in_app_browser, in_app_updates, browser_use, browser_use_full_cdp_access, browser_use_external, computer_use, remote_plugin, plugin_sharing, image_generation, resize_all_images, item_ids, skill_mcp_dependency_install, skill_search, mentions_v2, steer, guardian_approval, goals, collaboration_modes, tool_call_mcp_elicitation, auth_elicitation, personality, fast_mode, tui_app_server, remote_compaction_v2, workspace_dependencies",
        "feature flag overrides": "none",
        "feature flags enabled": "39",
        "log dir": "/Users/<REDACT>/.codex/log",
        "mcp servers": "5",
        "model": "gpt-5.6-sol",
        "model provider": "openai",
        "sqlite home": "/Users/<REDACT>/.codex"
      },
      "remediation": null,
      "durationMs": 0
    },
    "git.environment": {
      "id": "git.environment",
      "category": "git",
      "status": "ok",
      "summary": "git version 2.55.0",
      "details": {
        ".git entry": "directory",
        "PATH git #1": "/opt/homebrew/bin/git",
        "PATH git #2": "/usr/bin/git",
        "PATH git entries": "2",
        "git branch": "<REDACT>",
        "git build options": "git version 2.55.0; cpu: arm64; no commit associated with this build; sizeof-long: 8; sizeof-size_t: 8; shell-path: /bin/sh; rust: disabled; feature: fsmonitor--daemon; gettext: enabled; libcurl: 8.7.1; zlib: 1.2.12; SHA-1: SHA1_DC; SHA-256: SHA256_BLK; default-ref-format: files; default-hash: sha1",
        "git exec path": "/opt/homebrew/opt/git/libexec/git-core",
        "git version": "git version 2.55.0",
        "repo detected": "true",
        "repo root": "<REDACT>",
        "selected git": "/opt/homebrew/bin/git"
      },
      "remediation": null,
      "durationMs": 95
    },
    "installation": {
      "id": "installation",
      "category": "install",
      "status": "ok",
      "summary": "installation looks consistent",
      "details": {
        "PATH codex #1": "/opt/homebrew/bin/codex",
        "current executable": "/opt/homebrew/bin/codex",
        "install context": "brew (package /opt/homebrew/Caskroom/codex/0.147.0, bin /opt/homebrew/Caskroom/codex/0.147.0/bin, resources /opt/homebrew/Caskroom/codex/0.147.0/codex-resources, path /opt/homebrew/Caskroom/codex/0.147.0/codex-path)",
        "managed by bun": "false",
        "managed by npm": "false",
        "managed by pnpm": "false",
        "managed package root": "not set"
      },
      "remediation": null,
      "durationMs": 2
    },
    "mcp.config": {
      "id": "mcp.config",
      "category": "mcp",
      "status": "ok",
      "summary": "MCP configuration is locally consistent",
      "details": {
        "configured servers": "5",
        "disabled servers": "1",
        "stdio servers": "3",
        "streamable_http servers": "2"
      },
      "remediation": null,
      "durationMs": 1176
    },
    "network.env": {
      "id": "network.env",
      "category": "network",
      "status": "ok",
      "summary": "network-related environment looks readable",
      "details": {
        "proxy env vars": "none"
      },
      "remediation": null,
      "durationMs": 0
    },
    "network.provider_reachability": {
      "id": "network.provider_reachability",
      "category": "reachability",
      "status": "ok",
      "summary": "active provider endpoints are reachable over HTTP",
      "details": {
        "ChatGPT base URL": "https://chatgpt.com/backend-api/ reachable (HTTP 404)",
        "reachability mode": "ChatGPT auth"
      },
      "remediation": null,
      "durationMs": 216
    },
    "network.websocket_reachability": {
      "id": "network.websocket_reachability",
      "category": "websocket",
      "status": "ok",
      "summary": "Responses WebSocket handshake succeeded",
      "details": {
        "DNS": "2 IPv4, 0 IPv6, first IPv4",
        "auth mode": "chatgpt",
        "connect timeout": "15000 ms",
        "endpoint": "wss://chatgpt.com/backend-api/<redacted>",
        "handshake result": "HTTP 101 Switching Protocols",
        "model provider": "openai",
        "models etag present": "true",
        "provider name": "OpenAI",
        "proxy env vars": "none",
        "reasoning header": "false",
        "server model present": "false",
        "supports websockets": "true",
        "wire API": "responses"
      },
      "remediation": null,
      "durationMs": 628
    },
    "runtime.provenance": {
      "id": "runtime.provenance",
      "category": "runtime",
      "status": "ok",
      "summary": "running brew on macos-aarch64",
      "details": {
        "commit": "unknown",
        "current executable": "/opt/homebrew/bin/codex",
        "install method": "brew (package /opt/homebrew/Caskroom/codex/0.147.0, bin /opt/homebrew/Caskroom/codex/0.147.0/bin, resources /opt/homebrew/Caskroom/codex/0.147.0/codex-resources, path /opt/homebrew/Caskroom/codex/0.147.0/codex-path)",
        "platform": "macos-aarch64",
        "version": "0.147.0"
      },
      "remediation": null,
      "durationMs": 0
    },
    "runtime.search": {
      "id": "runtime.search",
      "category": "search",
      "status": "ok",
      "summary": "search is OK (bundled)",
      "details": {
        "search command": "/opt/homebrew/Caskroom/codex/0.147.0/codex-path/rg",
        "search command readiness": "file exists",
        "search provider": "bundled"
      },
      "remediation": null,
      "durationMs": 0
    },
    "sandbox.helpers": {
      "id": "sandbox.helpers",
      "category": "sandbox",
      "status": "ok",
      "summary": "sandbox configuration is readable",
      "details": {
        "approval policy": "OnRequest",
        "codex-linux-sandbox helper": "none",
        "execve wrapper helper": "/Users/<REDACT>/.codex/tmp/arg0/<REDACT>/codex-execve-wrapper",
        "filesystem sandbox": "restricted",
        "network sandbox": "restricted"
      },
      "remediation": null,
      "durationMs": 0
    },
    "state.paths": {
      "id": "state.paths",
      "category": "state",
      "status": "ok",
      "summary": "state paths and databases are inspectable",
      "details": {
        "CODEX_HOME": "/Users/<REDACT>/.codex (dir)",
        "active rollout files": "467 files, 317879022 total bytes, 680683 average bytes",
        "archived rollout files": "0 files, 0 total bytes, 0 average bytes",
        "goals DB": "/Users/<REDACT>/.codex/goals_1.sqlite (file)",
        "goals DB integrity": "ok",
        "log DB": "/Users/<REDACT>/.codex/logs_2.sqlite (file)",
        "log DB integrity": "ok",
        "log dir": "/Users/<REDACT>/.codex/log (dir)",
        "memories DB": "/Users/<REDACT>/.codex/memories_1.sqlite (file)",
        "memories DB integrity": "ok",
        "queue DB": "/Users/<REDACT>/.codex/queue_1.sqlite (file)",
        "queue DB integrity": "ok",
        "sqlite home": "/Users/<REDACT>/.codex (dir)",
        "state DB": "/Users/<REDACT>/.codex/state_5.sqlite (file)",
        "state DB integrity": "ok",
        "thread history DB": "/Users/<REDACT>/.codex/thread_history_1.sqlite (file)",
        "thread history DB integrity": "ok"
      },
      "remediation": null,
      "durationMs": 313
    },
    "state.rollout_db_parity": {
      "id": "state.rollout_db_parity",
      "category": "threads",
      "status": "ok",
      "summary": "rollout files and state DB thread inventory agree",
      "details": {
        "default model provider": "openai",
        "rollout DB active files": "467",
        "rollout DB active rows": "467",
        "rollout DB archive mismatches": "0",
        "rollout DB archived files": "0",
        "rollout DB archived rows": "0",
        "rollout DB duplicate DB paths": "0",
        "rollout DB duplicate rollout thread ids": "0",
        "rollout DB malformed file names": "0",
        "rollout DB missing active rows": "0",
        "rollout DB missing archived rows": "0",
        "rollout DB model providers": "openai=467",
        "rollout DB rows": "467",
        "rollout DB scan cap reached": "false",
        "rollout DB scan errors": "0",
        "rollout DB sources": "cli=429, subagent:other=27, subagent:thread_spawn=8, vscode=3",
        "rollout DB stale rows": "0"
      },
      "remediation": null,
      "durationMs": 165
    },
    "system.environment": {
      "id": "system.environment",
      "category": "system",
      "status": "ok",
      "summary": "OS language en-US",
      "details": {
        "EDITOR": "set",
        "GH_PAGER": "set",
        "GIT_PAGER": "set",
        "LANG": "en_US.UTF-8",
        "LC_ALL": "C.UTF-8",
        "LC_CTYPE": "C.UTF-8",
        "LESS": "set",
        "PAGER": "set",
        "VISUAL": "set",
        "os": "Mac OS 26.5.2 [64-bit]",
        "os language": "en-US",
        "os type": "Mac OS",
        "os version": "26.5.2"
      },
      "remediation": null,
      "durationMs": 4
    },
    "terminal.env": {
      "id": "terminal.env",
      "category": "terminal",
      "status": "ok",
      "summary": "terminal metadata was detected",
      "details": {
        "COLORFGBG": "15;0",
        "COLORTERM": "truecolor",
        "NO_COLOR": "1",
        "TERMINFO_DIRS entry": [
          "/Applications/iTerm.app/Contents/Resources/terminfo (dir)",
          "/usr/share/terminfo (dir)"
        ],
        "TERM_PROGRAM": "iTerm.app",
        "color output": "disabled (NO_COLOR)",
        "effective locale": "C.UTF-8",
        "stderr is terminal": "false",
        "stdin is terminal": "false",
        "stdout is terminal": "false",
        "terminal": "iTerm2",
        "terminal size": "80x24",
        "terminal version": "3.7.0beta9"
      },
      "remediation": null,
      "durationMs": 6
    },
    "terminal.title": {
      "id": "terminal.title",
      "category": "title",
      "status": "ok",
      "summary": "terminal title default",
      "details": {
        "terminal title activity": "true",
        "terminal title items": "activity, project-name",
        "terminal title project source": "git repo root",
        "terminal title project value": "<REDACT>",
        "terminal title source": "default"
      },
      "remediation": null,
      "durationMs": 0
    },
    "updates.status": {
      "id": "updates.status",
      "category": "updates",
      "status": "ok",
      "summary": "update configuration is locally consistent",
      "details": {
        "cached latest version": "0.147.0",
        "check for update on startup": "true",
        "last checked at": "<REDACT>",
        "latest version": "0.147.0",
        "latest version status": "current version is not older",
        "update action": "brew upgrade --cask codex",
        "version cache": "/Users/<REDACT>/.codex/version.json"
      },
      "remediation": null,
      "durationMs": 73
    }
  }
}

What issue are you seeing?

After upgrading from Codex CLI 0.146.x to 0.147.0, the TUI displays this message during startup:

MCP startup interrupted. The following servers were not initialized: appsignal, codex_apps, linear, node_repl, <REDACT>_readonly

This status appears to be incorrect or stale. Codex’s logs show that each named MCP server subsequently initializes successfully, without an authentication failure, timeout, or transport error.

The affected servers include:

  • Two streamable HTTP servers
  • The built-in codex_apps server
  • A local Node REPL stdio server
  • A project-scoped PostgreSQL toolbox stdio server whose identifying name has been redacted

After startup, /mcp and the available tool catalog show tools from all five servers. codex doctor --json also reports overallStatus: "ok" and an internally consistent MCP configuration.

This is therefore primarily a status-reporting problem: the message says the servers “were not initialized,” even though initialization continues in the background and completes successfully.

What steps can reproduce the bug?

  1. Configure multiple optional MCP servers, including at least one stdio server that takes several seconds to initialize.
  2. Upgrade Codex CLI through Homebrew:

``sh
brew upgrade --cask codex
codex --version
``

  1. Confirm the installed version is codex-cli 0.147.0.
  2. Start the interactive TUI:

``sh
codex
``

  1. Begin interacting with or typing into the TUI while MCP startup is still in progress.
  2. Observe the following status message:

``text
MCP startup interrupted. The following servers were not initialized: ...
``

  1. Wait several seconds and inspect /mcp or the available MCP tool catalog.
  2. Observe that the servers listed as “not initialized” have actually initialized and their tools are available.
  3. Run:

``sh
codex doctor --summary
``

  1. Observe that the installation, network, WebSocket, authentication, and MCP configuration checks all pass.

On this machine, repeated startup logs showed initialization completing approximately as follows:

node_repl: initialized
codex_apps: initialized
linear: initialized
appsignal: initialized
<REDACT>_readonly: initialized

The slowest project-scoped stdio server completed within approximately 5–13 seconds and has a configured 60-second startup timeout. The Node REPL has a configured 120-second startup timeout. No timeout was reached.

No thread ID is included because the warning occurs during TUI startup, before a task-specific thread is needed.

What is the expected behavior?

If optional MCP initialization continues in the background, the TUI should not report those servers as definitively “not initialized.”

A more accurate status would be something like:

MCP startup is continuing in the background: ...

The status should then update or disappear when those servers initialize.

If startup is interrupted only at the UI/waiting layer, the message should distinguish that from an actual MCP initialization failure. Only servers that genuinely fail, time out, or are cancelled should be reported as not initialized.

Additional information

  • This started immediately after upgrading to CLI 0.147.0.
  • It was not observed with the previous 0.146.x installation.
  • The 0.147.0 changelog mentions non-blocking optional MCP startup and changes to terminal input handling while MCP servers initialize, so this may be related to the new startup lifecycle.
  • The experimental mcp_2026_07_28 feature is not enabled.
  • All five named servers are usable in the same session where the warning was reported.
  • Relevant logs, with paths and identifying information removed, contain successful Service initialized events for every named server and do not contain a corresponding startup timeout or fatal connection failure.

View original on GitHub ↗

8 Comments

github-actions[bot] contributor · 21 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #36486
  • #36682

Powered by Codex Action

tsuvic · 21 days ago

This matches earlier-reported issues — same underlying mechanism, now directly reproduced (see the update below):

  • #36486 — TUI falsely reports "MCP startup interrupted" for servers that did connect
  • #36682 — the app-server side: duplicate mcpServer/startupStatus/updated notifications, including spurious cancelled events, for servers started exactly once
  • #36190 — the same false "not initialized" report with a custom provider

Two additional data points:

  • The banner already reproduced on 0.146.0 (#36486); 0.147.0's non-blocking optional MCP startup likely changed the timing rather than introducing it.
  • My machine's app-server traces (~/.codex/logs_2.sqlite, desktop 26.803.41515 / bundled 0.147.0-alpha.6.5) also contain start_server_task{server_name=…}:initialize:serve_inner: task cancelled events during thread/start and thread/resume, for servers such as codex_apps and node_repl — the same signature noted in #36486/#36682.

Per #36486, [features] plugins = false consistently removed the warning (reported workaround, not a fix).

Update — deterministic direct repro + code path (0.147.0-alpha.6.5, isolated CODEX_HOME, synthetic stdio MCP servers whose initialize responses are delayed):

  1. codex — wait for the "Starting MCP servers (0/N) … esc to interrupt" header
  2. press ESC while servers are still starting (no active turn)
  3. the banner appears, listing exactly the servers still Starting — a server that had already become Ready before ESC is correctly excluded:
⚠ MCP startup interrupted. The following servers were not initialized:
  fake_a, fake_b, fake_c, fake_e, fake_f, fake_g, fake_h

Code path (current main): ESC with no active turn → Session::interrupt_taskcancel_mcp_startup() (codex-rs/core/src/session/mod.rs:4074) → pending startup tasks emit McpStartupStatus::Cancelled (codex-rs/codex-mcp/src/connection_manager.rs:451–545) → forwarded as mcpServer/startupStatus/updated { status: Cancelled } (codex-rs/app-server/src/bespoke_event_handling.rs:217) → TUI renders the warning for every Cancelled server (codex-rs/tui/src/chatwidget/mcp_startup.rs:186).

So a user-cancelled eager startup is reported with the same wording as an initialization failure, while the servers simply start on next use — matching the report's observation that everything works afterwards. The thread/start / thread/resume variant of the spurious task cancelled traces is the same Cancelled mechanism reached via runtime replacement rather than ESC.

Suggested direction: treat user-cancelled startup separately from failures — a neutral message ("startup skipped; servers start on first use") or no warning at all, since nothing actually failed.

morluto · 20 days ago

Independent Linux reproduction on Codex CLI 0.147.0 with two local stdio MCP servers: Flameox 0.1.12 and Jacobian 0.9.0.

The TUI reported:

⚠ MCP startup interrupted. The following servers were not initialized: flameox, jacobian

Both server commands were then verified with the exact initialize request used by Codex (protocolVersion: "2025-06-18"): each returned a valid MCP initialize result and exited cleanly when stdin closed; neither wrote stderr.

The local Codex log also shows the startup timeline:

startup_prewarm: omitting pending optional MCP server server_name=flameox
startup_prewarm: omitting pending optional MCP server server_name=jacobian
...
mcp.runtime.refresh:new{server_name=flameox}: ... Service initialized as client

For Flameox, the successful initialization was recorded about four seconds after it was omitted as pending. This confirms the problem is not limited to the built-in or HTTP MCPs: it also affects independently maintained Python stdio servers on Linux, and the warning does not establish an MCP-side failure.

anthony-chaudhary · 19 days ago

Corroborated on Windows 11 with codex-cli 0.147.0 and the same all-server false negative pattern.

The TUI reported these four servers as not initialized:

  • codex_apps
  • dos (stdio)
  • fak (stdio)
  • openaiDeveloperDocs (streamable HTTP)

The authoritative local logs_2.sqlite startup process (pid:50440:e865d723-a011-4f93-ac63-5a851a430040) records successful rmcp::service ... Service initialized as client events for all four: codex_apps and openaiDeveloperDocs at 14:59:22, then fak and dos at 14:59:25. That process has zero MCP WARN/ERROR rows. Immediately afterward, /mcp/tool availability was healthy; the fak-side independent probes also passed (fak doctor mcp --json valid initialize, and fak dev codex-mcp-health --json returned RECONNECT_OK).

This rules out a fak startup failure in this occurrence and matches the 0.147.0 UI/wait-layer regression described here. It also differs from the real plugin-refresh cancellation/process leak in #37025: no failed server and no stray fak serve --stdio child remained.

hackf5 · 13 days ago

Another reproduction on Linux/WSL2 where the affected server is streamable HTTP, not stdio.

Environment:

  • codex-cli 0.147.0
  • Ubuntu 24.04.4 LTS on WSL2, x86_64
  • Context7 configured as an enabled streamable_http server at https://mcp.context7.com/mcp
  • Authentication supplied by a static HTTP header (credential value redacted)

The first turn did not receive the Context7 tools and Context7 was reported/unavailable as though startup had failed. The SQLite log shows a startup/refresh race rather than an MCP-side failure:

07:43:12.030  server_name=context7 ... Service initialized as client
                protocol_version="2025-06-18"
                server_info name="Context7" version="4.0.1"

07:43:12.054  startup_prewarm ... mcp.runtime.resolve_for_step:
                omitting pending optional MCP server server_name=context7

07:43:12.926  server_name=context7 ... task cancelled
07:43:12.943  server_name=context7 ... quit_reason=Cancelled

07:43:13.204  server_name=context7 ... Service initialized as client
07:43:13.206  thread/start ... server_name=context7 ... task cancelled
07:43:13.210  thread/start ... server_name=context7 ... quit_reason=Cancelled

There was no Context7 HTTP authentication error, transport error, protocol error, or startup timeout. codex mcp get context7 continued to show the server as enabled with transport: streamable_http and a masked configured header.

The logs also contain warnings that org.freedesktop.secrets is unavailable while Codex attempts to load OAuth tokens. Those warnings occur for multiple HTTP MCP servers and appear non-causal here: Context7 accepted the configured static header and returned a valid initialize response.

This corroborates the runtime-replacement/cancellation path described above. One additional user-visible consequence in this reproduction is that, although Context7 successfully initialized, its tools were absent from the first turn's tool snapshot. The snapshot had already omitted the server as pending and was not rebuilt for that turn after initialization completed.

ragtimelab · 9 days ago

Independent reproduction on macOS 15.7.8 (24G824), x86_64, with Codex CLI 0.147.0 (observed 2026-08-19 KST).

This reproduces in the interactive TUI with no keyboard input during startup. Context7 is a local stdio server launched as npx -y @upstash/context7-mcp (Context7 4.0.2). codex doctor --summary --ascii reports 17 OK, 0 warnings, and 0 failures; the MCP configuration is locally consistent.

A representative no-input TUI launch showed the interruption banner even though the backend log recorded every configured server as initialized first:

05:41:50.824  11 mcpServer/startupStatus/updated events emitted in one burst
05:41:51.010  codex_apps  Service initialized as client
05:41:51.115  remote installed plugin sync completed (materialized_remote_plugins=[])
05:41:51.350  node_repl   Service initialized as client
05:41:51.479  aside       Service initialized as client
05:41:51.550  remote installed plugin sync completed (materialized_remote_plugins=[])
05:41:52.375  remote installed plugin sync completed (materialized_remote_plugins=[])
05:41:52.831  context7    Service initialized as client (v4.0.2)
05:42:00.977  unscoped codex_apps startup task cancelled

The TUI then reported all four servers as not initialized. In ordinary launches the banner often names only Context7, which is the slowest of the four.

Context7 itself is healthy:

  • A direct MCP initialize handshake through npx succeeds in 1.61 s, well below the documented 10 s default startup timeout.
  • A fresh codex exec --ephemeral session successfully called Context7's resolve-library-id tool and returned /reactjs/react.dev.
  • Increasing startup_timeout_sec therefore does not match the observed cancellation timing or failure mode.

I also ran a non-persistent control launch:

codex -s read-only -c 'features.plugins=false'

In that run there were zero remote installed-plugin sync events, all four MCP servers initialized (Context7 in about 1.4 s), and no interruption banner appeared during a 15-second observation window. The actual config file was not modified.

This seems to corroborate the plugin-sync/runtime-reconciliation path in #37025 together with the duplicate/stale startup-status behavior in #36682, rather than an MCP transport, Context7, authentication, or timeout failure. It may also be relevant that #36895 is already included in 0.147.0, yet this no-input reproduction remains.

tsuvic · 9 days ago

Adding a second source of Cancelled found in source — the ESC path from my earlier comment is not the only one, which may account for reproductions with no keypress.

Every startup task also waits on a publication gate before reporting its outcome; if the gate's sender is dropped without publishing (the MCP runtime being replaced/discarded), the task returns StartupOutcomeError::Cancelled with no user action:

  • McpPublicationGate::wait() returns false when the watch sender is dropped (codex-rs/codex-mcp/src/runtime.rs:128–159)
  • the gate-checked spawns at codex-rs/codex-mcp/src/connection_manager.rs:446, 467, 562, 681 all return Err(StartupOutcomeError::Cancelled)

This is the same Cancelled status the TUI renders as "MCP startup interrupted / not initialized", so anything that swaps the runtime while servers are still starting (session start/resume replacing the MCP runtime) surfaces the identical misleading banner — and matches the spurious task cancelled startup traces observed during desktop thread/start / thread/resume. It also lines up with @ragtimelab's observation that the banner disappears with features.plugins=false: plugin-sync churn (e.g. the unscoped codex_apps startup task being cancelled) is exactly the kind of startup replacement that reaches this path without any keypress.

This reinforces the earlier suggested direction: the user-visible status should distinguish real failures from lifecycle cancellation — or suppress the warning for Cancelled entirely, since the servers start on next use. (Verified on main @67ed4e7.)

tsuvic · 9 days ago

Still reproduces on 0.148.0 (release binary, macOS 26.5.2 arm64) — same shape as the ESC-triggered repro in my original comment.

Repro on 0.148.0 (isolated, no auth; temp CODEX_HOME with three synthetic stdio MCP servers whose initialize responses are delayed 1 s / 8 s / 8 s, ESC injected at t=2 s while the two slow servers are still Starting):

⚠ MCP startup interrupted. The following servers were not initialized:
  fake_slow_a, fake_slow_b

The 1 s server (Ready before ESC) is again excluded — the list is a snapshot of what was still Starting at cancel time, not a set of failures.

Code state (current main). The ESC chain is unchanged: ESC with no active turn → interrupt_taskcancel_mcp_startup() (codex-rs/core/src/session/mod.rs:4091–4098), per-server Cancelled status (codex-rs/codex-mcp/src/connection_manager.rs), forwarded at codex-rs/app-server/src/bespoke_event_handling.rs:219, and the TUI renders the same "interrupted / not initialized" warning at codex-rs/tui/src/chatwidget/mcp_startup.rs:185–191. With the second, keypress-free source of Cancelled (publication gate) described in my follow-up also still present, 0.148.0 covers neither trigger.

The earlier suggestion therefore stands: cancelled-but-healthy startup should be reported distinctly from failures (or not at all), since the servers simply start on next use and nothing actually failed.