Skip to content

MCP surface

hallouminate serve starts a stdio MCP server. It is stateless beyond its tool router and a startup-captured working directory; every tool call dials the local daemon over a Unix domain socket, and serve auto-spawns the daemon if none is up.

Read-side tools (ground, list_files, list_tree, backlinks, corpus_stats) that omit corpus default to the wiki for the repository containing the daemon’s working directory — repo:<NAME>:wiki for the deepest [[repository]] whose path is an ancestor of the cwd. When the cwd sits under no configured repo, the caller must name a corpus explicitly.

The mutating tools (add_markdown, delete_markdown) and read_markdown always require an explicit corpus, to avoid accidental writes to the wrong wiki or ambiguous reads.

Every corpus the daemon knows about — explicit [[corpus]] entries plus derived repo:NAME:wiki and repo:NAME:corpus corpora. No params. Call this first to learn what’s available.

The files currently visible in a corpus, honoring its paths/globs/exclude rules. Param: corpus (defaults to wiki-for-cwd). Returns an array of {path, absolute_path}.

The same files as list_files, grouped into a {path, absolute_path, files, subdirs} tree. Subdirs with no markdown beneath them are pruned. Use this for progressive disclosure — navigate the wiki without reading every index.md first. Param: corpus (defaults to wiki-for-cwd).

Semantic search. Embeds the query with the configured embedding model (default snowflake/snowflake-arctic-embed-s), retrieves top chunks from LanceDB, and rolls up per-file with breadcrumb context. Params: query (required), corpus, top_files, chunks_per_file, limit, snippet_chars. Returns a ripgrep-style outline in content and the full structured response in structuredContent.docs.

Atomic-write a markdown file to the corpus’ first configured root, then refresh just that file’s LanceDB rows. For repo:*:wiki corpora it also rebuilds the link list inside each ancestor index.md between the <!-- HALLOUMINATE:INDEX-START --> / <!-- HALLOUMINATE:INDEX-END --> markers — scaffolding a missing index.md, preserving prose outside the markers, and leaving marker-less files alone. Params: corpus, path, content, overwrite (default false). Symlinks and parent-dir escapes are rejected by the sandbox. Returns advisory lint warnings (empty-destination links, empty mermaid blocks, heading-level jumps) without blocking the write.

Verbatim UTF-8 contents of a file in a corpus. Params: corpus, path. Use this before add_markdown { overwrite: true } to inspect current content.

Unlink a file from the corpus’ first root and prune its rows from the index. Irreversible. For repo:*:wiki corpora it also re-walks the ancestor index.mds so they no longer link to the deleted file. Params: corpus, path.

Bulk (re)build the LanceDB index for one or all corpora. Param: corpus (optional; omit to rebuild every configured corpus). Use this when files were touched outside hallouminate.

Index health statistics for one corpus: number of indexed files, total chunk row count, newest index timestamp (last_indexed_ms, null when the corpus has never been indexed), and how many on-disk files matching the corpus globs are not yet indexed. Param: corpus (defaults to wiki-for-cwd, same resolution as list_files). structuredContent is { corpus, indexed_files, total_chunks, last_indexed_ms, unindexed_files }.

Corpus-relative paths of every page that links to the given page via a [[wikilink]]. Params: corpus (defaults to wiki-for-cwd, same as ground), path (the target page’s relative path). structuredContent is { corpus, path, backlinks }; content is a newline-joined list of backlink paths, or a message noting there are none. Use this to find which pages reference a page before renaming or deleting it.

Markdown is stored verbatim — hallouminate imposes no schema. The convention the indexer counts on:

  • One topic per file. The chunker splits on H1/H2/H3 headings.
  • First non-blank line is # Title. The H1 is the breadcrumb root for every chunk and the gloss in the parent index.md link list.
  • File stem matches the slug — lowercase, kebab-case, .md.
  • Idempotent writes — add_markdown rejects existing files unless overwrite: true; read_markdown first so you don’t clobber blind.
Daemon variant JSON-RPC code Meaning
InvalidParams -32602 Caller input failures (bad corpus name, unsafe path, missing arg).
Internal -32603 Server / transport faults, including “daemon unavailable”.

When the daemon is unreachable, calls return -32603 — the MCP server does not fall back to opening a local LanceDB handle, since that’s exactly the multi-process race the daemon exists to prevent.