# What the MCP memory server remembers, and why only one machine can read it

> The MCP memory server keeps a knowledge graph in one JSONL file per machine. How to set it up, what it stores, and what memory a team shares needs instead.

Source: https://baalda.com/blog/mcp-memory-server
Site: Baalda, https://baalda.com
Published: 2026-11-02

**Short answer.** The MCP memory server is the Model Context Protocol project's reference server for persistent assistant memory. It stores entities, relations and observations as a knowledge graph in one JSONL file, set by MEMORY_FILE_PATH, on the machine that runs it. It suits one person in one client. Its own README rules out sharing the file over a network filesystem, so a team needs memory somewhere every machine writes through.

The MCP memory server is the Model Context Protocol project's own reference server for giving an assistant persistent memory: a small knowledge graph of entities, relations and observations, saved as one JSONL file on the machine that runs it. It is a good memory for one person in one client, and it was never built to be the memory a team shares.

That second half is the part the directory listings skip, and it is where the trouble starts. The memory sits in a file only one process at a time can safely write, on a disk only one person can reach, in a format nobody is meant to read. A fact Claude learned from you on Monday is invisible to your colleague's Claude on Tuesday, and if it learned something wrong, the only way to fix it is to ask the model to delete an observation. This post covers what the server is, how to set it up properly, and what memory several people share has to look like instead, which is the problem Baalda, an open source app that keeps a team's notes as plain markdown files, is built around.

## What is the MCP memory server?

It is `@modelcontextprotocol/server-memory`, published on npm from the `modelcontextprotocol/servers` repository under the MIT licence. Its README describes it as "a basic implementation of persistent memory using a local knowledge graph", and the graph has three parts:

- **Entities**, the nodes, each with a unique name, a type such as `person` or `organization`, and a list of observations.
- **Relations**, directed links between two entities, "always stored in active voice", such as `works_at`.
- **Observations**, single facts stored as strings on an entity, which the README says "should be atomic (one fact per observation)".

The server exposes nine tools to the assistant: `create_entities`, `create_relations`, `add_observations`, `delete_entities`, `delete_observations`, `delete_relations`, `read_graph`, `search_nodes` and `open_nodes`. It also offers the whole graph as one resource, `memory://knowledge-graph`, and sends an update notification on that resource whenever a write tool changes it.

As of 2 November 2026 the current version is 2.0.1, published on 28 October 2026. Version 2.0.0, from 19 October, moved it to the version 2 TypeScript SDK and raised the floor to Node.js 24 or later.

## How do you set up the MCP memory server in Claude Code and Claude Desktop?

In Claude Desktop it is an entry in `claude_desktop_config.json`. The README's version, with the one setting you should not skip:

```json
{
  "mcpServers": {
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"],
      "env": {
        "MEMORY_FILE_PATH": "/Users/you/memory/memory.jsonl"
      }
    }
  }
}
```

In Claude Code the same server is one command. Anthropic's MCP docs note that `--env` must not sit directly before the server name, so `--transport stdio` goes between them, and everything after `--` is passed to the server untouched:

```bash
claude mcp add --env MEMORY_FILE_PATH=/Users/you/memory/memory.jsonl \
  --transport stdio memory -- npx -y @modelcontextprotocol/server-memory
```

**Always set the file path.** When `MEMORY_FILE_PATH` is unset, the README says the file defaults to "`memory.jsonl` in the server directory", and the source resolves that directory from the location of the package's own code. Run through `npx`, that is wherever npx unpacked the package, which is not a folder you chose or back up. Since 2.0.0 a leading `~` in the path is expanded to your home directory, because MCP clients pass the value from JSON where no shell expands it.

The README also ships an example system prompt, written for a Claude.ai Project's custom instructions, that tells the model to begin every chat by "Remembering..." and to collect identity, behaviours, preferences, goals and relationships for a `default_user`. That tells you what the server was designed for: personalising one person's chats.

## What does the memory actually look like on disk?

Each entity and each relation is one line of JSON. Two facts about a project become something like this:

```json
{"type":"entity","name":"Billing_Service","entityType":"service","observations":["Retries failed webhooks 3 times","Owned by the payments team"]}
{"type":"relation","from":"Billing_Service","to":"Stripe","relationType":"calls"}
```

Three details from the source matter more than they look:

- **Every write rewrites the whole file.** The server loads the graph, changes it, and saves every line again to a temporary file that it renames over the original, so an interrupted write never leaves half a graph.
- **Search is a substring match.** `search_nodes` lowercases the query and keeps any entity whose name, type or any observation contains it. There is no ranking and no semantic search, and `read_graph` simply returns everything.
- **Nobody is meant to read it.** The file is valid JSON, so you can open it, but it is a storage format for the model, not a page a colleague would read to learn how billing works.

Figure: The same knowledge stored two ways: the JSONL lines in the MCP memory server's file on one laptop, and a markdown note in a shared vault that a person and an assistant both open

For a personal memory none of that is a problem. For a team's knowledge every one of those three becomes one.

## Can a team share one MCP memory server?

Not across machines, and the README says so itself. Each MCP client starts its own server process, which talks to that client over stdio and listens on no network port. Two clients on one laptop pointed at the same file are two processes writing one file, and the server handles that well: every write takes an exclusive lock file, `<memory file>.lock`, so the writes take turns. A write that cannot get the lock within 60 seconds fails with a tool error rather than overwriting anything.

Then comes the line that ends the team version: "The lock relies on exclusive file creation, which local filesystems provide; a network filesystem that does not honour it cannot be shared safely this way."

