name: add-mnemon description: Add persistent graph-based memory to NanoClaw agents using mnemon. Agents recall context before responding and remember insights after. Each group gets isolated memory with optional global shared store.
/add-mnemon
Add mnemon persistent memory to your NanoClaw installation. After running this skill, every agent session will have access to a per-group memory graph that persists across conversations.
Architecture
Host Container
~/.mnemon/data/{group}/ ──rw──→ /home/node/.mnemon/data/default/ (private)
~/.mnemon/data/global/ ──ro──→ /home/node/.mnemon/data/global/ (shared)
Each group gets its own isolated mnemon store. An optional global store provides shared read-only knowledge across all groups.
Phase 1: Pre-flight
Verify mnemon is installed on the host:
mnemon --versionIf not installed:
- macOS / Linux (Homebrew):
brew install mnemon-dev/tap/mnemon - Go install:
go install github.com/mnemon-dev/mnemon@latest
- macOS / Linux (Homebrew):
Verify the container image exists:
docker image inspect nanoclaw-agent:latest >/dev/null 2>&1 && echo "OK"Fetch the latest mnemon version for the Dockerfile:
curl -s https://api.github.com/repos/mnemon-dev/mnemon/releases/latest | grep -o '"tag_name": "v[^"]*"' | cut -d'"' -f4 | sed 's/^v//'
Phase 2: Apply Code Changes
2a. Install mnemon in the container image
File: container/Dockerfile
Add the following block after the apt-get install section and before the npm install -g line. Replace 0.1.1 with the version from Phase 1 step 3:
# Install mnemon for persistent agent memory
ARG MNEMON_VERSION=0.1.1
RUN ARCH=$(dpkg --print-architecture) && \
curl -fsSL "https://github.com/mnemon-dev/mnemon/releases/download/v${MNEMON_VERSION}/mnemon_${MNEMON_VERSION}_linux_${ARCH}.tar.gz" \
| tar -xz -C /usr/local/bin mnemon && \
chmod +x /usr/local/bin/mnemon
This works for both amd64 and arm64 architectures.
2b. Add the container skill
File: container/skills/mnemon/SKILL.md
Create this file with the mnemon container skill content. This skill teaches the agent inside the container when and how to use mnemon. It should include:
- Memory stores section: Explain that the default store is per-group (private, read-write) and the global store is shared (read-only, accessed via
--store global --readonly). - Recall guide: Default recall on every new user message. Use
mnemon recall "<query>" --limit 5. Also check the global store:mnemon recall "<query>" --store global --readonly --limit 5. Craft focused keyword-rich queries. - Remember guide: Decision tree — Step 1: Does this exchange contain a user directive, reasoning conclusion, or durable observed state? Step 2: Does a memory already exist (create/update/skip)? Step 3: Is it worth storing?
- Workflow: remember → link (evaluate semantic/causal candidates with judgment) → recall.
- Commands: Full mnemon command reference (remember, link, recall, search, forget, related, gc, status, log).
- Guardrails: Never store secrets. Never write to the global store. Categories: preference, decision, insight, fact, context. Max 8,000 chars per insight.
2c. Add volume mounts for mnemon data
File: src/container-runner.ts
In the function that builds volume mounts (where the existing group folder and Claude session mounts are defined), add two new mounts after the Claude sessions mount:
// Per-group mnemon memory store (private, read-write)
const groupMnemonDir = path.join(homedir(), '.mnemon', 'data', group.folder);
fs.mkdirSync(groupMnemonDir, { recursive: true });
mounts.push({
hostPath: groupMnemonDir,
containerPath: '/home/node/.mnemon/data/default',
readonly: false,
});
// Global shared mnemon memory (read-only, optional)
const globalMnemonDir = path.join(homedir(), '.mnemon', 'data', 'global');
if (fs.existsSync(globalMnemonDir)) {
mounts.push({
hostPath: globalMnemonDir,
containerPath: '/home/node/.mnemon/data/global',
readonly: true,
});
}
Adapt the mount syntax to match the existing pattern in container-runner.ts (it may use string format like hostPath:containerPath:ro or an object format — match whichever the file uses).
Important: The mkdirSync call ensures the per-group mnemon directory exists on the host before the container starts, preventing mount failures.
2d. Add lifecycle hook scripts
Create container/hooks/mnemon/ with four shell scripts. These run inside the container at Claude Code lifecycle events to actively drive memory operations.
File: container/hooks/mnemon/prime.sh
#!/bin/bash
# mnemon SessionStart hook — report memory stats on session init.
STATS=$(mnemon status 2>/dev/null)
if [ -n "$STATS" ]; then
INSIGHTS=$(echo "$STATS" | sed -n 's/.*"total_insights": *\([0-9]*\).*/\1/p' | head -1)
EDGES=$(echo "$STATS" | sed -n 's/.*"edge_count": *\([0-9]*\).*/\1/p' | head -1)
echo "[mnemon] Memory active (${INSIGHTS:-0} insights, ${EDGES:-0} edges)."
else
echo "[mnemon] Memory active."
fi
File: container/hooks/mnemon/user_prompt.sh
#!/bin/bash
# mnemon UserPromptSubmit hook — remind agent to evaluate recall/remember.
echo "[mnemon] Evaluate: recall needed? After responding, evaluate: remember needed?"
File: container/hooks/mnemon/stop.sh
#!/bin/bash
# mnemon Stop hook — remind agent to consider remember after responding.
INPUT=$(cat)
MSG=$(echo "$INPUT" | jq -r '.last_assistant_message // ""' 2>/dev/null)
if echo "$MSG" | grep -qiE "mnemon remember|sub-agent.*remember|Stored.*imp="; then
exit 0
fi
echo "[mnemon] Consider: does this exchange warrant a remember sub-agent?"
File: container/hooks/mnemon/compact.sh
#!/bin/bash
# mnemon PreCompact hook — save key insights before context compaction.
echo "[mnemon] Context compaction starting. Review this session and remember the most valuable insights (up to 5) before context is compressed. Delegate to Task sub-agents now."
Make all scripts executable: chmod +x container/hooks/mnemon/*.sh
2e. Copy hooks into container and register in settings.json
File: container/Dockerfile
Add after the mnemon binary install block:
# Copy mnemon hook scripts
COPY hooks/mnemon/ /app/hooks/mnemon/
RUN chmod +x /app/hooks/mnemon/*.sh
File: src/container-runner.ts
In the block where settings.json is created for each group session (look for writeFileSync with settings.json), merge mnemon hooks into the settings object:
// Register mnemon lifecycle hooks
const mnemonHooks = {
SessionStart: [{
hooks: [{ type: 'command', command: '/app/hooks/mnemon/prime.sh' }]
}],
UserPromptSubmit: [{
hooks: [{ type: 'command', command: '/app/hooks/mnemon/user_prompt.sh' }]
}],
Stop: [{
hooks: [{ type: 'command', command: '/app/hooks/mnemon/stop.sh' }]
}],
PreCompact: [{
hooks: [{ type: 'command', command: '/app/hooks/mnemon/compact.sh' }]
}],
};
// Merge into existing settings.hooks (preserve any existing hooks)
const existingHooks = settings.hooks || {};
for (const [event, entries] of Object.entries(mnemonHooks)) {
existingHooks[event] = [...(existingHooks[event] || []), ...entries];
}
settings.hooks = existingHooks;
Adapt this to match the existing settings.json construction pattern in container-runner.ts.
Phase 3: Setup
Initialize the global shared store on the host (optional — skip if you don't need cross-group shared memory):
mnemon store create globalRebuild the container image:
./container/build.shRestart the NanoClaw service:
# macOS with launchd: launchctl kickstart -k "gui/$(id -u)/com.nanoclaw" # Or manually: npm run dev
Phase 4: Verify
Verify mnemon works inside the container:
docker run --rm --entrypoint mnemon nanoclaw-agent:latest --versionVerify mnemon status inside a running container:
docker run --rm --entrypoint mnemon nanoclaw-agent:latest statusSend a test message to the WhatsApp bot and check that the agent mentions memory operations in its reasoning.
Verify data persistence on the host:
ls ~/.mnemon/data/ # Should show directories for each active group
Removal
To remove mnemon from your NanoClaw installation:
- Remove from Dockerfile: delete the
ARG MNEMON_VERSION+RUN ... mnemonblock and theCOPY hooks/mnemon/line - Remove container skill:
rm -rf container/skills/mnemon/ - Remove hook scripts:
rm -rf container/hooks/mnemon/ - Remove volume mounts from
src/container-runner.ts: delete the mnemon mount blocks - Remove hooks registration from
src/container-runner.ts: delete the mnemon hooks merge in settings.json - Rebuild:
./container/build.sh - (Optional) Remove data:
rm -rf ~/.mnemon/data/