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:
localnever leaves this machine,meshreaches the peers you have admitted,publicreaches the open fabric. Agent memory defaults tomesh. For a memory that must never leave the laptop, set that index tolocal— 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.
| Tool | What it does |
|---|---|
memory_remember | Persist a fact, decision, or preference |
memory_recall | Retrieve what is relevant to the question at hand |
memory_forget | Delete by id or scope (pinned entries survive by default) |
memory_rollup | Fold older entries into a summary so recall stays sharp |
memory_drift_check | Score 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-namealone is a partition, not a fortress. For anything you care about, pin node IDs with--admit-peerwhen 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
- Install a node
- Architecture — how a query executes with no coordinator
- Trust and verification — identity, signatures, and policy