Pathrule
Writing
Engineering
/Sertan Helvacı/15 min read

Memory MCP Servers for AI Coding Agents: What Each One Stores

Search for a memory MCP server and you get a list of names with near-identical descriptions.

They are not near-identical.

They disagree about what a memory is, where it lives, and whether anything reaches the agent before it thinks to ask, and that last disagreement is the one the protocol was never going to resolve.

Short answer

A memory MCP server is a Model Context Protocol server whose tools let an agent store knowledge and read it back in a later session. The actively maintained ones are the protocol's reference server, Mem0, Zep through Graphiti, Supermemory and Basic Memory. They differ in what a memory is, where it runs, and whether anything arrives before the agent asks.

Pathrule
Pathrule routes scoped team knowledge into AI coding sessions.

What this covers

  • The protocol's own reference server, published as @modelcontextprotocol/server-memory, models a local knowledge graph of entities, relations and observations, exposes nine tools plus a knowledge-graph resource, and persists to a JSONL file whose location is set by MEMORY_FILE_PATH.
  • OpenMemory was the local-first answer most people bookmarked: Docker, a vector store, a dashboard on localhost:3000 and four tools. It is no longer part of the Mem0 repository and its documentation path now resolves to the Mem0 docs home, so anyone standardised on it is doing an unplanned migration.
  • Mem0's current MCP surface is hosted at mcp.mem0.ai/mcp, needs a Platform account, exposes eleven tools, and stores memories in the Mem0 account rather than on your machine. Separately, Mem0 ships a Claude Code plugin that captures evidence through lifecycle hooks and exposes only one local MCP tool, which is a push design rather than a pull one.
  • Zep's Graphiti ships an MCP server over a temporal knowledge graph: episodes as provenance, entities as nodes, and facts as edges carrying validity windows, so a fact can be closed rather than overwritten. The MCP server deployment expects Docker with Neo4j.
  • Supermemory's MCP server is hosted at mcp.supermemory.ai/mcp, authenticates with OAuth rather than an API key, organises knowledge into spaces, and exposes seven tools including whoAmI and listSpaces for access scoping.
  • Basic Memory is AGPL-3.0, runs locally in Python, and stores everything as Markdown files on disk with observations and wikilinks forming the graph, plus semantic search with optional cross-encoder reranking and an optional paid cloud sync.
  • ByteRover moved off MCP as its primary connector. Version 4 ships a Desktop app plus a published skill installed with npx skills add, with bind, query, record and dream verbs, connecting ten agents including Claude Code, Codex, OpenCode and Cursor.
  • Wiring differs per client: claude mcp add writes ~/.claude.json or a committed .mcp.json with local, project and user scopes resolved in that order; Codex reads TOML from ~/.codex/config.toml and its codex mcp add handles stdio only; Cursor uses .cursor/mcp.json; OpenCode uses an mcp object in opencode.json with an explicit local or remote type.
  • The gap MCP leaves is timing. A tool is pull, so a constraint the agent never suspected is never asked about and the miss is silent. Push needs a hook, which needs a local runtime, and Claude Code's four hook events differ in whether they can add context, block a call, or only observe after the fact.

Comparison

ServerWhat a memory isWhere it runsHow the agent gets it
MCP reference serverAn entity with observations, plus typed relations between entitiesYour machine, one JSONL fileNine tools it calls, plus a readable memory://knowledge-graph resource
Mem0An extracted fact scoped to a user, agent, app or runHosted, in your Mem0 accountEleven tools over HTTP, or a Claude Code plugin that captures through hooks
Zep / GraphitiAn edge between entities, carrying a validity window and its source episodeYour infrastructure, expecting Docker and Neo4jTools for episodes, entities, hybrid search and graph maintenance
SupermemoryAn extracted memory or an uploaded document, inside a spaceHosted, OAuth, no API keySeven tools, including identity and space listing
Basic MemoryA Markdown note, with observations and wikilinks forming the graphYour disk, plain files, optional cloud syncTools tagged with behaviour hints so the agent picks without probing
PathruleA typed memory, rule or skill attached to a repository pathLocal runtime plus hosted store, or a cloud-only endpointPushed at hook time before the first tool call, with MCP as the deep path

