[GH-ISSUE #441] [Bug] MCP cold start exhausts Codex startup deadline #251

Closed
opened 2026-10-15 18:23:00 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @morluto on GitHub (Jul 26, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/441

Bug Description

REA's MCP process can exhaust the 30-second Codex startup deadline that rea setup configures. On a cold launch, importing the production entrypoint consumed about 20 seconds before the server could answer MCP initialize; modest client startup contention is therefore enough for Codex to report:

MCP client for `rea` timed out after 30 seconds.
MCP startup incomplete (failed: rea)

This is also a package-validation gap. The current runtime and package smoke tests exercise MCP connectivity after build, doctor, or other repository activity has warmed the same module graph, and they do not assert a cold time-to-initialize budget.

Steps to Reproduce

  1. Configure Codex with the value generated by REA:

    [mcp_servers.rea]
    command = "/absolute/path/to/rea/scripts/rea.mjs"
    args = ["mcp"]
    startup_timeout_sec = 30
    
  2. Start Codex in an environment where REA's compiled runtime and dependencies are not already in the filesystem cache.

  3. Observe that Codex can time out while starting the rea MCP server.

The following diagnostics were also run against the same checkout:

/usr/bin/time -f 'elapsed=%e maxrss=%M' \
  node -e 'await import("/root/rea/dist/main.js")'

First observed run:

elapsed=20.09 maxrss=345404

An MCP SDK probe launching scripts/rea.mjs mcp observed:

{"connected_ms":21027}
{"listed_ms":21902,"tools":39}

A subsequent warm import completed in 2.72 seconds, confirming that the result is sensitive to cache state.

Expected Behavior

The production MCP entrypoint should answer initialize with enough headroom to operate reliably inside the startup deadline installed by rea setup. Heavy provider and tool-family implementations should not have to load before the transport can initialize a target-free session.

Package validation should measure the installed executable from a genuinely cold process boundary and fail when time-to-initialize exceeds the supported budget.

Actual Behavior

src/main.ts eagerly imports the shared runtime, server construction, and browser providers before starting stdio. src/application/runtime.ts in turn eagerly imports Hopper, Ghidra, native, artifact, and managed providers. The resulting production graph contains 693 compiled JavaScript files; the measured cold import consumed roughly two-thirds of the configured Codex deadline before the MCP handshake.

CODEX_STARTUP_TIMEOUT_SECONDS is fixed at 30 seconds and setup tests assert that exact configuration. However:

  • tests/runtime.test.ts exercises the already-built runtime in the repository test environment.
  • scripts/verify-package-mcp.mjs runs the production MCP doctor before connecting to the packaged MCP server, warming runtime files used by the subsequent startup.
  • Neither path records or asserts cold time-to-initialize or startup peak RSS.

Increasing startup_timeout_sec would reduce the immediate failure rate, but it would not detect future startup regressions or remove the eager initialization cost.

Environment

  • REA version: 2.5.1, commit 90bb1610
  • Node.js version: v24.18.0
  • npm version: 11.16.0
  • OS: Linux 6.8.0-136-generic x86_64
  • Hopper Disassembler version: not applicable; target-free MCP startup
  • Target binary format: none

Additional Context

  • MCP client: Codex
  • Configured startup timeout: 30 seconds, generated by REA
  • The configured command was an absolute local scripts/rea.mjs path, so rea being absent from PATH was not part of this failure.
  • No target or provider process was opened during the measured target-free initialization.

A possible direction is a minimal MCP bootstrap that starts stdio and serves initialize before lazily loading provider-specific implementations. Regardless of implementation, a regression test should preserve a cold package boundary and assert an explicit initialize deadline without first importing or probing the production runtime.

Originally created by @morluto on GitHub (Jul 26, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/441 ## Bug Description REA's MCP process can exhaust the 30-second Codex startup deadline that `rea setup` configures. On a cold launch, importing the production entrypoint consumed about 20 seconds before the server could answer MCP `initialize`; modest client startup contention is therefore enough for Codex to report: ```text MCP client for `rea` timed out after 30 seconds. MCP startup incomplete (failed: rea) ``` This is also a package-validation gap. The current runtime and package smoke tests exercise MCP connectivity after build, doctor, or other repository activity has warmed the same module graph, and they do not assert a cold time-to-initialize budget. ## Steps to Reproduce 1. Configure Codex with the value generated by REA: ```toml [mcp_servers.rea] command = "/absolute/path/to/rea/scripts/rea.mjs" args = ["mcp"] startup_timeout_sec = 30 ``` 2. Start Codex in an environment where REA's compiled runtime and dependencies are not already in the filesystem cache. 3. Observe that Codex can time out while starting the `rea` MCP server. The following diagnostics were also run against the same checkout: ```bash /usr/bin/time -f 'elapsed=%e maxrss=%M' \ node -e 'await import("/root/rea/dist/main.js")' ``` First observed run: ```text elapsed=20.09 maxrss=345404 ``` An MCP SDK probe launching `scripts/rea.mjs mcp` observed: ```json {"connected_ms":21027} {"listed_ms":21902,"tools":39} ``` A subsequent warm import completed in 2.72 seconds, confirming that the result is sensitive to cache state. ## Expected Behavior The production MCP entrypoint should answer `initialize` with enough headroom to operate reliably inside the startup deadline installed by `rea setup`. Heavy provider and tool-family implementations should not have to load before the transport can initialize a target-free session. Package validation should measure the installed executable from a genuinely cold process boundary and fail when time-to-initialize exceeds the supported budget. ## Actual Behavior `src/main.ts` eagerly imports the shared runtime, server construction, and browser providers before starting stdio. `src/application/runtime.ts` in turn eagerly imports Hopper, Ghidra, native, artifact, and managed providers. The resulting production graph contains 693 compiled JavaScript files; the measured cold import consumed roughly two-thirds of the configured Codex deadline before the MCP handshake. `CODEX_STARTUP_TIMEOUT_SECONDS` is fixed at 30 seconds and setup tests assert that exact configuration. However: - `tests/runtime.test.ts` exercises the already-built runtime in the repository test environment. - `scripts/verify-package-mcp.mjs` runs the production MCP doctor before connecting to the packaged MCP server, warming runtime files used by the subsequent startup. - Neither path records or asserts cold time-to-initialize or startup peak RSS. Increasing `startup_timeout_sec` would reduce the immediate failure rate, but it would not detect future startup regressions or remove the eager initialization cost. ## Environment - REA version: 2.5.1, commit `90bb1610` - Node.js version: v24.18.0 - npm version: 11.16.0 - OS: Linux 6.8.0-136-generic x86_64 - Hopper Disassembler version: not applicable; target-free MCP startup - Target binary format: none ## Additional Context - MCP client: Codex - Configured startup timeout: 30 seconds, generated by REA - The configured command was an absolute local `scripts/rea.mjs` path, so `rea` being absent from `PATH` was not part of this failure. - No target or provider process was opened during the measured target-free initialization. A possible direction is a minimal MCP bootstrap that starts stdio and serves `initialize` before lazily loading provider-specific implementations. Regardless of implementation, a regression test should preserve a cold package boundary and assert an explicit initialize deadline without first importing or probing the production runtime.
bsakaguchi 2026-10-15 18:23:00 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#251
No description provided.