mnem

mcp
Guvenlik Denetimi
Gecti
Health Gecti
  • License — License: Apache-2.0
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 10 GitHub stars
Code Gecti
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
  • Permissions — No dangerous permissions requested
Purpose
This is an offline, versioned knowledge graph system designed to provide persistent memory for AI agents. It uses hybrid retrieval methods to help agents recall facts and relationships across sessions without requiring an LLM or a cloud connection.

Security Assessment
The overall risk is Low. The tool runs entirely offline and does not make external network requests. Because it is written in Rust, it is highly resilient to standard memory-safety vulnerabilities. A lightweight code scan of 12 files found no dangerous patterns, hardcoded secrets, or attempts to execute shell commands. Additionally, it does not request any dangerous system permissions.

Quality Assessment
The project demonstrates strong software engineering practices. It is actively maintained, with repository activity as recent as today, and uses CI pipelines for automated testing. The code is published to standard registries like crates.io and docs.rs. It is licensed under the permissive Apache-2.0 license, making it safe for integration into most projects. While the community is currently small (10 GitHub stars), the provided documentation and transparent design strongly suggest a reliable and well-built utility.

Verdict
Safe to use.
SUMMARY

Git for Knowledge Graphs: versioned agent memory with hybrid GraphRAG retrieval. Runs entirely offline, no LLM required.

README.md
mnem logo

mnem

Git for Knowledge Graphs: versioned agent memory with hybrid GraphRAG retrieval. Runs entirely offline, no LLM required.

License: Apache-2.0
CI
crates.io
docs.rs
MSRV 1.95
Runs on Linux macOS Windows WASM


What it is · Install · Quickstart · Integrate · Commands · GraphRAG · Benchmarks · vs others · Docs · Contributing


What it is

A content-addressed knowledge graph with hybrid GraphRAG retrieval, versioned commits, and deterministic ingest, built as a persistent memory substrate for AI agents.

Every node carries a cryptographic identity derived from DAG-CBOR + BLAKE3: the same content produces the same CID on any machine. Retrieval fuses vector (HNSW), sparse (BM25/SPLADE), and multi-hop graph traversal via RRF in a single pass, and every response reports exactly what candidates were seen and what got dropped at your token budget. Ingest is LLM-free. Single binary. No cloud. Compiles to wasm32.

What you get

mnem is strongest when:

  • facts accumulate across many sessions and you need to reason over history
  • queries require multi-hop traversal ("how does X relate to Y")
  • ingest must be deterministic and auditable - same bytes, same CIDs
  • deployment is edge, offline, or WASM (no network, no daemon required)
  • multiple agents write independently and need to merge without conflicts
Meaning
unique unique - not available in any other agent-memory system today
rare rare - available in 1-2 peers, often gated behind paid tiers
- standard capability, done well
  1. unique Versioned + 3-way mergeable. Commits, branches, diff, log, three-way merge, signed Ed25519 history. Two agents writing the same scope offline reconcile by graph + embedding merge, not "last write wins". → Core concepts

  2. unique Content-addressed objects. Every node / tree / sidecar / commit has a CID derived from canonical DAG-CBOR + BLAKE3. Identical content collapses across machines. Determinism + replay become real, not a slogan. Peers use opaque UUIDs. → Core concepts

  3. unique Token-budget transparency. Every retrieve emits tokens_used, candidates_seen, dropped counters. No silent truncation. No other agent-memory system exposes this as first-class response fields.

  4. unique WASM-clean core. mnem-core has no tokio, no filesystem, no network. Same retrieval logic compiles unchanged to wasm32 - runs in Chrome, on Cloudflare Workers, on Lambda cold-start. Graphiti + mem0 are Python + external DB stacks; they cannot ship to the edge.

  5. unique Skills as graphs, not markdown. Today, agent skills live in flat .md files - downloaded, pasted into prompts, hand-edited, never queried. mnem promotes them to a versioned, queryable, mergeable graph. Export your graph, import someone else's, diff the two, merge the parts you want.

  6. rare Best-in-class retrieval recall. Beats open-source peers on LoCoMo (+0.218 R@5), ConvoMem (+0.047), and MemBench (+0.120) under the same embedder; matches MemPalace on LongMemEval (R@5 0.966). Numbers reproducible with the shipped harness. → Benchmarks

  7. rare Plug-and-play. Bundled ONNX MiniLM-L6-v2 runs in-process. No Ollama, no API keys, no cold-start network call. mnem init and you're retrieving. mem0 + Graphiti both require an external LLM endpoint at ingest. → Install

  8. rare Single binary. ~40 MB Docker image. Embedded redb store. No daemon, no cloud, no account. Runs offline.

  9. rare Deterministic ingest. No LLM at ingest. parse + chunk + extract is statistical (KeyBERT optional), so same bytes in produces same CIDs out. Audit-friendly, fuzz-tested, byte-identical across machines. → Ingest pipeline

  10. rare Swappable providers. Embedder, sparse encoder, reranker, and LLM all set via config strings. Switch local ONNX to hosted Cohere with one flag. No fork, no rebuild. Most peers ship single-path stacks; provider swap is architectural here. → Embedding providers

  11. rare Four surfaces, one core. CLI, HTTP, MCP, and Python all wrap the same engine. mnem integrate wires the MCP server into Claude Desktop and other hosts. → CLI reference | MCP

  12. rare Property + fuzz tests. Parsers are property-tested + fuzz-harnessed; CAR round-trip and merge-commit are byte-identical. Trust signal usually only seen at the infra-DB tier.

  13. Hybrid GraphRAG retrieval. Vector (HNSW) + sparse (BM25 / SPLADE) + graph traversal, fused via RRF. GraphRAG built in and optional: on for multi-hop, off when dense saturates.


Install

[!NOTE]
--features bundled-embedder ships an in-process ONNX MiniLM-L6-v2 so mnem retrieve works with zero configuration. Omit the flag if you want to bring your own embedder (Ollama, OpenAI, Cohere) via .mnem/config.toml.

macOS / Linux
cargo install --locked mnem-cli --features bundled-embedder

# CUDA-accelerated embedder (Linux, NVIDIA GPU)
cargo install --locked mnem-cli --features bundled-embedder-cuda
Windows
cargo install --locked mnem-cli --features bundled-embedder

# DirectML-accelerated embedder (any GPU vendor on Windows)
cargo install --locked mnem-cli --features bundled-embedder-directml
npm / Node.js
⚠️ Temporarily unavailable
mnem-cli is not yet available on npm due to a package lock-out period and will be available by 2026-05-05. Use cargo install --locked mnem-cli --features bundled-embedder or download the prebuilt binary in the meantime.
npm install -g mnem-cli
mnem --version

# or without a global install (one-shot)
npx mnem-cli --version

Downloads the prebuilt native binary for your platform at install time. Node 18+ required. Bundled embedder included — no Ollama or API key needed.

Python (PyPI)
pip install mnem-cli
mnem --version

Ships the mnem binary as a manylinux / macOS / Windows wheel with the bundled embedder pre-baked.

Docker
docker run --rm -p 9876:9876 ghcr.io/uranid/mnem:latest http serve

The image includes the bundled embedder. Run mnem mcp inside the container for the MCP server surface.

From source
git clone https://github.com/Uranid/mnem
cd mnem
cargo install --path crates/mnem-cli --features bundled-embedder

Requires Rust 1.95+. If needed: rustup install 1.95 && rustup default 1.95.

mnem --version
mnem doctor        # checks embedder + store + config, prints a green/yellow/red checklist

Full install matrix: docs/src/install.md.


Quickstart

mkdir my-graph && cd my-graph
mnem init
mnem ingest README.md
mnem retrieve "what does this project do"

Five minutes from zero. See docs/src/quickstart.md for the full walkthrough.


mnem integrate - wire into any agent host

One command wires the MCP server entry, the UserPromptSubmit hook (for hosts that support it), and the mnem system prompt into the host's project-rules file. Restart the host and the agent starts using mnem automatically.

mnem integrate                           # interactive: detect installed hosts and prompt
mnem integrate claude-code               # wire a specific host, skip interactive detection
mnem integrate --all                     # wire every detected host without prompting

mnem integrate --check                   # report wired state for all hosts; nothing changes
mnem integrate --dry-run                 # preview what would be written without changing anything
mnem integrate --show claude-code        # print the MCP JSON block for manual copy-paste

mnem integrate --no-hooks                # skip UserPromptSubmit hook wiring
mnem integrate --no-system-prompt        # skip system prompt wiring
mnem integrate --target-repo ~/notes     # point the MCP server at a specific graph, not the global one

