RE-call Setup

Working with Claude

Give Claude your memory, and the rules for using it.


You already registered the server in step 7 of the install guide. This page is the part that step could not hold: every tool the server exposes, the instructions that decide whether Claude ever calls them, and the boundaries that stop it writing where it should not.

01

What actually changes

Two things, and it is worth being precise about both, because the gap between what people expect here and what the server does is where the disappointment usually lives.

Claude checks what you already decided before it answers. When you propose something you have proposed before, it can call recall_search, find the note where you settled the question, and tell you it is settled instead of cheerfully designing it again.

Claude writes new facts back. When a decision gets made in a session, it can write a small markdown file into memory/ and index it, so the next session starts knowing it. Your memory grows as a by product of working, rather than as a chore you keep meaning to do.

What it is not

Registering the server does not change how Claude thinks. It adds tools to a list. A tool that nothing tells Claude to call is a tool Claude will mostly not call, which is why the CLAUDE.md block matters more than the registration does. Everything on this page assumes both are in place.

Three more expectations worth setting honestly before you go further.

  • Memory contains what you indexed, and nothing else. There is no background crawl of your repository, your chat history, or your files.
  • The server runs no generator. recall_evidence hands back passages plus the exact prompt to answer with, and Claude is the one that writes the answer. That separation is deliberate: the thing that retrieves is not the thing that speaks.
  • An abstention is an answer. If memory has nothing that clears the confidence threshold, the honest output is "I do not know", and both the tool and the instructions treat it that way.
02

Wiring it up

The server ships in an optional extra. Install it alongside the embedder you already use, then register it one of two ways.

python -m pip install "recall-rag[fastembed,mcp]"

Method one: the CLI

One command, registered against your Claude Code installation.

claude mcp add recall -- python -m recall_mcp.server

Method two: a file in the project

Save this as .mcp.json in your project root, next to the .env the wizard wrote. I recommend this one, because it carries the environment explicitly: the connection string and the trust mode are visible in the file rather than inherited from wherever the command happened to be run.

.mcp.json
{
  "mcpServers": {
    "recall": {
      "command": "python",
      "args": ["-m", "recall_mcp.server"],
      "env": {
        "RECALL_SERVING_DSN": "postgresql://recall:recall@localhost:5432/recall",
        "RECALL_TENANT": "default",
        "RECALL_TRUST_MODE": "development"
      }
    }
  }
}

The server does not read your .env

This is the single most common reason a correctly installed server behaves as though nothing is configured. Claude Code launches the process itself, and the only settings it receives are the ones in the env block above. Every value you want the server to have has to be repeated there, including RECALL_SERVING_DSN and RECALL_TRUST_MODE.

On macOS and Linux, change "command": "python" to "python3".

The module path is exact

python -m recall_mcp does not work. It has to be python -m recall_mcp.server. The installed recall-mcp console script is the same entry point, so use it if you prefer a shorter command.

Claude Desktop

Same JSON block, different file. Claude Desktop reads claude_desktop_config.json, and it only picks up changes on a restart.

PlatformWhere the file livesAfter editing
Windows %APPDATA%\Claude\claude_desktop_config.json Quit Claude Desktop completely and start it again.
macOS ~/Library/Application Support/Claude/claude_desktop_config.json Quit Claude Desktop completely and start it again.
Why the server always reads the table named chunks

The stdio server opens the default chunks table and takes no table flag. That is a deliberate narrowing: a server that could be pointed at any table would need the client to be trusted to name one, and the client here is a language model.

The consequence is worth knowing before you debug it. If you indexed a demo corpus into a named table from the CLI, the server will not see those rows, and searches will come back empty with nothing obviously wrong. Index into the default table, or into the tenant you set in RECALL_TENANT, and the rows appear.

Server not appearing after all this? Claude Code problems.

03

The ten tools

The server registers ten tools. Four of them are the ones you will see used daily, one is destructive, and five belong to the reasoning and rewrite layer, which is opt in and which most installations never touch.

Everyday

ToolWhat it doesWhen Claude should call it
recall_search Searches memory and returns hits carrying a trust verdict and a calibrated confidence, plus an abstained flag and an advice field stating what to do with the result. Before proposing an idea, forming a hypothesis, or repeating past work. This is the consult step, not the answer step.
recall_evidence Builds a citable evidence bundle from passages the trust layer cleared, and returns a system prompt and a user message alongside them. The client generates the answer. When about to answer from memory rather than merely check it. Every citation must be a chunk_id from the bundle.
recall_index Adds a markdown file or folder to memory. Confined to RECALL_INDEX_ROOT, which defaults to the server's working directory. Indexing a file again replaces its chunks rather than duplicating them. After writing a durable fact into memory/, so the new file is searchable from the next turn.
recall_stats Reports memory freshness and size: how many chunks exist, when the newest was indexed, and whether the index has gone stale. When you want to know whether memory is actually populated, or whether it has stopped being fed.

Destructive

ToolWhat it doesBefore you allow it
recall_forget Permanently deletes indexed memory for the source values you name. Requires the recall:forget scope. Irreversible. Read the boundaries section. There is no undo, and a source that did not match comes back in sources_not_found rather than being silently counted as removed.

