Labsco
jagoff logo

memo

โ˜… 2

from jagoff

Local-first long-term memory for coding agents โ€” in-process embeddings (MLX/CPU), hybrid vector+BM25 search, markdown as source of truth. No cloud, no keys.

๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅโœ“ VerifiedFreeQuick setup
<div align="center"> <img src="docs/banner.jpg" alt="memo โ€” local memory for AI" width="100%" />

memo

Local-first semantic memory for AI agents โ€” with time-travel, contradiction radar, and automatic synthesis.

PyPI Downloads Python License: MIT MCP

</div> <!-- mcp-name: io.github.jagoff/memo -->

memo gives any MCP-aware agent (Claude Code, Codex, Devin, OpenCode, Cursor, Cline, Continue, โ€ฆ) a long-term memory that runs entirely on your own machine โ€” macOS on Apple Silicon via Apple MLX, or Linux / Ubuntu on a CPU sentence-transformers backend (pipx install "mlx-memo[cpu]", see docs/ubuntu.md). Each memory is a plain Markdown file; embeddings live in a single sqlite file; the embedder, reranker, and LLM run in-process โ€” no Ollama, no Qdrant, no cloud API, no keys. Your prompts and memories never leave the machine.

<div align="center"> <img src="docs/diagram-loop.svg" alt="Save a fact once and any later session recalls it automatically, all stored locally on your own machine." width="760" /> </div> <div align="center"> <img src="docs/demo.gif" alt="memo in a terminal: save a fact once, then a later session recalls it automatically." width="760" /> </div>

What makes memo different

Capabilitymemomem0lettacogneeengrambasic-memorycipher
100% local (no cloud API)โœ…โš ๏ธโš ๏ธโš ๏ธโœ…โœ…โš ๏ธ
Time-machine (rewind corpus to any date)โœ…โŒโš ๏ธโŒโŒโš ๏ธโš ๏ธ
Contradiction radar (detect + resolve conflicts)โœ…โš ๏ธโš ๏ธโŒโš ๏ธโŒโŒ
Synthesis pipeline (auto-infer cross-cluster insights)โœ…โŒโœ…โš ๏ธโŒโŒโš ๏ธ
Cross-Mac git sync (shared corpus, no server)โœ…โŒโš ๏ธโŒโœ…โœ…โš ๏ธ
Cloud sync (opt-in replication)โœ…โœ…โœ…โœ…โœ…โœ…โœ…
TUI (terminal UI)โœ…โŒโš ๏ธโŒโœ…โŒโœ…
Obsidian as source-of-truthโœ…โŒโš ๏ธโŒโŒโœ…โŒ
Knowledge graph + entity extractionโœ…โœ…โŒโœ…โŒโœ…โš ๏ธ
Eval regression gate (pre-commit wireable)โœ…โš ๏ธโš ๏ธโš ๏ธโŒโŒโŒ
Multi-modal (images, audio OCR)โœ…โš ๏ธโš ๏ธโœ…โŒโŒโŒ
MCP surface profiles (token economy)โœ…โŒโŒโš ๏ธโš ๏ธโœ…โŒ
Passive capture (auto-extract from transcripts)โœ…โš ๏ธโœ…โœ…โœ…โŒโš ๏ธ
Session timeline (context before/after)โœ…โŒโŒโŒโœ…โš ๏ธโš ๏ธ

<sub>โœ… first-class ยท โš ๏ธ partial, config-gated, or add-on ยท โŒ absent. Verified mid-2026 against each project's docs/repo: mem0, letta (formerly MemGPT), cognee, engram, basic-memory, cipher. Closest comparators: basic-memory (local-first + Obsidian + MCP โ€” memo's exact thesis) and cipher (memory layer for coding agents).</sub>

Why it pays for itself โ€” in tokens

memo is built to spend fewer tokens, not more.

  • 92% smaller MCP surface. The default agent profile exposes 10 tools / ~1.2k schema tokens, versus 126 tools / ~15k tokens for the full surface โ€” that overhead is paid every session, in every client. memo trims it to almost nothing.
  • Recall injects the answer instead of re-deriving it. Ambient recall surfaces the top memory before the agent answers, on a tight ~160-token budget. The agent stops re-explaining what it already figured out last week.

On a ~200-memory corpus, memo roi estimates ~80k tokens of model work avoided per session. The number is corpus-specific; it grows as memo learns more.

TechniqueHow to enableTypical saving
Compact recall formatexport MEMO_RECALL_FORMAT=compact~65% per injection
Trivial prompt gateOn by default~25% fewer injections
Context file compressionmemo compress-context CLAUDE.md30โ€“40% smaller context

