A single binary that makes Karpathy's LLM Wiki pattern scale — across projects, across machines, across time.
In April 2026, Andrej Karpathy published llm-wiki.md — a pattern for building personal knowledge bases where an LLM incrementally builds and maintains a persistent wiki instead of re-discovering knowledge from scratch on every query.
The core insight is genuinely good: compile knowledge once at ingest time, query the compiled wiki forever.
But there's a structural flaw nobody said plainly enough.
The pattern relies on index.md — a markdown file listing every page in the wiki — as the LLM's navigation layer. The LLM reads it first on every query to figure out which pages are relevant, then loads those pages.
This works beautifully up to ~100 pages.
After that, the math breaks:
500 pages → index.md alone = ~8,000 tokens
+ 5 pages loaded = ~10,000 tokens
= 18,000 tokens consumed before reasoning starts
= context window half gone before the LLM says a word
The wiki becomes more valuable as it grows. The index makes it less usable as it grows. The thing that was supposed to help becomes the bottleneck.
Replace index.md with a real search engine.
Not Elasticsearch. Not a vector database service. Not a Python stack with 40 dependencies.
A single Rust binary that runs on your machine, offline, forever.
llmwiki search "temperature effect on photosynthesis"
[1] bio/photosynthesis.md (score: 0.94)
How plants convert light to glucose via chlorophyll.
C3/C4/CAM variants. Temperature sensitivity 25-35°C.
→ match at: L67 "temperature" · L89 "thermal stress"
[2] bio/enzymes/rubisco.md (score: 0.87)
CO₂ fixation enzyme. Rate peaks at 30°C, inhibited above 40°C.
→ match at: L23 "temperature"
[3] bio/chloroplast.md (score: 0.71)
Organelle where photosynthesis occurs. Membrane destabilizes above 42°C.
→ match at: L12 "thermal"
The LLM gets 3 snippets (~150 tokens) and decides what to read in full. Context window stays free for reasoning.
10,000 pages or 100 pages — the LLM always sees the same number of tokens.
your-wiki/
bio/
photosynthesis.md ← source of truth, plain markdown
cellular-respiration.md
.index/ ← generated by llmwiki, never committed
tantivy/ ← keyword index, BM25
vectors.usearch ← semantic index, cosine similarity
meta.jsonl ← page metadata, descriptions, titles
checksum.json ← for incremental reindex
~/.llmwiki/
wikis.json ← registry of all your wikis
current.txt ← active wiki (set by `llmwiki use`)
The separation matters:
Human layer: .md files → Obsidian, VSCode, git, any editor
Search layer: .index/ → llmwiki, invisible to human workflow
LLM layer: MCP tools → search(), read(), write()
LLM writes pages. Rust indexes them. Human reads in Obsidian. No one steps on anyone else.
cargo install llmwikiOr from source:
git clone https://github.com/krakiun/llm-wiki
cd llm-wiki
cargo build --release# In your wiki directory
cd my-wiki
llmwiki init # creates .index/, registers wiki, adds to .gitignore
llmwiki index # build the search index
llmwiki serve # start MCP server for Claude
llmwiki setup-claude # configure Claude Code or Claude Desktopllmwiki init [--wiki-root PATH]Initializes a wiki in the current directory (or --wiki-root):
- Creates
.index/directory structure - Adds
.index/to.gitignore - Registers the wiki in
~/.llmwiki/wikis.jsonand sets it as default
llmwiki index [--incremental]Builds (or updates) the search index. --incremental skips files whose content hash hasn't changed.
llmwiki watchWatches for file changes and auto-reindexes in the background.
llmwiki search "query" # hybrid (default): BM25 + semantic
llmwiki search "query" --keyword # keyword-only (BM25)
llmwiki search "query" --semantic # semantic vector search only
llmwiki search "query" --graph # expand results via wiki link graph
llmwiki search "query" --graph --hops 2 --backlinks --similarityllmwiki read path/to/page.md
llmwiki read path/to/page.md --section "Background"Register and manage multiple wikis from a central registry (~/.llmwiki/wikis.json):
llmwiki wikis add <name> <path> # register a wiki
llmwiki wikis list # list all registered wikis
llmwiki wikis remove <name> # unregister
llmwiki wikis default <name> # set defaultSwitch the active wiki (affects MCP tool defaults without restarting the server):
llmwiki use alpha # all tools now default to "alpha" wiki
llmwiki use personal # switch back# Start with all wikis from the registry
llmwiki serve
# Start with specific wikis (explicit subset)
llmwiki serve --wiki personal:/home/user/notes --wiki alpha:/home/user/code/alphaThe serve command starts the MCP server. The active wiki (set by llmwiki use) determines which wiki tools default to when no wiki parameter is specified.
llmwiki setup-claude # configure both Claude Desktop and Claude Code
llmwiki setup-claude --desktop # Claude Desktop only (~/.config/claude-desktop/)
llmwiki setup-claude --code # Claude Code only (local .mcp.json)
llmwiki setup-claude --code --global # add to ~/.claude/settings.json insteadllmwiki session-start # load working memory, stale pages, wiki stats
llmwiki session-end "summary" # save session summary to wiki/sessions/YYYY-MM-DD.md
llmwiki decay # show confidence decay across all pages
llmwiki stale [--threshold 0.3] # list pages below confidence threshold
llmwiki promote path/page.md working # set memory tier (working/episodic/semantic/procedural)
llmwiki consolidate # list pages ready to move to a higher tier
llmwiki file-insight "question" "answer" [--score 0.9] # save a Q&A as a wiki insightllmwiki entities # list all extracted entities
llmwiki entities --type person # filter: person|project|library|concept|file|decision|bug
llmwiki entities --query "Redis" # substring filter
llmwiki supersede old/page.md new/page.md # mark a page as replaced by anotherWhen running as an MCP server, Claude gets these tools:
| Tool | Description |
|---|---|
search |
Keyword, semantic, or hybrid search. Returns ranked snippets. |
read |
Read a full page or extract a section by heading. |
write |
Create or update a page. Auto-reindexes on write. |
reindex |
Rebuild the index (incremental by default). |
list |
List pages by path prefix or tag. |
list_wikis |
Show all registered wikis and which is active. |
switch_wiki |
Change the active wiki (same as llmwiki use <name>). |
session_start |
Load working memory, recent activity, stale pages, wiki stats. |
session_end |
Save a session summary to wiki/sessions/YYYY-MM-DD.md. |
All tools that operate on content accept an optional wiki parameter:
search("Redis TTL bug") → searches ALL wikis
search("Redis TTL bug", wiki="alpha") → searches only "alpha"
write("path.md", content, wiki="personal") → writes to "personal"
cd ~/code/alpha
llmwiki init # registers as "alpha" in ~/.llmwiki/wikis.json
cd ~/code/beta
llmwiki init # registers as "beta" alongside "alpha"
cd ~/notes
llmwiki init # registers as "notes"Create a .mcp.json in each project so Claude Code knows the primary wiki when it opens that directory:
{
"mcpServers": {
"llmwiki": {
"command": "llmwiki",
"args": ["serve", "--wiki-root", "/Users/you/code/alpha"]
}
}
}llmwiki setup-claude --code generates this file automatically.
llmwiki use alpha # Claude's tools now default to alpha wiki
llmwiki use personal # switch context without restarting the serverClaude sees:
{
"current_project": "alpha",
"context": [{ "wiki": "alpha", "working_memory": [...] }],
"other_wikis": [{ "wiki": "personal" }, { "wiki": "beta" }]
}Every wiki page has a YAML frontmatter block:
---
title: Redis TTL Behavior
description: TTL is key-level, not value-level. SET resets TTL to -1 (no expiry). GETSET preserves TTL. EXPIRE is idempotent.
confidence: 0.91
updated: 2026-06-01
tags: [redis, caching, backend]
tier: working
---
# Redis TTL Behavior
Full content here...description— dense summary shown in search results (~200 chars max)confidence— 0.0–1.0, decays over time, triggers stale alertstier— memory tier:working|episodic|semantic|procedural
| Karpathy pattern | llmwiki | |
|---|---|---|
| Navigation | Load index.md into context |
search() tool, zero tokens |
| 100 pages | Works well | Works well |
| 1,000 pages | index.md overflows context | Same performance |
| 10,000 pages | Unusable | Same performance |
| Token cost per query | Grows with wiki size | Constant regardless of size |
| Multiple projects | One wiki per Claude instance | Cross-project, one server |
| Stale content | Manual review | confidence decay + alerts |
| Source of truth | LLM-generated prose | Plain markdown, git-tracked |
Human-first. Files are plain markdown. Open in Obsidian, VSCode, or cat. No lock-in, no proprietary format.
Git-friendly. Content lives in .md files. .index/ is in .gitignore. git diff shows exactly what the LLM changed and when.
Offline. No API keys. No cloud. Tantivy and usearch run on-device. fastembed downloads the embedding model once and caches it locally.
One binary. cargo install llmwiki. Done.
This project is a direct response to Andrej Karpathy's llm-wiki.md pattern. The core idea — persistent, compounding knowledge compiled by an LLM — is his. We just solved the retrieval problem that makes it viable at scale.
Built in Rust. Inspired by a gist. Designed for the knowledge that matters most — the kind no model was trained on.