Reasoning and rewrite

Additive and opt in. recall_search and recall_evidence behave identically whether or not you ever use these.

ToolWhat it doesWhen it earns its place
recall_reasoning_query Runs a bounded reasoning query over trusted retrieval, obeying the configured policy and budget, and returns cited output, review state, a clarification, or an abstention. When a question needs more than one hop across memory and you still want the trust layer in front of it.
recall_reasoning_projection Inspects the generation bound reasoning graph projection without answering anything. When you want to see what structure was derived from your corpus, rather than a conclusion drawn from it.
recall_reasoning_proposals Lists inference proposals as review candidates. They are candidates, never trusted memory. When reviewing what the layer thinks might be true, before any human decides whether it is.
recall_rewrite_plan Plans a corpus rewrite: which key a proposal would declare, and in which file. It writes nothing. Before a human applies the change themselves. There is no apply tool on this surface, and that omission is the design.
recall_reasoning_audit Audits reasoning integration state and returns diagnostics. Before relying on any of the four tools above, to confirm the layer is actually wired and healthy.
Why there is no rewrite apply tool

Applying a rewrite requires a reviewer identity and an audit note. If the MCP surface accepted those, the model would supply them, and the human gate would become a field the model fills in rather than a person who decided. The plan is available to the agent; the apply lives at recall rewrite apply, where a person runs it.

04

The CLAUDE.md block

If you answered yes to the scaffolding question in the wizard, this block is already in your CLAUDE.md, between two HTML comment markers. It is what turns ten available tools into a habit.

CLAUDE.md
<!-- recall setup begin -->
## Using recall

This project is indexed by recall. Call `recall_search` before proposing an idea, forming a hypothesis, or repeating past work. If a closed decision or falsified hypothesis surfaces, do not re-litigate it.

- When `abstained` is true, no hit survived the trust gate (or `decision: abstain` from `recall_evidence`) — say you do not know instead of answering from degraded hits.
- Use `recall_evidence` instead of `recall_search` when about to answer from memory rather than just consult it; cite only `chunk_id` values from its `items`.
- Write new durable facts to `memory/`, one file per fact, indexed by `memory/MEMORY.md` (see that file for the format), then call `recall_index` on `memory/` so the new file and the updated index both become searchable.
<!-- recall setup end -->

That is the wizard's text as written, punctuation included.

Four instructions, and each one buys you something specific.

The instructionWhat it buys you
Call recall_search first Without it, Claude answers from the conversation in front of it and from what the model already knows. Neither of those contains last month's decision. This line is the difference between a memory that exists and a memory that is used.
Respect abstained A model that reads "no confident hit" as an obstacle will route around it, and the routing produces a fluent guess. This line says the abstention is the answer. It is the instruction that protects everything the trust layer does.
Use recall_evidence when answering It admits only passages the trust layer cleared, and it hands back the citations. You get an answer whose sources you can open, instead of a paraphrase whose origin you have to take on faith.
Write durable facts to memory/ This is what makes the corpus grow without you maintaining it by hand. One file per fact, listed in memory/MEMORY.md, then indexed so the next session can find it.

Extend outside the markers, not inside

Re-running recall setup replaces everything between <!-- recall setup begin --> and <!-- recall setup end -->, and leaves the rest of CLAUDE.md untouched. Anything you write inside the markers is lost on the next run. Put your own rules in their own section above or below the block.

Rules worth adding yourself

The scaffolded block is deliberately minimal, because it has to be right for every project. In my own CLAUDE.md I add three things outside the markers. First, a rule that a fact only goes into memory/ once it is settled, so sessions do not fill the corpus with half decided thinking. Second, an instruction to name the file after the decision rather than the date, because a search matches on meaning and a date carries none. Third, a note that a corrected fact should supersede the old file rather than sit beside it, since two files disagreeing is worse than neither existing.

The memory page covers what makes a file worth indexing in more detail.

05

The self recall loop

Four moves, repeated. Search before answering, respect an abstention, write the durable fact back, index it. The whole product is that loop closing.

One. Search before answering. You propose something. Claude calls recall_search before it responds, and memory returns what you already concluded.

A hit that settles the question

Output
recall_search("raise the public API rate limit to 500/min")
  abstained: false
  ok    conf=0.84  rate-limits.md  'Clients may issue 100 requests per minute...'
  advice: a prior decision covers this; do not reopen it without new evidence

Two. Respect an abstention. Ask something memory does not cover and the tool says so, plainly, instead of returning the nearest paragraph.

An abstention

Output
recall_search("what did we conclude about the refund window?")
  abstained: true
  reason: no hit above the calibrated confidence threshold (probable corpus gap)

This is the part that matters

Everything else in RE-call exists to make the abstention trustworthy, so an agent that works around it throws away the entire mechanism. The failure is subtle because it is invisible from the outside: a model that treats "no confident hit" as a hurdle produces an answer that reads exactly like a well sourced one, in the same voice, with the same confidence, and nothing in the transcript marks it as invented. A memory you cannot distinguish from a guess is worse than no memory, because you stopped checking.

