[object Object]

← back to Exo Helper

Verify Claude Code and Codex use the shared Exo helper

a9fdb8ecaccb7cc589db5ebc453701dd4db14721 · 2026-09-09 10:48:10 -0700 · Steve Abrams

Files touched

Diff

commit a9fdb8ecaccb7cc589db5ebc453701dd4db14721
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Sep 9 10:48:10 2026 -0700

    Verify Claude Code and Codex use the shared Exo helper
---
 .gitignore                     |  1 +
 README.md                      |  6 ++--
 verification/client-proof.json | 72 ++++++++++++++++++++++++++++++++++++++++++
 verification/decision.md       | 40 +++++++++++++++++++++++
 verification/e2e-proof.json    | 58 ++++++++++++++++++++++++++++++++++
 5 files changed, 174 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index 6e500e4..fa05569 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ dist/
 build/
 .next/
 verification/private/
+verification/*client*.jsonl
diff --git a/README.md b/README.md
index e0e63fc..7816372 100644
--- a/README.md
+++ b/README.md
@@ -23,11 +23,11 @@ Combined prompt/context limit: 16,000 characters. Output: 512 tokens by default,
 
 ```sh
 npm ci --ignore-scripts
-codex mcp add exo-helper -- /opt/homebrew/bin/node /Users/macstudio3/Projects/exo-helper/server.mjs
-claude mcp add --scope user exo-helper -- /opt/homebrew/bin/node /Users/macstudio3/Projects/exo-helper/server.mjs
+codex mcp add exo-helper --env EXO_TIMEOUT_MS=45000 -- /opt/homebrew/bin/node /Users/macstudio3/Projects/exo-helper/server.mjs
+claude mcp add exo-helper --scope user -e EXO_TIMEOUT_MS=45000 -- /opt/homebrew/bin/node /Users/macstudio3/Projects/exo-helper/server.mjs
 ```
 
-Set Codex's `[mcp_servers.exo-helper]` `tool_timeout_sec = 120` to allow time for local inference. For Claude, the registration may pass `EXO_TIMEOUT_MS=45000` so the bridge deadline fits within Claude's normal tool timeout. Neither setting changes the primary model.
+Both registrations set a 45-second inference deadline to fit the clients' tool timeouts. The preflight has its own eight-second deadline. Neither setting changes the primary model.
 
 After registration, new sessions load the helper. In an existing Claude Code session, use `/mcp` to reconnect; restart the session if the new server is absent. Start a new Codex session to load its new MCP configuration.
 
diff --git a/verification/client-proof.json b/verification/client-proof.json
new file mode 100644
index 0000000..9dd39f3
--- /dev/null
+++ b/verification/client-proof.json
@@ -0,0 +1,72 @@
+{
+  "verdict": "PASS",
+  "codex": {
+    "calls": [
+      "exo_status",
+      "ask_exo"
+    ],
+    "answer": {
+      "request_id": "00cd9a70-fd70-42bd-a083-e0516e2151a9",
+      "response_id": "3f9abb4e-c17c-4587-aa02-1671705da566",
+      "model": "mlx-community/Qwen3-VL-4B-Instruct-4bit",
+      "answer": "42",
+      "finish_reason": "stop",
+      "truncated": false,
+      "usage": {
+        "prompt_tokens": 103,
+        "completion_tokens": 3,
+        "total_tokens": 106,
+        "prompt_tokens_details": {
+          "cached_tokens": 82,
+          "audio_tokens": 0
+        },
+        "completion_tokens_details": {
+          "reasoning_tokens": 0,
+          "audio_tokens": 0,
+          "accepted_prediction_tokens": 0,
+          "rejected_prediction_tokens": 0
+        }
+      },
+      "elapsed_ms": 1248,
+      "review_required": true
+    }
+  },
+  "claude_code": {
+    "calls": [
+      "mcp__exo-helper__exo_status",
+      "mcp__exo-helper__ask_exo"
+    ],
+    "answer": {
+      "request_id": "a99d9529-023f-4bc4-ace2-1e6833b52acd",
+      "response_id": "2afe0c0a-e2ff-4a86-ae8f-16e8e822a8f2",
+      "model": "mlx-community/Qwen3-VL-4B-Instruct-4bit",
+      "answer": "42",
+      "finish_reason": "stop",
+      "truncated": false,
+      "usage": {
+        "prompt_tokens": 103,
+        "completion_tokens": 3,
+        "total_tokens": 106,
+        "prompt_tokens_details": {
+          "cached_tokens": 85,
+          "audio_tokens": 0
+        },
+        "completion_tokens_details": {
+          "reasoning_tokens": 0,
+          "audio_tokens": 0,
+          "accepted_prediction_tokens": 0,
+          "rejected_prediction_tokens": 0
+        }
+      },
+      "elapsed_ms": 1607,
+      "review_required": true
+    }
+  },
+  "configuration": {
+    "codex_primary_provider_and_policy_preserved": true,
+    "claude_existing_mcp_entries_preserved": true,
+    "both_helper_registrations_persisted": true,
+    "observed_unrelated_difference": "node_repl.args differs from pre-install snapshot; current value preserved"
+  },
+  "initial_failed_attempt": "First Claude verification omitted --mcp-config, so no MCP servers loaded. Corrected invocation is the evidence source; initial generated text was not treated as filesystem evidence."
+}
diff --git a/verification/decision.md b/verification/decision.md
new file mode 100644
index 0000000..4ad12fc
--- /dev/null
+++ b/verification/decision.md
@@ -0,0 +1,40 @@
+# DTD Verdict — Exo helper integration
+
+## Decision: A — optional shared MCP helper
+
+Confidence: medium · Vote: 2/2 valid voters · Panel availability: 2/6
+
+| Reference | Provider/runtime | Model | Vote | Reason |
+|---|---|---|---|---|
+| Claude | Anthropic | not invoked | abstain | Canonical DTD ZERO_COST_REQUIRED disables this voter |
+| Codex | Signed-in Codex CLI | gpt-6-astra | A | Preserve primary agents; validate the actual integration |
+| Qwen | Exo/MLX on M3 Ultra | mlx-community/Qwen3-VL-4B-Instruct-4bit | A | Bounded helper uses an already verified cached model |
+| Grok | xAI | not invoked | abstain | Paid API disabled |
+| Kimi | Moonshot | not invoked | abstain | Paid API disabled |
+| Muse | not invoked | unavailable | abstain | User excludes Ollama |
+
+The task-local panel adapts the skill's Qwen voter to Exo chat completions and omits Muse. It does not call Ollama. The first Qwen answer lacked the required verdict marker and was not counted; a format-corrected rerun returned VERDICT: A. Codex's signed-in CLI resolved gpt-6-astra, as recorded in its log; no claim is made that gpt-5.3-codex ran.
+
+## Dissent
+
+None among the two valid votes. Four voters abstained, so this is limited agreement.
+
+## Post-decision Codex debate
+
+Result: KEEP. The prosecutor objected that basic inference establishes neither coding reliability nor productivity savings. The defender required enforced bounds, no execution tools, optional use, and primary-agent review. The judge retained A for a reversible helper, without claiming improved speed, savings, or distributed performance.
+
+## Why this verdict
+
+A cached model fits available memory and answers requests. Both coding clients can use the same bounded MCP interface while retaining their primary models and approvals. Larger models and automatic delegation are outside this implementation.
+
+## Adversarial review transcript
+
+**PROSECUTOR:** A mistakes feasibility for usefulness. One successful text response proves neither reliable summaries nor acceptable latency under coding workloads. A 4B model can produce plausible errors that cost the primary agents more to review than generating the answer themselves. MCP adds maintenance, resource contention, and another route for sensitive context to enter logs. “Bounded” is undefined: without enforced timeouts, concurrency limits, and input limits, it provides no protection. The strongest alternative is to retain standalone Exo and establish practical value before integrating it. Only two models voted; their agreement does not supply the missing evidence.
+
+**DEFENDER:** Those objections defeat automatic delegation and replacement of the primary agents, but A proposes neither. Its scope is optional, bounded access to an already cached model for reviewed drafts and summaries. Integration can make the relevant limits enforceable: finite input/output sizes, a request deadline, one inference at a time, and explicit failure responses. Exo needs no authority to execute commands or change files. A shared server implementation avoids duplicating the adapter for both clients; it need not mean a shared persistent process. No useful distributed inference or coding competence is assumed. Standalone testing would still leave the actual MCP interaction untested, whereas this limited adapter allows that interaction to be evaluated directly.
+
+**JUDGE:** The prosecutor establishes that productivity gains are unproven and that nominal bounds are insufficient. The defender nevertheless answers the decisive objection: the evidence required for a reversible, optional integration is lower than that required for relying on its outputs. A remains justified within its stated limited scope; broad or automatic delegation would be a different decision.
+
+FINAL: KEEP
+
+The controlling argument is proportionality: verified basic inference supports a small, explicitly bounded MCP integration while hosted agents retain responsibility and review. It does not establish coding reliability, speed improvements, or distributed performance. Enforced limits and optional use make A defensible despite those unknowns; the two valid votes alone do not.
\ No newline at end of file
diff --git a/verification/e2e-proof.json b/verification/e2e-proof.json
new file mode 100644
index 0000000..87b6258
--- /dev/null
+++ b/verification/e2e-proof.json
@@ -0,0 +1,58 @@
+{
+  "ticket": "TK-11320",
+  "intent": "Claude Code and Codex delegate a bounded task to a ready Exo model via the same stdio MCP implementation, without Ollama",
+  "risk_tier": "R2",
+  "timestamp": "2026-09-09T17:47:42.552873+00:00",
+  "environment": "macstudio3; Exo localhost:52415; Claude Code 2.1.258; Codex 0.153.4; MCP SDK 1.29.0",
+  "runtime_build_commit": "a75cf53106adfdd6f0f380774a6e731643cd3b10",
+  "baseline": "3 live cluster nodes; zero active model instances. Cached Qwen3-VL-4B fits local M3 Ultra. Existing hosted providers remain primary.",
+  "retained_instance": "cca7f90e-cddd-430f-8c65-fafb9c2ab642",
+  "commands": [
+    "npm test (9/9 passed)",
+    "npm run verify (real MCP SDK clients)",
+    "codex mcp add/get exo-helper",
+    "claude mcp add/get exo-helper",
+    "codex exec --ephemeral --ignore-user-config with isolated helper MCP config",
+    "claude -p --strict-mcp-config --mcp-config verification/mcp-config.json with only helper tools allowed"
+  ],
+  "boundaries": [
+    {
+      "boundary": "Exo instance creation -> real text generation",
+      "verdict": "PASS",
+      "response_id": "46bd74e2-d01e-4fd1-a7be-78611645ad0a"
+    },
+    {
+      "boundary": "SDK client -> stdio discovery -> Exo readiness -> inference -> text response",
+      "verdict": "PASS",
+      "evidence": "integration.json"
+    },
+    {
+      "boundary": "Actual Codex CLI -> Exo helper -> local inference",
+      "verdict": "PASS",
+      "request_id": "00cd9a70-fd70-42bd-a083-e0516e2151a9",
+      "response_id": "3f9abb4e-c17c-4587-aa02-1671705da566"
+    },
+    {
+      "boundary": "Actual Claude Code CLI -> Exo helper -> local inference",
+      "verdict": "PASS",
+      "request_id": "a99d9529-023f-4bc4-ace2-1e6833b52acd",
+      "response_id": "2afe0c0a-e2ff-4a86-ae8f-16e8e822a8f2"
+    },
+    {
+      "boundary": "Both global registrations persisted; primary providers and policies retained",
+      "verdict": "PASS",
+      "evidence": "client-proof.json"
+    }
+  ],
+  "negative_checks": "Oversized input, unloaded model, unreachable Exo, HTTP failure, model mismatch, timeout without retry, per-process concurrency, and non-loopback URL rejected. No automatic model load, provider fallback, or external tools.",
+  "cleanup": "Test client processes exited. Cached model intentionally remains loaded. Private config backups retained under ignored verification/private. Raw test traces ignored. No scheduled jobs or extra listening service installed.",
+  "rollback": "Remove only exo-helper with codex mcp remove exo-helper and claude mcp remove exo-helper -s user. Existing Exo and model files are retained.",
+  "limitations": [
+    "This model runs on the M3 Ultra alone; no distributed inference benchmark is claimed.",
+    "Small-model answers require review; only arithmetic and bounded extraction validated.",
+    "Current sessions may require reconnect/new session to discover the added server.",
+    "Concurrency bound is per bridge process; Exo schedules work from separate coding clients.",
+    "If model is unloaded later, helper reports MODEL_NOT_READY; it does not auto-start models."
+  ],
+  "verdict": "PASS"
+}

← a75cf53 auto-data-snapshot: 2026-09-09T10:37:25 (4 data files) — ver  ·  back to Exo Helper  ·  Keep raw CLI verification traces local 76ebd91 →