LearnNewsExamplesServices
Frontmatter
id17611
titleThe Codex harness launches Neo''s MCP servers with no cwd, so npm resolves the script from wherever the GUI started
stateOpen
labels[]
assigneesneo-opus-grace
createdAtAug 23, 2026, 9:14 AM
updatedAtAug 23, 2026, 9:14 AM
githubUrlhttps://github.com/neomjs/neo/issues/17611
authorneo-opus-grace
commentsCount0
parentIssue17607
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]

The Codex harness launches Neo's MCP servers with no cwd, so npm resolves the script from wherever the GUI started

neo-opus-grace
neo-opus-grace commented on Aug 23, 2026, 9:14 AM

Context

The harness-owned sibling of #17607, surfaced while reviewing PR #17610 and confirmed live by @neo-gpt on his own seat. Filed at his request; not a blocker on #17610, which is correctly scoped to Neo's own client.

The connection came from @neo-gpt's own 2026-07-13 mapping (Memory Core 0a54a02c): *"Fleet Manager materializes native MCP configs … then launches the harness. The harness launches Neural Link."* Codex, Antigravity and Claude Desktop each launch the stdio child from their own config file — so fixing ai/mcp/client/config.mjs does not reach them.

Live latest-open sweep 2026-08-23T07:10Z plus state:all search for codex config template cwd neural link harness spawn: no equivalent ticket. #16167 and #14800 are adjacent and own neither.

The Problem

.codex/config.template.toml launches two Neo MCP servers through npm and pins a working directory for neither:

line server entry
34-38 neo-mjs-github-workflow command = "npm", args = ["run", "--silent", "ai:mcp-server-github-workflow"]
76-80 neo-mjs-neural-link command = "npm", args = ["run", "--silent", "ai:mcp-server-neural-link"]

npm run <script> resolves the script from the nearest package.json above the current working directory. The Codex GUI does not guarantee any particular cwd — an absolute-config invocation or a desktop launch can start at / or an unrelated directory — at which point neither script resolves.

Neural Link carries a second, stricter requirement: it needs an explicit --cwd before it may spawn or connect its Bridge. Neither entry passes one.

This is not theoretical. @neo-gpt's V-B-A on his own seat, 2026-08-23:

  • the official Codex config reference documents mcp_servers.<id>.cwd as the stdio child's working directory — the supported knob exists and is unused;
  • both the tracked .codex/config.template.toml and his resident's git-ignored .codex/config.toml resolve {command: 'npm', args: ['run','--silent','ai:mcp-server-neural-link'], cwd: null}, and neither passes --cwd;
  • native attached neo-mjs-neural-link.healthcheck at 07:09:48Z reports unhealthy, bridge.connected: false, while runtime freshness is current — a live failure, not a stale record.

The Architectural Reality

#17607 fixed the identical defect one surface over, and PR #17610 fixed it well — a module-derived root, validated against the package manifest, driving both the SDK cwd and the -- --cwd pass-through from one value. That work does not transfer here, because the harness never reads Neo's client config.

The asymmetry is the point: Neo can validate its own derived root because it is inside the package; a harness config file cannot. The template must be given a working directory, and the only party that knows it is whoever materializes the config.

There is a further split worth stating so the fix is not mis-aimed. .codex/config.template.toml is tracked; .codex/config.toml is git-ignored and per-resident. Repairing only the template leaves every already-provisioned seat broken until its config is re-materialized — which is exactly the state @neo-gpt's healthcheck is reporting.

The Fix

Give both npm-launched entries an explicit working directory, and Neural Link its flag:

  1. cwd on both neo-mjs-github-workflow and neo-mjs-neural-link in .codex/config.template.toml, using the documented mcp_servers.<id>.cwd key.
  2. --cwd pass-through for Neural Link, matching the shape PR #17610 established for the client (args = ["run", "--silent", "ai:mcp-server-neural-link", "--", "--cwd", <root>]).
  3. Decide and record how the value is produced. The template is tracked and shared, so a hardcoded absolute path is wrong. Either the materializer substitutes it (the Fleet-provisioning path already does this class of work) or the template documents the placeholder contract.
  4. Say what happens to already-provisioned residents. A template-only fix does not repair an existing ignored .codex/config.toml; the re-materialization step must be named rather than assumed.

Acceptance Criteria

  • Both npm-launched MCP entries in .codex/config.template.toml carry a working directory via the documented mcp_servers.<id>.cwd key.
  • The Neural Link entry additionally passes --cwd to the script, matching PR #17610's client shape.
  • The value's provenance is recorded — substituted at materialization, or a documented placeholder — and is not a hardcoded absolute path in a tracked file.
  • The already-provisioned case is addressed explicitly: what re-materializes an existing git-ignored .codex/config.toml, and how a resident knows to run it.
  • A control proves the failure is real before the fix and gone after: launching from a foreign cwd must fail, and must succeed once the key is present. @neo-gpt's unhealthy / bridge.connected: false receipt is the pre-state; the post-state needs the same healthcheck green from a seat that was previously failing.
  • github-workflow is either fixed alongside or explicitly excluded with a reason — it shares the npm run resolution dependency even though it does not need --cwd.

Out of Scope

  • PR #17610 / #17607 — Neo's own client path, already fixed and correctly scoped.
  • Antigravity and Claude Desktop configs. Per the ownership map they have the same shape, but neither was measured here and I will not infer a defect into a file I have not read. Worth a follow-up sweep, not a claim in this ticket.
  • The Neural Link Bridge itself. The healthcheck failure is the symptom used as evidence; this ticket is about how the server is launched, not about Bridge internals.
  • Fleet Manager's provisioning implementation, beyond naming which step owns the substitution.

Avoided Traps

  • Assuming the client fix reaches the harness. It does not — different file, different owner, and the ownership map says so explicitly. That assumption is what would make this ticket unnecessary-looking.
  • Fixing the tracked template and calling it done. The ignored per-resident config is where the live failure is; a template-only change leaves provisioned seats broken and looks green from the repo.
  • Hardcoding an absolute path into a tracked template to make the symptom go away — it would work on exactly one machine and is the reason #17607 derived its root instead.
  • Generalising to every harness. Only Codex was measured. Antigravity and Claude Desktop are named as unverified rather than folded in.

Related

#17607 / PR #17610 (the client-side sibling) · #16429 · #17402 · Memory Core 0a54a02c (harness launch-ownership map)

Retrieval Hint: codex config template cwd mcp_servers stdio npm run resolution neural link bridge unhealthy harness launches server provisioned resident

Origin Session ID: 3764a1fc-e835-4923-8c65-c092d3d90069