Reading a memory MCP server's docs quickly

  • Find the unit. Look at the arguments on the write tool. If they take a user_id, the server is built for memory about a person. If they take a path or a project, it is built for memory about a codebase.
  • Count the write tools. One add tool with an action field is a different design from six mutation tools on a graph, and it tells you how much structure the server expects to hold.
  • Check where the bytes land. A file path in the README means your disk. An OAuth endpoint means someone else's, with the boundary question that follows.
  • Look for a hook, a plugin or a skill. If the vendor ships one alongside the MCP server, they have concluded that tool calls alone do not deliver reliably, which is worth knowing before you conclude otherwise.
  • Ask what a contradiction does. Overwrite, append, or close the old fact with a validity window. Only the third keeps the history queryable.
  • Read the export path. A store you can read as plain files has already answered the question of what happens if the project stops.

What an MCP memory server actually settles

A memory MCP server is a Model Context Protocol server whose tools let an agent write something down and read it back after the conversation ends. The value of doing it over MCP rather than as a bespoke integration is straightforward and real: the store becomes reachable from whichever agent the team is using this quarter, without one integration per tool per client. New to the protocol itself: what is the Model Context Protocol.

What the protocol settles is transport, discovery and the shape of a tool call. What it does not settle is everything that makes one of these servers behave differently from another: what counts as a memory, what a memory is attached to, what happens when two stored facts disagree, and when the knowledge reaches the model. The category explanation for that gap is on the MCP memory server pillar. This piece is the inventory underneath it: what each server actually stores, where it runs, and how you wire it into the four agents people actually use.

One framing to carry through. Everything below is a pull design unless it says otherwise. The agent decides to call a tool, and the store answers. That is the correct shape for a lookup the agent knows it wants, and it has a specific blind spot that the last two sections come back to.

The reference server, and the model everything else is measured against

The Model Context Protocol ships a memory server of its own, published as @modelcontextprotocol/server-memory and described in its own README as a basic implementation of persistent memory using a local knowledge graph. It is the honest baseline, and it is worth understanding first because the rest of the category is legible as a set of departures from it.

Its data model has exactly three things in it. Entities are the nodes: a unique name, a type such as person or organization, and a list of observations. Relations are directed connections between entities, and the README is specific that they are stored in active voice. Observations are discrete strings attached to an entity, and the guidance is that each should be atomic, one fact per observation. That last constraint is doing more work than it looks like: it is what keeps deduplication tractable later.

The tool surface is nine calls. Six mutate: create_entities, create_relations, add_observations, delete_entities, delete_observations, delete_relations. Three read: read_graph, search_nodes, open_nodes. There is also a resource at memory://knowledge-graph, and the mutation tools emit notifications/resources/updated so a subscribed client can follow along. Persistence is a JSONL file, located by the MEMORY_FILE_PATH environment variable, defaulting to memory.jsonl beside the server.

It is also the cheapest experiment available in this category, and running it first will tell you more than a week of comparing feature pages: install it, work normally for a fortnight, then open the JSONL and read what the agent actually chose to keep. What you find there is a better specification than anything you would have written up front. What the server does not model is a repository path, a team, a rule with an enforcement level, or any notion of when knowledge should arrive, because none of those were its brief. A side by side against a context layer is at Pathrule vs the MCP memory server.

OpenMemory, and what happened to it

OpenMemory MCP is one of the most searched terms in this category, so it deserves a straight answer rather than a link to a dead page.

OpenMemory was Mem0's local-first memory server. It ran on your machine with Docker, kept a vector store behind it, and shipped a dashboard at http://localhost:3000 where you could browse and delete what had been stored and see which MCP clients were connected. Its tool surface was deliberately small: add_memories, search_memory, list_memories and delete_all_memories. The pitch was a shared persistent memory layer across Cursor, Claude Desktop, Windsurf, Cline and any other MCP client, with nothing leaving the machine.

It is no longer shipped. The openmemory directory is not in the Mem0 repository, and the documentation path that used to describe it now resolves to the Mem0 documentation home. Mem0's current answer for a local, self-hosted store is the open source Mem0 server rather than OpenMemory, and its current answer for MCP is a hosted endpoint.

