notefeed
All notes

trilium-recall: Claude remembers what you wrote in Trilium

If you connect Claude (or any AI assistant) to Trilium, it can search your notes. But it rarely does that on its own. Before starting a task, a model doesn't stop to ask "do my notes already know something about this?", because it doesn't know what it doesn't know. So it works out again things you already wrote down, or gets them wrong.

trilium-recall fixes that. It's a small container next to Trilium that indexes your notes and hands the assistant the few lines that matter. It runs as a plain MCP server, so any client can use it.

What it does#

  • Indexes all your text and code notes, with keyword search plus a multilingual embedding model. It handles German and English, so a German note answers an English question. It only reads Trilium through ETAPI, and you can delete its index and rebuild it at any time.
  • Is just an MCP server. Add one URL to claude.ai, Claude Code or any other MCP client and you're done: there's no plugin and nothing to install on the client. The server's instructions tell the model when to call recall. Each call returns up to three short passages with note IDs, or nothing.
  • Optional: runs automatically in Claude Code. A plugin adds a prompt hook that checks every prompt before Claude sees it. When your notes hold something relevant, Claude starts with it in the context. When they don't, nothing is added.

In numbers#

Measured on my own Trilium (280 notes, 49 test questions); yours will differ:

  • > 85 % of questions get the right note among the first three. Trilium's built-in search manages around 40 %, because it needs every word of the question in the note.
  • > 90 % of questions the notes can't answer get nothing back, instead of three weak guesses.
  • < 20 ms per lookup, typically.

Charts and the full comparison are on the Measurements page. The repo includes a public test Trilium, so anyone can reproduce the test numbers.

Running it#

It's one compose service next to Trilium, plus an ETAPI token and a password:

  trilium-recall:
    image: ghcr.io/marceltov/trilium-recall:latest
    restart: unless-stopped
    environment:
      RECALL_LOGIN_PASSWORD: ${RECALL_LOGIN_PASSWORD}   # openssl rand -hex 32
      RECALL_BASE_URL: https://recall.example.org       # public URL; turns on the OAuth login
      RECALL_INSTANCES: main
      TRILIUM_MAIN_URL: http://trilium:8080
      TRILIUM_MAIN_TOKEN: ${RECALL_ETAPI_TOKEN}
    volumes:
      - recall-index:/data
    ports:
      - "8082:8082"

Then add https://recall.example.org/mcp to your MCP client and log in once, or send the password as an Authorization: Bearer header. In Claude Code, for all your projects:

claude mcp add --transport http trilium-recall https://recall.example.org/mcp -s user
# then /mcp → Authenticate, and log in with RECALL_LOGIN_PASSWORD

On claude.ai, go to Customize → Connectors → Add custom connector and use the same URL. That's the whole setup.

Optional: if you use Claude Code and want recall on every prompt, without the model deciding when to look:

/plugin marketplace add Marceltov/trilium-recall
/plugin install trilium-recall

Details: how it works, run the engine, connect Claude.

It started inside my LLM wiki and understands its structure when there is one, but it works on any Trilium. An embedding model inside Trilium itself seems unlikely given Trilium's contribution rules (everything must work offline, and the bundle should stay small), so a separate container felt like the right place.

It's licensed AGPL-3.0-or-later. Feedback is welcome, and I'd love to hear how it does on other people's notes: the docs show how to measure your own.


Discussion on GitHub: TriliumNext discussion #12316.

Report