OMI/Obsidian memory tooling for AI agents: reproduce the integration on any machine, plus a local web app to view, edit, and add memory entries.
Mirrored on both GitHub and Codeberg. Issues filed on either are welcome; commits are pushed to both.
omind graph over an OMI vault — every note a node coloured by its OKF type (and sized by link degree), every [[wikilink]] an edge. Rendered from omind graph export (see docs/graph-demo).
OMI ("Open Mind Interface") is a folder of Markdown notes that an AI agent
reads and writes as long-term memory. omind does two things with it:
omind setup— idempotently registers omind's own node MCP server (omind node) with your agent — Claude Code by default, or Hermes, OpenClaw, OpenCode, Codex CLI, Gemini CLI, Claude Desktop, Kiro, VS Code, and Amazon Q via--agent(see Other agents below) — pointed at an OMI folder inside an Obsidian vault, and initializes the folder as a mesh node (see below). After this, the agent persists memory across sessions through the MCP tools — and across machines through the mesh. Setup also installs a PreToolUse(Bash) fresh-base git guard (git-fresh-base.sh) that blocks branching off a localmain/master/developthat is behind itsorigin/*counterpart (it fetches first, fails open otherwise).omind mesh— peer-to-peer replication: every machine runs a full local node and nodes sync over git+ssh, with per-note Lamport versioning and a field-level merge driver. No central server, full offline operation. Deleting archives (restorable) instead of removing. See docs/mesh.md (design) and docs/mesh-ops.md (operation).omind serve— a small local web app (FastAPI + Tailwind) to view, edit, and add memory entries in that same folder, without opening Obsidian. Ships with five themes and a switchable UI in six languages (English, Spanish, French, Arabic, Russian, Chinese), including right-to-left layout for Arabic.omind doctor— diagnose the wiring in one shot: Claude CLI + git onPATH, theomiMCP server registered at user scope with the right command, the OMI folder readable, mesh health (node identity, merge driver, per-peer ahead/behind, last-sync age, unresolved conflicts), backup health (unconfigured / last-success age / failing), and whether the auto-memory hooks have recorded any recent failures.omind backup— encrypted, unattended off-machine backup of the OMI folder, wrapping restic (see Encrypted backup below).omind guard— the OMI-compliance guard: a layered set of agent hooks that make the agent consult memory before it acts and hard-block dangerous commands, enforcing identically across Claude Code, Hermes, OpenCode, and Codex (see The OMI-compliance guard below).omind checkpoint— a scheduled job that records what the agent has been doing every N minutes into a daily worklog note, by mining the trails the hooks already capture (see Activity checkpoints below).
The web UI works fully offline (fonts, styles, and the Markdown renderer are
vendored — no CDN). It shows backlinks for the open note, refreshes the list
live as other tools write the folder, guards against clobbering external edits,
and has keyboard shortcuts (/ search, n new, j/k to move, Ctrl/Cmd+S
to save, Esc to cancel).
Everything runs locally. No accounts, no cloud, no cost.
One-step bootstrap (checks/installs dependencies, installs omind, verifies):
# clone, then:
scripts/bootstrap.sh # or: --remote codeberg, --vault PATHIt auto-installs uv (user-local, no root — and it bootstraps Python ≥3.10 for
you), checks for git/claude with install guidance if either is missing,
then runs omind setup + omind doctor. Note: omind itself has no Docker and
no Node.js dependency — it needs only git and an agent CLI (Claude Code on
the default path; Hermes, OpenClaw, OpenCode, and Codex are each wired with
omind setup --agent <name> once their own CLI is installed — see Other
agents below).
Manual — an isolated CLI install straight from the git remote:
# via uv (recommended — also provides a compatible Python if the system one is <3.10)
uv tool install git+https://github.com/CryptoJones/omind.git
# or via pipx
pipx install git+https://github.com/CryptoJones/omind.gitEither puts the omind command on your PATH in its own virtualenv. Codeberg
works too — swap in git+https://codeberg.org/CryptoJones/omind.git.
For development, install editable from a clone (see CONTRIBUTING.md):
git clone https://github.com/CryptoJones/omind.git
cd omind
pip install -e ".[dev]"Provision the MCP wiring for your agent — Claude Code by default; add
--agent hermes|openclaw|opencode|codex|gemini|claude-desktop|kiro|vscode|q
for the others (see Other agents below). Idempotent; safe to re-run:
omind setup --vault "$HOME/Documents/Obsidian Vault"Prefer to wire things in yourself? Print the same steps as copy-paste shell commands and JSON, personalized to your paths — nothing is changed for you:
omind quickstart --vault "$HOME/Documents/Obsidian Vault"It covers all five pieces (memory folder scaffold, mesh initialization, user-scope MCP registration, auto-memory hooks, fresh-base git guard hook), each independently applicable. The annotated walkthrough lives in docs/manual-setup.md.
Run the web UI over the same memory folder:
omind serve --vault "$HOME/Documents/Obsidian Vault"
# open http://127.0.0.1:8765Preview what setup would do without changing anything:
omind setup --vault "$HOME/Documents/Obsidian Vault" --dry-runCheck that everything is wired up correctly:
omind doctor --vault "$HOME/Documents/Obsidian Vault"Add or update a single memory note safely — it creates the note, or updates it in place if the title already exists, through the same locked, atomic write path every other tool uses (body comes from stdin):
echo "the body of the note" | omind note --title "An Insight" --tags thesis,attentionBack up or migrate the whole memory dataset:
# export — json (default; portable & diffable) or targz (full-fidelity snapshot)
omind export --vault "$HOME/Documents/Obsidian Vault" --out omi-export.json
omind export --vault "$HOME/Documents/Obsidian Vault" --format targz --out omi.tar.gz
# import — format auto-detected by extension
omind import omi-export.json --vault "$HOME/Documents/Obsidian Vault"Import adds new notes and leaves identical ones untouched; a note whose content
differs is kept as-is on disk and reported, unless you pass --force. Imports
never delete.
The vault is long-term memory on one disk; omind backup keeps an encrypted
copy off-machine, wrapping restic:
# one-time: generate the password file (0600) and create the encrypted repo
omind backup init --repo sftp:host:/path # or a local path, s3:, b2:, …
# snapshot now, with 7-daily / 4-weekly / 6-monthly retention
omind backup run
# restic check + restore the latest snapshot's index.md and diff it live
omind backup verify
# unattended: a daily systemd user timer running `backup run`
omind backup install-timerEvery external command runs with a timeout, so a restic hung on a dead link
fails loudly instead of wedging the timer; three consecutive failures write a
BACKUP FAILING note into the vault so the problem surfaces in session
priming, and omind doctor reports backup health either way. If restic is
absent, run degrades to unencrypted rsync --link-dest snapshots and doctor
warns about the degradation.
Copy ~/.config/omind/backup.pass somewhere safe off-machine. It encrypts
every snapshot; losing it with the disk makes the backups unreadable.
OMI is just a folder of plain Markdown notes — one note per memory, fully human-editable (open the folder as an Obsidian vault). It is also a conformant Open Knowledge Format bundle (see below). Each note has a stable shape so tools and the merge driver can read and write individual fields without stepping on each other:
- a YAML frontmatter block — the note's OKF metadata: the required
typeplustitle,description,tags, andtimestamp; - a
# Titleand a## Metadatablock (created date,#tags, and the meshRev:Lamport stamp), kept alongside the frontmatter so existing tooling and un-upgraded mesh peers keep reading it unchanged; ## Summary/## Detailsfree text;## Connections—[[wikilinks]]to related notes (the graph the web UI andomind linttraverse);## Action Items(a checkbox list) and## References.
Open Knowledge Format (OKF). omind speaks
OKF —
Google Cloud's vendor-neutral, Apache-2.0
specification
for representing knowledge as a directory of Markdown files with YAML
frontmatter, readable by any agent or tool with no SDK, runtime, or lock-in.
Every note omind writes leads with a frontmatter block carrying the one field
OKF requires (type) plus the recommended title / description / tags /
timestamp, and index.md is the OKF directory listing — so an omind vault
drops straight into any OKF-aware consumer. Migrate a pre-OKF vault in place with
omind convert (idempotent; --check validates the three conformance rules,
--dry-run previews). More: the
OKF spec
and okf.md.
One writer, always. Every write — omind note, the omind node MCP server an
agent calls, the web UI, the mesh merge — goes through a single locked, atomic
path: an advisory flock, an atomic os.replace, and a note_version
compare-and-swap that rejects a write made against a stale read. That is what lets
several agents and tools touch the same folder at once without corrupting it.
"Deleting" a note archives it (hidden, restorable) rather than removing it.
A maintained index.md lists the most recent notes; that index plus the latest
session state is exactly what the guard's priming injects at session start. Run
omind lint to catch drift (broken wikilinks, orphaned or near-duplicate notes,
missing titles). The cross-machine replication story — git-backed mesh, per-note
Lamport versioning, the field-level merge driver — is its own section:
The memory mesh.
Memory only helps if the agent actually reads it before acting — and an agent
left to its own devices consults memory inconsistently and will happily run a
destructive command. The guard closes both gaps with a small stack of hooks
around every tool call. omind setup installs it for Claude Code; the other
harnesses wire it through the per-agent adapters.
It enforces the same rules everywhere and fails open at every layer — a
broken hook can never wedge the agent.
- Priming (injection). On session start the agent is handed the recent-memory
index + latest session state, so the relevant memory is in front of it before
the first turn (Claude Code
SessionStart, Hermespre_llm_call, …). - The consult gate. A
PreToolUsehook blocks the first action of each turn until the agent reads OMI; one OMI search/read clears the gate for the rest of the turn. The gate is a per-turn sentinel under the state dir, reset on the harness's turn boundary. - The verifier. Clearing the gate by reading any note isn't enough, so a
PostToolUseverifier judges whether the consult was actually relevant to the turn's task — a deterministic keyword-overlap prefilter decides the clear cases, and only the ambiguous middle shells out to headlessclaude -p(fail-open). Default is WARN (it logs the off-topic consult and nudges toward better notes); opt-in REQUIRE (OMI_VERIFY_REQUIRE=1) re-closes the gate until a relevant consult happens. The thresholds (OMI_VERIFY_HIGH/OMI_VERIFY_LOW) and an always-relevant allowlist (OMI_VERIFY_ALWAYS_RELEVANT) are tunable, and the check primes on the agent's own recent off-topic consults. - Hard blocks. A policy of high-risk command patterns (deleting a repo, a destructive git push, rewriting auth config, …) is blocked unconditionally, regardless of the gate, with the reason and the on-point notes to read.
- The compliance log + learning loop. Every guard-relevant action is appended
to
compliance.jsonl; aPostToolUsedetector records soft-rule matches as evidence, and recidivism escalates a rule (soft → hard → verifier) over time (omind guard learn/escalate).
Cross-harness by construction. Each harness is described as data — a
HarnessSpec (can it hard-block? which block-output format?) — and its hook pipes
its event to omind guard adapter --harness <name>, so a rule learned under one
agent blocks under all of them. omind guard selftest replays canned deny events
through every harness's renderer to verify the wiring without a live agent.
Inspect and operate it with omind guard log (recent denies/violations),
omind guard policy (active rules), omind guard status (which harnesses are
guarded), omind guard explain "<cmd>" (dry-run a command), and
omind guard verify --explain (why a consult scored relevant or off-topic).
omind guard repair (and omind doctor) re-heal a wedged or drifted hook-set.
The Playbook is the small set of always-on operator rules — the cross-cutting
procedures (sudo, secrets, forges, "pull before you work", "do it yourself") that a
fresh agent instance otherwise keeps re-learning the hard way. It lives as a priming
file, Playbook.md, in the OMI vault, and omind surfaces it two ways:
- Always in context.
Playbook.mdis injected verbatim into every session's SessionStart context (alongsideindex.md), so the rules are present whether or not the agent thinks to search for them — they do not depend on the per-turn gate's relevance matching to surface. - Enforced at the action. The guard backs the most-violated rules with hard
blocks keyed on the command, not the task. Raw
sudois blocked and redirected to the installedfleet-sudowrapper, which reads the fleet sudo password frompassitself — so no instance ever guesses a per-hostpassentry or hands the user a command to paste. A deliberate rawsudoopts in withOMI_SUDO_OK=1, exactly like the Codeberg-mirrorOMI_PUSH_GITHUB=1escape hatch.
Edit the rules by editing Playbook.md in the vault; add enforcement with a seed
rule in omind.policy. The Playbook is the guard's priming made explicit: don't
ask a fresh instance to remember — put the rule in front of it, and block the wrong
action.
You can't reliably force a running agent to do something on a wall clock —
agents are turn-driven and idle between messages. So to "record recent work every
N minutes," omind doesn't ask the agent: omind checkpoint is a scheduled job
that mines the two trails the hooks already capture — the per-action journal
(Journal/Session Journal <date>.md) and the cross-harness compliance log —
and upserts a per-day Worklog <date> note with a timestamped section per
run (one note per day, so it stays a single recent-memory slot instead of
flooding the index).
# summarize the last 15 minutes into today's worklog note, now
omind checkpoint --since 15m
# or run it unattended every 15 minutes via a systemd user timer
omind checkpoint install-timer --every 15m
omind checkpoint uninstall-timer # stop + remove itThe summary is deterministic (action counts by tool + guard denies/violations);
--llm adds a one-paragraph claude -p narrative, fail-open to the deterministic
text. Because it's a scheduled job — the same systemd-user-timer mechanism as
omind backup and omind mesh — it doesn't depend on the agent's cooperation,
which is what makes it a reliable record rather than a hopeful instruction.
Claude Code is the default, but the
same OMI folder can back any agent. omind setup --agent ... provisions several
more out of the box —
Hermes Agent,
OpenClaw,
OpenCode, and
OpenAI Codex CLI:
omind setup --agent hermes --vault "$HOME/Documents/Obsidian Vault" # Hermes Agent
omind setup --agent openclaw --vault "$HOME/Documents/Obsidian Vault" # OpenClaw
omind setup --agent opencode --vault "$HOME/Documents/Obsidian Vault" # OpenCode
omind setup --agent codex --vault "$HOME/Documents/Obsidian Vault" # OpenAI Codex CLIThe OMI-compliance guard (hard-blocks + the per-turn consult gate) enforces
across harnesses, not just Claude Code: Hermes via its pre_tool_call hook,
OpenCode via a tool.execute.before plugin, and Codex CLI (>= 0.117) via its
Claude-schema PreToolUse/PermissionRequest command hooks in
~/.codex/hooks.json — so a rule learned under one agent blocks under all of
them. omind setup --agent codex also persists Codex [hooks.state] trust for
the omind-owned hook definitions it just wrote, so a fresh Codex session can run
the guard and OMI priming hooks without a manual /hooks approval pass. The hash
is computed from the exact hook definition on that machine, including the local
omind executable path; if you later edit the hook by hand, re-run setup or use
Codex's /hooks UI to review the changed definition. omind guard selftest
replays a canned deny through every harness's renderer to confirm the wiring
without a live agent.
Codex also gets the omi MCP server registered — under [mcp_servers.omi] in
~/.codex/config.toml, the same table codex mcp add writes. Unlike every
other agent config omind touches, config.toml is TOML, so this merge is
done with tomlkit (round-trip parsing) instead of the JSON idiom the rest
share; only the mcp_servers.omi table is ever touched, and a config.toml
that doesn't parse is never overwritten. Codex has no memory skill because it
reads the MCP tools directly.
For Codex, one command installs the whole integration:
omind setup --agent codex --vault "$HOME/Documents/Obsidian Vault"That command idempotently:
- Registers the
omiMCP server in~/.codex/config.toml. - Installs the OMI guard on
PreToolUseandPermissionRequestin~/.codex/hooks.json. - Installs
SessionStartOMI priming, using the same recent-memory context Claude Code receives. - Writes a managed global
~/.codex/AGENTS.mdbootstrap pointer that tells fresh Codex sessions to read OMI first. - Persists Codex hook trust for those omind-owned hook groups under
[hooks.state]in~/.codex/config.toml.
Then restart Codex and verify:
omind doctor --agent codex --vault "$HOME/Documents/Obsidian Vault"omind setup --agent <name> adapts to where each agent keeps its config. The
three memory-backing agents — Hermes, OpenClaw, and OpenCode — get the full
treatment:
- The shared steps — OMI folder scaffold + mesh initialization — identical to
the Claude Code path, so every agent talks to one memory folder through
the same
omind nodeserver. - Registers the
omiMCP server where the agent looks for it:mcp_serversin~/.hermes/config.yaml(Hermes),mcp.serversin~/.openclaw/openclaw.json(OpenClaw — legacy~/.clawdbot/~/.moltbotinstalls detected too), or themcpblock in~/.config/opencode/opencode.json(OpenCode). Only omind's own entry is ever touched; a config file that doesn't parse is never overwritten. - Installs an
omind-omi-memoryskill that teaches the agent to read memory through the MCP tools and write it throughomind note— the single-writer path that keeps concurrently running agents from corrupting the folder (see docs/mesh.md → "Node types & the single-writer rule"). - Wires session-start priming so the agent reads OMI first — Hermes via a
pre_llm_callhook (pre-approved in itsshell-hooks-allowlist.jsonso it loads without a prompt), OpenClaw via a managedMEMORY.mdbootstrap. It is the sameomind hookpayload (recent-memory index + latest session state) Claude Code injects through itsSessionStarthook.
The Gemini CLI is wired guard-only — just the hard-block hook described
above (the BeforeTool hook under hooks in ~/.gemini/settings.json); its
MCP-memory registration, skill, and priming are a separate follow-up. Codex
CLI gets guard, MCP-memory registration, SessionStart priming, and the global
AGENTS bootstrap pointer (see above), but no memory skill because it uses the
MCP tools directly. OpenCode priming is likewise not wired yet (its MCP
server and skill are). The cross-harness guard reaches Claude Code, Hermes,
OpenCode, Codex, and Gemini as hard-block; OpenClaw is wired
detect-only — its POST /hooks/agent gateway receives the guard verdict but
deny-enforcement is unverified against a live gateway, so the verdict is advisory
until hard-block is proven.
Four more agents are wired by MCP registration alone — omind drops the omi
server into the tool's own config file and nothing else (no guard, no skill); the
agent reaches memory through the MCP tools the server exposes:
omind setup --agent claude-desktop --vault "$HOME/Documents/Obsidian Vault" # Claude Desktop app
omind setup --agent kiro --vault "$HOME/Documents/Obsidian Vault" # Kiro IDE
omind setup --agent vscode --vault "$HOME/Documents/Obsidian Vault" # VS Code (native MCP)
omind setup --agent q --vault "$HOME/Documents/Obsidian Vault" # Amazon QEach writes only the omi entry it owns and refuses to overwrite a config file it
can't parse. Config locations: Claude Desktop's claude_desktop_config.json (under
~/Library/Application Support/Claude on macOS, ~/.config/Claude on Linux,
%APPDATA%\Claude on Windows; mcpServers block); Kiro's ~/.kiro/settings/mcp.json
(mcpServers); VS Code's user-level mcp.json (under the same per-OS app-support dir
as Claude Desktop but Code/User; a servers block with type: stdio); and Amazon
Q's ~/.aws/amazonq/mcp.json (mcpServers). Restart the tool afterward to load the
server.
omind doctor --agent hermes|openclaw|opencode|codex|gemini|claude-desktop|kiro|vscode|q
diagnoses that agent's wiring, and omind quickstart --agent <name> prints the manual
steps (YAML/JSON snippets personalized to your paths) if you'd rather merge them in
yourself.
The auto-memory journal hooks (the per-action trail) remain Claude Code-only; the other agents' actions reach OMI through the MCP skill instead.
See CHANGELOG.md for release notes.
2.0.0 turned omind from a single-machine tool into a git-backed mesh —
every machine runs a full local memory node, and the nodes replicate to one
another peer-to-peer over git, so memory is shared across the house with
no central server and full offline operation. Concurrent writes build on
the per-node write safety (advisory flock + atomic os.replace +
note_version compare-and-swap) and add cross-node Lamport versioning
with a field-level merge; "deleting" a note archives it (hidden,
restorable) rather than tombstoning it. Design:
docs/mesh.md; operation:
docs/mesh-ops.md.
Apache 2.0. See LICENSE.
Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/
![omind's knowledge graph over a vault's [[wikilinks]]](/CryptoJones/omind/raw/main/docs/graph.png)