The reason to spend a section on a retired product is that the lesson generalises and it belongs in the adoption decision, not in the postmortem. A memory store is not a library you can pin a version of and forget: it holds accumulated knowledge that gets more expensive to move every month you add to it. Before you standardise a team on one of these, read the export path. A store that is already plain files on your disk has answered the question in advance, which is most of why the next two entries in this list are worth taking seriously.

Mem0: a hosted server, and a plugin that does not use it

Mem0's MCP server today is hosted at https://mcp.mem0.ai/mcp. It needs a Mem0 Platform account, and it authenticates either through a browser sign-in the client opens the first time a tool is used, or with an API key sent as a bearer token for headless environments. Its own documentation is explicit about the trade: nothing runs on your machine, and the memories you store this way live in your Mem0 account rather than on your computer.

The tool surface is the largest in this survey at eleven calls, and its shape tells you what the unit is. Alongside the expected add_memory, search_memories, get_memories and update_memory, there is list_entities and delete_entities, where an entity is a user, agent, app or run. That is a memory system built around who or what a fact belongs to, which is the right unit for memory about a person and the wrong one for a convention that belongs to services/billing. The head to head is at Pathrule vs Mem0.

The more interesting thing Mem0 ships is not the MCP server. It is a Claude Code plugin that captures evidence locally through lifecycle hooks, extracts memories in a detached background worker, and exposes exactly one local MCP tool for search alongside a set of slash commands. Read that design carefully: a memory vendor with a perfectly good hosted MCP server also built a hook-based capture path and cut the tool surface down to a single call. That is not an accident of packaging. It is a vendor concluding that tool calls alone are not a reliable way to get memory in and out of a coding agent, which is the argument the last section of this piece makes from the other direction.

Zep and Graphiti: a temporal graph over MCP

Zep's open source engine is Graphiti, and the repository includes an MCP server. What it exposes is shaped by the graph underneath: episode management, entity and relationship handling, semantic and hybrid search, group management for organising related data, and graph maintenance operations.

The model is worth understanding because it is the only one in this survey that can express time. Entities are nodes with evolving summaries. Facts are edges, and an edge carries a temporal validity window, so a fact can be closed rather than overwritten when it stops being true. Episodes sit underneath as provenance, tracing a fact back to the raw source it came from. Custom entity types are declared as Pydantic models.

That combination buys something no similarity-ranked store can: the agent can be told that something used to be true and no longer is, with the history intact and the source attached. For a knowledge base where facts genuinely change and the change matters, that is the right shape, and it is the honest reason to accept the operational cost. The MCP server deployment expects Docker with Neo4j, which is a service to run rather than a file to write, although Graphiti itself supports FalkorDB, Kuzu and Amazon Neptune as alternative backends. Side by side: Pathrule vs Zep.

Supermemory: hosted, OAuth, organised into spaces

Supermemory's MCP server is a remote endpoint at https://mcp.supermemory.ai/mcp. Connecting opens a browser for OAuth rather than asking for an API key, and part of the sign-in is choosing which spaces the client is allowed to reach. A space keeps one team's documents and memories together so retrieval does not mix unrelated work, and a request can name a space for one call without changing the active one.

Seven tools: search_memory for semantic recall with optional profile context, add_memory which also handles forgetting through an action field rather than a separate tool, listDocuments and getDocument for the source material, listMemories for the extracted entries and their source document ids, plus listSpaces and whoAmI for resolving access. The presence of the last two is the tell: this is a multi-tenant product where knowing what the caller is allowed to see is part of the tool surface.

The positioning is broader than coding, and the documentation says so directly: engineering and research teams carrying project context across assistants, and finance, legal, medical and operations teams working from their own source material. That breadth is a genuine strength for a company knowledge base and a mismatch for repository conventions, for the same unit reason as Mem0. The long version is in Pathrule vs Supermemory.

Basic Memory: Markdown on your disk, shaped as a graph

Basic Memory is the local-first entry that is actually still maintained, and it is the closest thing the category has to a replacement for what OpenMemory was. It is AGPL-3.0, installs from PyPI, needs Python 3.12 or newer, and stores everything as plain Markdown files on your disk.

