← Back to blog

Claude Code remembers your project. It doesn't remember you.

claude-codememorymcptutorial

Claude Code has a memory system. It writes notes to itself automatically (build commands, debugging patterns, coding preferences) and loads them at the start of every session.

It's genuinely useful. And it has one fundamental limitation: every git repository gets its own isolated memory. What Claude learns in Project A stays in Project A.

That means every personal preference you've taught Claude has to be re-taught from scratch in every new project. Your commit message style, your preferred patterns, the tools you never want it to suggest.

You probably do this without thinking about it. A few corrections per session. A line added to CLAUDE.md. It accumulates. Then you start a new project and it's gone.


What Claude Code's memory actually looks like

Claude Code stores memory in ~/.claude/projects/<path-hash>/memory/. The path hash is derived from the absolute filesystem path of your project. Two different projects = two different directories = zero sharing between them.

You can see your current project's memory by running /memory inside a session. It opens a folder that looks something like this:

~/.claude/projects/-Users-you-code-my-app/memory/
├── MEMORY.md          # index, loaded at every session start (first 200 lines)
├── debugging.md       # notes on debugging patterns
└── api-conventions.md # API design decisions

This structure is per-repo. It doesn't follow you. It doesn't cross project boundaries. If you work on 10 repositories, you have 10 separate memory silos.


The re-teaching problem

Here's what this looks like in practice. You teach Claude something in one project:

You: "Don't add Co-Authored-By to commit messages unless I ask."

Claude: Got it, I'll leave that out by default.
[saves to ~/.claude/projects/-Users-you-code-project-a/memory/]

Three weeks later, new project:

You: "Write a commit message for this."

Claude: feat: add user authentication

Co-Authored-By: Claude <claude@anthropic.com>

You: "Don't add Co-Authored-By."

You've had this exact conversation before. Claude hasn't.

This isn't a bug. It's by design: project memory is project-specific. The design makes sense for project knowledge. The architecture of Project A shouldn't bleed into Project B. But it breaks down for personal preferences that should follow you everywhere, not stay locked to a repository.


What's missing: a user scope

Claude Code's memory is all project-scoped. There's no concept of "this preference belongs to me, not to this codebase."

That's the gap. The things you'd want to persist across all your projects:

  • Commit message conventions ("no Co-Authored-By", "conventional commits always")
  • Tool preferences ("use pnpm, not npm", "never suggest Prettier, I use dprint")
  • Output style ("show me the diff before writing files", "explain your reasoning first")
  • Anti-patterns you've learned ("don't use this pattern in React, it breaks on re-renders")

None of these belong to a specific project. They belong to you. But there's nowhere in Claude Code's native memory system to put them.

The workaround most people land on is ~/.claude/CLAUDE.md. This global file is loaded in every session. But it's static. You write it, Claude reads it, that's it. Claude can't update it based on corrections you give mid-session, can't prune things that are no longer relevant, can't search it semantically. It's a config file, not a memory layer.


Fixing it with db0

db0 is an MCP server that adds a structured memory layer to Claude Code. One of its four memory scopes, user, is exactly what's missing: facts that persist across all projects, for all sessions, tied to you rather than to a codebase.

When Claude writes a memory with scope: "user", it goes into a single database that's shared across every project. Every session in any directory can read it.

Install

# Available in all your projects, all sessions
claude mcp add --scope user --transport stdio db0 -- npx -y @db0-ai/claude-code

Or project-level, committed to git and shared with your team:

claude mcp add --scope project --transport stdio db0 -- npx -y @db0-ai/claude-code \
  -e DB0_STORAGE=.db0/memory.sqlite

Commit .mcp.json; add .db0/ to .gitignore.

Which scope flag to use:

Flag Config location Active in
--scope user ~/.claude.json All your projects
--scope project .mcp.json in project root This project, for the whole team
--scope local ~/.claude.json This project only, privately

The --scope user flag is the important part. It puts the MCP server in your global config so every project gets it. Without it, db0 only runs in the current project.

Verify: ask Claude "what db0 tools do you have?" and it should list 10 tools starting with db0_.


The four memory scopes

Scope Persists Use for
user Forever, across all projects Personal preferences, cross-project patterns
agent Forever, this codebase Project-specific patterns, architecture decisions
session Current session In-progress decisions
task Current task Scratch work

Use user for preferences that follow you. Use agent for patterns specific to a codebase. Claude Code's built-in memory maps roughly to agent scope. db0 adds the user layer that was missing.


The re-teaching problem, solved