There is a second, sharper version of the same mistake. An abstention means the gate ran and found nothing worth standing behind. A trust refusal means the gate could not run at all: the database is down, the index is not ready, the calibration is missing. Read the second as the first and the agent concludes there is no prior memory, then confidently reopens a question that was in fact settled. They must not be collapsed into one.

Three. Write the durable fact back. Once something is actually decided, it goes into memory/ as its own file, with the frontmatter the starter index documents, and a line added to memory/MEMORY.md.

memory/refund-window.md
---
name: refund-window
description: How long a customer has to request a refund.
metadata:
  type: project
---

Refunds may be requested within 30 days of purchase. Agreed
14 August 2026. Support asked for 60; finance would not carry
the liability, and 30 matches what the terms page already said.

Four. Index it. Claude can do this itself by calling recall_index on memory/. You can do the same from your own terminal, and it is worth knowing the command for the times a session ends before the tool runs.

python -m recall.cli index memory/

Indexing a file again replaces its chunks rather than adding a second copy, so running this after every edit is safe and is the habit to build.

Why the wizard's auto index ignores your tenant and table flags

The auto index step the wizard runs at the end of recall setup always writes to table chunks and tenant default, even when you passed different values on the command line. If your project uses a non default tenant or table, those rows will not appear in that tenant's searches, and you should index memory/ yourself against the right one instead.

The same step is skipped entirely under RECALL_ENV=production, where indexing from the local filesystem is not a thing the server should be doing at all. There, memory is built by your deployment pipeline.

06

Safety boundaries

You have handed a language model a tool that writes to a database and a tool that deletes from one. Three things bound what it can do with them.

RECALL_INDEX_ROOT

This is the boundary that stops the agent indexing arbitrary paths. recall_index may only read inside it, and it defaults to the server's working directory. Ask the agent to index your home folder, or a colleague's project, or a directory of credentials, and the request is refused before anything is read.

The default is reasonable and most people leave it. Setting it explicitly is better, because then the bound is a decision you made rather than a side effect of where Claude Code happened to start. Add it to the env block in .mcp.json.

.mcp.json
"env": {
  "RECALL_SERVING_DSN": "postgresql://recall:recall@localhost:5432/recall",
  "RECALL_TENANT": "default",
  "RECALL_TRUST_MODE": "development",
  "RECALL_INDEX_ROOT": "C:/Users/you/project/memory"
}

A request that exceeds the configured file count or byte ceiling is also refused, before anything is embedded, so a pointed instruction cannot quietly run up a large indexing job.

The recall:forget scope

recall_forget requires the recall:forget scope, and deletion is confined to the server's own tenant: it cannot reach another tenant's memory. On an authenticated transport, that scope is the gate, and a caller that does not hold it is denied before the request touches the store.

Deletion is permanent

recall_forget is irreversible

There is no undo, no trash, and no snapshot the tool restores from. It is the right to erasure path, which is exactly what you want when something was indexed that should never have been retained, and exactly what you do not want fired off casually by an agent tidying up.

Check sources_not_found in the response before believing a name was actually forgotten. A source that did not match is reported there rather than counted as removed, so a typo produces a clear "that did not exist" instead of a false confirmation.

My own rule: recall_forget is a tool I run myself, from my own terminal, on sources I have first confirmed with a search. It is available to the agent because right to erasure has to be reachable, not because it is a routine part of the loop.

07

Verifying it works

Start Claude Code in the folder holding your .mcp.json, then run /mcp. You are looking for a server named recall, connected, offering the tools from section three.

Outside Claude, this lists what is registered and whether each server starts.

claude mcp list

You should see

Output
recall: python -m recall_mcp.server (stdio) • connected

Then ask Claude a question you know your memory answers, and watch it call recall_search before it replies. If it answers without calling anything, the server is fine and the CLAUDE.md block is what is missing.

The other useful check is to run the server yourself. It is a stdio server, so it starts and then waits silently for input, which is success. What you are looking for is the absence of a traceback in the first second.

python -m recall_mcp.server

When the server does not appear

What you seeWhat it usually is
No recall server listed at all Claude Code was started somewhere other than the folder holding .mcp.json, or the JSON has a syntax error. A trailing comma is enough to make the whole file ignored.
Listed, but it fails to start The mcp extra is not installed in the interpreter being launched, or the module path is wrong. It is recall_mcp.server, never recall_mcp.
python: command not found On macOS and Linux the command field has to be python3.
Connected, but every call errors The database is not running, or RECALL_SERVING_DSN is missing from the env block. Remember that the .env file is not read here.
Connected, searches always empty Your rows are in a different table or tenant. The server reads table chunks and the tenant named in RECALL_TENANT.
Every result flagged uncertified Expected while RECALL_TRUST_MODE=development is set and no calibration has been published. Measure a threshold and the flag goes away.
It refuses rather than answering Strict mode with no certified calibration for the tenant. Either publish one, or set RECALL_TRUST_MODE=development for local work.

Still stuck? Claude Code problems goes through each of these with the exact error text.

Further reading