Skip to content

fix(mcp): env-scoped stdio start runs inline instead of bridging (#87) - #145

Merged
devinmlowe merged 2 commits into
mainfrom
worktree-fix-87
Sep 21, 2026
Merged

devinmlowe merged 2 commits into
mainfrom
worktree-fix-87

Conversation

@devinmlowe

Copy link
Copy Markdown
Owner

Closes #87.

Root cause

decideStdioMode (src/interfaces/mcp/bridge.ts) probed /health before looking at its own env, and runBridge forwards tools/call verbatim — so ENGRAM_SCOPE / ENGRAM_READ_SCOPES / ENGRAM_DB_PATH of the stdio process were resolved under the daemon's env. The Hermes plugin is stdio-only and always sets ENGRAM_SCOPE, so every profile wrote global and read every scope whenever the daemon was up.

Fix

At the one decision point every stdio start routes through:

  • ENGRAM_SCOPE / ENGRAM_READ_SCOPES (non-blank) → inline, no probe; stderr names the variable: running inline (ENGRAM_SCOPE=hermes:career is per-process; the daemon would ignore it).
  • /health now reports dbPath; with ENGRAM_DB_PATH set the bridge is used only when it matches (path.resolve), else inline. A daemon without dbPath (older build) keeps bridging.

Docs: README, CLAUDE.md, docs/integrate-your-agent.md, CHANGELOG (Fixed).

Tests

Three regression tests in tests/interfaces/mcp/bridge.test.ts (unit for both rules, plus an end-to-end child with ENGRAM_SCOPE and a healthy daemon that never opens a daemon session). They fail on main (3) and pass here (0). npm run lint clean; full suite 132 files / 1692 tests pass.

Not done (deliberately): translating env into per-call scope / read_scopes inside the bridge — tools without those params (show, fetch_snippets, recall_drill) still read env, so translation would leak. Inline is the only complete fix.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BoKzYWjzY9jngoKL35LWSA

devinmlowe and others added 2 commits September 21, 2026 01:31
… bridge

Pins the fix before it lands: ENGRAM_SCOPE / ENGRAM_READ_SCOPES on a stdio
start force inline without probing, ENGRAM_DB_PATH bridges only when the
daemon's /health reports the same database, and an end-to-end child with
ENGRAM_SCOPE set never opens a daemon session. Autoresearch baseline
(iteration 0): these fail on main.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BoKzYWjzY9jngoKL35LWSA
Root cause: decideStdioMode probed /health first and bridged whenever the
daemon answered, while runBridge forwards tools/call verbatim — so
ENGRAM_SCOPE / ENGRAM_READ_SCOPES / ENGRAM_DB_PATH in the stdio process's
env (every Hermes profile child sets the first two) were resolved under
the daemon's env instead. Every profile wrote global and read every scope.

Fix, at the one decision point all stdio starts route through:
- ENGRAM_SCOPE / ENGRAM_READ_SCOPES set (non-blank) → inline, no probe,
  reason names the variable.
- /health now carries dbPath; ENGRAM_DB_PATH set and different → inline.
  A daemon without dbPath (older build) keeps bridging.
Docs: README, CLAUDE.md, integrate-your-agent, CHANGELOG (Fixed).

Autoresearch iteration 1: bridge.test.ts failures 3 → 0, lint passes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BoKzYWjzY9jngoKL35LWSA
@devinmlowe
devinmlowe merged commit 030d291 into main Sep 21, 2026
10 of 12 checks passed
@devinmlowe
devinmlowe deleted the worktree-fix-87 branch September 21, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant