๐ง hallouminate ๐ง
Persistent, repo-local knowledge for coding agents.
hallouminate gives your coding agent a wiki it writes and searches โ plain markdown you review and commit with the code. The markdown files remain the source of truth; hallouminate builds a derived local index so agents can retrieve the right context without rereading the entire repository.

- Human-owned: ordinary markdown in
.hallouminate/wiki/, readable and editable with any text editor. - Agent-native: a focused MCP surface for searching, reading, and safely updating the wiki.
- Local-first: embeddings and search run on your machine; no hosted account or content upload is required.
- Repo-aware: each repository gets its own wiki, with optional union search across repositories.
hallouminate is not a code-intelligence engine: it can index source files as text, but it does not parse symbols, types, or call graphs. Pair it with your code-search tools; use hallouminate for the durable knowledge those tools cannot infer โ the architecture, conventions, gotchas, and reasons behind a design.
Install ยท First run ยท Full documentation ยท How it compares
Install
The preferred install is via npm โ the package is a thin shim whose
postinstall downloads the matching prebuilt binary from the GitHub release.
No Rust toolchain, no protoc:
Alternatives that fetch the same prebuilts, in cascade order:
|
Prebuilts cover Apple-silicon macOS (aarch64-apple-darwin) and x86_64 /
aarch64 Linux (glibc โฅ 2.39). Re-run the install command any time to upgrade.
Source builds need protoc (the lancedb build dependency:
brew install protobuf / apt install protobuf-compiler); from a git
checkout, cargo build --release lands the binary at
target/release/hallouminate.
Intel macOS and older-glibc Linux have no prebuilt (ort/ONNX Runtime ships
no Intel-mac build โ pykeio/ort#556); use the source build there. Windows
is unsupported โ the daemon is Unix-only (Unix domain socket + flock);
see #48.
Verify with hallouminate --version.
Plugin setup (recommended)
The plugin pack is the preferred integration: one install registers the MCP
server (bundled .mcp.json launching hallouminate serve) and the wiki
skills (/hallouminate:install, wiki authoring workflows). Install it through
the harness-native route:
| Harness | Install the plugin / skills | MCP registration |
|---|---|---|
| Claude Code | /plugin marketplace add paulnsorensen/hallouminate โ /plugin install hallouminate@hallouminate |
Bundled .mcp.json; user fallback: claude mcp add hallouminate --scope user -- hallouminate serve |
| Codex | codex plugin marketplace add paulnsorensen/hallouminate, restart, then codex plugin add hallouminate@hallouminate (or install from /plugins) |
Bundled .mcp.json |
| Copilot CLI | copilot plugin marketplace add paulnsorensen/hallouminate โ copilot plugin install hallouminate@hallouminate |
Bundled .mcp.json |
| OMP | /marketplace add paulnsorensen/hallouminate โ /marketplace install hallouminate@hallouminate |
Bundled Claude-compatible .mcp.json |
| Cursor | Teams/Enterprise: import https://github.com/paulnsorensen/hallouminate under Plugins โ Team Marketplaces. Local: clone, copy or symlink plugins/hallouminate to ~/.cursor/plugins/local/hallouminate, then reload/restart Cursor. |
Bundled .mcp.json through the Cursor manifest |
| Gemini CLI | From a checkout: gemini extensions install ./plugins/hallouminate --consent. From an extracted release archive: gemini extensions install ./hallouminate-skills-<version>/plugins/hallouminate --consent. |
Inline in gemini-extension.json; bundled skills are auto-discovered |
| opencode | Copy plugins/hallouminate/skills/ to ~/.config/opencode/skills/ |
Add { "mcp": { "hallouminate": { "type": "local", "command": ["hallouminate", "serve"] } } } to opencode.json |
Without the plugin: skills + MCP by hand
The plugin is a convenience wrapper โ both halves can be wired manually:
- MCP โ register the stdio server directly:
- Claude Code:
claude mcp add hallouminate --scope user -- hallouminate serve - opencode: the
opencode.jsonsnippet from the table above - Any other MCP client: launch
hallouminate serveover stdio โ ornpx -y hallouminate serveto skip the PATH install entirely (first run pays the binary download)
- Claude Code:
- Skills โ copy
plugins/hallouminate/skills/into your harness's skills directory (Claude Code:~/.claude/skills/; opencode:~/.config/opencode/skills/). Skills are optional โ the MCP tools work without them.
First run
hallouminate config initโ scaffold the XDG baseline config.hallouminate init-repo <name>in your repo โ seed.hallouminate/config.tomlplus the wiki skeleton; the wiki becomes therepo:<name>:wikicorpus. Identical on every harness.hallouminate indexโ build the index (auto-spawns the daemon and downloads the embedding model on first use).hallouminate ground "<a question your wiki answers>"โ prove the loop.
Usage
hallouminate serve starts the stdio MCP server (auto-spawning the daemon if
none is running) โ this is what an MCP client launches:
From a source checkout, run subcommands through cargo:
MCP
hallouminate serve starts a stdio MCP server. Tools:
groundโ semantic search.indexโ bulk (re)build a corpus index.corpus_statsโ index health for one corpus: indexed file count, total chunk rows, newest index timestamp, and unindexed-file count.list_corporaโ list every configured corpus.list_filesโ flat list of relative paths in a corpus.list_treeโ the same files grouped into a directory tree, for progressive disclosure without reading everyindex.md.add_markdownโ write a markdown file under the corpus' first root, atomic and no-symlink-follow, with auto-reindex of just that file. Returns advisory lintwarnings(empty-destination links, empty mermaid blocks, heading-level jumps) without blocking or rewriting the content.read_markdownโ verbatim UTF-8 file contents. Use before overwriting.delete_markdownโ unlink the file and prune its rows from the index.backlinksโ corpus-relative paths of every page that links to a given page via a[[wikilink]].
Markdown content is stored verbatim โ hallouminate imposes no schema.
Convention for LLM wiki authors: one topic per file, first line # Title,
file stem matches the slug.
Config
The config lives at $XDG_CONFIG_HOME/hallouminate/config.toml
(~/.config/hallouminate/config.toml by default).
hallouminate config initโ scaffold a baseline config.hallouminate config showโ print the effective merged config for the current working directory (baseline + repo layer).hallouminate config validateโ parse and flag unknown top-level keys.hallouminate config downloadโ pre-fetch the configured embedding model so the firstindexdoesn't pay the download cost.
Cross-repo union search
ground (and the read/list tools) resolve corpora relative to the caller's
working directory:
- Inside a repo โ the request defaults to that repo's
repo:<name>:wiki. - Above all repos (e.g.
cd ~/Dev) โ agroundcall with no explicitcorpussearches the union of every effective corpus: discovered sub-repo wikis + baseline-registered[[repository]]wikis, plus user-declared[[corpus]]entries and each repository'srepo:<name>:corpussource corpus when configured. The results are merged and re-ranked into one response, and each hit is attributed to its source corpus (file-levelcorpusplus per-chunkprovenance.corpus).
The downward walk is bounded: it honours .gitignore, skips hidden
directories (except .hallouminate itself), caps its depth, and never scans
above the working directory. Walk-discovered wikis are deduped against the
baseline by resolved path; a discovered local config that collides with a
baseline repository of the same name wins, with a cross-repo-union warning
on the response rather than a silent shadow.
Passing an explicit corpus always pins the search to that one corpus,
unchanged. Writes (add_markdown / delete_markdown) still require an
explicit single-root corpus โ the multi-root union is read- and search-only.
How the daemon works
A long-lived local daemon owns the LanceDB ground directory, the repository registry, and per-corpus mutation locks. The CLI and the stdio MCP server are thin clients that talk to it over a Unix domain socket.
- Auto-spawn โ
hallouminate serve,index, andgroundstart a detached daemon automatically when none is listening; there is nothing to start by hand. - Socket resolution order โ
HALLOUMINATE_SOCKET(explicit full-path override; setting it also disables auto-spawn โ the caller owns the daemon lifecycle), else$XDG_RUNTIME_DIR/hallouminate/daemon.sock, else~/.cache/hallouminate/daemon.sock. - Lifecycle โ
hallouminate daemon status/stop/restart; barehallouminate daemonruns it in the foreground. Only one instance per socket can run (flock-guarded). - Version-skew respawn โ after a binary upgrade, the next client pings the running daemon and compares versions; a mismatch stops the stale daemon and spawns a fresh one. No manual restart needed after upgrades.
- Diagnostics โ anything the auto-spawned daemon emits before its logger
is up (panics, early config errors) lands in
~/.local/state/hallouminate/daemon-bootstrap.log($XDG_STATE_HOME). - Process logs โ
$XDG_STATE_HOME/hallouminate/hallouminate.log(default~/.local/state/hallouminate/hallouminate.log) rotates exactly at 10 MiB into numbered archives and retains at most 100 MiB. Configure[logging].max_file_bytes/max_total_bytes, or override them withHALLOUMINATE_LOG_MAX_FILE_BYTES/HALLOUMINATE_LOG_MAX_TOTAL_BYTES.[watch].failure_reminder_secsdefaults to 60 seconds; override it withHALLOUMINATE_WATCH_FAILURE_REMINDER_SECSor set0to disable suppression. - Windows โ the daemon model is Unix-only; see #48.
FAQ
How do I turn embeddings off?
Dense embeddings are on by default, using the
snowflake/snowflake-arctic-embed-s model. On first index hallouminate
downloads that model and fuses its vector signal with lexical search.
To run lexically only โ full-text search + ripgrep + rerank, no embedding
model downloaded (just the tokenizer used for chunking) โ set enabled = false
in ~/.config/hallouminate/config.toml:
[]
= false
Changing the embedding mode (or model) for a ground directory that was already
indexed under a different mode trips the store's mismatch guard on the next
run. Delete the ground directory and re-run hallouminate index to rebuild:
Which embedding models are supported?
Set embeddings.model in your config to one of these (all embed to 384-dim
vectors). Omitting embeddings.model selects the default.
| Model | Notes |
|---|---|
snowflake/snowflake-arctic-embed-s |
Default. English, symmetric retrieval. |
BAAI/bge-small-en-v1.5 |
English, symmetric retrieval. |
intfloat/multilingual-e5-small |
Multilingual, asymmetric retrieval; no quantized variant. |
Skill pack
A cross-harness plugin pack ships in this repo under
plugins/hallouminate: skills for installing
hallouminate and authoring wikis, plus MCP registration for each supported
plugin format. Claude Code and OMP use .claude-plugin/marketplace.json,
Codex uses .agents/plugins/marketplace.json, Copilot CLI uses the payload's
root plugin.json, Cursor uses .cursor-plugin/, and Gemini CLI uses
gemini-extension.json โ see the install matrix.
tests/plugin_manifests.rs pins every manifest to the crate version, and the
release-skills workflow publishes versioned plugin-pack archives on every
v* release tag.
License
MIT โ see LICENSE.