DEV Community

Jonathan Wilcox
Jonathan Wilcox

Posted on • Originally published at app.kireo.app

CLAUDE.md vs. a memory MCP: what actually goes where

If you use Claude Code or Cursor for real work, you already have a CLAUDE.md (or an AGENTS.md, or a .cursorrules). You've written down the build command, the "we use pnpm, not npm," the folder layout, the one weird thing about the auth flow. And it works. The agent reads it at the start of every session and stops making the same three mistakes.

So when someone shows up saying "add a memory MCP server to your agent," the honest first reaction is: why? I already have a file the agent reads. That's a fair question. This post answers it properly — including the cases where the honest answer is "you don't need one yet."

Disclosure up front: I build one of these (Kireo — more at the bottom). So read this as a builder trying not to oversell, not a neutral survey. But the framework below is the one I actually use to decide what goes in a markdown file and what goes in a memory store, and it holds no matter whose store you use.

The one distinction that matters: who writes it, and how often it changes

Here's the split that has survived contact with real projects:

CLAUDE.md Memory MCP
Who writes it You, by hand The agent, while working
What it holds Stable facts Accumulated decisions, dead ends, gotchas
How it changes You edit it when it drifts It grows every session
How the agent uses it Loaded into context every time Queried on demand

CLAUDE.md is for stable facts a human curates. "Run pnpm --filter api test. The API talks to Postgres and Redis. Don't touch generated/." You typed those. You re-read them when they drift. They change maybe once a month.

A memory store is for dynamic facts an agent accumulates. "Tried batching the embedding upload at 500 symbols per request — the embedding service chokes on batches that large, so I capped it at 100." Nobody hand-edits that into CLAUDE.md. The agent hit it on Tuesday, and by Thursday, in a fresh session, it's just gone — unless something wrote it down.

The test I use: would I open the file and type this by hand? If yes, it's a CLAUDE.md fact. If it's a byproduct of doing the work — a decision, a dead end, a "we tried X and it broke Y" — it wants a memory store, because you are never going back to curate it into markdown.

You don't need a memory MCP yet if…

I would rather you not bolt on a server you don't need, so here's the honest checklist. If all of these are true, a well-kept CLAUDE.md is enough, and adding infrastructure is just overhead:

  • One project. Your context still fits, and one file describes it.
  • One tool. You live in Claude Code, or only in Cursor — not both.
  • One machine. Same laptop, same setup, every day.
  • Small, curatable volume. The stable facts are few enough that you're happy maintaining them by hand, and you rarely hit "the agent solved this exact thing last week and I can't get it back."

If that's you, close this tab and go keep a good CLAUDE.md. Most solo, single-repo projects live here, and there's nothing to fix. A memory store is a tool for a problem you may not have yet.

When the file stops being enough

Four triggers move the needle. When you hit them, a static file starts losing:

1. Multiple tools. You start a feature in Claude Code, then jump to Cursor for the UI. Two tools, two separate CLAUDE.md-style files, and the context you built up in one is invisible to the other. Because MCP is an open protocol, a memory server both tools speak means a single store: written by whichever tool you were in, readable from the other.

2. Multiple machines. Laptop plus desktop plus a cloud dev box. A file per machine drifts out of sync fast. A store is one place, reachable from all of them.

3. Team-shared context. A CLAUDE.md in git is shared — but it shares stable facts you agreed to commit. The accumulated "we tried X, it broke Y" is exactly what a new teammate's agent would benefit from, and exactly what nobody writes into the committed markdown. A shared namespace in a store carries the long tail that never makes it into the file.

4. Volume past hand-curation. Beyond a certain size, CLAUDE.md becomes a wall of text that eats context on every session whether or not any line is relevant today. A store flips that: nothing loads until the agent runs a search and pulls back the top few results it actually needs. If it never searches, that costs zero context.

