Knowledge vault + personal plugin
Plain markdown · Claude Code plugin · no embeddings · no MCP · no daemon
inbox/ → distil-vault skill → curated knowledge-vault folders, read directly by Claude.
What it is
A curated personal knowledge base — strategy, decisions, patterns,
playbooks, project hubs, people notes, voice — that Claude Code reads
directly from the filesystem with Read, Grep, and Glob. About 216
markdown files at last count, fitting inside Claude's context window
with room to spare. The companion plugin (issei-plugin)
ships the skills that interact with it:
search-vault, distil-vault,
lint-vault, plus a handful of voice and meeting helpers.
Why the project is interesting
Not because of what it is now, but because of what it used to be.
The first version was an MCP server. FastMCP protocol layer; SQLite FTS5
for lexical search; LanceDB for vectors; Ollama
nomic-embed-text:v1.5 for embeddings; a file watcher that
re-indexed on every change; a hybrid scorer that blended FTS and vector
similarity. About 600 lines of plumbing. The Claude session would call
a custom tool, the tool would run hybrid retrieval, and the top-k
chunks would come back as context.
I deleted all of it.
Why I deleted it
Three things happened in the same week. First, I noticed the vault was
216 files and growing — but not so fast that it would ever stop fitting
in context. The "retrieval problem" the MCP was solving wasn't a real
problem at this scale. Second, I measured the search-quality lift over a
plain Grep + Glob workflow on the same corpus: 3–5%, on heavily curated
short documents. Not nothing, but not 600 lines of plumbing and an
Ollama daemon dependency. Third, three real bugs in the indexing path
showed up at once: the Windows file watcher missed MCP-authored files
(atomic rename via os.replace doesn't fire
on_modified reliably on the renamed target); FTS and vector
writes weren't atomic, leaving the two indexes ~20% out of sync; the
chunk tokenizer didn't match the embedder's, so retrieval was scoring
against the wrong segments.
At that point the cost-benefit was clear. The MCP stack was solving a problem that didn't exist yet, generating problems that did, and blocking the actual lift — which is the discipline of distilling notes well — behind plumbing maintenance.
What replaced it
A markdown convention and three plugin skills.
The convention is a folder taxonomy (strategy,
patterns, playbooks, decisions,
projects, people, voice,
references, daily) with a frontmatter schema
that enforces title, created,
tags, and links on every note. The
links field is the load-bearing one — every new note has
to declare its inbound and outbound edges, which forces the writer to
locate the new content in the existing graph rather than letting it pile
up un-linked.
The skills do the work the MCP used to do, but at write time instead of
query time. search-vault is a Glob + Grep + Read pipeline —
no index, no embedding, just patterns over filenames and frontmatter.
distil-vault takes raw inbox material and produces a
curated note plus updates to 5–15 cross-referenced
neighbours, so synthesis happens once, by the LLM, when the note is
written. lint-vault runs whole-vault consistency checks —
missing backlinks, orphan files, frontmatter drift.
The shift in framing: synthesis happens at write time (the LLM updates 5–15 cross-referenced pages when new material lands), not at query time. That's what keeps the vault navigable as it grows; without it, files pile up un-linked and the "Claude reads the whole vault" affordance erodes.
The pattern the project actually demonstrated
Vector retrieval is the right answer for a class of problem — long-form corpora, mixed-domain knowledge, multi-tenant systems, RAG over content you don't control. None of those apply to a personal vault. The interesting bit is recognising when the platform-level solution is the wrong size for the actual workload, and being willing to delete 600 lines of code that worked.
There's a longer version of this argument in writing.
Links
- Repository: private (vault contains personal notes)
- Claude Code — the runtime the plugin ships into