# MidMem

> Middleware memory layer for LLM agents: a shared knowledge store with hybrid retrieval, tiered memory, a knowledge graph, and governance, exposed over MCP, CLI, and API.

- **Type:** MCP server
- **Install:** `agentstack add mcp-u4csolutions-midmem`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [U4CSolutions](https://agentstack.voostack.com/s/u4csolutions)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [U4CSolutions](https://github.com/U4CSolutions)
- **Source:** https://github.com/U4CSolutions/MidMem

## Install

```sh
agentstack add mcp-u4csolutions-midmem
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# MidMem KB Store an LLM Wiki Router

A self-contained **LLM Wiki middleware layer**: a single source-of-truth knowledge store with
**hybrid retrieval (lexical + vector)**, tiered memory, a typed knowledge graph, claim
provenance, **fail-closed governance**, and an Obsidian projection — exposed to LLM agents over
the **Model Context Protocol (MCP)**, a CLI, and a programmatic API.

> **New here?** [Getting started](docs/GETTING-STARTED.md) (5 minutes, offline-capable) ·
> [Concepts](docs/CONCEPTS.md) · [Wire your agent](docs/INTEGRATION-MODES.md) ·
> [Operations](docs/OPERATIONS.md) · generated [tool/CLI/config reference](docs/README.md#reference-generated--node-scriptsgen-docsmjs-drift-checked-in-ci)

It is the broker between AI agents and their knowledge: agents `ingest`, `query`, and `remember`
through the router; the knowledge store sits *behind* it. Built for the OpenClaw + Hermes
dual-stack, but pure-core and modular — it runs in **4 modes** (standalone curation · OpenClaw
add-on · Hermes add-on · bridge) via exactly three surfaces: CLI, MCP, and the `bin/hook.mjs`
pre/post-turn seam. See [Integration](#integration) + `docs/INTEGRATION-MODES.md`.

> **Status (2026-07-02; 2026-08 wave appended 2026-08-06):** foundation + cross-agent scope + native→middleware bridge + retrieval
> upgrades (trust, trigram, token-budget, graph-boost, dim-guard) + selectable Qdrant vector backend +
> hand-off memory gate + self-driving lifecycle (decay / usage-earned promotion / auto-projection) +
> trigger-less `proactiveRecall` + DELEGATE-52 extraction grounding + **work-memory events with
> deterministic auto-ingest & categorization** (Brain adaptation) + **P4 temporal/workflow ranking
> boosts** + **P5 concept-node embeddings, communities & query routing** + **P6 claim supersede /
> contradiction / current()** + **P7 offline Brain-style benchmark** + **concept canonicalization
> (case/plural dedupe, curated `merge-concepts`, alias-aware retrieval)** + **vault projection
> pruning (stale pages removed; case-insensitive-share-safe slugs)** + **realpath ingest guard** +
> **log/audit/vector retention**.
>
> **2026-08 wave:** **transition verifier** (TRUSTMEM supersede/promote gates) + **write-path claim
> conflict tagging** (MOSAIC) + **projection QA probes** (WiCER) + **memory-function axis**
> (episodic/semantic/procedural/prospective) + **capture packs** (domain extensibility as data) +
> **prospective memory** (intent + trigger; cron fires, MidMem informs) + **revision export**
> (stable-byte JSONL snapshot) + **bulk hygiene family** (`close-tasks` · `forget-entries` ·
> `forget-nodes` with cascading edge delete) + **orphan-edge integrity sweep** in retention.
> Tested: smoke **163/163** + bench green (`npm run verify`); claims-vs-code audit:
> [`docs/ARCHITECTURE-BASIS.md`](docs/ARCHITECTURE-BASIS.md).
> Runnable Node ESM, **zero external dependencies** (Node ≥ 22.13 built-ins only: `node:sqlite`,
> `crypto`, `fetch`). `packages/core/` is the sole package — the active, self-contained foundation
> (the superseded interim scaffold was removed; it remains in git history if ever needed).

---

## Why

A single always-loaded memory file does not scale — it taxes every turn's context window. This
middleware decouples **capacity** from per-turn context: agents hold a tiny canonical index and
pull the relevant slice **on demand** via hybrid retrieval from an unbounded, shared store.

## Architecture

```mermaid
flowchart TB
    src([sources]) -->|ingest| extract["LLM extract — concepts · claims · embeddings(deterministic offline fallback)"]
    extract -->|transactional write| DB[("state.db — SINGLE source of truthentries · entries_fts (FTS5/BM25) · vectorsnodes · edges · claims · log")]

    DB -->|"project (LLM-owned)"| vault[["Obsidian vault (projection)"]]
    verify["verify (deterministic, one graph)"] -->|"consistency check"| DB

    DB |"query: FTS5 ⊕ trigram ⊕ vector (RRF) + trust / graph boosts"| mcp{{"MCP server (37 tools) · CLI · hook seam"}}

    mcp  oc["OpenClaw(daily driver)"]
    mcp  hz["Hermes Agent(build workhorse)"]
    mcp  cc["Claude Code(frontier orchestrator)"]

    cc -->|"plans · QAs · drives via kanban / ACP"| hz
    skills["MidMem Skills Library (Claude Code)midmem-dev · midmem-orchestratormidmem-ingest-review · midmem-record"] -.->|equip| cc
```

The three consumers share one `state.db` over the same MCP/CLI/hook surface. **Claude Code** is the
frontier-orchestration overlay: it drives Hermes (plan → dispatch build → QA) and records durably —
equipped by the **MidMem Skills Library** that ships in [`skills/`](skills/).

- **`state.db` is the source of truth**; the markdown vault is a deterministic projection of it.
- **Hybrid retrieval**: SQLite FTS5/BM25 (token lexical) ⊕ FTS5-trigram (substring lexical) ⊕ vector
  cosine (semantic), fused via Reciprocal Rank Fusion, plus trust + graph ref-chain boosts and an
  optional token budget. Vectors are incremental — lexical works standalone.
- **Vector backend is pluggable**: `sqlite` (in-DB JSON cosine, zero-dep, default) or `qdrant` (external ANN).
- **Tiers**: `fact` (raw, 7d TTL) → `memory` (synthesized, 30d) → `wisdom` (curated, ∞), with trust scoring.
- **Scope**: every entry is `openclaw` | `hermes` | `shared` — private working memory + a shared commons.
- **Hand-off gate ("firstware")**: pushes a memory brief into an agent hand-off so the receiver can't overlook it.

---

## Abstraction layers

The middleware is composed of swappable layers. **Required** layers must be present to function as
an LLM Wiki middleware; **recommended** layers add capability and are safe to defer.

| Layer | Module | Required? | Purpose | Swap / configure |
|---|---|---|---|---|
| **Integration / transport** | `bin/mcp-server.mjs` (MCP stdio) · `bin/cli.mjs` · `src/orchestrator.mjs` (API) | **Required** | The contract agents speak. MCP is primary; CLI + API are alternates. | register per stack (below) |
| **Store** | `src/db.mjs` (`state.db`) | **Required** | Single source of truth + unified index. | `MIDMEM_DB_PATH`; move to a shared path/NAS |
| **Retrieval** | `src/retrieval.mjs` | **Required** | Hybrid FTS5 ⊕ trigram ⊕ vector (RRF) + trust/graph boosts + token budget. | `fusionWeights`, `rrfK`, `trustWeight` |
| **Vector store** | `src/vectorstore.mjs` | **Required** | Pluggable ANN: `sqlite` (default) \| `qdrant`. Holds id→vector; `state.db` keeps metadata. | `MIDMEM_VECTOR_BACKEND`, `MIDMEM_QDRANT_URL` |
| **Embedding** | `src/embeddings.mjs` | **Required\*** | Vectors for the semantic lane + dimension guard. *Deterministic fallback if no model.* | `MIDMEM_EMBED_MODEL`, `MIDMEM_LLM_ENDPOINT` |
| **Governance** | `src/governance.mjs` | **Required** | Fail-closed policy gating on every mutation. | extend `defaultPolicies()` |
| **Tiered memory** | `src/memory.mjs` | Recommended | fact→memory→wisdom lifecycle (TTL, promote, archive). | `tiers` in config |
| **Extraction** | `src/extract.mjs` | Recommended | LLM concept/claim extraction. *Heuristic fallback.* | `MIDMEM_EXTRACT_MODEL` |
| **Graph** | `src/graph.mjs` | Recommended | Typed entities/edges; wikilinks; graph-context. | — |
| **Claims / provenance** | `src/claims.mjs` | Recommended | Synthadoc-style claim audit trail. | — |
| **Verification** | `src/verify.mjs` | Recommended | Deterministic contradiction/identity checks. | `sigmaStrictMode` |
| **Projection** | `src/project.mjs` | Recommended | Render `state.db` → Obsidian markdown. | `OBSIDIAN_VAULT_PATH`, `WIKI_PATH` |
| **Scope** | (in store/retrieval/governance) | Required *for dual*, else optional | Multi-agent private + shared partitioning. | `MIDMEM_AGENT_SCOPE` |
| **Bridge** | `src/bridge.mjs` (`midmem bridge`) | Recommended | Pull each stack's flat native memory into the store. | `bridgeSources` |
| **Trust / feedback** | (memory + retrieval) | Recommended | `trust_score` + usage/`feedback` loop; boosts ranking. | `trustWeight`, `feedback` tool |
| **Hand-off gate** | `src/handoff.mjs` (`handoff_brief`) | Recommended | Push a scoped memory brief into an agent hand-off (firstware). | profiles `local` / `frontier` |

\* The embedding layer is required for semantic recall, but the system **runs without a live model**
via a deterministic hash embedder (lexical retrieval still works). Load a real model before
production ingest so vectors are semantically meaningful.

---

## Integration

The middleware speaks MCP, so any MCP-capable agent can use it. Three supported topologies:

> **How knowledge is *captured* per stack** (OpenClaw · Hermes · Claude Code), what's reliable and what
> isn't, is in **[`docs/STACK-CAPTURE.md`](docs/STACK-CAPTURE.md)**. Packaged, reusable per-turn capture
> code + honest deployment status is in **[`integrations/`](integrations/)** (Hermes core capture is
> LIVE; the OpenClaw plugin is retired/reference). Engineering + grounding rules:
> **[`docs/DEVELOPMENT-GUIDELINES.md`](docs/DEVELOPMENT-GUIDELINES.md)**.

### Claude Code (composes with any option below)
Two files and you're wired — a project-root `.mcp.json` pointing at a thin `midmem-mcp` wrapper,
approved once via `"enabledMcpjsonServers": ["midmem"]` in `~/.claude/settings.json`. The wrapper
sources the same shared env file as your `midmem` CLI wrapper (single source of truth — never
duplicate env), sets `MIDMEM_AUTO_INGEST=0` (auto-ingest keeps exactly one owner), and execs
`bin/mcp-server.mjs`. All 37 tools then load natively in every session. Full recipe + the three
guardrails (env drift, ingest ownership, long-lived-process vs core development):
**[`docs/INTEGRATION-MODES.md` §5](docs/INTEGRATION-MODES.md)**. The in-repo
[skills library](skills/) equips the sessions themselves.

### Option A — OpenClaw only (1:1)
Register the MCP server in OpenClaw; it's the sole consumer. A single agent needs no scope
partitioning, so use `MIDMEM_AGENT_SCOPE=shared`.

```bash
openclaw mcp set middleware-memory '{
  "command": "node",
  "args": ["/path/to/midmem-kb-store/packages/core/bin/mcp-server.mjs"],
  "env": {
    "MIDMEM_DB_PATH": "/path/to/midmem-kb-store/state.db",
    "OBSIDIAN_VAULT_PATH": "/path/to/vault",
    "WIKI_PATH": "LLM Wiki",
    "MIDMEM_LLM_ENDPOINT": "http://localhost:1234/v1",
    "MIDMEM_EMBED_MODEL": "bge-m3",
    "MIDMEM_AGENT_SCOPE": "shared"
  }
}'
```

### Option B — Hermes only (1:1)
Register in `~/.hermes/config.yaml`; Hermes is the sole consumer. `MIDMEM_AGENT_SCOPE=shared`.

```yaml
mcp_servers:
  middleware-memory:
    command: node
    args:
      - /path/to/midmem-kb-store/packages/core/bin/mcp-server.mjs
    env:
      MIDMEM_DB_PATH: /path/to/midmem-kb-store/state.db
      OBSIDIAN_VAULT_PATH: /path/to/vault
      WIKI_PATH: LLM Wiki
      MIDMEM_LLM_ENDPOINT: http://localhost:1234/v1
      MIDMEM_EMBED_MODEL: bge-m3
      MIDMEM_AGENT_SCOPE: shared
