From 4dcd2959ec2d788fd8dbb221f75f535537857ff8 Mon Sep 17 00:00:00 2001 From: Joakim Persson Date: Thu, 30 Apr 2026 11:21:38 +0000 Subject: [PATCH] docs+installer: how to register mempalace with opencode MCP, probe for it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two missing pieces bundled here: 1. The README described the MCP server wrapper (mempalace-mcp-server, a 3-line shell script that exec's the venv's python) as the canonical answer on a uv-tool install. That is over-engineered and out of step with the live reference box: opencode.json there uses ['mempalace-mcp'] directly, which is the shim uv tool install already creates. Rewrote the section to put the simple canonical answer first and demote the wrapper to a legacy-fallback sidebar. New 'Registering mempalace with opencode' section covers: - The one-entry JSON stanza to paste into the mcp object. - A full minimal opencode.json for someone starting fresh (with the 'instructions' array pointing at the wake-up protocol). - Custom palace path variant. - Claude Code one-liner (claude mcp add mempalace -- mempalace-mcp). - Pointer at 'mempalace mcp' subcommand which prints the currently- recommended snippets — useful when upstream updates conventions. - Troubleshooting table (tools absent / server unavailable / ModuleNotFoundError) with per-symptom fixes. The legacy-fallback subsection explains what the wrapper script was for (the pip-install → uv-tool-install transition era), shows its 3-line implementation for completeness, and is explicit about not using it for new installs. Verification checklist updated: now runs 'which mempalace-mcp' and 'mempalace-mcp --help' against the shim, not the wrapper. 2. install.sh gains a matching probe: after the existing wake-up protocol check, it grep-checks ~/.config/opencode/opencode.json for 'mempalace' + 'mempalace-mcp' substrings. Present → clean success line. Missing → actionable warning that prints the exact JSON stanza to add plus a pointer to the README anchor and the 'mempalace mcp' CLI helper. Skipped when opencode.json doesn't exist (non-opencode hosts). Textual grep rather than strict JSON parse: we don't want to hard-depend on python/jq at install time, and the two substrings together are specific enough to avoid false positives. Prerequisites list gets a 5th bullet flagging MCP registration as required and pointing at the new section + the installer probe. Smoke-tested both scenarios on the reference box — config with mempalace entry present (all ticks green), config with entry removed (actionable warning, correct snippet shown), config restored to original state. --- README.md | 100 ++++++++++++++++++++++++++++++++++++++++++----------- install.sh | 35 +++++++++++++++++++ 2 files changed, 114 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index e243484..3f66d5d 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ See [`ARCHITECTURE.md`](ARCHITECTURE.md) §6 for the full upstream roadmap. - Python 3 (stdlib `sqlite3` only — no extra deps) - [opencode](https://github.com/anomalyco/opencode) with an active session DB at `~/.local/share/opencode/opencode.db` *(only needed for `mempalace-session`)* - The mempalace **wake-up protocol** at `~/.config/opencode/instructions/mempalace.md` — without it, opencode loads the mempalace skill but never auto-runs it at session start, so most of mempalace's value is forfeited silently. Shipped by the [skillset repo](https://gitea.jordbo.se/joakimp/skillset); deploy via `./deploy-skills.sh --bootstrap` once per machine. `mempalace-toolkit/install.sh` probes for this file and warns if it's missing. +- The mempalace **MCP server registered in `~/.config/opencode/opencode.json`** — without this, opencode has no way to reach the mempalace tools and every `mempalace_*` call silently fails. See [Registering mempalace with opencode](#registering-mempalace-with-opencode-or-other-mcp-clients) below for the one-line JSON stanza. `install.sh` probes for this too. ### Installing mempalace itself (prerequisite) @@ -104,37 +105,94 @@ The last `python -c` line in the RUN step is a build-time sanity check: if the i See [opencode-devbox/Dockerfile](https://gitea.jordbo.se/joakimp/opencode-devbox/src/branch/main/Dockerfile) §"MemPalace install" for the full production version (adds `INSTALL_MEMPALACE=true` build arg so the install can be skipped to shave ~300 MB off the image). -#### MCP server wrapper (required for MCP clients on a system install) +#### Registering mempalace with opencode (or other MCP clients) -MCP clients (opencode, Claude Code, Kiro) spawn the mempalace MCP server as a subprocess. On a *personal-machine* install the command is just `mempalace-mcp` — the uv tool shim finds the venv's Python automatically. +Installing `mempalace` via `uv tool install` puts two shims on `PATH`: `mempalace` (the CLI) and `mempalace-mcp` (the MCP server). Neither the skill nor `mempalace-toolkit` will give you anything useful in opencode until the MCP server is registered in `~/.config/opencode/opencode.json`. -**Pitfall that bit us during the first opencode-devbox attempt:** on a *system install* with `UV_TOOL_DIR=/opt/uv-tools`, the system `python3` cannot import `mempalace` because the modules live in the isolated venv under `/opt/uv-tools/mempalace/lib/...`, not in system site-packages. Any MCP config that reads +**Add to opencode.json:** ```json -{ "command": ["python3", "-m", "mempalace.mcp_server"] } +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "mempalace": { + "type": "local", + "command": ["mempalace-mcp"] + } + } +} ``` -will fail at spawn with `ModuleNotFoundError: No module named 'mempalace'` — and because MCP failures are reported as "server unavailable" rather than surfacing the stderr, the root cause is easy to miss. +If you already have other MCP servers configured, add the `mempalace` entry into the existing `mcp` object — don't replace the whole file. opencode's JSON is merged shallow-ly. -**Fix:** ship a thin wrapper on `PATH` that exec's the venv's own Python. opencode-devbox ships this as `/usr/local/bin/mempalace-mcp-server`: +**Minimal full opencode.json for someone starting fresh** (adjust `model` to your preferred provider): + +```json +{ + "$schema": "https://opencode.ai/config.json", + "model": "anthropic/claude-opus-4-6", + "share": "disabled", + "autoupdate": false, + "instructions": [ + "~/.config/opencode/instructions/mempalace.md" + ], + "mcp": { + "mempalace": { + "type": "local", + "command": ["mempalace-mcp"] + } + } +} +``` + +Note the `instructions` array: this is what tells opencode to load the wake-up protocol at session start (see the previous section on installing that file via `skillset --bootstrap`). + +**Custom palace path** (rare — default `~/.mempalace/palace/` works for everyone): + +```json +"command": ["mempalace-mcp", "--palace", "/path/to/palace"] +``` + +**Claude Code** has a one-liner helper: + +```bash +claude mcp add mempalace -- mempalace-mcp +``` + +…or `mempalace mcp` prints the current recommended snippets on demand: + +```bash +mempalace mcp # shows `claude mcp add` + direct-run commands +``` + +**After editing the config**, restart opencode (or your MCP client). Verify the connection: + +```bash +# From inside an opencode session: +# mempalace_status → should return palace stats, not "tool unavailable" +``` + +If the MCP tools don't show up in your agent's tool list, the most common causes are: + +| Symptom | Likely cause | Fix | +|---|---|---| +| `mempalace_*` tools absent from tool list entirely | opencode.json not re-read | Restart opencode. | +| Server reported "unavailable" at startup | Shim not on `PATH`, or CLI itself broken | Run `mempalace-mcp --help` manually; fix PATH or re-run `uv tool install mempalace`. | +| `ModuleNotFoundError: No module named 'mempalace'` in logs | You configured `["python3", "-m", "mempalace.mcp_server"]` instead of `["mempalace-mcp"]` | Use the shim. See the legacy-fallback section below if you specifically need the python-invocation form. | + +#### Legacy fallback: `mempalace-mcp-server` wrapper + +Older MCP configs sometimes reference `["python3", "-m", "mempalace.mcp_server"]`. This worked when mempalace was installed via `pip install --break-system-packages` into the system site-packages, but breaks after switching to `uv tool install` — system `python3` cannot import mempalace from the isolated venv. On opencode-devbox a thin wrapper script on `PATH` bridged the two worlds during the transition: ```sh #!/bin/sh -# Launcher for the MemPalace MCP server on a uv-tool install. -# System python3 cannot import mempalace from the isolated venv, -# so exec the venv's python directly with the mcp_server module. +# /usr/local/bin/mempalace-mcp-server exec /opt/uv-tools/mempalace/bin/python -m mempalace.mcp_server "$@" ``` -…and MCP configs reference the wrapper instead: +With the wrapper in place, MCP configs referencing `["mempalace-mcp-server"]` work on a `uv tool install` setup. -```json -{ "command": ["mempalace-mcp-server"] } -``` - -If you're on a personal-machine install (default `uv tool install` paths), you don't need the wrapper — `mempalace-mcp` is already a shim that does the right thing. The wrapper is specifically the workaround for the non-default `UV_TOOL_DIR` setup. - -See [opencode-devbox/AGENTS.md](https://gitea.jordbo.se/joakimp/opencode-devbox/src/branch/main/AGENTS.md) ("Critical conventions" → "MemPalace install path") for the authoritative reference. +**This is legacy; don't use it for new installs.** The modern `["mempalace-mcp"]` form — the uv-tool shim — does the same job without the extra script. The wrapper is documented here only so you know what to look for if you encounter an older config or a machine that was set up during the transition. #### Verification checklist @@ -148,12 +206,12 @@ mempalace --version # → v3.3.3+ without import errors # CLI can import its own modules (catches venv vs site-packages mismatch) mempalace status 2>&1 | head -3 # → either palace stats or "No palace found" — not a Python traceback -# MCP server reachable (system install — only relevant if you set up the wrapper) -which mempalace-mcp-server # personal install: skip, uses `mempalace-mcp` directly -mempalace-mcp-server --help 2>&1 | head -5 # should show MCP server help, not import error +# MCP shim reachable and runnable +which mempalace-mcp # → a shim path matching the `mempalace` CLI location +mempalace-mcp --help 2>&1 | head -5 # → MCP server help, not a Python traceback ``` -If any of these produce `ModuleNotFoundError`, you've hit the venv-mismatch pitfall. Re-read the MCP wrapper section above. +If any of these produce `ModuleNotFoundError`, the isolated venv is broken — re-run `uv tool install --force mempalace` (or the system-install equivalent with `UV_TOOL_DIR` set) and check the verification again. ### Install mempalace-toolkit diff --git a/install.sh b/install.sh index 04e9c28..3ba7e2b 100755 --- a/install.sh +++ b/install.sh @@ -186,6 +186,39 @@ check_wake_up_protocol() { return 0 } +# ── Verify mempalace is registered as an MCP server in opencode.json ── +# Even with mempalace installed and the wake-up protocol in place, opencode +# won't actually launch the MCP server (so mempalace_* tools won't appear in +# the agent's toolset) unless ~/.config/opencode/opencode.json declares a +# server under .mcp.mempalace with command ["mempalace-mcp"] (or the legacy +# wrapper equivalent). +# +# This is a lightweight textual check — we don't parse JSON strictly, just +# look for the expected substring. False negatives are acceptable (a weirdly +# formatted but valid config), false positives less so but very unlikely +# given the specific shim name. Skipped on non-opencode hosts. +check_opencode_mcp() { + local opencode_config="$HOME/.config/opencode/opencode.json" + [[ -f "$opencode_config" ]] || return 0 # no config → nothing to check + + if grep -q '"mempalace"[[:space:]]*:' "$opencode_config" 2>/dev/null \ + && grep -q 'mempalace-mcp' "$opencode_config" 2>/dev/null; then + ok "mempalace MCP server registered in opencode.json" + return 0 + fi + + warn "mempalace MCP server NOT registered in $opencode_config" + printf ' Without this, opencode loads the skill but no mempalace_* tools\n' + printf ' are reachable at runtime, so search/diary/KG calls silently fail.\n' + printf ' Add this entry under the top-level "mcp" object:\n' + printf ' "mempalace": { "type": "local", "command": ["mempalace-mcp"] }\n' + printf ' Or open a fresh config with:\n' + printf ' mempalace mcp # prints current recommended snippets\n' + printf ' Full details (including Claude Code one-liner) in:\n' + printf ' README.md#registering-mempalace-with-opencode-or-other-mcp-clients\n' + return 0 +} + do_install() { echo echo "mempalace-toolkit installer" @@ -205,6 +238,8 @@ do_install() { echo check_wake_up_protocol echo + check_opencode_mcp + echo ok "Done." echo echo "Next: ./bin/mempalace-session --dry-run"