Skip to content

Add merlin

This guide explains what merlin adds to Anna, what the scaffold expects from it, and where its setup lives.

Anna starts fine without it: on day one the record is a handful of files and grep finds everything. Plan on adding it soon, though. With daily conversations and a few projects going, the record grows faster than you'd think, and recall is the first thing to suffer.

When you'll want it

The record only grows: every day adds a journal entry with real command output, and every project adds runbooks, host notes and lessons. In the deployment Anna came from, with daily use and several projects at once, the journal passed a megabyte in about five weeks, next to 80-odd lessons. At that size, searching by literal words stops working well. These are the signs:

  • she answers "I mentioned before…" or "when did we…" by guessing, or needs several tries to find it;
  • a search for a word pulls up pages of unrelated days;
  • she misses something because you described it in different words than the record does;
  • the always-loaded lessons index (memory/MEMORY.md) is getting long because it's doing the job of a search.

When you notice the first of these, add merlin. It's easier while the record is still small enough to check that the index finds what you expect.

New to this?

merlin is a search engine for your record. It reads the Markdown files, builds an index, and answers questions like "when did we last change the backup schedule?" with the sections that match. It plugs into Claude Code as an MCP server: a small program that gives Claude Code extra tools, here tools named search, history and so on. The files stay the truth: the index is built from them and can always be rebuilt.

What it adds

Without merlin With merlin
The memory engine reads memory/MEMORY.md, greps the record for literal words and reads matching journal days. It searches an index of the whole record, by meaning as well as words, with dates and document types.
The action gate reads hosts/<host>.md before a reboot. It can also ask for a host's history across the journal (host_history).
The morning check has no index to report on. It reports whether the index is fresh (index_status).
Drafts and the stream are redacted with the built-in patterns. They can use merlin's redaction patterns.

It's a separate project

merlin has its own repository, its own install and its own documentation: https://github.com/kaibae19/merlin. The scaffold doesn't install it, start it or index your record. This page covers only what the Anna scaffold does with it.

To set it up, follow merlin's quick start: Docker Compose runs the database, the embedder and merlin on one machine, and you keep the index fresh with a timer. In its .env:

RECORD_DIR=/home/you/anna-record          # the output of: anna-config paths.record
MERLIN_TOML=../examples/anna/merlin.toml  # the layout made for an Anna record

The Anna layout knows the record's folders. Its one requirement: every hosts/<name>.md starts with front matter naming the host (new ones get it from hosts/_template.md; see The record's layout). A first index of a new record takes a few minutes; merlin only indexes committed files, which the wrap-up takes care of.

What the scaffold expects

An MCP server named merlin

Anna refers to merlin's tools by name, mcp__merlin__<tool>, so the server must be registered in Claude Code under the name merlin. The tools the scaffold uses:

Tool Used by
search anna-memory, anna-action-gate (standing permissions in memory lessons)
history anna-memory
host_history anna-memory (mode: host-history), anna-action-gate (what depends on a host before a reboot)
get_document anna-memory (reads the hit it quotes)
list_documents anna-memory
index_status anna-memory (once per question), /anna-morning

Visible to every part of Anna

The permission files already allow merlin, so nothing needs editing once the server is registered:

Part Settings file Entry
headless runs (morning, evening, clock) ~/.claude/anna-headless-settings.json mcp__merlin__*
the bot ~/.claude/anna-tg-<instance>-settings.json mcp__merlin__*
the brain runs with permissions off (no entry needed)
the engines their tools: line in agents/anna-memory.md and agents/anna-action-gate.md listed by name

So the server has to be available to the brain's session, to claude -p runs started by anna-run, and to the bot's session in ~/anna-<instance>. Registering it at Claude Code's user scope does that, since all three run as the same user from different directories.

Register it at user scope (merlin's README, Connecting Claude Code):

claude mcp add --scope user merlin -- \
  docker compose -f ~/merlin/deploy/compose.yaml run --rm -T app python -m merlin.mcp_server

Note

The bot's settings set "disableClaudeAiConnectors": true, which turns off claude.ai connectors in the bot's session. A merlin server you register yourself in Claude Code isn't a claude.ai connector.

Pointed at your record

merlin indexes the folder at paths.record. Print it with:

anna-config paths.record

The record's conventions are written with an index in mind: one ### per topic in the journal (a section is what gets embedded), hosts named the same everywhere, stale runbook sections marked (superseded YYYY-MM-DD: see § X) as their first line rather than deleted (The record's layout).

Optional: merlin's redaction

bin/anna_cfg.py tries from merlin.redact import redact. If that works, the stream and the session drafts are redacted with merlin's patterns; if not, with the built-in ones. It works when merlin is installed as a Python package Anna's scripts can import, or when the environment variable MERLIN_PATH points at a merlin checkout. The scaffold doesn't set MERLIN_PATH anywhere: the hooks run in Claude Code's environment and the timers in systemd's, so set it where both see it if you use it.

Check that it works

In the brain, ask a question about something you know is in the record:

When did we set up the backup check?

The brain should hand it to anna-memory, and the returned block should say index: fresh (merlin answered) rather than index: files (no index) (merlin wasn't available, so it read the files).

The next morning report should also say whether the index is fresh.

Without merlin

Nothing breaks. anna-memory reads the files, anna-action-gate reads host records, the morning check skips the index line, and redaction uses the built-in patterns. /anna-setup suggests adding merlin later, once the record has grown.