What gets wired:

  • MCP server (mcpServers.mnem) - the agent gets full mnem tool access via mnem mcp --repo <graph>; defaults to the global graph (~/.mnemglobal/.mnem)
  • UserPromptSubmit hook (Claude Code only) - runs mnem retrieve before each message, auto-injecting relevant memory into context
  • System prompt - mnem usage instructions injected into the host's project-rules file

The hook always queries your project's .mnem/ first (walking up from the current directory), then falls back to mnem global retrieve automatically. The hook and system prompt behave the same regardless of which default knowledge graph you choose during setup. Use --target-repo only if you want the MCP server to point somewhere other than the global graph.

Auto-detects and configures:

  • Claude Code
  • Claude Desktop
  • Cursor
  • Continue
  • Zed
  • Gemini CLI

Any other MCP-aware host works via a hand-edited mcpServers entry pointing at mnem mcp --repo <path> - see docs/src/mcp.md.

The agent gets the full mnem toolset as native tools: retrieve, commit, ingest, tombstone, traverse, global graph access, and more. No extra daemon, no port to manage. Full tool reference: docs/src/mcp.md.


Commands

Every command accepts --help for the full flag reference.

Init and health

mnem init      # create a new graph in the current directory
mnem doctor    # probe embedder + store + config; green/yellow/red checklist
mnem stats     # nodes, edges, refs, embedder health, repo size

Adding knowledge

mnem ingest notes.md                        # parse a file into Doc + Chunk + Entity nodes
mnem ingest --recursive docs/               # ingest a directory recursively
mnem ingest --chunker recursive report.pdf  # PDF with sliding-window chunking
mnem add node -s "Alice leads the infra team"                       # label defaults to "Node"
mnem add node --label Fact -s "Alice leads the infra team"          # add a single fact node
mnem add edge --from <uuid> --to <uuid> --label works_at            # connect two nodes

The ingest pipeline is deterministic: no LLM at ingest time, same bytes in always produce the same CIDs out. Audit-friendly and fuzz-tested.

Retrieving knowledge

mnem retrieve "what did we decide about the API design"  # searches local .mnem/ first, falls back to global
mnem -R ~/notes retrieve "query"                         # target a specific graph explicitly

-R <path> is a global flag that redirects any command to a specific repository directory. It overrides the walk-up search from the current directory and any default set via mnem integrate. Applies to all subcommands: mnem -R ~/notes status, mnem -R ~/notes log, etc.

Hybrid retrieval: vector (HNSW) + sparse (BM25/SPLADE) + graph traversal, fused via RRF. See GraphRAG for tuning flags.

The global graph

[!NOTE]
mnem has two scopes: the local graph (.mnem/ in your project directory) and the global graph (~/.mnemglobal/.mnem/). The global graph is for cross-project, cross-session facts that should follow you everywhere.

When to use local vs global:

Use local .mnem/ for Use mnem global for
Project-specific facts, decisions, code context People, preferences, facts that span all projects
Per-repo memory that travels with the repo Knowledge you want every session and every agent to see
Anything you'd commit alongside the code Cross-session continuity

mnem global is a full mirror of mnem but operates exclusively on the global graph:

mnem global retrieve "what is Alice's current role"     # search the global graph only
mnem global ingest contacts.md                          # ingest a file into the global graph
mnem global add node --label Entity:Person \
  --prop name=Alice -s "Alice leads the infra team"     # add a node to the global graph

The mnem integrate command sets up the agent to read local first and fall back to global automatically - no manual switching required during normal use.

History and branching

mnem log              # commit history
mnem diff             # what changed between commits
mnem branch           # list branches
mnem branch create feature-x    # create a new branch
mnem merge <branch>   # three-way merge (graph + embedding merge, not last-write-wins)

Inspect and explore

mnem query --where name=Alice                  # exact property match
mnem query --where kind=Person --with-outgoing knows  # match + follow edges

mnem ref              # list refs
mnem cat-file <cid>   # show a raw object
mnem blame <node-id>  # which commit introduced a node

Export, import, and servers

mnem export > graph.car        # dump the graph as a CAR archive
mnem import graph.car          # load a CAR archive into the current graph

mnem mcp                       # start the MCP JSON-RPC server over stdio
mnem mcp --repo ~/notes        # point the MCP server at a specific graph
mnem http serve                # start the HTTP JSON API (loopback by default)

Benchmarks

mnem bench                                       # interactive TUI; select benchmarks to run
mnem bench run --benches longmemeval --limit 50  # run a specific benchmark
mnem bench fetch longmemeval                     # download benchmark datasets
mnem bench results ./bench-out                   # re-render results from a prior run
mnem completions bash   # emit bash completion script (pipe into your shell rc)
mnem completions zsh    # zsh
mnem completions fish   # fish

