Structural intelligence
for your Obsidian
vault.

A markdown vault grows into a pile. eno indexes it into a queryable surface, gardens the orphans and stubs and drift, and exposes it — to you on the command line, to coding agents over MCP, to sibling tools over HTTP. Light core, no LLM dependency, no phone-home.

$ pip install enowiki
$ export ENO_VAULT_DIR=~/vault
$ eno index
$ eno hygiene
→ 34 orphans · 12 stubs · 8 stale · 3 broken links · 2 drift candidates

Why eno

Every "what does my vault know about X?" costs a full-text grep plus a fat LLM read. Every tool that wants the vault as memory pays that tax. eno is the structural layer that makes markdown behave like a real knowledge store.

Token-efficient by construction

Index queries return paths and small excerpts, never whole notes. LLM operations are two-phase: cheap planning over the index, then targeted reads. Nothing loads your entire vault into a prompt.

The vault is its own dashboard

Gardening reports are written back into the vault as notes under 9 Vault Health/ — wikilinkable, graph-visible, and indexable by eno itself. No bespoke UI for things markdown already shows well.

Drift, not broken links

A [[Some Concept]] written before its note exists is groundwork, not a bug. The real bug class is drift: a wikilink that almost resolves (em-dash vs hyphen, casing, trailing punctuation) and silently doesn't. eno separates the two.

Resurface, don't enforce

eno surfaces the forgotten and suggests — it never auto-merges, auto-deletes, or rewrites note bodies. Every structural change keeps a human in the loop. Orphans aren't bugs; they're forgotten gold.

Local-first, no beacon

The core has no network dependency at all. The optional LLM extra routes through somm, which is local-first (ollama) by default — vault prose never has to leave your machine.

Install

# structural core + `eno` CLI — no LLM dependency:
# (PyPI package is `enowiki`; the command is `eno`)
$ pip install enowiki

# MCP server for coding agents, and the HTTP service:
$ pip install eno-mcp eno-service

# + local-first distillation & semantic dedup (fold, tiling):
$ pip install enowiki[llm]

Python 3.12+. Point eno at your vault with --vault PATH or $ENO_VAULT_DIR — there is no default, because a tool that operates on your notes should never guess which directory that is.

Retrieve, excerpt-first

$ eno search "mechanism design"
$ eno neighbors "2 Projects/Acme/Widget.md"
→ 4 backlinks · 7 outbound — paths + titles, not full notes

MCP for your coding agent

A stdio server gives any MCP client — Claude Code, Cursor, Windsurf — a structural view of the vault. The intelligence is the calling agent; eno needs no model of its own here.

Retrieval & health tools

eno_search, eno_note, eno_neighbors, eno_concepts, eno_frontier, eno_hot, eno_orphans, eno_stubs, eno_stale, eno_broken_links, eno_drift, eno_hygiene, eno_health. Your agent grounds its answers in what you've actually written, cheaply.

Write back with provenance

eno_create_note and eno_append_to_note let an agent file content into the vault, carrying an author so machine-written pages stay distinguishable from yours.

fold & tiling — the LLM extra

pip install enowiki[llm] adds two local-first intelligence features. Both route through somm; eno itself makes no assumption about a model runtime, and calling them without the extra returns a clean install hint, not a crash.

eno fold — cited distillation

Distills a date range or a topic (by wikilink, folder, or tag) into a structured, cited rollup note — with supersession metadata and fold-of-folds level stacking. Extractive-only, with a count-check that flags any numeric claim or citation date not present in the sources.

eno tiling — semantic dedup

Finds notes that say the same thing in different words, in two confidence bands. A signal for human review, never an auto-merge. Complements title-based duplicate detection with a body-content similarity axis.