How to add persistent memory to Claude Code
One npx install line, and Claude Code writes to a persistent memory during a session and reads back what it wrote weeks ago — across restarts, across projects, across machines.
Claude Code is stateless between sessions by default. Every new invocation starts with an empty conversation, an empty CLAUDE.md unless you've written one, and no recollection of the file you asked it to fix last Tuesday. That's fine for one-off tasks. It's frustrating for anyone using it as a daily driver on a real project.
Gnosem fixes this in one line: npx gnosem-install. The installer registers Gnosem as an MCP server in Claude Code's config, prompts for your Gnosem API key, and exits. From that point Claude Code has five persistent memory tools available (memory_write, memory_search, memory_list, memory_forget, memory_supersede) and will call them naturally during a session.
Prereqs
- Claude Code installed. If not: docs.anthropic.com/claude-code.
- A Gnosem API key. Free at gnosem.dev — no credit card, 200-memory free tier.
Nothing else. No Docker, no infra, no separate database to run.
Install
npx gnosem-install
The installer:
- Detects your Claude Code config path (
~/.claude/mcp_servers.jsonor the equivalent OS-specific location). - Prompts for the Gnosem API key (starts with
gn_). - Adds a
gnosementry with the endpointhttps://gnosem.dev/mcpand the Bearer header set to your key. - Prints a success message with the next step.
Restart Claude Code. The five tools appear in the tool list. That's the whole setup — 15 seconds if your API key is already in your clipboard.
If you'd rather do it by hand, the JSON block Gnosem writes is:
{
"mcpServers": {
"gnosem": {
"url": "https://gnosem.dev/mcp",
"headers": {
"Authorization": "Bearer gn_YOUR_KEY_HERE"
}
}
}
}
Same block works verbatim for Claude Desktop, Cursor, Windsurf, and Zed. Same API key across every client. That's the whole point of running memory as a shared MCP endpoint — see Gnosem vs. mem0, Letta, Zep for why that matters.
How Claude Code actually uses it during a session
Once the tools are registered, Claude Code decides when to call them based on its usual tool-use heuristics. In practice, you don't have to say "save this to memory" — the model will call memory_write whenever it encounters something worth remembering, and it will call memory_search whenever a new task looks like it might benefit from prior context. The pattern is the same as how Claude Code decides when to run Grep or Read.
A concrete example. First session — you ask Claude Code to help refactor the auth layer of a Python API:
User: The auth layer here is a mess. Sessions are stored in Redis but the token format is JWT and there's no obvious refresh flow. Can you refactor it so the refresh happens transparently on 401?
Claude Code reads the code, does the refactor across three files, writes tests. Near the end of the session, unprompted, it saves a memory:
memory_write({
content: "Refactored auth layer of api-server (Python/FastAPI).
Uses JWT access tokens + refresh tokens stored in Redis under
key pattern 'refresh:{user_id}'. Access token TTL = 15min,
refresh TTL = 30d. Transparent refresh via 401-catch middleware
in app/middleware/auth.py. Tests in tests/test_auth_refresh.py.",
tags: ["auth", "api-server", "refactor"],
written_by: "claude-code"
})
Note the written_by field. Every Gnosem memory carries provenance about which client wrote it. Useful later when you're auditing your memory to see what each vendor put in.
Two weeks later, new session, different feature:
User: I need to add rate limiting to the same api-server. Users should get 100 req/min free, 1000 req/min if they're paid. Read from Redis too so it survives restarts.
Before writing any code, Claude Code fires:
memory_search({
query: "api-server auth Redis middleware pattern",
k: 5
})
Gnosem returns the auth-refactor memory from two weeks ago, plus whatever other related things you'd saved. Claude Code reads that back, sees the middleware pattern already established for auth, and writes rate-limit middleware that mirrors the same pattern — same file layout, same Redis key convention, same testing style. You didn't have to re-explain any of it.
The tokens saved on this pattern add up fast. A 500-token memory recall replaces a 3,000-token re-explanation and re-exploration of the existing code. Multiply by ten sessions a week.
What Claude Code writes unprompted
From observing sessions, Claude Code tends to save memories in these situations:
- A non-obvious architectural decision it made ("chose to use X because Y").
- A configuration choice the user explicitly requested ("user wants tabs, not spaces").
- The location of an important file or a naming convention it discovered.
- A workaround for a bug or platform quirk.
- Any explicit user statement of preference or intent ("we're using Postgres 16", "this is a monorepo").
It rarely saves memories about routine work (a normal file edit, a passing test) because those don't have re-use value. This is emergent from the tool descriptions — Gnosem's memory_write description explicitly says "save things worth remembering later," not "log everything."
You can also write memories directly
You don't have to wait for the model to decide. You can just tell it:
User: Remember that our team uses conventional commits, and we always squash-merge PRs.
Claude Code will fire a memory_write with that content. From then on, any Claude Code session on any machine (as long as the API key is the same) knows to write commits in the conventional-commits style, and to reach for git merge --squash rather than a plain merge. This is the practical use case that pulls the most weight for teams: policies and conventions that would otherwise live in a wiki nobody reads.
The cross-vendor payoff
The magic isn't Claude Code alone — CLAUDE.md already handles single-tool project memory pretty well. The magic is that the memory carries over when you switch tools.
Open Cursor next week to write some UI. Cursor with the same Gnosem API key sees the same memories Claude Code wrote. When you say "add a new endpoint following our conventions," Cursor's model fires memory_search and finds the auth pattern, the rate-limit pattern, the commit convention — all of it. No re-onboarding.
Open ChatGPT via a Custom GPT Action pointed at Gnosem's REST endpoint (planned). Same thing. Open a fresh Windsurf install after switching laptops. Same thing.
Managing and inspecting
From inside a Claude Code session you can list what's there:
User: What have you been remembering about this project?
Claude Code will call memory_list and summarize. You can also ask it to forget things:
User: Forget the memory about that Redis pattern — we switched to Valkey.
It'll find the memory with memory_search, then call memory_forget with the id. Or use memory_supersede to replace rather than delete — the old row is marked superseded (excluded from future reads) and the new content becomes current, preserving audit trail.
You can also inspect and manage memories from the web dashboard at gnosem.dev — full list view, tag filtering, and manual delete.
If you run your own Gnosem
The source is MIT. If you'd rather point Claude Code at your own Gnosem deployment on your own Cloudflare account, replace https://gnosem.dev/mcp with your Worker's URL in the config block above. Everything else works the same because it's the same server code. See Building an MCP Server on Cloudflare Workers for the architecture notes.
Try npx gnosem-install and open Claude Code. Ask it something project-specific. Come back tomorrow and ask a related question. The second time should feel meaningfully less like starting from zero. That's the feature.