A vendor-neutral wire format for agent memory operations.
Read the spec · How memorywire relates to MCP · Security
Everyone else built a memory store. memorywire is the vendor-neutral protocol and governance layer that sits above all of them.
Memory storage for AI agents is saturated — mem0, Letta, Cognee, Zep, and a dozen others each ship their own format, their own database, and their own lock-in. memorywire is not another store. It's the thin, stable layer above them: one wire format so any agent can talk to any backend, carry its memory across runtimes, and let a human review and approve what gets remembered before it's committed.
If you already run mem0, Letta, or Cognee, keep them. memorywire gives you a single interface across all of them, plus a governance plane to audit what they remember.
memorywire's edge is position, not feature count. Four things set it apart from the rest of the agent-memory ecosystem.
1. It's an interop layer, not a silo. memorywire defines five operations (remember, recall, forget, merge, expire) as a stable JSON-Schema wire format, and routes them across pluggable backends — sqlite-vec, mem0, Letta, Cognee, and pgvector on day one. Every other project asks you to adopt its store and its format. memorywire lets you keep what you have and talk to all of it through one surface.
2. Governance is built in. When approval_required is set on a write, a remember call stages instead of commits. The governance UI shows a structured diff against current state; a reviewer approves or rejects; the decision is audit-logged. Controlling and auditing what an agent is allowed to remember is a production need that the major open-source memory frameworks don't ship today — this is where memorywire earns its keep.
3. Routers compose. The memory router itself implements the MemoryStore protocol, so a router can be a backend for another router. Fan-out, fusion, and graph-boost all nest cleanly — an architectural property most memory systems don't have.
4. Procedural memory is first-class. Agent how-to is stored as serializable transitions state machines you can replay and inspect — not flattened into text or vectors. memorywire treats semantic, episodic, procedural, and emotional as distinct, spec-defined types rather than one undifferentiated blob.
In the interest of an honest pitch: STM↔LTM consolidation and tiering are shared with systems like MemOS; RRF is a standard retrieval-fusion technique — the adversarial-fusion result in §5 of the paper measures the well-known Byzantine-robustness of RRF in the agent-memory routing context, not a new theorem; and MCP composition is documented at docs/MCP-RELATIONSHIP.md (three composition modes: memorywire-as-MCP-tool today, memorywire-as-MCP-extension targeted for v0.5). memorywire's claim isn't that these are new — it's that wrapping them in a vendor-neutral protocol with a governance plane is the part nobody else is doing.
Governance UI — diff and approve a pending memory, audit the decision:
memorywire CLI — remember, recall, forget:
memorywire recover — the concept: an agent's memory holds benign facts, poison from untrusted sources, and a directive hidden inside a trusted memory. Recovery purges the untrusted poison by provenance, quarantines the hidden directive for human review, and keeps the benign facts:
...and the CLI in action:
Recovery uses provenance as the primary lever (the strongest signal per the
PurgeBench benchmark) and is honest about the
entangled case — a directive hidden in a trusted memory is quarantined for a human, not
silently deleted. See docs/recovery.md.
Reproduce: docs/demos/README.md.
| Component | State |
|---|---|
| Spec v0 (5 operations × 4 memory types, JSON Schema 2020-12) | draft published |
Reference implementation (pip install memorywire) |
shipped — not yet on PyPI |
| Backend adapters (5) | sqlite-vec, mem0, letta, cognee, pgvector |
| Memory router (RRF fusion + 1-hop graph boost) | shipped |
FSM procedural memory (transitions library) |
shipped |
| STM↔LTM async transformer | shipped |
memorywire CLI (remember / recall / forget / recover) |
shipped |
| Governance UI (Starlette + HTMX, FSL-licensed) | shipped, see ui/ |
| LongMemEval / LoCoMo benchmark | v0.2 (microbench live — see Benchmarks) |
| IETF Internet-Draft | v0.5 |
Spec and reference implementation are Apache-2.0. The governance UI is source-available under FSL and auto-converts to Apache-2.0 two years after each release.
pip install "memorywire[sqlite-vec]"
# with every backend
pip install "memorywire[sqlite-vec,mem0,letta,cognee,postgres]"
# then, e.g., clean a poisoned store:
memorywire recover --agent my-agent --store sqlite-vec://./mem.db --dry-runFrom source (for development):
git clone https://github.com/mthamil107/memorywire
cd memorywire
uv venv && uv pip install -e ".[sqlite-vec]"memorywire ships an MCP server, so any MCP-aware agent (Claude Desktop, IDE assistants) gets persistent, recoverable memory by adding it to the client config — no code:
{ "mcpServers": { "memorywire": { "command": "memorywire-mcp",
"env": { "MEMORYWIRE_STORE": "sqlite-vec://./mem.db", "MEMORYWIRE_AGENT": "assistant" } } } }The agent gains remember / recall / forget / merge / expire / recover tools. Install
with pip install "memorywire[mcp,sqlite-vec]"; see docs/mcp-server.md.
import asyncio
from memorywire import Memory, MemoryType
async def main():
mem = Memory(
agent_id="customer-bot",
stores=["sqlite-vec://./mem.db", "mem0://default"],
)
await mem.remember(
"Alice is allergic to peanuts",
type=MemoryType.SEMANTIC,
user_id="alice@example.com",
)
await mem.remember(
"On 2026-03-10 Alice reported a billing issue",
type=MemoryType.EPISODIC,
user_id="alice@example.com",
)
hits = await mem.recall(
"what should I avoid feeding alice?",
k=5,
hops=1,
)
for h in hits:
print(f"{h.score:.2f} {h.type} {h.content}")
asyncio.run(main())End-to-end demos that actually run: examples/01_quickstart.py (50 facts → recall → forget) and examples/03_procedural_fsm.py (FSM procedural memory).
memorywire stays out of the way. The user talks to the agent; the agent makes the memorywire calls. Two clarifications that come up before anything else:
The user never picks "short-term vs long-term." Everything lands in short-term first. A background task (the STM↔LTM transformer) scores items on importance, recency, and recall frequency on a timer, promotes the important ones to long-term, and ages the rest out. Automatic. Nobody tags each message.
Approval is opt-in, not per-response. Gating is off by default — writes commit straight through. When you do turn it on (by setting approval_required on the writes you want reviewed), you scope it — "only review memories tagged sensitive," or "only writes from this source" — so a human sees the 5% of writes that matter (preferences, PII, anything you'd regret storing wrong), not every passing message. The gate is for the writes that count, not a tollbooth.
What the user / agent experiences What memorywire does under the hood
------------------------------------- ---------------------------------------
1. User asks: "what does Alice avoid?" --> mem.recall(query, k=5, hops=1)
fans out to every configured store,
RRF-fuses results, returns top-K hits
2. Agent reads the recall context --> (no memorywire call -- agent's own prompt)
3. Agent generates a reply --> (no memorywire call -- model inference)
4. Agent decides to write a fact: mem.remember(content, type=SEMANTIC,
"Alice mentioned a peanut allergy" --> approval_required=?)
if approval_required is unset (default):
committed, returns memory_id
if approval_required is true:
staged with PENDING sentinel,
surfaces in governance UI as a diff,
committed only after a human approves
5. Background, on a timer --> STM<->LTM transformer
(user and agent both do nothing) scores items by importance/recency/
recall-count, promotes important ones
to long-term, evicts the rest
6. User switches frameworks later --> same wire format,
(e.g. swaps mem0 for Letta) same MemoryStore Protocol --
the agent's memory travels with it
Three pre-empted questions, one per row people fixate on:
- Row 4 — "Do I have to approve everything?" No. Default off; scope it when on.
- Row 5 — "Do I tag short-term vs long-term per message?" No. The transformer does it.
- Across rows — "Isn't this only for multi-agent setups?" No. The entire left lane is one person talking to one agent. The cross-vendor part is multiple stores, not multiple agents.
A support agent for an e-commerce site running two backends: sqlite-vec:// for fast local recall and mem0:// for the team's shared customer-profile store. The operator has scoped approval to writes tagged health.
Turn 1. Customer says "I'm allergic to peanuts and I want to reorder my usual." Agent issues mem.recall("what does this customer usually order?", user_id="alice@..."). Both stores return hits; RRF fuses them; the agent sees order history. Agent replies with the reorder. Agent then writes two memories:
"Alice is allergic to peanuts"(type=SEMANTIC, taggedhealth,approval_required=true)"On 2026-03-10 Alice reordered her usual cart"(type=EPISODIC, no approval — ordinary event)
The episodic write commits immediately. The semantic one stages as pending and shows up in the governance UI as a diff against current state (no prior allergy facts on file). The operator approves it; it commits with an audit-logged decision.
Turn 14, three weeks later. Customer says "send me my usual." recall() returns the long-term semantic fact (the peanut allergy) plus three recent episodic events (cart history). The peanut-snack item is filtered out before the agent suggests it. By now the STM↔LTM transformer has expired half a dozen low-importance episodic items from turns 2–13 that nobody recalled and that scored low on recency.
The user never picked a tier, never approved a routine event, and the agent never lost the safety-critical fact.
+----------------------+
| Governance UI |
| approvals . audit | FSL-licensed
| health . patterns |
+----------+-----------+
| same SQLite DB
v
+---------------------+ +-------------------+ +---------------------+
| Agent / SDK |-->| Memory router |-->| MemoryStore |
| memorywire CLI | | RRF k=60 | | sqlite-vec | mem0 |
| memorywire.Memory | | + graph boost | | letta | (your own) |
+---------------------+ +-------------------+ +---------------------+
|
+----------+----------+
v v v
procedural STM<->LTM governance
FSM (via transformer channel
transitions) (HITL approve)
Five operations. remember, recall, forget, merge, expire. Each is a JSON-Schema-defined request/response shape.
Four memory types. semantic (facts), episodic (events with time/place), procedural (how-to, encoded as transitions-compatible FSMs), emotional (sentiment associations).
MemoryStore Protocol. A runtime-checkable async Protocol with remember / recall / forget / merge / expire / health / capabilities. Any backend implementing it composes.
Memory router. Fans queries out across N stores, fuses results with RRF (k=60 by default), applies an optional 1-hop graph boost, returns a unified RecallHit list. The router itself implements MemoryStore, so routers compose.
FSM procedural memory. Store agent how-to procedures as transitions state machines — serialize, replay, inspect, edit in the UI. Spec §7 fixes the JSON shape.
STM↔LTM transformer. Always-on async background task. Scores short-term items on importance + recency + recall-count and promotes them to long-term storage; evicts the rest. Pluggable scorer; deterministic clock injection for tests.
Governance channel. Optional. When configured, remember-with-approval_required calls stage instead of commit; the UI shows a structured diff against current state; reviewers approve or reject and the decision is audit-logged.
The full surface is one page: docs/spec/v0.md.
Recall@5 = 1.000 on 42 gold-id queries (50 total; 8 no-match probes excluded), ingest p50 37.8 ms, recall p50 40.6 ms —
sentence-transformers/all-MiniLM-L6-v2+sqlite-vec{:memory:}, CPU-only.
This is a microbench, not LongMemEval/LoCoMo (deferred to v0.2). 100 hand-authored facts, 50 labelled queries (paraphrase / exact-match / multi-hit / no-match). Reproduce with python scripts/run_microbench.py. Full methodology and caveats in docs/benchmarks.md.
memorywire is a layer above the storage frameworks — not a competitor. The router calls into them.
| Project | Storage | Cross-vendor wire format | Diff-and-approve UI | FSM procedural memory |
|---|---|---|---|---|
| memorywire | uses theirs | ✓ | ✓ | ✓ |
| mem0 | own | — | — | — |
| Letta | own | — | — | — |
| Cognee | own | — | — | — |
| Zep / Graphiti | own | — | — | — |
| MCP memory extension | n/a | proposed | — | — |
If you already use mem0 or Letta or Cognee — keep using them. memorywire gives you a stable interface across them and a governance plane to audit what they remember.
Memory storage is saturated. Memory operations, governance, and the cross-vendor protocol layer above storage are not. The discovery story — four sequential research scouts converging on the same meta-pattern — lives in docs/kickoff/FINDINGS-CONTEXT.md. The honest roadmap (best / likely / worst case + acquisition signals) is in docs/kickoff/FUTURE.md.
src/memorywire/ # protocol + reference implementation (Apache-2.0)
schemas/ # JSON Schema 2020-12 files (operations + types)
store/ # MemoryStore adapters (sqlite-vec, mem0, letta, cognee, pgvector)
governance/ # diff / health / audit helpers
ui/ # governance UI (Starlette + HTMX, FSL)
docs/ # spec + adapter guide + benchmarks
spec/v0.md # the memorywire wire format
kickoff/ # origin story, architecture, findings
examples/ # runnable end-to-end demos
tests/ # unit / conformance / integration (env-gated) / benchmarks (opt-in)
scripts/ # verify_spec, run_microbench
v0.2 (post-launch hardening, 4–6 weeks) — LongMemEval + LoCoMo grader runs, calibrated recall threshold cutoff, privacy_intent flags (consent / retention / share-scope), MCP working-group RFC, governance UI multi-tenant per-session agent scoping.
v0.5 (Q3 2026) — Spec frozen, IETF Internet-Draft submitted (draft-<name>-memorywire-00), cross-language ports begin (Rust / TypeScript), benchmark leaderboard.
v1.0 (Q1 2027) — Stable wire format, federated multi-tenant primitives, enterprise governance (SSO / RBAC), W3C Community Group.
Kill triggers and pivots: docs/kickoff/PROJECT-PLAN.md.
memorywire is in early v0 development. Report vulnerabilities privately via GitHub's "Report a vulnerability" feature on the repo Security tab, or via the contact in SECURITY.md — not through public issues. Scope, supported versions, and disclosure timing are documented there. The host application is responsible for authentication and transport security; memorywire delegates these by design.
Spec edits, new adapters, and bug fixes welcome. Start with CONTRIBUTING.md and docs/adapters.md. Conventional Commits; one concern per PR.
Local dev:
uv venv && uv pip install -e ".[sqlite-vec,mem0,letta]"
uv pip install pytest pytest-asyncio pytest-cov ruff mypy
.venv/Scripts/python.exe -m pytest -m "not integration and not benchmark"- Protocol + reference implementation: Apache-2.0
- Governance UI (
ui/): Functional Source License 1.1 — source-available; auto-converts to Apache-2.0 two years after each release
Modelled on MCP (cross-vendor protocol shape), informed by the LongMemEval, LoCoMo, and Governed Memory papers, and by the published architecture writeups of mem0, Letta, Cognee, Zep/Graphiti.
The diff-and-approve workflow draws on the Co-memorize HITL pattern surfaced in the Governed Memory literature.
This project was originally drafted as "AMP — Agent Memory Protocol" in May 2026. A prior project named AMP exists at github.com/akshayaggarwal99/amp (an MCP-native memory server, created Dec 2025) — a different shape than this one. We renamed to memorywire before launch to avoid confusion. Full context: docs/PRIOR-WORK.md.
What memorywire is: a wire format, a reference implementation, and a governance UI. What it is not: an algorithmic invention.




