Agent tooling · 2026
AgentMemory
ForkPersistent memory for coding agents over MCP, so context survives between sessions.
74 MCP tools
Agent tooling
2026
My contribution
Work on the memory layer and MCP surface on top of the upstream iii engine — retrieval shaping, write policy, and client integration across MCP hosts.
Built on agentmemory , which deserves the credit for the engine underneath.
Key decisions
- The memory layer speaks MCP over a hand-rolled JSON-RPC stdio transport rather than binding to one host's SDK, so the same 74 tools serve Claude Code, Copilot CLI, Cursor, Gemini CLI, Codex CLI, OpenCode and anything else implementing the protocol.
- Retrieval fuses BM25, vector similarity and graph traversal with reciprocal rank fusion and an optional reranker, because returning the wrong memory confidently is strictly worse than returning none, and no single ranking signal holds up across every query shape.
- A write gate scores novelty, quality, provenance, scope and sensitivity before anything is admitted to the store, because a memory that accepts every observation fills future context windows with noise that merely looks like knowledge.
- The standalone MCP shim proxies to a running engine when one is configured but only lets read-only tools fall back to the local file-persisted store on failure, because absorbing a server's rejection of a mutating write into a divergent local copy would silently fork the memory.
The re-explanation tax
Every new session with a coding agent starts from nothing. The conventions, the reason that module is structured oddly, the thing you tried last week that did not work — all of it gets re-established from scratch, or worse, silently violated because the agent never knew.
AgentMemory is a persistent store the agent reads and writes through MCP. Twelve hook events per host — session start, prompt submit, pre- and post-tool-use, failure, stop, session end and the rest — feed what the agent does into the store as observations, which are compressed into memories; the next session’s start hook injects the relevant slice back into context. Because it speaks MCP rather than integrating with one host, the same memory is available to Claude Code, Copilot CLI, Cursor, Gemini CLI, Codex CLI, OpenCode and anything else that implements the protocol.
What makes it hard
Storage is trivial; retrieval is the entire problem. Return too much and you have spent the context window on recall instead of work. Return too little and the memory may as well not exist. Return the wrong thing confidently and the agent acts on a stale fact — which is strictly worse than having no memory, because it looks like knowledge.
The retrieval path is a hybrid: BM25 with stemming, synonyms and CJK segmentation; local ONNX embeddings over an in-process vector index, or Qdrant when an external store is configured; and traversal over the memory relation graph — the three fused with reciprocal rank fusion and an optional reranker. The write side is gated the same way the read side is shaped: every candidate memory is scored on novelty, quality, provenance, scope and sensitivity before admission, and a retention pass decays memories by access history, so a fact whose code has moved on fades instead of answering forever.
Built on upstream
This is contribution work on top of the iii engine, not a project of mine from scratch. The engine’s three primitives — worker, function, trigger — carry the whole system: memory operations register as engine functions, state lives in engine KV scopes, and REST and event triggers expose the API, so there is no separate database, queue or web framework underneath. The pin to iii 0.11.2 is deliberate: 0.11.6 moves to a sandboxed-worker model the current registration has not been refactored for, and the mismatch shows up as reconnect loops and empty searches.
My work is the memory layer and the MCP surface — retrieval shaping, write policy, and the client integration across MCP hosts: the Claude Code, Copilot and Codex hook packs, the OpenCode plugin, and the standalone MCP shim. The upstream project is linked above and deserves the credit for the engine underneath.