@engramx/openclaw
v0.4.0
Published
EngramX memory plugin for OpenClaw — persistent, decentralized agent memory
Readme
EngramX + OpenClaw Integration
Hybrid memory plugin for OpenClaw: local SQLite for fast search, EngramX canister as the persistent source of truth, and periodic database backup to the canister for disaster recovery. Auto-detects active databases (SQLite, QMD, LanceDB) from openclaw.json.
Architecture
The canister exposes two storage systems: Files (memory markdown + session JSONL) and Blobs (SQLite backup chunks). Sessions are stored as JSONL files under sessions/{agentId}/{key}.jsonl — no separate session API.
┌──────────────────────────────────────────────────────────────────────┐
│ OpenClaw Gateway │
│ │
│ memory_search / memory_get ─────► Local SQLite (sqlite-vec + FTS5) │
│ (sub-100ms hybrid search) ▲ │
│ │ file watch + re-index │
│ engram_append_memory ──► EngramX ──────┤ │
│ (source of truth) canister │ sync to local disk │
│ │ ▼ │
│ │ memory/*.md (local files) │
│ │ sessions/{agentId}/*.jsonl │
│ │ │
│ periodic backup ────────────┤ │
│ (every 6h) │ detected DBs ───────► EngramX │
│ │ (SQLite/QMD/LanceDB, 1.9 MiB chunks)│
│ │ │
│ engram_wallet_balance ──────┘ Direct canister access (wallet) │
└──────────────────────────────────────────────────────────────────────┘Why hybrid?
| Concern | Local SQLite | EngramX Canister | |---|---|---| | Search latency | 50-200ms (vector + FTS5) | Not available (search removed) | | Write latency | <1ms | 2-5s (ICP consensus) | | Persistence | Lost if machine dies | Survives anything (on-chain) | | Vector search | sqlite-vec cosine distance | Not available | | Disaster recovery | None | Backup API (500 MiB max) |
The SQLite database is a derived cache — it's rebuilt from markdown files + an embedding provider. EngramX stores the source markdown. If you lose your machine, pull the files from EngramX and the SQLite index rebuilds automatically.
What it provides
Search tools (local SQLite — fast)
| Tool | Description |
|---|---|
| memory_search | Hybrid vector + FTS5 search across memory (sub-100ms) |
| memory_get | Read a local memory file by path |
These are identical to OpenClaw's built-in memory-core tools. Search never hits the canister.
Engram tools (canister — persistent)
| Tool | Description |
|---|---|
| engram_append_memory | Append to a memory file (writes to canister + local disk). Owner-protected paths are read-only for operators. |
| engram_read_memory | Read a file directly from the canister |
| engram_list_memory | List all files in the canister (includes session JSONL files) |
| engram_wallet_balance | Check engram wallet balance |
No
engram_transfer/ write / delete / rollback tools — operators are append-only and have no owner-level fund control by design.
Sessions are stored as regular files (sessions/{agentId}/{key}.jsonl) and are visible via engram_list_memory. There is no separate session tool.
Background services
- Memory sync — pulls markdown files from canister to local disk on startup and periodically (default: every 60 min). Local writes are pushed back to the canister.
- Database backup — auto-detects active databases from
openclaw.jsonand uploads snapshots periodically (default: every 6 hours). Usessqlite3 .backupfor consistent SQLite snapshots,tar.gzfor directory-based backends (QMD, LanceDB). SHA-256 deduplication skips unchanged databases. - Session sync — serializes conversation transcripts to JSONL and appends them to
sessions/{agentId}/{key}.jsonlin the canister after each conversation. Always enabled.
CLI commands
openclaw memory search <query> # Search local SQLite (fast)
openclaw engram status # Canister status
openclaw engram sync # Pull/push memory files now
openclaw engram backup # Backup all detected databases now
openclaw engram restore # List available backups (grouped by type)
openclaw engram files # List canister memory files (includes sessions)Option 1: Hosted (engramx.ai)
Use this when your engram is running on the IC mainnet via engramx.ai.
1. Create an engram
Sign up at engramx.ai and create an engram. Note your canister ID.
2. Create an operator invite
In the engramx.ai dashboard, go to Access > Operators and click "Create Invite".
3. Pair and install
# First host — push local memory to engram
npx @engramx/client pair <INVITE_CODE> --engram <CANISTER_ID> --openclaw
# Replacement host — restore from engram
npx @engramx/client pair <INVITE_CODE> --engram <CANISTER_ID> --openclaw --recoverThis generates a session key, registers the operator, installs the plugin, configures openclaw.json, and either migrates local files or restores database backups. A local checkpoint is saved first — run engramx rollback to undo.
4. Verify
openclaw engram statusManual configuration
If you need to customize the plugin config, edit ~/.openclaw/openclaw.json:
{
"plugins": {
"slots": {
"memory": "memory-engramx"
},
"entries": {
"memory-engramx": {
"canisterId": "xxxxx-xxxxx-xxxxx-xxxxx-xxx",
// Memory file sync: canister <-> local disk
"sync": {
"onStartup": true, // pull files when OpenClaw starts
"intervalMinutes": 60, // sync every hour
"pushOnWrite": true // write to both canister and local
},
// Database backup: auto-detects SQLite/QMD/LanceDB
"backup": {
"enabled": true,
"intervalMinutes": 360 // backup every 6 hours
}
}
}
}
}Option 2: Local Development
Use this to develop and test against a local ICP replica before @engramx/client is on npm.
Prerequisites
- Node.js >= 22.12
- pnpm 10.x
- ICP CLI (
icp) - The engramx repo cloned locally
- The openclaw (OpenClaw) repo cloned locally
1. Start EngramX locally
cd /path/to/engramx
pnpm local:start
pnpm local:create-engram # note the ENGRAM_ID2. Configure protected paths (optional)
Designate which file paths are owner-protected (read-only for operators):
icp canister call <ENGRAM_ID> setProtectedPaths '(vec { "SOUL.md"; "USER.md"; "AGENTS.md" })' -e local3. Build and link @engramx/client
cd /path/to/engramx/packages/client
pnpm install && pnpm build
pnpm link --global4. Set up the plugin in OpenClaw
cp -r /path/to/engramx/integrations/openclaw /path/to/openclaw/extensions/memory-engramx
cd /path/to/openclaw/extensions/memory-engramx
pnpm install
pnpm link --global @engramx/client5. Create an operator and pair
# Create an invite (as the engram owner)
icp canister call <ENGRAM_ID> createOperatorInvite \
'("openclaw-dev", record { canRead = true; canWrite = true; canTransfer = false; dailySpendingLimitE8s = opt 0 })' \
-e local
# Pair and configure OpenClaw in one step
npx @engramx/client pair <INVITE_CODE> --engram <ENGRAM_ID> --openclaw --host http://localhost:4943The --openclaw flag installs the plugin config in ~/.openclaw/openclaw.json automatically.
6. Run OpenClaw
cd /path/to/openclaw
pnpm gateway:watch7. Verify
openclaw engram status
openclaw engram sync
openclaw engram backup # triggers backup of all detected databasesResetting local state
cd /path/to/engramx
pnpm local:reset --nuke && pnpm local:start
# Repeat steps 1 and 5 to recreate engram + operatorConfiguration Reference
| Key | Type | Default | Description |
|---|---|---|---|
| canisterId | string | required | Engram canister ID (also reads ENGRAM_CANISTER_ID env) |
| sessionKeyPath | string | ~/.engramx/session.key | Path to Ed25519 operator session key |
| host | string | https://ic0.app | ICP replica host |
| memoryDir | string | memory | Local directory for memory markdown files |
| sync.onStartup | boolean | true | Pull memory files from canister on startup |
| sync.intervalMinutes | number | 60 | Periodic sync interval (0 = disabled) |
| sync.pushOnWrite | boolean | true | Write to both canister and local disk |
| backup.enabled | boolean | true | Enable periodic database backup (auto-detects SQLite/QMD/LanceDB) |
| backup.intervalMinutes | number | 360 | Backup interval in minutes (minimum 30) |
| backup.dbLabel | string | auto | Label for backup snapshots |
Environment Variables
| Variable | Description |
|---|---|
| ENGRAM_CANISTER_ID | Fallback canister ID if not set in config |
| ENGRAM_SESSION_KEY_PATH | Override session key path |
| OPENCLAW_STATE_DIR | Override .openclaw directory location |
Disaster Recovery
If you lose your machine:
# On a clean machine — create a new operator invite from the dashboard, then:
npx @engramx/client pair <INVITE_CODE> --engram <CANISTER_ID> --openclaw --recoverThis registers a new operator, installs the plugin, restores the latest database backups (SQLite, QMD, LanceDB — whichever were detected), and saves a checkpoint. Memory files sync automatically on next OpenClaw startup.
A local checkpoint is saved before any changes. Run engramx rollback to undo.
The only thing that needs regeneration is the embedding vectors, which are computed locally by the embedding provider (OpenAI, Gemini, etc.). The embedding cache in the database backup avoids re-computing embeddings for unchanged content.
Manual recovery
If you prefer fine-grained control:
- Set up OpenClaw + this plugin on a new machine
- Run
openclaw engram sync— pulls all memory files from the canister - Run
openclaw engram restore— lists available backups grouped by database type - Download and restore via the client SDK's backup API