The design decision that matters is that the files are the store, not an export of it. You and the agent write to the same Markdown, a sync process keeps the index in step, and the graph is built out of observations and wikilinks inside the notes rather than held in a separate database. That means every property a repository file has, being readable, greppable, diffable and yours, applies to the memory too. Search is semantic rather than plain keyword, with optional cross-encoder reranking for higher quality hybrid results.

One detail is unusually thoughtful and worth stealing regardless of what you adopt: every tool is tagged with behaviour hints, read-only, destructive or idempotent, so an agent can pick the right one on demand instead of burning context trying things to see what they do. Cloud sync exists as an optional paid layer, and it is genuinely optional rather than the real product with a local mode attached.

ByteRover left MCP, and that is the most interesting data point here

ByteRover started as an MCP-connected memory layer for coding agents, with a context tree of Markdown under a local directory. Version 4 is not that. It is a Desktop application that manages spaces and teams, plus a published skill that runs inside the agent, installed with npx skills add campfirein/skills and requiring Node 20 or newer. Desktop connects it to ten agents, including Claude Code, Codex, OpenCode, Cursor, GitHub Copilot and Gemini CLI, and some of those share a global skills folder so one install covers several.

The skill is organised around four verbs, and the verbs are the argument. bind connects a project folder to the space the agent should use. query retrieves relevant project memory before work starts. record saves durable knowledge after useful work is completed. dream reviews cleanup and consolidation proposals for what has accumulated. That is a write path with an explicit review step and a read path with an explicit position in the turn, which is a great deal more opinionated than a tool the model may or may not call.

Put this next to Mem0's hook-based Claude Code plugin and a pattern is visible. Two independent memory vendors, both of whom shipped working MCP servers, have added a second delivery mechanism that does not rely on the agent deciding to call a tool. Nobody is abandoning the protocol, and they should not: MCP is still how the store gets reached from four different clients without four integrations. What they are abandoning is the assumption that a tool call is a sufficient delivery mechanism. Head to head: Pathrule vs ByteRover.

Wiring one into Claude Code, Codex, Cursor and OpenCode

The protocol is uniform. The configuration is not, and this is where an afternoon disappears.

Claude Code takes claude mcp add [options] <name> <url-or-command> and supports HTTP, stdio and WebSocket, with SSE deprecated. The part worth learning properly is scope. Local scope is the default and writes to ~/.claude.json under the current project, so it is yours alone. Project scope writes .mcp.json at the repository root, which is committed and therefore shared with the team. User scope also writes ~/.claude.json but applies across all your projects. When the same server is defined more than once, resolution runs local, then project, then user, then plugin-provided servers, then connectors. For a stdio server, remember the -- separator: claude mcp add --transport stdio <name> -- npx -y <package>.

Codex reads MCP servers from ~/.codex/config.toml as TOML, not JSON, under a [mcp_servers.<name>] table. Its codex mcp add only supports stdio servers, so an HTTP endpoint has to be written into config.toml by hand or added through the app UI. Codex also carries a bearer token from an environment variable rather than inline, which is the right default and worth keeping. Its instruction chain is a separate mechanism entirely: see Codex memory: what persists between sessions.

Cursor uses .cursor/mcp.json in the project and a global file in the home directory, in the familiar mcpServers object shape. OpenCode uses an mcp object in opencode.json, and unlike the others it makes the distinction explicit: "type": "local" with a command array, or "type": "remote" with a url, plus enabled, headers and timeout. OpenCode's documentation also states the warning the others leave implicit, that MCP servers add to your context and you should be careful which ones you enable, which is a real constraint once you have three of them connected.

Four formats for one server is exactly the problem that made the protocol worth having in the first place, one level up. Writing the same endpoint into each client's own configuration file is a solvable, boring problem, and it is what connect an MCP tool once for every AI engine is about.

The thing MCP does not settle: when the memory arrives

Every server above, in its MCP form, is pull. The agent decides it needs something and calls a tool. This is efficient, it puts the judgment where the context is, and it is the only thing a hosted endpoint can do, because a cloud connector cannot see your working directory or take part in the agent's startup.

The gap that leaves is not in anyone's implementation, which is exactly why comparing tool surfaces will never expose it. A protocol call needs a caller, and the caller is a model judging from the turn in front of it that a lookup is warranted. A task description does not announce the constraint the task is about to violate, so the judgment comes out negative and no call is made. A call that is not made returns no error, fills no log line and moves no metric, so every server in this survey will report itself perfectly healthy through the precise session in which it prevented nothing. You find out in code review, if you are lucky.

