modelcontextprotocol / modelcontextprotocol/servers
memory: safer persistence defaults, atomic writes, quotas, redaction, and destructive-operation guardrails
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 90.5k
- Forks
- 11.7k
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 5
Description
Summary
While auditing and hardening local MCP server usage, I reviewed @modelcontextprotocol/server-memory and built a local hardened wrapper for our environment. I am opening this issue to share findings and possible upstream improvements.
This is not a report about a known data loss incident in the upstream package. It is a defense-in-depth report about persistence defaults and operational safety for a memory tool exposed to autonomous agents.
Package/runtime reviewed
- Package:
@modelcontextprotocol/server-memory@2026.1.26 - License observed: MIT
- Author observed: Anthropic, PBC
- Upstream repo/issue tracker:
modelcontextprotocol/servers - npm maintainers observed from registry during local review:
jspahrsummers,pcarleton,thedsp,ashwin-ant,ochafik
Findings
-
Default persistence path can land inside the package directory.
Local source evidence showed a default path based onpath.dirname(fileURLToPath(import.meta.url)), withmemory.jsonlunder the packagedistdirectory whenMEMORY_FILE_PATHis not configured. This creates operational fragility:- package reinstall/update can remove or overwrite memory state
- global/package directories are not intuitive user data locations
- backup/sync behavior is unclear
-
Writes appear to be whole-file writes without explicit atomic replace and lock discipline.
For agent memory, interrupted writes or concurrent host usage can corrupt or lose state. This is especially relevant when the same memory server is configured across multiple MCP hosts. -
No obvious mutation journal or backup trail.
Debugging accidental writes or deletes is hard without append-only audit entries or backup snapshots. -
Destructive tools are available by default.
delete_entities,delete_observations, anddelete_relationsare useful, but high-impact. In an agent context, accidental deletion should require explicit operator opt-in or confirmation mode. -
No obvious quotas/caps.
Large observations or graphs can become a memory/latency issue. Whole-graph reads and writes are also sensitive to unbounded growth. -
No obvious secret redaction before persistence.
Memory can become a persistent prompt-injection and secret-retention surface if fetched web content, logs, stack traces, or credentials are persisted without sanitization. -
No namespace isolation by default.
A single global memory file shared across workspace/host contexts can mix unrelated operational memories unless the user manually configures paths.
Local hardening behavior that worked well
For our local wrapper, we preserved the upstream-compatible 9 tool names:
create_entities, create_relations, add_observations, delete_entities,
delete_observations, delete_relations, read_graph, search_nodes, open_nodes
We added:
- explicit persistence outside
node_modules, defaulting to a user data path - refusal to persist under
node_modules - namespace support for workspace separation
- cross-process lock with stale-lock cleanup
- temp-write plus rename, with backup file
- append-only mutation audit journal
- quotas for entity/relation counts and observation sizes
- secret redaction before writes
- destructive tools disabled unless
LCV_MCP_MEMORY_ALLOW_DESTRUCTIVE=1
Validation from local wrapper
Smoke output from the hardened local wrapper:
memory tools: add_observations,create_entities,create_relations,delete_entities,delete_observations,delete_relations,open_nodes,read_graph,search_nodes
memory read_graph entities=0 relations=0
A redaction/destructive-operation check also behaved as intended in local testing:
create {"entities":[{"name":"redaction-proof","entityType":"test","observations":["token [REDACTED]"]}]}
delete [{"type":"text","text":"delete_entities is disabled by default. Set LCV_MCP_MEMORY_ALLOW_DESTRUCTIVE=1 to enable destructive memory mutations."}]
Suggested upstream changes
- Default persistence to an OS/user data directory instead of the installed package directory.
- Refuse or strongly warn when
MEMORY_FILE_PATHresolves insidenode_modulesor another package-managed path. - Use atomic write/replace and cross-process locking.
- Add backup and append-only mutation audit journal options.
- Add quotas for graph size, entity count, relation count, and observation length.
- Redact common secret patterns before persistence.
- Add namespace support or document recommended per-workspace file paths.
- Gate destructive tools behind an explicit environment flag or confirmation mechanism.
Compatibility note
Most of these can be additive and opt-in, except the safer default persistence path. If changing the default is too disruptive, a migration warning plus documented MEMORY_FILE_PATH recommendation would still help users avoid package-dir persistence.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No source file or test is named. Begin by locating the @modelcontextprotocol/server-memory persistence implementation and the handlers for the nine listed tools, then review existing tests and smoke checks. The work is complete only when the selected safety changes have separately defined acceptance checks for persistence, mutation protection, quotas, redaction, and namespace behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- backend, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100