| name | add-skill-claude-mem |
| description | Add persistent memory (claude-mem) to NanoTars agent containers. Creates systemd service for the worker daemon, configures env vars. Run once after claude-mem plugin is installed. |
Add Claude-Mem to Agent Containers
Run all commands automatically. Only pause if a step fails.
UX Note: When asking the user questions, prefer using the AskUserQuestion tool instead of just outputting text.
How It Works
The claude-mem worker daemon runs on the host (port 37777, bound to 0.0.0.0) and stores observations in a SQLite + vector DB at /root/.claude-mem/. Docker containers reach the host via host.docker.internal using the --add-host=host.docker.internal:host-gateway flag (configured in container-runtime.ts).
Preflight
Before installing, verify NanoTars is set up:
[ -d node_modules ] && echo "DEPS: ok" || echo "DEPS: missing"
docker image inspect nanoclaw-agent:latest &>/dev/null && echo "IMAGE: ok" || echo "IMAGE: not built"
if grep -q "ANTHROPIC_API_KEY\|CLAUDE_CODE_OAUTH_TOKEN" .env 2>/dev/null || [ -f "$HOME/.claude/.credentials.json" ]; then echo "AUTH: ok"; else echo "AUTH: missing"; fi
If any check fails, tell the user to run /nanotars-setup first and stop.
Prerequisites
- claude-mem plugin installed (
claude plugin add @thedotmack/claude-mem)
- Bun runtime installed
Install
-
Verify prerequisites:
ls /root/.claude-mem/claude-mem.db
ls /root/.claude/plugins/cache/thedotmack/claude-mem/*/scripts/worker-service.cjs 2>/dev/null | head -1
BUN_PATH=$(which bun 2>/dev/null || echo "/root/.bun/bin/bun")
$BUN_PATH --version
If the database does not exist, stop and tell the user to install claude-mem first.
-
Kill orphaned worker processes:
pkill -f 'worker-service.cjs.*--daemon' 2>/dev/null || true
sleep 2
curl -s --max-time 2 http://127.0.0.1:37777/api/health >/dev/null 2>&1 && echo "WARNING: Port 37777 still in use" || echo "Port 37777 is free"
-
Create wrapper scripts at /root/.claude-mem/:
/root/.claude-mem/run-worker.sh:
#!/bin/bash
PLUGIN_DIR="/root/.claude/plugins/cache/thedotmack/claude-mem"
WORKER=$(ls -td "$PLUGIN_DIR"/*/scripts/worker-service.cjs 2>/dev/null | head -1)
if [ -z "$WORKER" ]; then
echo "Error: claude-mem worker script not found in $PLUGIN_DIR" >&2
exit 1
fi
echo "Starting worker from: $WORKER"
exec /root/.bun/bin/bun "$WORKER" start
/root/.claude-mem/stop-worker.sh:
Verify
Tell the user:
Setup is complete. Test it by sending a WhatsApp message like "remember that my favorite coffee is a flat white" and then in a new conversation ask "what's my favorite coffee?"
Version Management
The wrapper scripts dynamically resolve the plugin version at runtime. After upgrading:
systemctl stop claude-mem-worker
pkill -f 'worker-service.cjs' 2>/dev/null; sleep 2
systemctl start claude-mem-worker
Troubleshooting
- Worker not starting:
journalctl -u claude-mem-worker -f and check /root/.claude-mem/logs/
- Container can't reach host: Verify
--add-host=host.docker.internal:host-gateway is in container-runtime.ts extraRunArgs()
- Port conflict:
lsof -i :37777 -- kill orphaned workers first
- Service status:
systemctl status claude-mem-worker
Per-group credential overrides: Not applicable. Claude-mem is a system-wide service shared across all groups.
Uninstall
-
Stop the service:
sudo systemctl stop claude-mem-worker
sudo systemctl disable claude-mem-worker
-
Remove the plugin:
rm -rf plugins/claude-mem/
-
Remove CLAUDE_MEM_URL from .env
-
Rebuild and restart NanoTars
Warning: Do NOT delete /root/.claude-mem/. This directory contains the shared memory database used by both the host and container agents. Removing the plugin only stops container access — the host's claude-mem continues to function independently.