From 25972b7499013d3b8ee46b4ee227fe8382f4efbf Mon Sep 17 00:00:00 2001 From: Joakim Persson Date: Thu, 30 Apr 2026 07:02:36 +0000 Subject: [PATCH] README: document uv-based mempalace install + MCP wrapper pitfall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mempalace-toolkit's Prerequisites section assumed mempalace was already installed but didn't explain how. The upstream mempalace repo only shows pip install, which fights PEP 668 on modern distros and leaks dependencies into system site-packages. The production pattern used in opencode-devbox (uv tool install) is cleaner but wasn't documented here. Adds a full 'Installing mempalace itself (prerequisite)' section with five subsections: 1. Why uv over pip — isolated venv, no PEP 668 fight, shim makes the CLI accessible from any bash/zsh terminal without manual venv activation. 2. Personal machine — with default paths (shim in ~/.local/bin, venv under ~/.local/share/uv/tools/). Simple one-liner plus PATH guidance. This is the recommended default. 3. System-wide / container install — the opencode-devbox pattern: UV_TOOL_DIR=/opt/uv-tools + UV_TOOL_BIN_DIR=/usr/local/bin, with the exact Dockerfile RUN step used in production (including the python -c build-time sanity check). Cross-references opencode-devbox/Dockerfile for the full canonical version. 4. MCP server wrapper — explains the 'missing venv when the container was deployed' pitfall from the first opencode-devbox attempt: with a non-default UV_TOOL_DIR, system python3 can't import mempalace, so MCP configs of the form ["python3", "-m", "mempalace.mcp_server"] fail silently with ModuleNotFoundError. Fix is a thin wrapper on PATH that exec's the venv's own python. Shows the exact 3-line shell wrapper from opencode-devbox/rootfs/usr/local/bin/ mempalace-mcp-server. Points at opencode-devbox/AGENTS.md 'Critical conventions' as the authoritative reference. 5. Verification checklist — /usr/local/bin/mempalace, MemPalace 3.3.3, and a minimal ======================================================= MemPalace Status — 4943 drawers ======================================================= WING: cli_utils ROOM: scripts 38 drawers ROOM: fzf 25 drawers ROOM: general 1 drawers WING: opencode_devbox ROOM: general 203 drawers ROOM: configuration 3 drawers WING: proxmox ROOM: general 1046 drawers WING: skillset ROOM: general 1118 drawers WING: wing_conversations ROOM: technical 1775 drawers ROOM: architecture 513 drawers ROOM: planning 164 drawers ROOM: problems 42 drawers ROOM: general 6 drawers ROOM: decisions 3 drawers WING: wing_orchestrator ROOM: diary 6 drawers ======================================================= smoke test that catches venv mismatches by failing with a Python traceback instead of a clean error message. Renames the existing 'Install' section to 'Install mempalace-toolkit' to disambiguate from the new mempalace install section — the toolkit's own install.sh still works the same, just labeled more precisely. ARCHITECTURE.md §4 prerequisites paragraph and SKILL.md prerequisites block both cross-reference the new section with anchor links, so any entry point into the docs leads the reader to the right recipe. --- ARCHITECTURE.md | 2 +- README.md | 119 +++++++++++++++++++++++++++++++++++++++++++++++- SKILL.md | 2 + 3 files changed, 120 insertions(+), 3 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index bd14f65..af7bc0b 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -134,7 +134,7 @@ What it drops: source code (`.py`, `.ts`, `.go`, `.rs`, …), lockfiles, `.git`, ## 4. Setup recipe (new machine) -Assumes: opencode already installed, `~/.local/share/opencode/opencode.db` exists, `mempalace` CLI installed (v3.3.3+). +Assumes: opencode already installed, `~/.local/share/opencode/opencode.db` exists, `mempalace` CLI installed (v3.3.3+). If mempalace isn't installed yet, [`README.md`](README.md#installing-mempalace-itself-prerequisite) covers the `uv tool install mempalace` flow for both personal machines and the `/opt/uv-tools/` container pattern used by opencode-devbox. ```bash # 1. Clone mempalace-toolkit (holds the two wrappers in bin/) diff --git a/README.md b/README.md index bee218c..7d9b0ff 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,126 @@ See [`ARCHITECTURE.md`](ARCHITECTURE.md) §6 for the full upstream roadmap. ### Prerequisites -- [MemPalace](https://github.com/MemPalace/mempalace) CLI v3.3.3+ +- [MemPalace](https://github.com/MemPalace/mempalace) CLI v3.3.3+ — **see [Installing mempalace itself](#installing-mempalace-itself-prerequisite) below if you haven't already**. - 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`)* -### Install +### Installing mempalace itself (prerequisite) + +mempalace-toolkit wraps the mempalace CLI but does not bundle it. The upstream [MemPalace repo](https://github.com/MemPalace/mempalace) documents `pip install mempalace` as the install method; `uv tool install` is cleaner and is the flow used in production containers like [opencode-devbox](https://gitea.jordbo.se/joakimp/opencode-devbox). + +**Why uv over pip:** +- Isolated venv per tool — mempalace's dependencies (chromadb, embedding model runtime, …) don't leak into system Python or your project venvs. +- No PEP 668 fight — modern Debian / Ubuntu / Homebrew Python all refuse `pip install` into the system site-packages. `uv tool install` sidesteps this entirely. +- The shim (`~/.local/bin/mempalace` by default) is a thin wrapper that automatically activates the isolated venv on invocation, so `mempalace` is available from any bash or zsh terminal without manual `source venv/bin/activate`. + +**Install uv** if it's not already on the machine: + +```bash +# macOS / Linux, official installer — puts uv in ~/.local/bin +curl -LsSf https://astral.sh/uv/install.sh | sh + +# Or: Homebrew on macOS +brew install uv + +# Verify +uv --version +``` + +#### Personal machine (recommended default) + +```bash +# Installs mempalace into an isolated venv under ~/.local/share/uv/tools/mempalace/, +# puts the `mempalace` shim into ~/.local/bin/. +uv tool install mempalace + +# Make sure ~/.local/bin is on $PATH (uv prints this if it isn't) +export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc or ~/.zshrc + +# Verify +mempalace --version # should print the installed version +which mempalace # should point into ~/.local/bin/ +``` + +After this, `mempalace` works the same from any bash or zsh terminal — interactive shell, script, cron, systemd user service, launchd agent, all fine. + +To upgrade later: `uv tool upgrade mempalace` (or `--all`). +To uninstall: `uv tool uninstall mempalace`. + +#### System-wide / container install (opencode-devbox pattern) + +For a Docker image or a multi-user box where the shim should live on the system `PATH` rather than in each user's `~/.local/bin`, use `UV_TOOL_DIR` + `UV_TOOL_BIN_DIR` to relocate both the venv and the shim: + +```bash +# In the Dockerfile — this is the pattern used by opencode-devbox +ENV UV_TOOL_DIR=/opt/uv-tools +ENV UV_TOOL_BIN_DIR=/usr/local/bin + +RUN mkdir -p /opt/uv-tools && \ + uv tool install --no-cache mempalace && \ + /opt/uv-tools/mempalace/bin/python -c "import mempalace; print('mempalace installed')" +``` + +After this: +- `/opt/uv-tools/mempalace/` — the isolated venv. +- `/usr/local/bin/mempalace` — the CLI shim (globally on `PATH`, works for every user). + +The last `python -c` line in the RUN step is a build-time sanity check: if the install silently failed, the build fails here rather than at runtime. + +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) + +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. + +**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 + +```json +{ "command": ["python3", "-m", "mempalace.mcp_server"] } +``` + +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. + +**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`: + +```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. +exec /opt/uv-tools/mempalace/bin/python -m mempalace.mcp_server "$@" +``` + +…and MCP configs reference the wrapper instead: + +```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. + +#### Verification checklist + +After any install (personal or system-wide), confirm: + +```bash +# CLI reachable from PATH +which mempalace # → a shim path +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 +``` + +If any of these produce `ModuleNotFoundError`, you've hit the venv-mismatch pitfall. Re-read the MCP wrapper section above. + +### Install mempalace-toolkit ```bash git clone ssh://git@gitea.jordbo.se:2222/joakimp/mempalace-toolkit.git ~/mempalace-toolkit diff --git a/SKILL.md b/SKILL.md index 97ef932..6aa4f0f 100644 --- a/SKILL.md +++ b/SKILL.md @@ -33,6 +33,8 @@ Both follow the same **stage-to-cache-then-mine** idiom — they curate input in Prerequisites: `opencode` installed with an active DB at `~/.local/share/opencode/opencode.db`, `mempalace` CLI v3.3.3+, Python 3 (stdlib `sqlite3` only — no extra deps). +**If mempalace itself isn't installed yet**, suggest `uv tool install mempalace` (not `pip install mempalace` — it fights PEP 668 on modern distros and leaks deps into system site-packages). For a system-wide install on a container or shared box, set `UV_TOOL_DIR=/opt/uv-tools` + `UV_TOOL_BIN_DIR=/usr/local/bin` before `uv tool install`, and ship an MCP wrapper on `PATH` that exec's the venv's Python — otherwise MCP clients fail silently with `ModuleNotFoundError`. Full recipe in `mempalace-toolkit/README.md#installing-mempalace-itself-prerequisite`. + ```bash # 1. Clone mempalace-toolkit (holds the two wrappers in bin/) git clone ssh://git@gitea.jordbo.se:2222/joakimp/mempalace-toolkit.git ~/mempalace-toolkit