Use cases

  • Continuity across sessions. Decide "we use Postgres, not Mongo" today; tomorrow, in a fresh session, the agent recalls it on its own โ€” recall injects the decision before it answers, so you never re-explain it.
  • Shared memory across agents. Save something while working in Claude Code; Codex, Cursor, or Cline pick it up later. They all read the same local store over MCP.
  • Memory that follows you across Macs. Start on the laptop, continue on the desktop. The corpus travels over serverless git sync and the agent starts with the same context on both.
  • Preferences and conventions that stick. "Tests first", "commit messages in English", "don't touch the auth module" โ€” say it once, the agent applies it every future session.
  • Contradiction radar. Change your mind on an old decision and memo flags the now-stale version โ€” the agent won't reintroduce what you already discarded.
  • Time-machine / audit. "What did we know about this bug last month?" Rewind the corpus to any date and see the state of knowledge at that point.
  • Instant project onboarding. A cold agent gets the project's durable decisions, facts, and preferences up front via the session-start briefing.
  • Fewer tokens, not more. Instead of re-deriving what you solved last week, recall injects the answer on a tight budget โ€” and the default MCP surface is ~10 tools, not ~120.

Hand it to your agent

memo installs itself if you hand the repo (or just the install line) to an AI agent:

Copy & paste โ€” that's it
curl -fsSL https://raw.githubusercontent.com/jagoff/memo/master/install.sh | bash
memo doctor --strict-runtime     # verify runtime is healthy

After install, tools surface as mcp__memo__memo_* (memo_save, memo_search, memo_ask, memo_get, memo_unified_briefing). Per-client setup (Claude Desktop, Cursor, Cline, Continue, manual JSON) is in docs/reference.md โ€บ MCP setup.

Core features

  • Ambient recall โ€” every prompt silently consults memory and injects top hits as context. Warm recall daemon keeps it under <200 ms. No /remember calls.
  • Auto-capture โ€” a Stop hook extracts durable insights from each exchange through a quality gate. The corpus grows on its own.
  • Session briefing โ€” SessionStart surfaces open loops, a memory of the day, and one-line crash recovery.

Key capabilities

๐Ÿ•ฐ๏ธ Time-machine

Rewind the corpus to any past date and query it as it was then:

Copy & paste โ€” that's it
memo as-of ask "what was the deployment strategy?" --date 2026-02-01
memo as-of search "redis config" --date 2026-01-15
memo diff --from 2026-01-01 --to 2026-03-01    # what changed

No other agent-memory system offers this. Full historical reconstruction via reverse-replay of history.db.

โšก Contradiction radar

Copy & paste โ€” that's it
memo contradict scan                  # detect conflicting facts corpus-wide
memo contradict triage                # resolve interactively: fuse / newer-wins / dismiss

The LLM classifies each candidate pair. Results persist in contradictions.db; resolved conflicts inform future saves.

๐Ÿ”ฎ Synthesis pipeline

Copy & paste โ€” that's it
memo synthesize                       # generate cross-cluster insights (LLM)
memo dream                            # nightly: signal gather โ†’ prune โ†’ orient

MEMO_SYNTHESIS_ENABLED=1 runs synthesis automatically during memo maintain. Nightly memo dream can also self-tune recall (MEMO_DREAM_TUNE_ENABLED=1): it mines ground-truth labels from real usage, adjusts the recall threshold, and auto-reverts if the eval baseline regresses.

๐ŸŒ Cross-Mac git sync

Copy & paste โ€” that's it
memo sync bootstrap git@github.com:yourname/memo-sync.git   # wire a shared corpus
memo sync once                                                # push/pull now

Pull-rebase-before-push. flock-based single owner per machine. Async debounced hooks keep the corpus current without blocking.

๐Ÿ“š Obsidian vault as source-of-truth

Copy & paste โ€” that's it
MEMO_MEMORIES_IN_VAULT=1 memo init                # store memories inside your vault
memo migrate --into-vault                          # non-destructive migration

Human edits in Obsidian win on the next memo reindex. The sqlite index is always rebuildable from the .md files.

๐Ÿ•ธ๏ธ Knowledge graph

Copy & paste โ€” that's it
memo graph neighbors "MLX"             # what's related
memo graph path "embedder" "reranker"  # how two concepts connect
memo entities                          # list extracted entities
memo links --id abc123                 # backlinks + outlinks

Entity extraction uses a dependency-free regex backend. For code-heavy corpora, memo can merge a codegraph symbol graph as the graph's primary layer (opt-in, MEMO_GRAPH_USE_CODEGRAPH) โ€” callers, callees, and imports become first-class edges, so recall and memo graph path reason over real code structure, not just text similarity. The merged graph also powers the memo_graph MCP tool and the entity-centric "Knowledge map" briefing.

๐Ÿฅ Health scoring & eval gates

Copy & paste โ€” that's it
memo health                                         # grounded rate, ROI, usefulness verdict
memo eval recall --labels eval/regression_labels.json --k 5
memo eval recall --gate                             # exit non-zero if precision drops
memo eval recall --update-baseline                  # snapshot current best

