如何修復 @modelcontextprotocol/server-memory 的 MEMORY_FILE_PATH 與 npx 快取問題
MCP memory server lost your memories? Fixing MEMORY_FILE_PATH and the npx cache
Mohammed Rafay 説明如何排查 `@modelcontextprotocol/server-memory` 的記憶檔案寫入 npx 快取,以及設定自訂路徑和還原舊記憶。
Disclosure: I'm Mohammed, founder of MemorySync. I drafted this article with AI assistance and reviewed it for accuracy against the official MemorySync and MCP server-memory, Claude Code docs. Install and setup steps were run on a Linux box (server-memory 2.0.0, Node 24, Claude Code CLI, the MemorySync installer in list/dry-run mode); the Windows, VS Code and Docker configs and the hosted server sign-in weren't run.
If you run the reference MCP memory server (@modelcontextprotocol/server-memory) through npx, you may have set MEMORY_FILE_PATH, told Claude a few things, and later found the file you pointed at empty. The memories were real. They were written somewhere else: inside npm's npx cache.
That's the long-running GitHub issue modelcontextprotocol/servers#692, "Memory MCP ignores custom storage path setting". The reporter's file ended up at a path like ~/.npm/_npx/<hash>/node_modules/@modelcontextprotocol/server-memory/dist/memory.json. Some people in the thread reported losing data when that cache was cleared or the package was updated. The issue was closed on Oct 19, 2026, when the reference servers were released as v2.
Below is how I'd find where your memory actually lives, pin it to a file you control, get the old data back, and decide whether you want a local file at all. The server behaviour comes from the server-memory README, its source and the issue thread. Client config comes from the Claude Code MCP docs. The MemorySync part comes from the MemorySync MCP docs. I'm building MemorySync, a hosted memory layer, so weigh that section with that in mind. I ran the Linux commands below against server-memory 2.0.0 on Node 24 before publishing; the Windows, VS Code and Docker variants are from the README and weren't run.
Why it happens
The server stores its knowledge graph (entities, relations, observations) as JSONL. In the current source the default path is memory.jsonl in the package directory, the folder the server's code was installed into (in 2.0.0 that's the package's dist folder). With npx -y @modelcontextprotocol/server-memory, that folder is inside the npx cache. So when the variable doesn't take effect, your memory sits in a cache directory that npm can replace at any time.
There are three ways to end up there:
-
The variable never reaches the server. In the issue, commenters suspected the client or
npxwasn't passing it through. When the maintainer closed it, he said v2 uses an absolute path as given "once the client passes the variable through". So the client config still matters. -
The path is relative. In v2, a relative
MEMORY_FILE_PATHis joined onto the package directory.memory.jsonlor./memory.jsonltherefore lands back in the npx cache. -
An older version. Older releases used
memory.json. When there's no custom path, the server renames a legacymemory.jsonin its default folder tomemory.jsonlon startup.
v2 also expands a leading ~ itself, because MCP clients pass env values from JSON and no shell does it for them.
Step 1: Find where your memory actually is
Before changing anything, look for the file the server has really been writing:
# macOS / Linux: find graph files inside the npx cache
find ~/.npm/_npx -path "*server-memory*" \( -name "memory.json" -o -name "memory.jsonl" \) 2>/dev/null
On Windows the npm cache is usually under %LocalAppData%\npm-cache\_npx. That's npm's default location, not something from the server docs, so check npm config get cache if it isn't there.
If you find a file with your entities in it, copy it somewhere safe now, before you touch the config or the cache.
Step 2: Use an absolute path and the current version
The server requires Node.js 24 or later when you run it through npx (per its README; npm lists 2.0.0 as the latest version). For Claude Desktop, the README's config looks like this, with an absolute path:
{
"mcpServers": {
"memory": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-memory"],
"env": {
"MEMORY_FILE_PATH": "/Users/you/mcp-data/memory.jsonl"
}
}
}
}
On Windows the README launches npx through cmd /c ("command": "cmd", "args": ["/c", "npx", "-y", "@modelcontextprotocol/server-memory"]) with the same env block.
My own additions: create the directory first, because the server saves atomically through a temp file next to the memory file and also puts a lock file there, so the folder must be writable. If you want to be sure you're on v2, pin it with standard npm syntax: @modelcontextprotocol/server-memory@2.0.0.
For Claude Code, pass the variable with --env, after the server name and before -- (that's the documented pattern for stdio servers):
claude mcp add memory --env MEMORY_FILE_PATH=/Users/you/mcp-data/memory.jsonl \
-- npx -y @modelcontextprotocol/server-memory
For VS Code, the README uses the same command/args shape under a top-level servers key in mcp.json. Add the same env block.
Restart the client fully after editing, since MCP config is read at startup.
Step 3: Check that it worked
Ask the assistant to remember one throwaway fact, then check that your file changed:
ls -l /Users/you/mcp-data/memory.jsonl && tail -n 3 /Users/you/mcp-data/memory.jsonl
If the file is still missing but the fact was "remembered", the variable isn't reaching the server. Run the find command from Step 1 again to see where the write went.
Step 4: Bring the old memory back
Put the file you rescued in Step 1 at your new MEMORY_FILE_PATH. If it's a legacy memory.json, rename it to memory.jsonl. That's the same rename the server does itself during its own migration. Then restart and ask the assistant to read the graph (the read_graph tool) to confirm your entities came back.
Step 5: Two more fixes from the docs and the thread
-
Docker instead of npx. The README's Docker config mounts a named volume (
-v claude-memory:/app/dist), so the default file lives in a Docker volume rather than the npx cache. The README also warns that an old volume can contain anindex.jsthe new container will overwrite. -
Run it with
nodedirectly. One commenter in the issue worked around it by installing the package globally and pointing the client at the installedindex.jswithnode, so nonpxlayer sits in between. That's a community workaround, not official guidance.
If two clients (say Claude Desktop and Claude Code) point at the same file, each starts its own server process. v2 takes a lock file during every write so they take turns. The README notes this relies on a local filesystem, so don't share the file over a network drive.
When a hosted memory server is the simpler answer
A local file is fine if one machine and a couple of clients are all you need. The trouble starts when you want the same memory on a laptop and a desktop, or in a CI job, and you end up syncing a JSONL file by hand.
That's the case MemorySync covers: its memory server is hosted at https://mcp.memorysync.io/mcp, so there's no local process and no file path to configure. Per the Connect a Client docs:
npx -y memorysync-mcp-install --list # show detected clients, change nothing
npx -y memorysync-mcp-install --dry-run # print what it would write
npx -y memorysync-mcp-install # configure every detected client
The installer backs up each config file before changing it. You sign in through the browser on first use. For headless setups the server also accepts a MemorySync API key in the X-API-Key header. Keep that key in an environment variable or CI secret, never in a committed config file. Restart the client afterwards.
It's a different model from the reference server, not a drop-in replacement. Instead of an entity/relation graph that the model edits directly, the assistant calls tools like search_memory and add_memory. add_memory runs server-side extraction, so filler is discarded and skipped is a normal result. The Memory Tools page lists all 15 tools. I'm not covering moving an existing memory.jsonl into it here.
Troubleshooting
-
Memory "works" but your file stays empty. The variable isn't reaching the server, or the path is relative. Use an absolute path and re-check the client's
env/--env. - Everything vanished after an update. The data was probably in the npx cache. Search it (Step 1) before anything else clears it.
- A write fails with a lock error. v2 gives up after 60 seconds rather than overwriting. Check for a stuck process, and make sure the folder is writable.
-
The hosted server shows no tools. Restart the client. A
405on a GET request is expected, per the MemorySync docs.
Sources
- GitHub issue modelcontextprotocol/servers#692 and its closing comment (Oct 19, 2026)
- server-memory README and
src/memory/index.ts(default path, relative-path and~handling, legacy rename, lock file); npm @modelcontextprotocol/server-memory 2.0.0 (Node >= 24) - Claude Code MCP docs: code.claude.com/docs/en/mcp (
--envfor stdio servers) - MemorySync docs: docs.memorysync.io/mcp/overview, /mcp/install, /mcp/tools
Try it
If you want to see a memory survive a full page reload before wiring up any client, the MemorySync playground runs the save, reload and recall loop in your browser: memorysync.io/try.
來源:DEV Community · dev.to