Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

llmwiki

A single binary that makes Karpathy's LLM Wiki pattern scale — across projects, across machines, across time.


The Problem

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.


The Fix

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.


Architecture

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.


Install

cargo install llmwiki

Or from source:

git clone https://github.com/krakiun/llm-wiki
cd llm-wiki
cargo build --release

Quick Start

# 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 Desktop

CLI Reference

Wiki setup

llmwiki 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.json and sets it as default
llmwiki index [--incremental]

Builds (or updates) the search index. --incremental skips files whose content hash hasn't changed.

llmwiki watch

Watches for file changes and auto-reindexes in the background.


Search

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 --similarity

Read & Write

llmwiki read path/to/page.md
llmwiki read path/to/page.md --section "Background"

Multi-wiki management

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 default

Switch 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

MCP Server

# 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/alpha

The 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.


Claude integration

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 instead

Memory & lifecycle

llmwiki 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 insight

Knowledge graph & entities

llmwiki 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 another

MCP Tools (for Claude)

When 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"

Multi-project workflow

Setup: one time per project

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"

Per-project .mcp.json

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.

Switching context

llmwiki use alpha     # Claude's tools now default to alpha wiki
llmwiki use personal  # switch context without restarting the server

Claude sees:

{
  "current_project": "alpha",
  "context": [{ "wiki": "alpha", "working_memory": [...] }],
  "other_wikis": [{ "wiki": "personal" }, { "wiki": "beta" }]
}

Page format

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 alerts
  • tier — memory tier: working | episodic | semantic | procedural

Why This Scales

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

Philosophy

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.


Video Tutorial

Video Tutorial


Credits

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.

About

No description, website, or topics provided.

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages