Atlas / MCP servers / skynetcmd / m3-memory

m3-memoryBLOCK

mcp/skynetcmd/m3-memory

Local-first Memory Framework for AI Agents · 99.2% LongMemEval-S retrieval @ k=10 · Supports Claude · Antigravity · LangChain · Hermes · Gemini · OpenCode · OpenClaw · MCP-native and plugins · Hybrid search (FTS5 + vector + MMR) · GDPR · FIPS 140-3 ready · 100% local (fully offline) or cloud capable

Verdict
BLOCK
Grade
F
Trust score
28 /100
Exposed tools
27 19r · 6w · 2d
Transport
stdio · streamable-http
License
Apache-2.0
Stars
26
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

A memory layer that outlives your agents. You switch from Claude Code to Cursor, upgrade your model, start fresh next week — and everything your tools learned about your project is gone. You re-explain the same decisions, the same preferences, the same hard-won context, over and over.

m3 fixes that. It's a private, local-first memory your agents share and build on — so your project's knowledge accumulates instead of resetting every time the agent does. One memory store, on your machine, that your tools and agents read from and write to — whether that's Claude Code, Cursor, Gemini CLI, or any MCP-compatible agent.

Building something yourself? m3 is a memory backend, not a framework, and MCP is optional — every tool is a JSON-in/JSON-out CLI call, scriptable from any language, hook or CI job. Jump to the developer section ↓

Under the hood, m3 treats agent memory as a distributed-systems infrastructure problem, not a simple retrieval feature — a shared, evolving, bitemporal, contradiction-aware knowledge base that multiple heterogeneous agents and machines read and write, built to stay consistent over months and years.

The memory improves without being asked. m3 is not only a store you write to and read back. An autonomous Cognitive Loop (m3_cognitive_loop.py) runs in the background and keeps working on what you already saved: deferred enrichment — classification, embedding, and entity extraction — runs off the hot path, so a write stays fast while the understanding of it deepens afterwards, and the loop builds an entity relationship graph from memories that arrived as plain text. Curation is m3's own work, not an LLM's. Near-duplicate detection is cosine similarity over emb

Read from source at commit 87e4e7388898OBSERVED · 2026-10-09
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (pypi)
claude mcp add m3-memory -- python m3-memory==2026.10.7.1
03

Exposed tools (27)

19 read · 6 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
files_corpus_createwriteRegister a new corpus with optional default overrides.
files_corpus_deletedestructiveDelete a corpus
files_corpus_getreadFetch a single corpus
files_corpus_listreadEnumerate corpora with row counts.
files_corpus_setwriteUpdate settings for an existing corpus. None args are no-ops.
files_dedupreadScan leaf embeddings for near-duplicates. Detection only —
files_dedup_listreadList near-duplicate candidate pairs with text snippets and paths.
files_dedup_reviewreadRecord a review decision:
files_entity_coalescereadDetect provisional-entity coalescing candidates (quarantine noise +
files_entity_coalesce_applywriteApply the reversible same_as/cluster overlay. Union of explicit
files_entity_coalesce_listreadList entity-coalescing candidate pairs (name + score + band).
files_entity_coalesce_reviewreadRecord review decisions in BULK: pass a list of {uuid, action} where
files_entity_coalesce_unapplydestructiveReverse one coalescence cluster (drop edges, clear flags, strip
files_extract_pendingreadDrain leaves with extraction_status=
files_getreadFetch one record by UUID. Tries file_nodes then leaves.
files_healthwriteDB integrity + FTS5 sync check. Set rebuild=True to fix drift.
files_indexreadReturn file-level summaries for triage.
files_ingestreadWalk a directory and ingest supported files into files.db.
files_link_renamewriteRe-point an existing file_node at a new path (rename / move).
files_promotablereadList top promotion candidates by usage-weighted heuristic score.
files_promotereadPromote (ascend) a fact / leaf / file_summary from files.db to
files_promotion_listreadList existing promotions. source_superseded=True surfaces
files_searchreadHybrid FTS5 + vector search over leaves.
files_staleness_reviewreadCompare filesystem against files.db. Surfaces stale, touched-only,
files_statsreadCorpus-level counters: file_nodes, leaves, embed coverage.
files_watch_oncereadSingle-pass staleness check + notification dispatch. Suitable
save_handoffwriteSaves the current AI session state for another agent to resume.
04

Trust audit

BLOCKgrade F · trust 28/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)FAIL
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (16 observation(s))
Network
declared (8 observation(s))
Shell
declared (7 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

CRITICALHard-coded secrets · secret.anthropic · CWE-798, CWE-321
bin/chatlog_redaction.py:346
result = scrub("sk-ant-foobar12345678901234567890", cfg_off)
CRITICALHard-coded secrets · secret.anthropic · CWE-798, CWE-321
bin/chatlog_redaction.py:347
assert result == ("sk-ant-foobar12345678901234567890", 0, [])
CRITICALHard-coded secrets · secret.anthropic · CWE-798, CWE-321
bin/chatlog_redaction.py:356
"here is sk-ant-api03-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 keep it safe",
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
bin/memory_bridge.py:245
exec(src, ns)  # nosec B102 - src is built from static ToolSpec catalog, not user input
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
m3_memory/cli.py:200
exec(code, {"__file__": str(bridge), "__name__": "__main__"})  # nosec B102
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHNetwork egress · net.env_exfil · CWE-200, CWE-319
m3_memory/embedder_admin.py:482
os.environ.copy() ... socket.create_connection
Why it matters. reads secrets in the same file that sends data out
HIGHHard-coded secrets · secret.db_uri · CWE-798, CWE-321
bin/m3_core/paths.py:717
M3_DATABASE=postgresql://u:p@host:5432/agent_memory
HIGHPrompt injection · prompt.override · CWE-94, CWE-1427
docs/AGENT_INSTRUCTIONS.md:16
If your host agent ships with a built-in memory system — Claude Code's auto-memory (flat `.md` files under `.claude/projects/*/memory/` with a `MEMORY.md` index), a proprietary scratchpad, or any othe
Why it matters. asks the agent to drop prior instructions or safety
Fix. remove the instruction
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
bin/catalog/lazy.py:21
mod = importlib.import_module(self.module_name)
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
bin/memory/backends/registry.py:146
importlib.import_module(module_name)
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
bin/memory_core.py:345
val = importlib.import_module(f"memory.{real_sub}")
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
bin/memory_core.py:347
val = getattr(importlib.import_module(mod_name), "sha256_hex")
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
bin/memory_core.py:354
val = getattr(importlib.import_module(mod_name), name)
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
bin/dashboard_server.py:2993
print(f"    http://{display_host}:{resolved_port}/?token={token}\n")
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
m3_memory/cli.py:861
print(f"    {token}\n")
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
m3_memory/cli.py:864
print(f"    Value  : Bearer {token}")
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:33
#M3_EMBED_FALLBACK_URL=http://127.0.0.1:8082   # tier-2 CPU HTTP embed service
MEDIUMHard-coded secrets · secret.anthropic · CWE-798, CWE-321
tests/bench_oxidation.py:368
"sk-ant-api03-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 and the CI token is "
MEDIUMHard-coded secrets · secret.anthropic · CWE-798, CWE-321
tests/test_chatlog_redaction.py:23
content = "My key is sk-ant-abc123def456xyz789ab"
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/ci.yml:343
M3_PRIMARY_PG_URL: postgresql://m3dev:m3devpass@localhost:5432/m3_citest
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/ci.yml:360
M3_PRIMARY_PG_URL: postgresql://m3dev:m3devpass@localhost:5432/m3_citest
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/ci.yml:382
M3_PRIMARY_PG_URL: postgresql://m3dev:m3devpass@localhost:5432/m3_citest
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.github/workflows/ci.yml:401
M3_PRIMARY_PG_URL: postgresql://m3dev:m3devpass@localhost:5432/m3_citest
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/test_serve_auth.py:588
secret = "super-secret-token-value-0123456789abc"
MEDIUMHard-coded secrets · secret.github · CWE-798, CWE-321
tests/test_chatlog_redaction.py:107
content = "Token: ghp_abcdefghijklmnopqrstuvwxyz1234"

Gates applied: critical_finding, instruction_override, no_behavioural_pass.

Audited 2026-10-09 · audit v0.4.1 · source sha 87e4e7388898full audit observations/trust-audit/mcp-server/skynetcmd__m3-memory.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-0987e4e7388898BLOCKF28first audit
06

Questions

What is the m3-memory MCP server?

Local-first Memory Framework for AI Agents · 99.2% LongMemEval-S retrieval @ k=10 · Supports Claude · Antigravity · LangChain · Hermes · Gemini · OpenCode · OpenClaw · MCP-native and plugins · Hybrid search (FTS5 + vector + MMR) · GDPR · FIPS 140-3 ready · 100% local (fully offline) or cloud capable

What tools does m3-memory expose?

27 in total: 19 read-only, 6 that write, and 2 that can delete or overwrite (files_corpus_delete, files_entity_coalesce_unapply). Every one is listed on this page with its risk.

Is m3-memory safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (28/100) and found 8 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does m3-memory need?

It reads AGENT_OS_MASTER_KEY, ANTHROPIC_API_KEY, DD_PASSWORD, DD_TOKEN, GEMINI_API_KEY, GH_TOKEN, GITHUB_TOKEN, GROK_API_KEY, LM_API_TOKEN, LM_STUDIO_API_KEY, M3_BYPASS_SURFACE_CAP and M3_CLOUD_AUTH_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does m3-memory run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as frontend at 0.0.0.

How current is this page?

The grade is for one exact copy of the source (87e4e7388898), read on 2026-10-09. The repository is watched and re-audited when it changes.

Advertisement