Same scenario as before, but now db0 is running:

Project A, first time:

You: "Don't add Co-Authored-By to commit messages."

Claude: db0_memory_write({
    content: "Never add Co-Authored-By to commit messages unless explicitly asked",
    scope: "user",
    tags: ["commits", "preference"]
  })
  Got it. I'll leave that out going forward.

Project B, three weeks later:

You: "Write a commit message for this."

Claude: [db0_memory_search runs at session start]
  → "Never add Co-Authored-By to commit messages unless explicitly asked"

  feat: add user authentication

  [no Co-Authored-By]

One correction. Applies everywhere. Forever — until you change it.


When preferences change: updating

Facts evolve. When they do, db0 retires the old version rather than leaving both to compete.

You: "Actually, start using gitmoji now, prefix commits with the right emoji."

Claude: db0_memory_update({
    oldContent: "Use conventional commits format",
    newContent: "Use gitmoji prefix on all commits",
    scope: "user"
  })
  Updated. Conventional commits is retired; I'll use gitmoji from here.

One call. db0 finds the old memory by semantic match on oldContent, supersedes it, and writes the new version. The old fact is preserved for audit but excluded from search. You always get the current truth, not an accumulation of contradictions.

This is something Claude Code's built-in memory can't do: when you teach it something new, the old fact stays in MEMORY.md alongside the new one. Claude has to guess which version is current.


Cross-device: memory that follows you between machines

Claude Code's built-in memory is machine-local. The path hash changes when the username or mount point differs. Same project, different machine, different hash, different memory directory.

By default, db0 uses SQLite locally at ~/.claude/db0.sqlite. For cross-device sync, point it at any hosted Postgres instance:

{
  "mcpServers": {
    "db0": {
      "command": "npx",
      "args": ["-y", "@db0-ai/claude-code"],
      "env": {
        "DB0_STORAGE": "postgresql://user:pass@your-host/db0"
      }
    }
  }
}

Free-tier Neon or Supabase works. Your user-scoped preferences follow you to any machine. agent-scoped project patterns sync wherever you work on the same codebase.

Mem0 solves cross-device sync by routing everything through their cloud API. db0 does it via Postgres you own. No account, no API key, no data leaving your infrastructure.


State checkpoints: picking up where you left off

Beyond memory, db0 adds execution state. Claude Code has no equivalent for this.

When you're mid-way through a multi-session task:

You: "Checkpoint this — auth module done, user module is next."

Claude: db0_state_checkpoint({
    step: 3,
    label: "auth-complete",
    metadata: { completed: ["auth"], remaining: ["user", "payments"] }
  })
  Saved. Next session I'll restore this and know exactly where we are.

Next session, different machine, same Postgres backend:

You: "Where were we?"

Claude: db0_state_restore()
  → step 3: "auth-complete"
  → remaining: user, payments

  We finished auth. Starting on the user module.

Claude Code memory tells Claude what the codebase is like. State checkpoints tell Claude what you were doing in it and where you stopped.


What happens on first install

You don't need to learn any tool names or API calls. After running the install command, just talk to Claude the way you normally would:

You: "Remember that I always want conventional commits."

Claude: Got it. I've saved that as a user-scoped preference.

Claude decides when to use db0 tools behind the scenes. When you correct a preference, it writes a user-scoped memory. When you ask about something it's seen before, it searches. When a fact changes, it updates the old one. You don't need to say "use db0" or name specific tools. The MCP protocol handles the wiring.

If you want more control, you can be explicit: "save this with user scope" or "search my memories for commit preferences." But most of the time, you just talk and Claude does the right thing.


How it fits alongside Claude Code's built-in memory

db0 doesn't replace Claude Code's built-in memory. It adds the layers that are missing.

CLAUDE.md Claude Code memory db0
Who writes it You Claude (automatic) Claude (via MCP tools)
Scope Project or user (static) Per git repo only user / agent / session / task
Cross-project preferences Manual, static file ✓ (user scope)
Cross-device sync Via git ✓ (Postgres)
Fact superseding Manual edit Accumulates stale facts ✓ (with audit trail)
Semantic search
State checkpoints

Use CLAUDE.md for project standards that don't change. Let Claude Code memory accumulate project patterns automatically. Use db0 for personal preferences that should follow you everywhere, and for multi-session task state.


Get started

claude mcp add --scope user --transport stdio db0 -- npx -y @db0-ai/claude-code

Then correct Claude on something you always have to re-teach. Tell it to remember with user scope. That's the last time you'll have to say it.