That last point is the real mechanical difference. A file is loaded. A store is queried. One is always in your context budget; the other is there only when the agent asks for it.

"But Claude Code already has auto memory"

It does, and it's genuinely useful — I use it. But it has a shape worth understanding before you assume it covers the same ground.

  • It's selective by design. The agent decides what's worth persisting. That's the right default — you don't want every stray thought in there — but it means the memory is only ever a subset of what happened. And you can't search what it chose not to write down. If it never recorded the OOM ceiling, there's nothing to recall later; you rediscover it the hard way.
  • It's per-tool. Claude Code's memory belongs to Claude Code. Cursor doesn't read it.
  • It's a file that loads into context, not a query. Mechanically it's closer to CLAUDE.md than to a searchable store: present whether relevant or not, rather than pulled on demand.

None of that makes it bad. It makes it the stable-facts-plus-a-bit layer, not the searchable-accumulation-across-tools layer. The two coexist happily: let Claude Code keep managing its file, and let a memory store hold the searchable long tail that spans your tools and machines.

If you decide you want the searchable layer

Here's what it looks like in practice, kept short and factual rather than pitched.

The agent gets a memory_save and a memory_search, plus memory_recall, memory_get, memory_update, memory_delete, memory_list_namespaces, and memory_health — eight tools total. It saves a decision or a gotcha when it judges one worth keeping; later, in any MCP client, it searches and gets the top few results back. Because it's an MCP server, "any client" includes both Claude Code and Cursor reading and writing the same store.

Two things I insisted on, because they're the parts that make me nervous as a user of other people's memory tools:

  • Everything is visible. There's a web dashboard where you can read, edit, and delete every memory. It is not a black box quietly accumulating who-knows-what.
  • Everything exports. Full JSON dump anytime — no lock-in. If the tool disappoints you, you leave with all your data.

On privacy, since it's usually the next question: the store keeps the memory text your tools explicitly send plus its metadata (namespace, tags, timestamps); the code index keeps derived embeddings and file paths, never your source. The full write-up is here: https://app.kireo.app/legal/privacy#data-storage.

Install is one line (free API key at https://app.kireo.app/api-keys):

claude mcp add kireo --scope user --env KIREO_API_KEY=ki_sk_xxx -- npx -y --package=@kireo/mcp-server kireo-mcp
Enter fullscreen mode Exit fullscreen mode

The takeaway

Put stable, human-curated facts in a file the agent reads. Put agent-accumulated, searchable facts in a store the agent queries. If you only have the first kind of fact, you only need the first kind of tool — and that's a fine place to stop.


Disclosure: I build Kireo, the memory MCP server used in the examples above. It's a free beta right now — generous limits, no card required. If the honest read of your setup is "a good CLAUDE.md is enough," that's a completely legitimate place to land, and I'd rather you stop there than pay a complexity tax for a problem you don't have. The framework holds regardless of whose store you use.

*Repo: github.com/wang1051992187/kireo-mcp-server · npm: @kireo/mcp-server · site: https://kireo.app/?utm_source=devto&utm_medium=blog&utm_campaign=launch-202608

Top comments (1)

Collapse
 
mads_hansen_27b33ebfee4c9 profile image
Mads Hansen

The file-vs-store distinction is useful. I’d add a second axis: authority. “Who writes it?” is only half the contract; the system also needs to know who may read, amend, supersede, or promote a memory into durable project guidance.

For each stored item I’d keep source/actor, project and branch scope, observed-at time, software/config version, confidence, and an expiry or revalidation trigger. New evidence should not silently overwrite an older contradiction; preserve both and make the conflict visible. Team-shared namespaces also need ACL and tenant-isolation tests, because a relevant memory from the wrong repo or customer is worse than no recall.

A nice lifecycle is: agent observation → searchable provisional memory → repeated/verified evidence → human-curated rule in CLAUDE.md. That keeps the store useful without letting stale or poisoned write-backs quietly become policy.