So the obvious workaround, putting `memory.jsonl` in a shared drive or a synced folder so everyone's assistant points at it, is the one the maintainers rule out. A file sync tool is worse still, because there is no lock at all between machines. Two laptops each rewrite the whole file, the sync tool sees two different versions of one file, and you get a conflict copy or a silent last-writer-wins. Either way one person's memory overwrites the other's, which is the same failure covered in [Obsidian sync conflicts](/blog/obsidian-sync-conflicts), with the added problem that nobody can read the two versions to merge them by hand.

Figure: Three laptops each running their own memory server and their own memory.jsonl, next to three laptops whose assistants all write through one vault server over MCP

Even if the file could be shared, it has no notion of who is asking. Whoever's assistant reads it gets the whole graph, which is the access question the [MCP safety post](/blog/is-mcp-safe) works through in detail.

## What does memory a team shares need instead?

Three things the memory server does not try to provide: one place every machine writes through, a write that is refused rather than lost when two people collide, and a format a person can open and correct. That is the shape Baalda takes, and the mechanism is plain.

**The memory is a note, not a graph.** In Baalda a vault is a folder of ordinary `.md` files on your own disk, synced to teammates in real time over CRDTs. What an assistant learns goes into a note, say `Decisions/billing.md`, that a colleague opens in the same editor a minute later. If the assistant wrote something wrong, the person who knows better fixes the sentence in place, rather than asking a model to call `delete_observations` on a string they cannot see.

**Every machine writes through one server.** The vault's MCP endpoint is HTTP, not a process per laptop, so Claude Code on three machines reaches the same notes:

```bash
claude mcp add --transport http baalda https://api.baalda.com/api/mcp \
  --header "Authorization: Bearer mcp_your_token_here"
```

For a local vault the address is `http://localhost:3010/api/mcp`, and for a self-hosted server it is your own URL plus `/api/mcp`. The assistant gets `search_notes`, `read_note`, `create_note`, `append_note`, `edit_note` and `update_note`, among others.

**Collisions are refused, not merged blind.** `read_note` returns a note's `revision`. Pass it back as `expectedRevision` on `update_note`, `append_note` or `edit_note`, and the write is refused if the note changed since the assistant read it. Where the memory server's lock makes two writers on one disk take turns, this makes writers on any number of machines notice each other.

**Each connection acts as the person who made it.** A token is minted per person, and every tool call is checked against that person's access to each file, so an assistant can only remember into, and recall from, the folders its owner can reach. The team setup this enables, several people's Claude Code sessions on one vault, is the subject of [Claude Code as a second brain for a team](/blog/claude-code-second-brain-for-a-team). Baalda is open source under Apache-2.0, free to run locally or self-host, with an optional managed Team plan.

## Where does this not help?

The memory server does some things a notes vault does not, and for some people it is simply the better choice.

- **A real graph.** Entities and typed relations let the model ask "what does Billing_Service call?" directly. Baalda notes have links between them, but there is no typed relation store, and `search_notes` is a search over notes, not a graph query.
- **Capture without asking.** With the README's prompt, the model gathers memories in the background on every chat. Baalda has no equivalent built in. An assistant writes to the vault when it is told to, or when your `CLAUDE.md` or a skill tells it when to.
- **Zero infrastructure.** The memory server is one `npx` line and a file. Baalda is an app to install, and the shared version needs a server, yours or the managed one.
- **One person, one client.** If the memory is your preferences and context in your own Claude Desktop, the memory server does exactly that and nothing here improves on it. The comparison across every memory layer, from `CLAUDE.md` up, is in [the best memory tool for Claude Code](/blog/best-memory-tool-for-claude-code).

The dividing line is the second person. The moment someone else needs to read, correct or add to what the assistant remembered, the memory has to stop being one file on one disk.

## FAQ

### What is the MCP memory server?

It is `@modelcontextprotocol/server-memory`, the reference memory server from the Model Context Protocol project, MIT licensed and published on npm. It gives an assistant nine tools to create, read, search and delete entities, relations and observations in a local knowledge graph, and saves that graph as one JSONL file. Version 2.0.1, published on 28 October 2026, requires Node.js 24 or later.

### Where does the MCP memory server store its data?

In the file named by the `MEMORY_FILE_PATH` environment variable. If you do not set it, the README says the default is `memory.jsonl` in the server directory, which the source resolves from the location of the package's own code. Run through `npx`, that is wherever npx unpacked the package, so set the variable to a path you choose and back up. A leading `~` is expanded to your home directory.

### How do I add the MCP memory server to Claude Code?

Run `claude mcp add --env MEMORY_FILE_PATH=/path/to/memory.jsonl --transport stdio memory -- npx -y @modelcontextprotocol/server-memory`. Anthropic's docs warn that the server name must not come directly after `--env`, which is why `--transport stdio` sits between them, and everything after `--` is passed to the server unchanged.

### Can two people share one MCP memory server file?

Not across machines. Each client starts its own server process, and writes are made safe by an exclusive lock file next to the memory file. The README states that the lock relies on exclusive file creation, which local filesystems provide, and that a network filesystem that does not honour it cannot be shared safely. A synced folder has no lock between machines at all, so two laptops rewriting the file produce a conflict rather than a merged memory.

### Is the MCP memory server the same as Claude's built-in memory?

No. Claude's own memory features are run by Anthropic inside its apps. The MCP memory server is a separate open source program you run yourself, which any MCP client can connect to, and its memory is the JSONL file on your disk rather than anything stored in your Claude account.
