A portable skill that gives AI coding agents persistent, structured memory inside Obsidian. Works across runtimes — Claude Code, Codex, Cursor, Antigravity, or anything that can shell out to a CLI.
Each project gets its own interlinked note graph: a home page, a map of content, a decision log, a run log, and timestamped session notes — all wired together with wikilinks so Obsidian's backlink graph becomes a navigable project history.
Use it when you want agents to remember the work, not just the chat window.
- Persistent project memory for AI coding agents — Keep decisions, gotchas, commands, fixes, and open questions in a local Markdown vault.
- Obsidian-native knowledge graph — Notes are real
.mdfiles with wikilinks, backlinks, and MOCs instead of a hidden database. - Automatic memory compaction — Turn hundreds of noisy run notes into a small active memory surface while archiving raw evidence.
- Local-first and portable — Works with Codex, Claude Code, Cursor, Antigravity, shell scripts, cron jobs, or any tool that can call
obmem. - Search without the sludge — Default search reads distilled active memory first and skips archived evidence unless you opt in.
AI agent memory, Obsidian automation, local knowledge management, coding assistant context, Claude Code hooks, Codex hooks, Cursor webhook memory, project decision logs, Markdown knowledge graphs, developer notes, and long-running software projects.
- Vault mapping — Associates a workspace directory with an Obsidian vault path. Ask once, persist forever.
- Project scaffolding — Creates
Project Memory/<project>/with Home, MOC, Run Log, Decisions, and Open Questions notes, pre-linked to each other. - Run logging — Records each agent session as a structured note: what was asked, what changed, why, and what's still open.
- Memory compaction — Distills noisy
Runs/history intoCurrent Memory, topic notes, and archived evidence notes without deleting raw sources. - Context retrieval — Searches the vault before answering so prior decisions and context surface automatically.
- Graph hygiene — Audits for unresolved links, active-memory orphan notes, dead ends, and backlink coverage; cold
Archive/evidence is excluded from orphan counts.
Most agent memory systems either disappear inside a product database or dump every turn into a pile of logs. This project takes a different path: every memory is a normal Obsidian note, compacted into a small active graph, linked with meaningful wikilinks, and searchable from the CLI.
That makes it useful for:
- agents that need project context before editing code;
- teams that want durable decisions without another SaaS account;
- developers who already live in Obsidian;
- experiments with retrieval, compaction, and graph-shaped memory.
# Install the CLI (isolated via pipx)
brew install pipx && pipx ensurepath
pipx install git+https://github.com/georgeantonopoulos/obsidian-cli-memory-bank-skill.git
# Verify
obmem doctorRequirements: Python 3.10+ and write access to the vault folder. obmem uses file-backed vault
operations for create, append, read, search, and audit, so Obsidian desktop does not need to be
running. If obsidian-cli is installed, doctor reports it as an optional helper, but the memory
bank does not depend on the app IPC bridge.
# 1. Map your workspace to a vault
obmem set-vault --vault-path "/path/to/your/obsidian/vault"
# 2. Reuse an existing project identity when possible
obmem list-projects
# 3. Bootstrap a new project only when needed
obmem init-project --project "My Project" --with-stub
# 4. Record a session
obmem record-run \
--project "My Project" \
--title "Implement queue retry" \
--summary "Added retry model and queue wiring." \
--prompt "User asked for per-item retry in export queue." \
--actions "Updated queue item state, manager logic, and UI actions." \
--decisions "Retry count defaults to 2 for safety." \
--tags "queue,retry"
# 5. Search for prior context
obmem search --project "My Project" --query "retry queue"
# 6. Audit graph health for this project only
obmem audit --project "My Project"
# 7. Preview compaction before moving or pruning notes
obmem compact-project --project "My Project" --max-runs 25 --dry-runThe skill works anywhere an agent can run shell commands. For runtimes with lifecycle hooks, adapter scripts automate the memory operations at the right moments:
| Lifecycle Point | What Happens | Claude Code | Codex |
|---|---|---|---|
| Session start | Health-check vault connectivity | SessionStart |
— |
| Before response | Search vault for relevant context | UserPromptSubmit |
— |
| After response | Log a structured run note | Stop |
agent-turn-complete |
| Before compaction | Persist transcript before context compression | PreCompact |
— |
| After memory write | Mirror MEMORY.md to vault |
PostToolUse |
— |
Full integration with 5 lifecycle hooks. See claude-code/INSTALL.md for setup.
# 1. Install CLI (if not done above)
pipx install git+https://github.com/georgeantonopoulos/obsidian-cli-memory-bank-skill.git
# 2. Install the skill
mkdir -p ~/.claude/skills/obsidian-cli-memory-bank
cp claude-code/SKILL.md ~/.claude/skills/obsidian-cli-memory-bank/SKILL.md
# 3. Install hooks
cp claude-code/hooks/*.py ~/.claude/hooks/
chmod +x ~/.claude/hooks/obsidian_*.py
# 4. Add hook entries to ~/.claude/settings.json (see INSTALL.md for JSON)Hooks provided:
| Script | Event | Purpose |
|---|---|---|
obsidian_sessionstart_hook.py |
SessionStart |
Validates vault health once per session |
obsidian_preprompt_hook.py |
UserPromptSubmit |
Searches Obsidian before each response |
obsidian_poststop_hook.py |
Stop |
Logs a run note after each agent stop |
obsidian_precompact_hook.py |
PreCompact |
Saves transcript summary before context compression |
obsidian_memory_sync_hook.py |
PostToolUse |
Mirrors MEMORY.md writes to vault |
All hooks silently no-op when no vault is mapped for the current workspace.
# Install the skill
mkdir -p "$CODEX_HOME/skills"
cp -R ./ "$CODEX_HOME/skills/obsidian-cli-memory-bank"
# Install the notify hook (auto-logs each turn)
chmod +x scripts/install_codex_notify_hook.sh scripts/codex_notify_hook.py
./scripts/install_codex_notify_hook.shThe installer is non-destructive — it won't overwrite unmanaged notify = ... settings in ~/.codex/config.toml.
For Cursor background-agent webhooks:
python3 /path/to/obsidian-cli-memory-bank-skill/scripts/cursor_notify_hook.py \
--skill-repo /path/to/obsidian-cli-memory-bank-skillSupports webhook fields: event, status, id, summary, source, target, and optional transcript fields (messages/conversation).
Optional security hardening:
- Set
CURSOR_WEBHOOK_SECRETfor HMAC-SHA256 verification - Pass signature via
CURSOR_WEBHOOK_SIGNATUREor includesignaturein the payload
If your payload lacks a workspace path, set CURSOR_WORKSPACE or CURSOR_PROJECT_DIR.
No stable public hook spec exists for Antigravity yet. Use direct CLI calls:
obmem record-run --project "Your Project" --title "Task summary" --summary "What changed and why"If your setup emits machine-readable turn events (e.g. via an embedded extension hook flow), the adapter script handles nested payloads:
python3 /path/to/obsidian-cli-memory-bank-skill/scripts/antigravity_notify_hook.py \
--skill-repo /path/to/obsidian-cli-memory-bank-skillFor any agent that can run shell commands:
- Load
SKILL.mdinto your agent's system prompt or project instructions. - Run
obmemcommands before/after tasks. - If the runtime exposes lifecycle events, adapt the hook scripts in
claude-code/hooks/orscripts/— the pattern is always: parse the event payload, callobmemwith the right arguments.
├── SKILL.md # Universal skill instructions (all runtimes)
├── claude-code/
│ ├── SKILL.md # Claude Code-native skill (uses obmem CLI)
│ ├── INSTALL.md # Claude Code setup guide
│ └── hooks/ # 5 lifecycle hook scripts
├── scripts/
│ ├── obsidian_memory.py # Core CLI (also available as obmem via pipx)
│ ├── hook_common.py # Shared hook runtime helpers
│ ├── codex_notify_hook.py # Codex adapter
│ ├── claude_notify_hook.py # Claude Code adapter (package-based alternative)
│ ├── cursor_notify_hook.py # Cursor webhook adapter
│ ├── antigravity_notify_hook.py # Antigravity adapter (best-effort)
│ ├── install_codex_notify_hook.sh # Codex hook installer
│ └── tests/ # Unit tests for all adapters
├── references/
│ └── obsidian-cli-patterns.md # Obsidian CLI command reference
└── agents/
└── openai.yaml # UI metadata for compatible systems
obmem show-vault # Display mapped vault for current workspace
obmem set-vault --vault-path "..." # Map workspace to vault
obmem doctor # Health check (optional CLI, vault mapping, permissions)
obmem list-projects # List existing project memory folders
obmem bootstrap --project "Name" # Create project note structure
obmem init-project --project "Name" # Bootstrap + stub content in one step
obmem record-run --project "Name" ... # Log a session note
obmem compact-project --project "Name" # Distill Runs/ into Current Memory, Topics, and Archive/Runs
obmem compact-project --project "Name" --include-archive # Refresh distilled memory from archive when no new runs exist
obmem search --project "Name" -q "x" # Search active distilled memory by keyword
obmem search --project "Name" -q "x" --include-archive # Include archived evidence in search
obmem read-note --path "..." # Read a specific note
obmem audit --project "Name" # Check graph hygiene inside one project
obmem set-audit-frequency --runs N # Auto-audit every N runs (0 = off)Use --workspace "/path" on any command to target a different workspace.
- Vault mappings persist in
state/vault_config.json(git-ignored). - Auto-audit triggers every 5 runs by default (configurable via
set-audit-frequency). compact-projectmoves new source notes fromRuns/toArchive/Runs/, marks themstatus: "compacted", prunes noisy run links from hub indexes, and rebuildsCurrent Memory.mdplusTopics/*.mdfrom the new batch and prior archived history. Repeated--max-runsbatches are cumulative instead of destructive.- Active distilled notes drop transcript wrappers and instruction boilerplate and redact common private values. Raw archived evidence is not rewritten; use
--include-archiveto refresh distilled memory after filter improvements even when no new runs exist. - Search skips
Archive/by default and ranks compacted memory and topic notes ahead of raw run logs, so retrieval starts from distilled knowledge. Use--include-archivewhen you need archived evidence. - Hook adapters are additive — the skill works fine without any hooks installed.
- Obsidian desktop, its official bundled CLI, a separately installed
obsidian-cli, andobmemhave independent update paths. Coreobmemoperations remain file-backed. - Choose manual recording or hook recording for a task; using both creates duplicate memory.
- Sanitize prompts and summaries before persistence. Never record secrets, credentials, access links, or unnecessary personal data.
python3 -m unittest discover -s scripts/tests -p 'test_*.py' -vIssues and small pull requests are welcome, especially around:
- new runtime adapters and hook examples;
- better compaction rules for large vaults;
- safer graph hygiene checks;
- README examples from real but sanitized workflows;
- packaging and install improvements.
Please keep examples free of private vault paths, company names, transcripts, tokens, or personal notes.
- The
state/directory may contain vault paths; it is git-ignored. .env*, caches, and platform artifacts are git-ignored.- Review command output before sharing logs publicly.
pipx upgrade obsidian-cli-memory-bank
pipx uninstall obsidian-cli-memory-bankMIT. See LICENSE.
