[Feature]: Defer runtime discovery until needed: Windows where probes consume 30s before MCP initialize

Author: bayi-95Created Sep 14, 2026Updated Sep 14, 2026
Labelsenhancement

Platform

Codex CLI

Feature description

Please move execution-runtime discovery off the MCP initialization critical path and cache runtime resolution on first use. Related: #670 (avoiding repeated PATH probes), but this report concerns the initial scan before the server can answer initialize.

Environment: Windows / PowerShell, Node 24.18.0, context-mode 1.0.169 (npm latest checked September 14, 2026), Codex Desktop with bundled codex 0.154.0-alpha.6.2. Installed as a standalone npm MCP server, launched directly with Node and server.bundle.mjs. No routing/session-capture hooks from context-mode.

Measured evidence

An isolated stdio MCP client took 31,271 ms to complete initialize. A diagnostic preload timed child_process.execSync/execFileSync/spawnSync, using syncBuiltinESMExports before importing the unchanged installed bundle. The 16 serial where invocations totalled 30,229 ms (96.7%). Python --version added 389 ms; a Git probe added 4 ms.

Command ms
where bun 2060
where bash 1880
where tsx 2030
where ts-node 1622
where python3 1944
where python 1734
where ruby 1988
where go 1456
where rustc 2322
where php 1562
where perl 2111
where Rscript 1673
where r 1779
where elixir 2036
where dotnet-script 1901
where bun 2131

Earlier uninstrumented isolated handshakes were approximately 32.2s and 34.9s. Direct where.exe also took about 1.93s on this machine, versus 1.86s via a shell; replacing execSync with execFileSync alone is not demonstrated to fix this. Why each Windows lookup is unusually expensive remains unproven. These are local observations, not a claim that every Windows host has this latency.

Reproduction / profiling

  1. Install [email protected] in an isolated directory on Windows with Node 24.18.0.
  2. Launch node node_modules/context-mode/server.bundle.mjs through a stdio MCP client, with CONTEXT_MODE_PLATFORM=codex, a dedicated CONTEXT_MODE_DIR, and PATH containing only the Node directory, Python directory, Windows System32, and Windows PowerShell directory. Set SHELL to the existing powershell.exe path. No model prompt or tool execution is necessary.
  3. Time spawn/connect through the initialize response. Then call tools/list to confirm successful initialization (11 tools in this direct client).
  4. To attribute synchronous probes, save this as profile.mjs and launch Node with --import file:///absolute/path/to/profile.mjs before the server entrypoint:
javascript
import cp from 'node:child_process';
import { syncBuiltinESMExports } from 'node:module';
for (const name of ['execSync', 'execFileSync', 'spawnSync']) {
  const original = cp[name];
  cp[name] = function (...args) {
    const start = performance.now();
    try { return original.apply(this, args); }
    finally {
      console.error(JSON.stringify({
        name, command: args[0], ms: performance.now() - start
      }));
    }
  };
}
syncBuiltinESMExports();

Inspect/redact diagnostic output before sharing: generic command arguments may contain private paths. The timings above are a targeted profiler, not output from ctx-debug.sh.

Use case

Our Codex configuration exposes only ctx_index, ctx_search and ctx_stats through the host-side enabled_tools filter. This filter does not tell the server to skip runtime discovery: the direct server still registers all tools, and the installed bundle eagerly calls its runtime-detection function before the MCP server is ready.

With context-mode.required=true, desktop task creation took 36.48-53.15s; one frontend request timed out at 30s and the backend replied later. Removing only required allowed an isolated ephemeral Codex thread/start to return in 935ms. That mitigates task-start blocking but does not speed up the context-mode server; desktop UI after this change has not yet been independently retested.

Searching/indexing users pay to locate Ruby, Go, Rust, PHP, Perl, R, Elixir, dotnet-script, etc., before performing any execution. No agents or network prewarm are involved in the direct 31.27s MCP handshake measurement. This differs from #634's synchronous install / Codex prewarm case.

Proposed solution

Preferred: lazily resolve and cache the specific runtime when an execution request needs it. Allow initialize and non-execution tools to respond without first locating every supported language. Keep explicit diagnostics free to request a full scan.

If tool schemas require an available-language list at registration time, consider separating the declared supported-language enum from actual runtime availability validation at execution time, or an explicit restricted/index-only startup mode. Please advise which contract fits the project best.

For Windows, consider direct filesystem-based PATH/PATHEXT resolution with process-local caching, preserving command precedence, quoted paths, supported executable extensions and Microsoft Store alias filtering. Do not simply assume missing runtimes or drop validation.

Suggested regression coverage: a deliberately slow/missing optional runtime must not delay initialize or ctx_index/ctx_search/ctx_stats; first execution resolves the selected runtime, repeated execution uses its cache, and missing-runtime errors remain actionable. Measure cold and warm startup on Windows as well as Linux/macOS. No production patch or claimed post-optimization speedup is included here.