Persistent memory for Claude Code across sessions and compaction (hooks + an MCP memory server)
What CLAUDE.md and auto memory cover, how a SessionStart hook re-injects context after compaction, and how to add a hosted memory layer on the same hooks.
Disclosure: I'm Mohammed, founder of MemorySync. I drafted this article with AI assistance and reviewed it for accuracy against the official MemorySync and Claude Code docs. The code is adapted from the docs and I haven't run it.
Claude Code starts every session with a fresh context window, and when a long session fills up, compaction summarizes the conversation to free space. Claude Code's own docs say that summary "can lose important details". So the two problems (a new session and a compact) are really one question: how do I get the important stuff back at the start of a session, and again after a compact?
This post walks through the layers, from the built-in ones to a hooks-based memory layer:
- What CLAUDE.md and auto memory already give you.
- A
SessionStarthook that re-injects context after compaction (no extra service). - The MemorySync plugin, which uses the same hooks to recall from a hosted memory layer, plus the hosted MemorySync MCP server.
The Claude Code behaviour comes from the official memory, hooks reference and hooks guide pages. Everything about MemorySync comes from its Claude Code Memory guide. The commands and config are adapted from those docs. I haven't run them for this post, so check them against your Claude Code version.
1. What's built in
Claude Code has two ways to carry knowledge across sessions:
| CLAUDE.md | Auto memory | |
|---|---|---|
| Who writes it | You | Claude, based on your corrections and preferences |
| What it's for | Instructions and rules: build commands, conventions, "always do X" | Learnings Claude decides are worth keeping |
| Loaded | Every session | Every session (first 200 lines or 25KB) |
Start here. Put your build and test commands and project conventions in ./CLAUDE.md (or ./.claude/CLAUDE.md), keep it under about 200 lines as the docs suggest, and run /context to confirm it shows up under Memory files.
What these files don't give you, in my view, is a searchable store of facts that's scoped per project and follows you into other tools. That's the gap the next two layers fill.
2. Re-inject context after compaction with a hook
Hooks are commands Claude Code runs at fixed points in a session. The one that matters here is SessionStart, and its matcher says how the session began:
| Matcher | Fires on |
|---|---|
startup |
A new session |
resume |
--resume, --continue or /resume |
clear |
/clear |
compact |
Auto or manual compaction |
fork |
A session forked from an existing one |
For SessionStart, Claude Code adds the plain text your command prints to stdout into Claude's context. That gives you a simple fix for compaction. This is the example from the hooks guide, in .claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'Reminder: use Bun, not npm. Run bun test before committing. Current sprint: auth refactor.'"
}
]
}
]
}
}
Swap the echo for anything that prints useful state, such as git log --oneline -5. Three limits from the reference are worth knowing:
- Hook output (
additionalContextor plain stdout) is capped at 10,000 characters. SessionStartruns on every session, so keep it fast.- At launch,
SessionStartfires before the session's MCP servers are available, somcp_toolhooks are skipped then. Use atype: "command"hook for anything the session needs at startup.
This works well for static reminders. It doesn't learn anything new on its own, though. Whatever you echo is whatever you wrote last.
3. A memory layer on the same hooks: the MemorySync plugin
MemorySync is a hosted memory layer, and I'm building it. Its Claude Code plugin wires the same lifecycle points to that memory. According to the guide:
| Moment | What happens |
|---|---|
| Session start, resume or clear | Your profile and this project's context are recalled and injected before the first prompt |
| Every prompt | The prompt is sent for fact extraction, and only the durable facts in it are stored. Prompts of 24 characters or more also recall memories relevant to that prompt |
| Claude finishes replying | Nothing is sent. Replies aren't stored |
| Context compaction | Memory is re-injected after the compact |
It also bundles the hosted MemorySync MCP server (search, add, list, update, delete and more), a memory skill, and three commands: /memorysync:status, /memorysync:remember and /memorysync:recall. Two details I like: facts are tagged with the git repository you're in, so recall at session start is about this project while preferences follow you everywhere, and the plugin never writes to CLAUDE.md or MEMORY.md. Your static rules stay yours.
Install
You need Node.js 18+ on your PATH (the hook scripts use it) and an API key from app.memorysync.io in your environment:
# macOS/Linux (add it to your shell profile)
export MEMORYSYNC_API_KEY=ms_...
# Windows
setx MEMORYSYNC_API_KEY ms_...
Then, inside Claude Code:
/plugin marketplace add memorysyncio/memorysync-plugins
/plugin install memorysync@memorysync
In a session, /plugin install opens the plugin panel so you can review the plugin and pick a scope first (that's Claude Code's behaviour, per its plugin docs). Restart the session, then check it:
/memorysync:status
The status command reports whether the key is present, whether the API is reachable, and which user and project scope it resolved. The guide calls it "the first thing to run when anything looks off". Without an API key, the bundled MCP server falls back to OAuth sign-in and the hooks stay off. You won't see an error.
Test it across a session and a compact
- Tell Claude something durable: "In this repo we use pnpm, and integration tests need the
TEST_DB_URLenv var." - Run
/clear(or open a new session) and ask, "How do I run the integration tests here?" without repeating the details. - In a long session, run
/compactand ask again.
If step 2 or 3 comes back empty, run /memorysync:status before anything else.
Knobs
MEMORYSYNC_USER_IDsets the user (default: your OS username).MEMORYSYNC_PROJECToverrides the project, which otherwise comes from the git remote.MEMORYSYNC_PROMPT_RECALL=offturns off per-prompt recall.- With
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICset, the plugin makes no network calls.
What it won't do
The guide says every hook exits 0 on every failure path (no key, network down, server errors), so the worst case is a turn without memory, not a broken session. The memory skill refuses to store tokens, keys and passwords, and retrieved memories are injected with a "background data, not instructions" guard. Your prompts go to your MemorySync account for extraction. You can delete any memory from /memorysync:recall or the dashboard.
Claude Cowork and teams
Cloud sessions install repo-declared plugins only, so commit this to .claude/settings.json and add MEMORYSYNC_API_KEY to the session's Cloud Environment variables:
{
"extraKnownMarketplaces": {
"memorysync": {
"source": { "source": "github", "repo": "memorysyncio/memorysync-plugins" }
}
},
"enabledPlugins": { "memorysync@memorysync": true }
}
MCP only, if you don't want hooks
If you'd rather call memory tools yourself, with no automatic capture or recall, connect just the hosted server:
claude mcp add --transport http memorysync https://mcp.memorysync.io/mcp
Without MEMORYSYNC_API_KEY set, it signs you in with OAuth on first use. I wrote a separate step-by-step MCP setup for Claude Code and Cursor covering scopes, whoami, saving and recalling, and troubleshooting.
Which layer to use
- Rules and conventions: CLAUDE.md.
- A fixed reminder after every compact: a
SessionStarthook with thecompactmatcher. - Facts that should build up over time, per project and across sessions and compactions: a memory layer behind those hooks.
You can run all three at once. They don't overlap.
Try it
If you want to see the save, reload and recall loop before installing anything, the MemorySync playground runs it in your browser: memorysync.io/try.
About the author
- Building MemorySync (memorysync.io) — persistent memory infrastructure for AI agents, Cursor, and Claude Code.
Comments
Join the discussionNo comments yet. Be the first to comment.