Full CLI reference: docs/src/cli.md.


GraphRAG

mnem ships GraphRAG built in. One knob per stage, opt-in per query, never required. Vector search alone handles most queries well - turn graph stages on when queries span multiple documents, require multi-hop reasoning, or need compositional answers.

Stages and flags

Stage Flag What it does
Vector lane always on HNSW over per-commit dense embeddings (default 384-d MiniLM).
Sparse lane config-driven BM25 + SPLADE-onnx, fused with vector via Reciprocal Rank Fusion. Toggled by [sparse] block in config.toml.
Vector candidate pool --vector-cap <N> Lift the dense pool size from default 256. Higher = better long-tail recall, +cost.
Result limit --limit <N> Final returned set (default 10). Short form: -n.
Graph expansion --graph-expand <N> Add N neighbours of top-K seeds via authored edges. Audit-recommended default 20 when graph is on.
Graph mode --graph-mode <decay|ppr> decay (default) = exponential weight by hop. ppr = Personalised PageRank over the hybrid adjacency index, paper-grade scoring for multi-hop.
Community filter --community-filter Run Leiden community detection; drop low-coverage communities before fusion. Default coverage threshold: 0.5.
KeyBERT extraction mnem ingest --extractor keybert Ingest-time keyphrase enrichment. Strengthens sparse + community signals. Pass at ingest, not retrieve.
Summarisation --summarize Centroid + MMR summary of the top-K, with diversity.
Cross-encoder rerank --rerank <provider:model> Post-fusion reorder. Supports cohere:rerank-english-v3.0, voyage:rerank-1, local.

Quick examples

# Dense baseline
mnem retrieve "what does this project do"

# Add multi-hop graph traversal
mnem retrieve "..." --graph-expand 20

# Full stack: graph-expand + community-filter + PPR + rerank
mnem retrieve "..." --graph-expand 20 --community-filter --graph-mode ppr --rerank cohere:rerank-english-v3.0

# Stack a cross-encoder reranker on top
mnem retrieve "..." --graph-expand 20 --community-filter --rerank cohere:rerank-english-v3.0

# Ingest with KeyBERT keyphrase enrichment (strengthens sparse + community signals)
mnem ingest --extractor keybert notes.md

When to enable

  • Single-document corpus, simple queries: leave graph off, vector search alone is enough
  • Multi-hop / compositional questions: --graph-expand 20
  • Long history with cross-document references: add --community-filter
  • Recall ceiling needed: stack --rerank on top
  • Keyphrase-enriched ingest: mnem ingest --extractor keybert at ingest time

Full retrieval architecture: docs/src/cli.md (retrieve flags)


Benchmarks

ONNX MiniLM-L6-v2 embedder, same bytes on every system. No LLM rerank.
Dense retrieval (vector + top-k); the LongMemEval Hybrid v4 row mirrors
MemPalace's harness helper. Reproduce: bash benchmarks/harness/run_bench.sh.

vs MemPalace

MemPalace's column carries their public headline numbers, cross-verified
by running their adapter end-to-end under our harness. mnem's column comes
from the same harness, same embedder bytes (ONNX MiniLM-L6-v2), same
dataset hashes. Both columns are reproducible; raw artefacts in
benchmarks/proofs/v0.1.0/.

Benchmark Split Metric MP mnem Delta
LongMemEval 500 Q R@5 session 0.966 0.966 0
LongMemEval 500 Q R@10 session 0.982 0.982 0
LoCoMo 1986 Q R@5 session 0.508 $\color{green}{\textbf{0.726}}$ +0.218
LoCoMo 1986 Q R@10 session 0.603 $\color{green}{\textbf{0.855}}$ +0.252
ConvoMem 250 (5x50) avg recall 0.929 $\color{green}{\textbf{0.976}}$ +0.047
MemBench simple/roles 100 R@5 0.840 $\color{green}{\textbf{0.960}}$ +0.120
MemBench highlevel/movie 100 R@5 0.950 $\color{green}{\textbf{1.000}}$ +0.050
LongMemEval 500 Q hybrid-v4 R@5 session 0.982 $\color{red}{\textbf{0.976}}$ -0.006

vs mem0

