Your AI agents forget everything between sessions. Memory fixes that.
Claude Code:
/plugin marketplace add maxtechera/memory
OpenClaw:
clawhub install memory
Run /memory setup once — session hooks fire automatically after that.
Session hooks capture what your agent learns — decisions, preferences, context — and persist it across compactions and session boundaries. Your next session picks up where the last one left off.
Requires: Obsidian with the Obsidian CLI (v1.12.7+) for long-term vault storage. Without Obsidian, hooks still save session state locally to ~/.claude/compaction-state/.
Picking up where you left off. Start a session, your agent already knows what you were working on, what decisions were made last week, and what the user prefers. No re-briefing, no context dump.
Running long projects. The WAL protocol captures decisions as they happen. Compaction events flush them to the vault. A month later you can ask "what did we decide about the auth system?" and get the answer.
Cross-platform context. Work in Claude Code on your Mac, switch to OpenClaw in a container, pick up in Gemini CLI. Memory syncs the HOT/WARM/COLD tiers across all of them via Obsidian vault or OpenClaw journals.
Reducing token spend. Instead of re-loading full project context every session, Memory surfaces only what's relevant. HOT memory (active session) stays tiny. WARM and COLD tiers are queried on demand.
/plugin marketplace add maxtechera/memory
claude plugin update memory@memory-skill
clawhub install memorygit clone https://github.com/maxtechera/memory.git ~/.claude/skills/memoryAfter installing, run the setup wizard:
/memory setup
This detects your Obsidian vault, symlinks the session hooks to ~/.claude/hooks/, and validates the CLI. Once setup completes, hooks fire automatically on every session — no manual invocation needed.
If auto-detection fails (e.g., Obsidian app isn't running), set the vault path manually in your shell profile (~/.zshrc or ~/.bashrc):
export OBSIDIAN_VAULT_PATH="$HOME/Documents/my-vault"Requires: Obsidian CLI v1.12.7+ installed and Obsidian app running for search/create operations. Without it, hooks fall back to direct filesystem writes.
Skip this if you don't use OpenClaw. This level is only for users running OpenClaw on Railway who want cross-platform journal sync.
export OPENCLAW_CONFIG_PATH="/path/to/openclaw-config"This enables /memory sync to include OpenClaw journals automatically.
The dream cycle analyzes your memory, consolidates insights, prunes old entries, and audits TTL decay. Trigger manually anytime:
/memory dream
Or set a cron schedule (Sunday 3am = 0 3 * * 0) in your shell profile:
export DREAM_SCHEDULE="0 3 * * 0"| Command | Description |
|---|---|
/memory sync |
Save everything to memory — all sources, all tiers, wiki |
/memory dream |
Consolidate + TTL audit + rebuild wiki (run weekly) |
/memory status |
Memory health: tier sizes, TTL alerts, last sync times |
/memory setup |
Configure vault path, detect platforms, install hooks |
/memory audit |
TTL audit + boundary check + health alerts |
/memory wiki sync |
Full pipeline: init → ingest all vault sources → Notion publish |
/memory wiki sync --full |
Full pipeline, reprocessing all sources from scratch |
/memory wiki init |
Initialize wiki/ folder structure in vault |
/memory wiki ingest [source] |
Process raw source → compile wiki pages |
/memory wiki ingest --from-memory |
Pull session digests + topics → wiki pages |
/memory wiki query [topic] |
Answer from compiled wiki, not raw sources |
/memory wiki sync notion |
Push publish-ready pages to Notion |
/memory wiki lint |
Health check: orphans, stale, broken links, missing provenance |
/memory wiki dream |
Bulk consolidation: merge, contradiction detection, rebuild index |
/memory wiki status |
Wiki stats: pages, stale count, publish queue, last sync |
When you start a Claude Code session, a small script runs in the background and tells the agent: where your vault is, what you were last working on, and where to find more context. That's it. No setup per session, no copy-pasting notes.
The same thing happens when the agent spawns a helper (a subagent). Before the helper starts working, it automatically receives a briefing: what the parent was doing, which project this belongs to, and where to look for more information.
A session from start to finish:
You open a session
→ agent learns your vault location + recent journal count
You work
→ agent notes decisions and current task as it goes (SESSION-STATE.md)
Claude needs to compress the conversation
→ current state is saved to your vault before anything is lost
You close the session
→ everything is flushed to the vault for next time
When the agent spawns a helper:
The helper gets a briefing before its first message:
What project/run this belongs to ← from .ship-run file
What the parent was working on ← from SESSION-STATE.md
Where to find more context ← MEMORY.md index + topic files list
How to query HOT / WARM / COLD ← access patterns
No re-briefing needed. The helper arrives knowing enough to start.
How the project ID travels to helpers (multi-agent runs):
At run start, the engine writes a small ID file:
echo "ship-ABC-123" > .ship-runEvery helper spawned in that folder picks it up automatically. If the file isn't there, the hook looks for an env var, then falls back to SESSION-STATE.md. You never wire this manually.
Think of these as three places the agent looks, from fastest to deepest:
HOT Always in context (≤2400 tokens)
MEMORY.md — index of what topics exist
SESSION-STATE.md — what's happening right now
WARM Loaded on demand, one topic at a time
memory/topics/*.md — facts about a domain, expire over time
memory/YYYY-MM-DD.md — daily journals
COLD Searched, never fully loaded
Obsidian vault — permanent knowledge, decisions, logs
The agent reads HOT on every session. It pulls WARM files when it needs domain context. It searches COLD when it needs something older or more specific.
- Detect — find what changed (new decisions, stale entries, expired TTLs)
- Classify — each insight goes to the right tier: fact → topics, pattern → vault, rule → AGENTS.md
- Write with proof — a sync report shows exactly what was saved, skipped, or flagged
┌────────────────────────────────────────────┐
│ OBSIDIAN VAULT │
│ (Single Source of Truth) │
│ knowledge/ | logs/ | projects/ | identity/ │
└──────────────────┬─────────────────────────┘
│ writes via Obsidian CLI
┌────────────┼────────────┐
│ │ │
┌─────┴─────┐ ┌───┴──┐ ┌─────┴──────┐
│ Claude │ │ Open │ │ OpenClaw │
│ Code │ │ + hooks│ │ (Railway) │
│ + hooks │ │ │ │ git → local │
└───────────┘ └──────┘ └────────────┘
Hooks fire automatically on Claude Code lifecycle events. No manual invocation needed.
| Hook | When | What It Does |
|---|---|---|
session-start-vault.sh |
Session starts | Injects vault awareness: path, note count, journal count |
pre-compact-vault.sh |
Before compaction | Appends SESSION-STATE to vault daily journal |
session-stop-vault.sh |
Session ends | Flushes state to vault + ~/.claude/compaction-state/latest.md |
agent-start.sh |
Subagent spawned | Injects run ID, parent task, MEMORY.md router, WARM topics into subagent context |
agent-stop.sh |
Subagent finished | Decrements agent counter |
compact-notification.sh |
After compaction | Prints vault stats + session state preview |
force-mcp-connectors.sh |
Session starts | Force-enables MCP connectors flag |
If not using /memory setup:
# Replace /path/to/memory with your actual install path
MEMORY_DIR="/path/to/memory" # e.g., ~/.claude/skills/memory
for hook in session-start-vault.sh pre-compact-vault.sh session-stop-vault.sh \
agent-start.sh agent-stop.sh compact-notification.sh force-mcp-connectors.sh; do
ln -sf "$MEMORY_DIR/hooks/$hook" ~/.claude/hooks/
doneThen add the following to the "hooks" key in ~/.claude/settings.json. If a hooks key already exists, merge the events below into the existing structure — do not replace the whole file.
{
"hooks": {
"SessionStart": [{ "hooks": [
{"type": "command", "command": "bash ~/.claude/hooks/session-start-vault.sh"},
{"type": "command", "command": "bash ~/.claude/hooks/force-mcp-connectors.sh"}
]}],
"PreCompact": [{ "hooks": [
{"type": "command", "command": "bash ~/.claude/hooks/pre-compact-vault.sh"}
]}],
"Stop": [{ "hooks": [
{"type": "command", "command": "bash ~/.claude/hooks/session-stop-vault.sh", "async": true}
]}],
"SubagentStart": [{ "hooks": [
{"type": "command", "command": "bash ~/.claude/hooks/agent-start.sh", "async": true}
]}],
"SubagentStop": [{ "hooks": [
{"type": "command", "command": "bash ~/.claude/hooks/agent-stop.sh", "async": true}
]}],
"Notification": [{ "matcher": "compact", "hooks": [
{"type": "command", "command": "bash ~/.claude/hooks/compact-notification.sh"}
]}]
}
}Note: ~/.claude/hooks/ must exist. If it doesn't: mkdir -p ~/.claude/hooks. The /memory setup wizard creates this directory and symlinks the hooks automatically — manual installation is only needed if you skipped the wizard.
After setup, work normally in a Claude Code session. When you're ready to save what you learned:
/memory sync
Example output:
Memory sync complete
Mode: 1 session
Topic files updated: 2 entries across 1 file
Obsidian: 0 patterns, 1 decision, 0 learnings, 1 journal
SESSION-STATE: flushed to memory/2026-04-10.md
TTL: 0 entries reviewed, 0 archived
Skipped (duplicates): 0
Health: OK
What happened: The agent classified your session insights, wrote facts to topic files (with TTL decay), synced decisions to your Obsidian vault, and created a daily journal entry. Your next session will have access to everything you saved.
/memory sync collects from all available sources in one pass:
| Source | Path | Available when |
|---|---|---|
| Session conversation | current context | always |
| Session state | SESSION-STATE.md |
always |
| Local journals | memory/YYYY-MM-DD.md |
if files exist |
| Compaction state | ~/.claude/compaction-state/latest.md |
if file exists |
| CC project memories | ~/.claude/projects/*/memory/*.md |
always |
| CC saved plans | ~/.claude/plans/*.md |
if files exist |
| OpenClaw journals | $OPENCLAW_CONFIG_PATH/memory/*.md |
if env var set |
| OpenClaw topics | $OPENCLAW_CONFIG_PATH/memory/topics/*.md |
if env var set |
Every sync routes to all tiers (HOT → WARM → COLD) and feeds the wiki automatically. Use /memory dream weekly to consolidate and rebuild the wiki index.
The wiki is a compounding knowledge base — compiled once from your vault sources, maintained by the LLM, published to Notion. Unlike RAG (which re-derives answers from raw docs every time), the wiki synthesizes knowledge into structured pages. You drop sources, run /memory wiki sync, and the wiki gets smarter over time.
Sessions → /memory sync → /memory wiki ingest --from-memory → /memory wiki sync notion → Notion
Two parallel knowledge systems — they never merge:
| System | Location | Authored by | Governed by |
|---|---|---|---|
| Vault | knowledge/ |
Human | TAXONOMY.md |
| Wiki | wiki/ |
LLM | wiki/schema.md |
The wiki feeds from your COLD tier (vault) and publishes outward to Notion. Index pages are curated to ≤30 entries — pages not in index.md don't operationally exist.
The continuous loop:
/memory sync— all sources → tiers (HOT/WARM/COLD) + wiki pages updated automatically/memory wiki ingest --from-memory— vault topics + session digests → wiki pages (manual re-ingest)/memory wiki sync notion— publish-ready pages → Notion
Cross-repo: Orchestrator domain skills invoke /memory sync at ticket completion to persist execution learnings into the wiki. Over time the wiki builds a knowledge graph of what worked, what failed, and why — across every domain.
Full operational spec in SKILL.md — Mode 5 section.
The most important rule: MEMORY.md contains facts. AGENTS.md contains rules. Never mix them.
| File | Contains | Never Contains |
|---|---|---|
MEMORY.md |
Facts, project index, pointers | Rules, instructions |
AGENTS.md |
Behavioral rules, policies | Facts, configs |
SESSION-STATE.md |
Live context, WAL entries | Long-term facts |
memory/topics/*.md |
Domain facts with TTL | Rules |
Obsidian knowledge/ |
Patterns, decisions, learnings | Ephemeral session data |
Boundary test: grep -c "NEVER\|ALWAYS\|must\|rule" MEMORY.md must return 0.
Every memory entry has a shelf life:
| Class | Suffix | Default TTL | Example |
|---|---|---|---|
| permanent | (no suffix) | forever | Core architecture decisions |
| operational | [date:6m] |
6 months | API versions, tool configs |
| project | [date:3m] |
3 months | Project-specific facts |
| session | [date:1m] |
30 days | Research notes, citations |
Dream (Mode 4) audits TTLs weekly and flags expired entries.
| Variable | Description | Default |
|---|---|---|
OBSIDIAN_VAULT_PATH |
Absolute path to Obsidian vault | Auto-detected if app running |
OBSIDIAN_CLI_PATH |
Path to obsidian CLI binary | /usr/local/bin/obsidian |
OPENCLAW_CONFIG_PATH |
Path to openclaw-config repo | None (Mode 2 only) |
MEMORY_ROUTER_MAX_LINES |
Max lines in MEMORY.md router | 15 |
MEMORY_TOPIC_MAX_ENTRIES |
Max entries per topic file | 50 |
DREAM_SCHEDULE |
Cron expression for weekly consolidation | 0 3 * * 0 |
memory/
├── SKILL.md # The skill — agents read this
├── WORKFLOW.md # 5-stage sync lifecycle
├── README.md # You are here
├── hooks/ # 7 session lifecycle hooks
├── docs/
│ ├── VISION.md # Vision deck
│ ├── STATE_MACHINE.md # Sync state transitions
│ ├── ARCHITECTURE.md # 3-tier memory reference
│ └── SYNC_PROTOCOL.md # Cross-platform contract
├── examples/ # Sync examples and reports
├── .claude-plugin/ # Claude Code marketplace manifests
├── .codex-plugin/ # Codex CLI discovery
├── .agents/ # OpenCode/OpenClaw skill discovery
├── gemini-extension.json # Gemini CLI manifest
├── .env.example # All configuration variables
├── .clawhubignore # Distribution exclusions
└── .github/workflows/ # CI validation + release
- Vault is the single source of truth — all platforms sync to Obsidian
- WAL-first — write session state before responding
- Facts and rules never mix — MEMORY.md ≠ AGENTS.md
- Everything decays — TTL is mandatory, permanent is explicit
- Dedup before write — search, patch, or skip
- Report what you did — structured output, not silent writes
MIT — see LICENSE.
Maintained by maxtechera.