{"id":"448db567-7252-4dbb-933e-0453d1a14fb6","slug":"memsem","kind":"mcp","name":"memsem","summary":"🧠 Semantic memory for AI agents — auto-writes durable facts, prioritizes, handles contradictions, semantic search. One command, works everywhere, 100% local.","owner":"WindSeries83","repoUrl":"https://github.com/WindSeries83/memsem","license":"MIT","licenseTier":"permissive","trust":"community","stars":2,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-08-04T04:43:42.000Z","addedAt":"2026-10-21T09:25:55.022Z","logoUrl":"https://avatars.githubusercontent.com/u/155915696?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["memory-knowledge","search","developer-tools"],"tags":["ai-agents","claude-code","llm","memory","opencode","persistent-memory","semantic-memory"],"runtime":"node","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-28T00:08:16.958Z","sample":false,"url":"https://conduits.dev/tools/memsem","language":"TypeScript","transports":["stdio"],"install":{"npm":"memsem"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<p align=\"center\">\n  🌍 <strong>Languages:</strong>\n  <a href=\"README.md\">🇬🇧 English</a> ·\n  <a href=\"README.fr.md\">🇫🇷 Français</a> ·\n  <a href=\"README.de.md\">🇩🇪 Deutsch</a> ·\n  <a href=\"README.es.md\">🇪🇸 Español</a> ·\n  <a href=\"README.it.md\">🇮🇹 Italiano</a> ·\n  <a href=\"README.pt.md\">🇵🇹 Português</a> ·\n  <a href=\"README.nl.md\">🇳🇱 Nederlands</a> ·\n  <a href=\"README.ru.md\">🇷🇺 Русский</a> ·\n  <a href=\"README.ja.md\">🇯🇵 日本語</a> ·\n  <a href=\"README.zh.md\">🇨🇳 中文</a> ·\n  <a href=\"README.ko.md\">🇰🇷 한국어</a> ·\n  <a href=\"README.pl.md\">🇵🇱 Polski</a> ·\n  <a href=\"README.tr.md\">🇹🇷 Türkçe</a> ·\n  <a href=\"README.uk.md\">🇺🇦 Українська</a> ·\n  <a href=\"README.hi.md\">🇮🇳 हिन्दी</a> ·\n  <a href=\"README.vi.md\">🇻🇳 Tiếng Việt</a>\n</p>\n\n<p align=\"center\">\n  <img src=\"assets/hero.svg\" alt=\"memsem — semantic memory for AI agents\" width=\"900\">\n</p>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/memsem\"><img src=\"https://img.shields.io/npm/v/memsem\" alt=\"npm version\"></a>\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/npm/l/memsem\" alt=\"License: MIT\"></a>\n  <img src=\"https://img.shields.io/badge/node-%3E%3D22.13-339933\" alt=\"Node >= 22.13\">\n  <a href=\"https://github.com/WindSeries69/memsem/actions\"><img src=\"https://img.shields.io/github/actions/workflow/status/WindSeries69/memsem/ci.yml?branch=main&label=CI\" alt=\"CI\"></a>\n  <img src=\"https://img.shields.io/badge/MCP-server-1f1f1f\" alt=\"MCP server\">\n  <img src=\"https://img.shields.io/badge/opencode-plugin-000\" alt=\"opencode plugin\">\n</p>\n\n> **Semantic memory for AI agents** — remembers what matters, knows what to forget.\n> One command to install. Works in *every* project, for *every* AI. 100% local.\n\n## Why — when big memory systems already exist?\n\nThey exist, and they got the hard parts right: vector stores (mem0), temporal\nknowledge graphs (Zep / Graphiti), agent frameworks (MemGPT / Letta). But they\nall share the same three flaws:\n\n1. **Brute storage, no structure.** They keep what you throw at them, and\n   retrieval is a similarity search over *everything*. The AI doesn't know\n   **where to look** — so it looks everywhere, and the noise drowns the signal.\n2. **No precision.** A fuzzy match is a fuzzy match: almost-right memories\n   fill the context budget and waste tokens.\n3. **No self-correction.** A fact contradicted months ago stays as strong as\n   the day it was written.\n\nmemsem fixes exactly these three things:\n\n- 🧭 **It knows where to search.** Every session starts with a routing card\n  (`memory-index.md`): themes + keywords, injected into the context. The AI\n  routes by theme, crosses projects, and only pays for what it needs.\n  Hierarchical themes + a live focus list keep the session's active branches\n  at full priority — the rest is attenuated, never lost.\n- 🎯 **It is precise.** Strict lexical search by default (50% word-match\n  threshold, no graph propagation unless you explicitly ask) — a query returns\n  the right facts, ranked by dynamic priority\n  (`importance × confidence × recency × frequency`). Precision is measured,\n  not assumed: **P@3 0.958** on the reference benchmark (51 facts, 20 queries,\n  [`scripts/bench.mjs`](scripts/bench.mjs), results in\n  [`DESIGN.md`](DESIGN.md) §11).\n- 🔄 **It corrects itself.** Contradictions fade the old fact instead of\n  overwriting it (\"I drank milk for years… wait, lactose intolerant\") — history\n  is always kept, critical facts (≥ 0.8) are protected. Background agents\n  extract durable facts at session end, consolidate small facts into patterns,\n  and recalibrate priorities — only when the memory stays *at least as\n  searchable*.\n\nAll the big-system promises, minus their flaws: one command, 100% local, and\nyour memory stays yours — never committed, per-user, shared across all your repos.\n\n## See it work\n\nInstall once, let it run. This is a real session on a throwaway database — your actual memory is never touched (`node scripts/demo.mjs`):\n\n<p align=\"center\">\n  <img src=\"assets/demo.svg\" alt=\"memsem demo — terminal output\" width=\"860\">\n</p>\n\n```\n=== memsem — demo on a temporary database ===\n(your real memory in ~/.memory-mcp stays untouched)\n\n1. The AI writes durable facts (memory_add_many)\n   → 4 facts written\n\n2. Strict search (lexical): memory_search { query: 'milk' }\n   → user → drinks → milk\n\n3. Semantic search (relax, local embeddings): memory_search { query: 'cheese', relax: true }\n   No shared word with « lactose » — the local semantic index (Ollama) bridges it\n   → lactose → is-present-in → cheese, yogurt, cream\n   → user → is-intolerant-to → lactose\n   → user → drinks → milk\n\n4. Soft supersession: the AI learns you no longer drink milk\n   → conflict: true, old fact faded (faded: [1])\n\n5. Search now returns the current fact\n   → user → drinks → no more milk (lactose intolerant)\n   → user → drinks → milk\n\nStats: 5 active memories, semantic index OK (mxbai-embed-large)\n```\n\n## Privacy — your memory is yours\n\n- **100% local** — stored in `~/.memory-mcp/memory.db` on *your* machine. No cloud, no telemetry, nothing leaves your computer.\n- **Never committed** — the database lives outside every repository. Clone a public repo, push code, share screenshots: your memory stays with you. Each user has their own memory.\n- **The memory follows *you***, not your projects — the same base is shared across all your repos. Create a new folder, a new repo: the memory is still there.\n\n## Install\n\n### opencode — one line\n\nAdd to `opencode.json` (project or `~/.config/opencode/opencode.json`):\n\n```json\n{ \"plugin\": [\"memsem\"] }\n```\n\nThat's it. The plugin registers the MCP server, injects the memory protocol and the memory index into every session, grants the needed permissions, and runs the background agents. Restart opencode.\n\n### Claude Code — one command\n\n```bash\nnpx -y memsem setup\n```\n\nThis registers the MCP server (`claude mcp add memory -- npx -y memsem`) and adds a \"memsem memory\" block to `~/.claude/CLAUDE.md` pointing to the full protocol.\n\n**Or install it with AI**: just paste into Claude:\n\n> Install the memsem persistent memory: run `npx -y memsem setup`, read `~/.memsem/memory-protocol.md`, and apply the protocol.\n\n### Any MCP client\n\n```bash\nnpx -y memsem\n```\n\nThe server speaks MCP over stdio. Point any MCP-capable host at it and inject `memory-protocol.md` into the host's instructions (e.g. as `AGENTS.md`) to make the AI autonomous.\n\n### Universal installer\n\n```bash\nnpx -y memsem setup        # detects and configures your hosts (opencode, Claude)\nnpx -y memsem setup --help # see options\n```\n\nIdempotent, safe, reversible (`--uninstall`).\n\n## How it works\n\n<p align=\"center\">\n  <img src=\"assets/architecture.svg\" alt=\"memsem architecture\" width=\"920\">\n</p>\n\n**The memory lifecycle** — every fact follows the same path:\n\n```mermaid\nflowchart LR\n    W[\"memory_add — subject → predicate → object\"] --> R[\"repeated → confidence ↑ frequency ↑\"]\n    W --> P[\"priority = f(importance, confidence, recency, frequency)\"]\n    R --> S{\"contradiction?\"}\n    S -- yes --> F[\"old fact fades progressively\"]\n    F --> A[\"archived — history always kept\"]\n    S -- no --> K[\"kept, reinforced\"]\n    A --> J[\"pinned & critical (≥ 0.8) are protected\"]\n```\n\n- **Atomic facts** — every memory is a `subject → predicate → object` triple with importance, confidence, frequency, tags, theme, provenance, trust and evidence.\n- **Themes & focus** — hierarchical themes (`food/drinks`) are the routing map; a search by theme crosses all projects. The `focus` list keeps the session's active themes at full priority.\n- **Dynamic priority** — `0.45 × importance + 0.25 × confidence + 0.2 × recency + 0.1 × frequency`. A critical fact beats a recurring pattern.\n- **Soft supersession** — contradictions fade the old fact (confidence decays) until it archives under a threshold. History is always kept.\n- **Semantic index (optional)** — each fact is embedded locally (`mxbai-embed-large` via Ollama); `relax: true` searches add cosine similarity (threshold 0.5). Without Ollama, everything works identically — strict lexical search.\n- **Evidence and time** — `inferred`, `verbatim` and `verified` trust states keep a short evidence trail; `recorded_at` is separate from `valid_from` / `valid_until`, with historical `asOf` queries.\n- **Review and scope** — uncertain facts can stay `pending`; rejection blocks their normalized value, project scope is isolated by default, and cross-project search is explicit.\n\n## Known limitations\n\nRead honestly, from an independent review ([Agent Memory Atlas](https://neoneye.github.io/agent-memory-atlas/systems/memsem/)):\n\n- **The automatic correction path has no lock.** A rejected value that is\n  *re-asserted* (say the same old transcript is read ten times) returns and\n  fades its own correction — an ordinary correction is archived at the third\n  re-assertion. Only a **human rejecting a candidate** writes a durable\n  suppression (`memory_suppressions`) that refuses the value outright. This is\n  a deliberate position (repetition is evidence) with a real cost.\n- **A pin protects survival, not visibility.** A pinned correction never loses\n  confidence and stays first in `memsem list`, but a repeated rejected value\n  can still take the top `memory_search` result.\n- **`import` writes past the gate** — restoring a backup reinstates a\n  suppressed value.\n- **A refused write leaves no audit row**, and purging a reviewed fact leaves\n  its text in `memory_candidates`.\n- **Consolidation and extraction safety rules are prompts, not code.**\n\nRough edges, not bugs — each is tracked in [DESIGN.md](DESIGN.md) roadmap and\nopen questions.\n\n## Comparison\n\n| | memsem | `CLAUDE.md` / notes | mem0 | Zep / Graphiti | official memory MCP | Obsidian as memory |\n|---|---|---|---|---|---|---|\n| Auto-writes during sessions | ✅ | ❌ | ⚠️ via app code | ⚠️ via app code | ❌ | ❌ |\n| Priority for context budget | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |\n| Contradictions (soft supersession) | ✅ | ❌ (overwrites) | ❌ (overwrites) | ✅ (temporal versioning) | ❌ | ❌ |\n| Semantic search | ✅ local (Ollama) | ❌ | ✅ (vector store) | ✅ (graph + embeddings) | ❌ | ⚠️ (plugins) |\n| Episodic memory + self-maintenance | ✅ | ❌ | ⚠️ (episodic add-ons) | ✅ (temporal knowledge graph) | ❌ | ❌ |\n| One memory across all your repos | ✅ | ❌ (per project) | ⚠️ (per app config) | ⚠️ (per app config) | ❌ | ⚠️ (vault) |\n| Zero dependency, `npx -y` | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |\n| Human-readable / editable | ⚠️ (CLI list/edit) | ✅ | ❌ | ❌ | ✅ (JSON) | ✅ |\n\n*Comparison as of Aug 2026, from public docs; capabilities evolve — verify before choosing.*\n\n## Command line\n\nEverything that can be done through MCP can be done from a terminal:\n\n```bash\nmemsem list [--theme x] [--project p] [--limit n] [--all]   # read your memory\nmemsem edit <id> [--object \"...\"] [--importance 0.6] [...]  # fix a fact by hand (audited)\n  memsem forget <id> [--yes]                                  # archive a fact (confirm)\n  memsem purge <id> [--yes]                                   # permanently erase a fact (confirm)\nmemsem doctor [--limit n] [--hours h]                       # most-modified facts — spot drift\nmemsem export [--output f] [--project p]                    # full JSON dump\nmemsem import <file.json>                                   # restore / merge a dump\nmemsem setup [--host opencode|claude]                       # install for your hosts\n```\n\nManual fixes are written to the audit journal — `memsem doctor` shows them too.\n\n## Configuration\n\nTunable constants (priority weights, thresholds, fade factors, model…) live in\n[`src/config.ts`](src/config.ts). Override any of them in `~/.memsem/config.json`\n(or `$MEMSEM_CONFIG`), deep-merged with validation:\n\n```json\n{ \"priority\": { \"importance\": 0.4, \"confidence\": 0.3 }, \"minLexical\": 0.4 }\n```\n\nSettings are documented and validated by a benchmark\n([`scripts/bench.mjs`](scripts/bench.mjs) — 51 facts, 20 queries, P@k/R@k across\nconstant sets; results in [`DESIGN.md`](DESIGN.md) §11).\n\n## Durability\n\nThe database is versioned and migrated automatically at startup (`schema_migrations`),\nwith an automatic backup before any migration (`~/.memory-mcp/backups/`, last 5 kept).\nWAL mode is on — a crash mid-write leaves the database intact. Full dumps and\nrestores via `memsem export` / `memsem import`.\n\n## Documentation\n\n- [`memory-protocol.md`](memory-protocol.md) — the protocol injected into your AI: how it writes, searches, and maintains memory automatically.\n- [`DESIGN.md`](DESIGN.md) — full design: vision, principles, the lactose case study, constant calibration, roadmap.\n- [`scripts/demo.mjs`](scripts/demo.mjs) — reproduce the demo above on a throwaway database.\n\n## Roadmap\n\n- [x] Semantic index (local Ollama embeddings)\n- [x] Episodic memory + session extraction\n- [x] Hippocampus consolidation + pairwise scoring judge\n- [x] Universal opencode plugin + `memsem setup`\n- [x] Versioned migrations + automatic backup + export/import\n- [x] Configurable constants, validated by a benchmark\n- [x] Secure judge: dry-run, audit journal, guardrails, `memsem doctor`\n- [x] CLI: `list` / `edit` / `forget` — fix a fact by hand\n- [x] Evidence contract, temporal validity, candidate review, audit and confirmed purge\n- [x] Multi-hop graph propagation (relax mode)\n- [ ] Write gate on the automatic path (supersession → suppression decision)\n- [ ] `import` behind the gate (consult suppressions)\n- [ ] Audit refused writes; purge candidate text; consolidation rules in code\n- [ ] Obsidian bridge: export/import memory as readable markdown notes\n\n## License\n\nMIT — free for anything. Your memory stays yours.\n"}