mem0 doesn't publish recall@K headlines on these datasets, so both
columns are our reproductions: we ran mem0's adapter end-to-end under
the same harness, same embedder bytes (ONNX MiniLM-L6-v2), and the
same per-item scoping (infer=False + user_id-per-item) documented
in benchmarks/results/methodology.md.
Both columns reproducible; raw artefacts in
benchmarks/proofs/v0.1.0/.

Benchmark Split Metric mem0 mnem Delta
LongMemEval 500 Q R@5 session 0.946 $\color{green}{\textbf{0.966}}$ +0.020
LongMemEval 500 Q R@10 session 0.962 $\color{green}{\textbf{0.982}}$ +0.020
LoCoMo 1986 Q R@5 session 0.466 $\color{green}{\textbf{0.726}}$ +0.260
LoCoMo 1986 Q R@10 session 0.676 $\color{green}{\textbf{0.855}}$ +0.179
ConvoMem 250 (5x50) avg recall 0.558 $\color{green}{\textbf{0.976}}$ +0.418
MemBench simple/roles 100 R@5 0.410 $\color{green}{\textbf{0.960}}$ +0.550
MemBench highlevel/movie 100 R@5 0.970 $\color{green}{\textbf{1.000}}$ +0.030
LongMemEval 500 Q hybrid-v4 R@5 session 0.930 $\color{green}{\textbf{0.976}}$ +0.046

Latency

Benchmark mean retrieve total wall (n questions)
LongMemEval 500 Q 711 ms 1127 s (~19 min)
LongMemEval 500 Q hybrid-v4 729 ms 1133 s (~19 min)
LoCoMo 1986 Q 333 ms 720 s (~12 min)
ConvoMem 250 (5x50) 398 ms 218 s (~4 min)
MemBench simple/roles 100 1874 ms (e2e) 187 s (~3 min)
MemBench highlevel/movie 100 491 ms (e2e) 49 s (~1 min)

(e2e) = end-to-end mean when the adapter doesn't expose phase timing.

Reproduce

mnem bench fetch longmemeval     # download datasets (one-time, 264 MB)
mnem bench                       # TUI; select benchmarks interactively
mnem bench run --benches longmemeval --limit 50 --non-interactive
mnem bench results ./bench-out   # re-render results from a prior run

# Legacy bash harness (canonical path for headline numbers)
bash benchmarks/harness/run_bench.sh

Methodology, raw artifacts, per-bench breakdowns: benchmarks/ and docs/src/benchmarks/.


Compared to others

Full matrix: docs/src/comparisons/README.md.


When NOT to use mnem

  • You need transactional OLTP. mnem is append-only with versioned history; row-level UPDATE/DELETE semantics aren't the model.
  • You need sub-50 ms cloud-scale retrieval at 10k+ QPS. mnem is local-first. Multi-region sharded retrieval is on the roadmap, not in v1.

Looking for hosted memory, multi-region replicas, shared graphs across teams, or a managed remote layer? A sibling project bringing those to mnem is in active development - watch this space.


Crates

Crate Role
mnem-cli mnem binary - one command for everything
mnem-core graph model, retrieval, indexing, sidecars
mnem-http HTTP JSON server
mnem-mcp MCP server (stdio)
mnem-py PyO3 Python bindings
mnem-embed-providers ONNX bundled, Ollama, OpenAI, Cohere
mnem-sparse-providers BM25, SPLADE-onnx
mnem-rerank-providers Cohere, Voyage
mnem-llm-providers OpenAI, Anthropic, Ollama
mnem-ingest parse + chunk + extract pipeline
mnem-extract entity extraction (KeyBERT, statistical NER)
mnem-ner-providers NER provider trait + built-in providers (RuleNer, NullNer)
mnem-bench benchmark harness (LongMemEval, LoCoMo, etc.)
mnem-graphrag community summarisation, centroid + MMR
mnem-ann HNSW wrapper
mnem-backend-redb redb-backed store
mnem-transport CAR codec + remote framing

Documentation


Contributing

Issues and PRs welcome. Start here:

License

Apache-2.0. See NOTICE for third-party attributions.


Unintegrate / remove

mnem unintegrate                  # interactive: pick which hosts to remove mnem from
mnem unintegrate claude-code      # remove one host
mnem unintegrate --all            # remove all wired hosts

Run mnem unintegrate --help for all options.


Find mnem useful? A star is the strongest signal we get from a satisfied builder - it helps the next agent developer find this repo when they're stuck on memory. We read every issue, every PR, every mention. Tell us what you built.

Yorumlar (0)

Sonuc bulunamadi