Skip to main content

Agent memory

Your coding assistant forgets everything the moment you close the window. Every session restarts from nothing: the decision you made last Tuesday, the reason you rejected the obvious fix, the name of the service that actually owns that table. You re-explain your own project to it, daily.

The usual answer is to send your context to somebody's cloud. Gnarl's answer is that the memory is a search index on hardware you already own — and because the node is a peer, that memory is shared across your machines without a server in the middle.

gnarl mesh setup --mesh-name my-brain --with-invite
claude mcp add --transport http gnarl-memory http://localhost:8080/mcp

That is the whole setup. Your assistant now has memory_remember and memory_recall, and what it learns on your laptop is recallable from your desktop.

Why a mesh instead of a database​

A single-machine memory is a file. The moment you have two machines it becomes a sync problem, and the usual fix is a hosted service that holds your context.

A Gnarl node is already a peer that replicates claims to other peers, so memory gets the same properties as any other index on the fabric:

  • It follows you. Remember something on the laptop, recall it from the desktop. Same private mesh, no account.
  • It survives a closed lid. With --replicas 2, a peer holds a copy — so recall still works when the machine that learned the fact is asleep.
  • No one is in the middle. Documents are indexed and matched locally. Nothing is uploaded to Lucenia, because there is no Lucenia in the path — no account, no API key, no server of ours to go down or be handed a subpoena.
  • It goes exactly as far as you say. The bullet above is replication, and a copy on a peer is real data on a real other machine. Each index carries a placement: local never leaves this machine, mesh reaches the peers you have admitted, public reaches the open fabric. Agent memory defaults to mesh. For a memory that must never leave the laptop, set that index to local — and accept that closing the lid takes it offline.
  • It spans distance. Two houses, two NATs: the mesh joins over a relay rather than requiring a VPN.

The tools your assistant gets​

Exposed over MCP at http://localhost:8080/mcp, so any MCP client — Claude Code, Cursor, or your own — can use them.

ToolWhat it does
memory_rememberPersist a fact, decision, or preference
memory_recallRetrieve what is relevant to the question at hand
memory_forgetDelete by id or scope (pinned entries survive by default)
memory_rollupFold older entries into a summary so recall stays sharp
memory_drift_checkScore an answer against pinned goals and anchors

Setting it up​

1. Start a node and create your mesh.

gnarl mesh setup --mesh-name my-brain --with-invite

Defaults that matter: private scope, --replicas 2 so one machine can go down, and cloud bootstrap plus relay on, so home NATs still join.

2. Point your assistant at your own node.

gnarl mcp install --client claude # or cursor, or codex

That writes the config and tells you where. It backs the file up first and keeps every other entry in it — ~/.claude.json holds your whole Claude Code configuration, not just MCP servers. Restart the client afterwards.

Use --print to see the block without touching anything:

gnarl mcp install --client codex --print

Codex is always printed rather than written, because merging into a TOML file we do not own would reformat it.

Doing it by hand
claude mcp add --transport http gnarl-memory http://localhost:8080/mcp

Cursor, in ~/.cursor/mcp.json:

{
"mcpServers": {
"gnarl-memory": {
"type": "http",
"url": "http://localhost:8080/mcp"
}
}
}

Each person points at their own localhost node, not someone else's IP. The mesh is what connects them.

The endpoint is always 127.0.0.1. /mcp answers the local machine and nothing else — it is gated on the connecting socket, not on a header — so pointing a second machine at this URL will not work, and is not how you share memory. That is what the mesh in step 3 is for.

3. Add a second machine.

# on the machine that already has the mesh
gnarl mesh invite --mesh-name my-brain --admit-peer <their-node-id>

# on the new machine, with the token you were given
gnarl mesh join --invite 'lucenia1.…'

gnarl status should show peers > 0 on both.

Try it​

Ask your assistant to remember something specific, then start a new session and ask for it back. Then put the first machine to sleep and ask again from the second.

That last step is the one worth doing. It is the difference between a notes file and a fabric.

Honest limits​

  • Recall quality depends on embeddings. The offline default is a hashing embedder, which matches words rather than meaning — paraphrased questions will miss. Configure a real embedder in Console → Settings → Memory embeddings, then rebuild the memory indexes.
  • --mesh-name alone is a partition, not a fortress. For anything you care about, pin node IDs with --admit-peer when you invite.
  • This is early-adopter software. Pre-1.0 and under active development: interfaces can change between releases, so treat memory you would be annoyed to lose as worth snapshotting.

Next​