hallouminate 0.7.0

A markdown corpus indexer for LLMs to build and query their own per-repo wikis.
Documentation

๐Ÿง€ hallouminate ๐Ÿง€

CI crates.io License: MIT Latest release OpenSSF Scorecard Conventional Commits Agent Skills PRs welcome Buy Me a Coffee

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.

Terminal demo: hallouminate answers a design question from the repository wiki, then shows the underlying markdown files

  • 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:

npm install -g hallouminate   # persistent โ€” puts `hallouminate` on PATH
npx hallouminate --version    # or one-off, no global install

Alternatives that fetch the same prebuilts, in cascade order:

curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/paulnsorensen/hallouminate/releases/latest/download/hallouminate-installer.sh | sh
cargo binstall hallouminate          # same prebuilts, via dist-manifest.json
cargo install hallouminate --locked  # source build โ€” needs Rust + protoc

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.json snippet from the table above
    • Any other MCP client: launch hallouminate serve over stdio โ€” or npx -y hallouminate serve to skip the PATH install entirely (first run pays the binary download)
  • 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

  1. hallouminate config init โ€” scaffold the XDG baseline config.
  2. hallouminate init-repo <name> in your repo โ€” seed .hallouminate/config.toml plus the wiki skeleton; the wiki becomes the repo:<name>:wiki corpus. Identical on every harness.
  3. hallouminate index โ€” build the index (auto-spawns the daemon and downloads the embedding model on first use).
  4. 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:

hallouminate serve

From a source checkout, run subcommands through cargo:

cargo run -- serve                       # stdio MCP server
cargo run -- index                       # bulk (re)index every configured corpus
cargo run -- ground "how does the daemon work"   # CLI semantic search
cargo run -- config show                 # print the effective merged config

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 every index.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 lint warnings (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 first index doesn'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) โ€” a ground call with no explicit corpus searches the union of every effective corpus: discovered sub-repo wikis + baseline-registered [[repository]] wikis, plus user-declared [[corpus]] entries and each repository's repo:<name>:corpus source corpus when configured. The results are merged and re-ranked into one response, and each hit is attributed to its source corpus (file-level corpus plus per-chunk provenance.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, and ground start 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; bare hallouminate daemon runs 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 with HALLOUMINATE_LOG_MAX_FILE_BYTES / HALLOUMINATE_LOG_MAX_TOTAL_BYTES. [watch].failure_reminder_secs defaults to 60 seconds; override it with HALLOUMINATE_WATCH_FAILURE_REMINDER_SECS or set 0 to 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:

[embeddings]
enabled = 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:

rm -rf ~/.local/share/hallouminate/ground
hallouminate index

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.