Wire --gate into a pre-commit hook to catch retrieval regressions before they ship. memo feedback records per-source ๐Ÿ‘/๐Ÿ‘Ž votes that teach the retriever which memories to surface (or hide) for similar queries.

๐Ÿ–ผ๏ธ Multi-modal ingestion

Copy & paste โ€” that's it
memo ocr-image screenshot.png               # macOS Vision OCR
memo multimodal add-image photo.jpg --title "whiteboard"
memo search "whiteboard diagram"            # finds it

Daemons

memo runs four background daemons:

DaemonCommandPurpose
recall-daemonmemo recall-daemon startWarm MLX embedder over socket (<200 ms recall)
idle-daemonauto-started by memo-mcpAuto-capture for MCP-only clients (Devin, OpenCode)
ingest-daemonmemo ingest-daemon startBulk vault ingestion
maint-daemonmemo maint-daemon startBackground cleanup + synthesis

All 104 CLI commands

<details> <summary>Click to expand</summary>

Core: save search ask get edit delete list

Recall & Hooks: recall recall-hook briefing continuity prewarm capture-tick capture-stop

Session & History: history as-of diff record-history session resume reflect mine-history episodes

Maintenance: reindex maintain dream consolidate synthesize dedupe cross-dedup retier contradict temporal compress-context

Analysis & Quality: health stats doctor lint analytics eval roi tokens token-savings usefulness gaps outcome profile

Knowledge Graph: graph entities entity extract-entities links version related

Advanced Search: embed rerank contextual chat chat-ask multimodal repo

Import / Export / Sync: import export backup restore sync ingest

Visualization: tui dashboard map logs hook-log

Setup & Config: init config install-mcp install-watcher uninstall-watcher install-slash install-statusline install-recall-hook install-shell-wrapper install-shims startup-banner migrate migrate-vault update watch release mcp-command

Daemons: recall-daemon ingest-daemon maint-daemon embed-daemon idle-daemon

Other: feedback query provenance mandate sleep-cycle ocr-image http-api codex-badge backend-native collaborative

</details>

MCP surface profiles

ProfileToolsSchema tokensUse when
agent (default)10~1.2kStandard agent work โ€” max token economy
core30~2.8kConstrained clients (Codex, OpenCode)
full123~15kPower users, debugging

Set via MEMO_MCP_PROFILE=full or in each client's MCP env config.

Non-MCP clients: memo http-api serves the same operations as a localhost REST API (plain JSON).

Retrieval architecture

Hybrid search: vec leg (MLX embedding on Apple Silicon, CPU sentence-transformers on Linux) + BM25 leg (FTS5/Tantivy, diacritic-folding for Spanish) fused via Reciprocal Rank Fusion โ†’ optional MLX cross-encoder rerank (Apple Silicon).

<div align="center"> <img src="docs/diagram-recall.svg" alt="A prompt runs a vector search and a keyword search in parallel; results are fused, reranked, and the top memory is injected." width="820" /> </div>

Markdown is the source of truth. The .md files are canonical; sqlite is a rebuildable index. A hand-edit in Obsidian wins on the next memo reindex. delete() removes the index first, then the file โ€” no silent data loss.

<div align="center"> <img src="docs/diagram-storage.svg" alt="Markdown files are canonical; the sqlite index is derived and can be rebuilt from them at any time." width="760" /> </div>

Embedding models:

ModelDimsDiskUse
Qwen3-Embedding-0.6B-4bit1024~0.4 GBDefault (fast, good)
Qwen3-Embedding-4B-4bit2560~2.5 GBHigher recall quality
Qwen3-Embedding-8B-4bit4096~5 GBMaximum quality

Switch with MEMO_EMBEDDER_MODEL + MEMO_EMBEDDER_DIMS (requires memo reindex --rebuild).

Documentation

TopicWhere
Full install detail, installer knobs, new-Mac migrationdocs/reference.md โ€บ Install
Per-client MCP setup + the /memo slash commanddocs/reference.md โ€บ MCP setup
All MCP tools referencedocs/reference.md โ€บ MCP tools
Ambient memory, recall daemon, capture & recall tuningdocs/reference.md โ€บ Ambient memory
Time-machine, session briefing, semantic mapdocs/reference.md โ€บ Surfaces
Full CLI reference + live dashboard (memo tui)docs/reference.md โ€บ CLI
All MEMO_* flags, model profiles, upgrading the embedderdocs/reference.md โ€บ Configuration
Architecture, sync tiers, design notesdocs/reference.md โ€บ Design & comparison

Contributors: git clone https://github.com/jagoff/memo && cd memo && uv pip install -e '.[dev]'. See CONTRIBUTING.md.

License & provenance

MIT โ€” see LICENSE. Forked philosophically from mem-vault (storage layout + frontmatter schema); the MLX backend pieces are ported from obsidian-rag. memo is one of three sovereign systems in a wider stack (Memflow, Synapse) โ€” the integration is opt-in everywhere; single-Mac users see zero behaviour change.