Push is the other half, and it needs a hook rather than a protocol feature. Claude Code exposes four events and they are not interchangeable. SessionStart fires once and can add context but cannot block. UserPromptSubmit fires per turn, can add context the model then acts on, and can block the prompt. PreToolUse fires before a tool call, can inspect the arguments, add context, and deny the call outright. PostToolUse fires after the tool has already run, so it can add context and warn but by definition cannot prevent anything. That last distinction is the whole difference between a constraint that is described and a constraint that is enforced, and it is why Claude Code hooks and CLAUDE.md end up doing different jobs.

The honest framing is not that push beats pull. Push costs a runtime on the machine, and it spends context every turn whether or not the turn needed it. Pull optimises for cost and push optimises for coverage. A lookup is a cost problem. A constraint that must never be violated is a coverage problem, and no amount of good ranking fixes a query that was never made.

How Pathrule uses both, and where it is the wrong answer

Pathrule is in this list, so here is its shape stated the same way as the others, including where it loses.

A memory is a typed record attached to a repository path, and there are three types rather than one: memories for what is true, rules for what must not happen, and skills for how a recurring job is done. The MCP surface is the same contract on every entry point, with read tools for context and bodies, write tools that materialise a missing node on the path rather than requiring you to build the tree first, and an activity log so what the agent did is reviewable later. The inventory is in the tools reference and the surface rules are in one contract, every surface.

The delivery is the hybrid. A local runtime, Pathrule Studio or the CLI, registers the hook profile each client actually exposes and reads a precomputed slice from a local cache, so the path-scoped knowledge is in context before the first tool call with no network round trip in the hot path. MCP is the deep path on top of that: discovery prompts, full bodies for a title the hook only named, and writes when something is worth keeping. Not everything is pushed, and that is deliberate. Skills are offered by name and never injected as a body, because a memory is a fact and a rule is a constraint but a procedure handed over unasked instructs the agent rather than informing it. The mechanics are in how hooks work and what arrives in full, and what arrives as a name.

What the hybrid costs, plainly. Hook delivery needs a process on your machine, so the hosted endpoint at mcp.pathrule.io/mcp cannot do it: it has no working directory to read and no pre-write event to hook, so it answers on request and cannot block a change, the same boundary any cloud-only connector has. Windsurf has no equivalent hook event either, so it receives a companion file at session start and MCP after that. Those are properties of the surface, not claims, and they are listed as such in the MCP overview.

Where Pathrule is the wrong choice: if the knowledge you are storing is about a person rather than a place in the repository, Mem0 or Supermemory is the correct unit and this is not. If facts in your domain change and the history of the change is the valuable part, Graphiti's validity windows do something Pathrule does not. And if you are one developer on one machine who wants durable scratch memory with no account, the reference server or Basic Memory is smaller and better, and you should start there.

Choosing, in one pass

Start from what you are actually losing. If it is knowledge about you and your preferences across tools, the unit is a person and the answer is Mem0 or Supermemory. If it is facts that change over time and you need to know when they changed, the answer is a temporal graph and that is Graphiti. If it is notes you also want to read and edit yourself, the answer is Markdown on disk and that is Basic Memory. If it is a place for one agent on one machine to put things with no account, the answer is the protocol's own reference server.

If it is the conventions and decisions that govern a codebase, and the failure that hurts is the agent confidently doing the thing your team decided two quarters ago not to do, then the unit is a path and the problem is timing, and a pull-only server will not fix it whatever its ranking quality. That is the case a context layer exists for, and the case where the extra cost of a local runtime buys something.

Whichever way that goes, do the free part before you install anything. Instruction files are already hierarchical in both Claude Code and Codex, and almost nobody uses the hierarchy, so a root file that has grown into an unreadable pile can usually be cut apart along directory lines in an afternoon. That is reviewable, costs nothing, and removes a surprising share of what looked like a retrieval problem. Whatever is left over is the brief you should be shopping with, and it will be a much better one than the brief you started with. The decision framework behind all six of these choices is in persistent memory for AI coding agents.