```

### Option C — Dual integration (OpenClaw + Hermes, shared store)
Register in **both**, pointing at the **same `MIDMEM_DB_PATH`** — one shared knowledge store. Set a
**distinct `MIDMEM_AGENT_SCOPE` per stack** (`openclaw` / `hermes`) so each gets private working
memory plus the shared commons:

- OpenClaw registration: `MIDMEM_AGENT_SCOPE=openclaw`
- Hermes registration: `MIDMEM_AGENT_SCOPE=hermes`

Behavior: writes default to the caller's scope; reads return the caller's scope **+ `shared`**;
publish cross-agent knowledge with `scope: "shared"`. Governance blocks an agent from writing the
other's private scope. Concurrency across the two server processes is handled by SQLite WAL +
`busy_timeout`. (This is the current OpenDuck deployment.)

| | Option A | Option B | Option C |
|---|---|---|---|
| Consumers | OpenClaw | Hermes | both |
| `MIDMEM_AGENT_SCOPE` | `shared` | `shared` | `openclaw` / `hermes` |
| Private + shared memory | — | — | ✅ |
| Shared `state.db` | n/a | n/a | ✅ (same path) |

### Claude Code overlay — frontier orchestration, tight Hermes integration
Any of the options above can be **driven by Claude Code** as a third consumer of the same `state.db`.
Claude Code is not a fourth store mode — it reaches the core through the identical **CLI + MCP + hook**
surface — but it plays a distinct role: the **frontier orchestrator**. It plans MidMem work, dispatches
the mechanical build to **Hermes** (over kanban / ACP), QAs each result, and records durably — so
Claude Code and Hermes integrate tightly around one shared knowledge store: Claude Code decides and
verifies, Hermes builds, and both read/write the same tiered memory.

- **Register** the MCP server for Claude Code like any consumer (`MIDMEM_AGENT_SCOPE=shared`, or a
  dedicated scope in a multi-stack deployment), or just use the `midmem` **CLI** directly.
- **Equip it** with the [MidMem Skills Library](skills/) — `midmem-dev` (change the core),
  `midmem-orchestrator` + `midmem-ingest-review` (curate + QA), `midmem-record` (durable capture).
- **Guaranteed capture**: a Claude Code `Stop`-hook can block a turn from ending until a recordable
  change is written to MidMem — the most reliable capture path in the stack (see
  [`docs/STACK-CAPTURE.md`](docs/STACK-CAPTURE.md) and the `midmem-record` skill).

### Skills — which one to use per integration
Two skills front the store; pick by how you're driving the stack:

| Skill | Lives in | Drives | Use it for |
|---|---|---|---|
| **`midmem-ops`** | OpenClaw (`workspace/skills/`) | the OpenClaw agent | recall / store / ingest / proactive-recall / feedback directly via the MCP tools |
| **`hermes-build-orchestrator`** | Claude Code (`.claude/skills/`) | a frontier model (plan + QA); Hermes/qwen + gpt-5.5 build via kanban | multi-card builds with a QA gate per card |
| **`midmem-dev`** | **this repo** (`skills/`) | a frontier model (Claude Code) | changing the **core** code: add/adjust a capability with the test→verify→commit→record loop + guardrails |
| **`midmem-orchestrator`** | **this repo** (`skills/`) | same loop, MidMem-specialized | bulk knowledge curation: batch ingest, re-ground, dedup, vault verify |
| **`midmem-ingest-review`** | **this repo** (`skills/`) | a frontier model | ingest + audit knowledge quality and **cross-check OpenClaw vs Hermes understanding** (confabulation/drift/contradiction/scope) |
| **`midmem-record`** | **this repo** (`skills/`) | a frontier model (Claude Code) | durable capture: distilled lesson → wisdom tier + commit + the `Stop`-hook harness-guaranteed recording pattern |

- **OpenClaw only (Option A):** use **`midmem-ops`** — the OpenClaw agent operates memory itself
  (recall/store/ingest); no Hermes needed.
- **Hermes only / a build (Option B):** use **`hermes-build-orchestrator`** — it plans, dispatches
  kanban cards to Hermes, and QAs each; Hermes reads/writes the store through the same MCP tools.
- **OpenClaw + Hermes (Option C):** OpenClaw uses **`midmem-ops`** for its own recall and
  **`hermes-router`** to route research/builds to Hermes; at the ACP boundary prepend a
  **`handoff_brief`** so durable memory rides along (local models won't pull it on their own).
  Builds run through **`hermes-build-orchestrator`**. Both stacks share one `state.db`.

> Long-horizon integrity: `hermes-build-orchestrator` caps interactions/card, restrains tools, and
> QAs after every write (DELEGATE-52 mitigations); ingest applies a deterministic **grounding check**
> so confabulated extractions never persist. Supporting Claude Code ops skills: `openduck-doctor`
> (diagnostics/RCA), `openduck-record` (changelog+midmem+commit), `openduck-config`, `openduck-security-audit`.
> The **MidMem Skills Library** (`skills/`, shipped with this repo) holds `midmem-orchestrator` +
> `midmem-ingest-review` — symlink them into `~/.claude/skills/` (see `skills/README.md`).

---

## Quick start

```bash
# No install needed (Node ≥ 22.13 built-ins only — node:sqlite is flag-free from 22.13).
cd packages/core
node test/smoke.mjs                          # end-to-end self-test (offline) → 163/163
npm run verify                               # smoke + Brain-sty

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [U4CSolutions](https://github.com/U4CSolutions)
- **Source:** [U4CSolutions/MidMem](https://github.com/U4CSolutions/MidMem)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-u4csolutions-midmem
- Seller: https://agentstack.voostack.com/s/u4csolutions
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
