rdmsm4x-changelog-20260924-1542-mem0-shared-claude-config-fleet-fix
rdmsm4x-changelog-20260924-1542-mem0-shared-claude-config-fleet-fix
mem0-shared (the fleet's shared memory MCP) was broken for every Claude Code session on all six Macs because Tyrell Build 32's first-launch onboarding (2026-09-23 ~15:13 EDT) pointed it at a nonexistent binary. It is repointed at each host's own ~/bin/mem0-mcp on all six hosts and verified connected on each. Two source fixes keep it that way: the fleet MCP reconciler now converges mem0-shared every 30 minutes, and Tyrell's bootstrap has a fix on a branch awaiting merge.
Written 2026-09-24 15:42 EDT on rdmsm4x by grok@rdmsm4x/grok0924 (Grok Bot, Rich's new assistant; working over ssh from rdmbair15m5). Ticket ISSUE-20260924-24. Covers 15:24 to 15:42 EDT.
Scope
- Hosts: rdmsm4x, rdmbair15m5, rdmbair13m5, jdmbair13m5 (richh, uid 502 only), rdmpw3265m, rdmpw3275m.
- Repos: fleet/maintenance, fleet (submodule pointer), apps/Tyrell (branch only).
- Per-host files: ~/.claude.json (the mcpServers.mem0-shared key only), and ~/.gemini/antigravity-cli/mcp/mem0-shared/server.json on 3 hosts.
Root cause
- Tyrell commit 413a5dc (2026-09-23) added
SelfBootstrap.configureAgentHarnesses().
- It writes mem0-shared =
/Contents/Helpers/ecsmem0 for Claude, Codex and Antigravity. - make_app_bundle.zsh never ships that file: Helpers contains tyrelld, ecsmem0d, replicantdb and tyrell-mcp.
- Even if it existed, ecsmem0 with no args only prints usage. MCP mode
is selected by the basename mem0-mcp or by the arg
mcp.
- It writes mem0-shared =
- Build 32's onboarding ran once per host 2026-09-23 15:13–15:17 EDT. The sentinel is ~/Library/Application Support/Tyrell/state/.onboarded_v2.
- The same onboarding rewrote tyrell and replicantdb too. fleet_mcp_reconcile.zsh re-converged those two within 30 minutes, but mem0-shared was outside its SERVERS set, so it stayed broken for about 24 hours.
- Codex was unaffected: its mem0-shared block already existed, pointing at ~/bin/mem0-mcp or an ssh to the hub. agy's real configs (~/.gemini/config/mcp_config.json and antigravity-ide/mcp_config.json) already point at ~/bin/mem0-mcp.
- Bundling ecsmem0 into Tyrell is NOT a fix. It opens the SQLite store directly, so on a spoke it would be a private silo (ISSUE-20260922-06).
Changes
| What | Where | Evidence / undo |
|---|---|---|
| mcpServers.mem0-shared → {"type":"stdio","command":"/Users/richh/bin/mem0-mcp","args":[],"env":{}}. Edited only if the value was the broken path. JSON-aware read-modify-write with a same-file-unchanged check, written atomically, then re-verified. | ~/.claude.json on all 6 | Backup
~/.claude.json.bak-grok-20260924-1529 on each host. Undo:
restore only that key from the backup. Do not copy the whole backup file
back over the live one; Claude rewrites it continuously. |
| server.json "command" → /Users/richh/bin/mem0-mcp | ~/.gemini/antigravity-cli/mcp/mem0-shared/server.json on jdmbair13m5, rdmpw3265m, rdmpw3275m (absent on the other 3) | Backup
server.json.bak-grok-20260924-1533 next to it |
| fleet_mcp_reconcile.zsh v1.6: mem0-shared is a REGISTRATION-ONLY server. It probes the host's own ~/bin/mem0-mcp and, if that answers, converges the Claude/Codex registration onto it. It never distributes a binary. A failed probe is an error, never a redeploy. | fleet/maintenance b984672, pushed to git.ecs0.net fleet/main | Tests: --dry-run current=6. Hermetic HOME test: broken entry → updated, with a backup and other keys preserved. Dead-wrapper control → error, config untouched. Undo: git revert b984672 |
| Submodule pointer bump | fleet 210efd5, pushed to fleet/main | git revert 210efd5 |
| SelfBootstrap writes |
apps/Tyrell branch grok/mem0-shared-path-ISSUE-20260924-24 @ 61bc9bc (worktree ~/dev/_worktrees/tyrell-grok-mem0-20260924), NOT merged | mock_onboarding_contract_test.zsh PASS; swiftc -parse OK. swift test not run (hub load ~110). Follow-up: TASK-20260924-14 |
Verification (measured, per host)
- Before:
claude mcp liston rdmbair15m5 and rdmsm4x (15:26) showedmem0-shared: /Applications/Tyrell.app/Contents/Helpers/ecsmem0 - ✘ Failed to connect — ENOENT. All six had the same entry in ~/.claude.json. - Wrapper check: ~/bin/mem0-mcp was probed over MCP stdio on all six. Each returned initialize → serverInfo ecsmem0 1.0.0, tools/list → 7 tools, and mem0_health → vector_count 26, collection mem0_shared_v1. Six of six were on the shared store, so no silo.
- After:
claude mcp listat 15:29:59 EDT showedmem0-shared: /Users/richh/bin/mem0-mcp - ✔ Connectedon all six: rdmsm4x, rdmbair15m5, rdmbair13m5, jdmbair13m5, rdmpw3265m, rdmpw3275m. - Reconciler: the scheduled launchd run of v1.6 at 15:41:03 EDT reported servers [tyrell, replicantdb, mem0-shared], current=6, updated=0, errors=0.
Not changed / notes
- No daemons were restarted (ecsmem0d, tyrelld) and no sessions were killed. Claude sessions already running keep their old MCP set until they restart.
- ticket-mcp is also broken on all six. The hub returns -32601; the spokes fail with ENOENT. It was out of scope and is filed as ISSUE-20260924-25.
- Apple Notes entry is PENDING. notes_changelog.zsh refuses non-Aqua (ssh) sessions, so it was handed to claude@rdmsm4x over the bus.