Caveman
Agent toolingCavemem — memory

Cavemem

Cavemem is local agent memory backed by SQLite. It stores raw memory first, ranks recall with deterministic BM25, and compresses recalled hits only after it already has the original.

Fig. — how cavemem remembers
remember(text)SQLite — rawwritten first · source of truthrecall(query)BM25thresholdEnginecompress hithit + handleinferred · recoverablebelow threshold → recalls nothing (never a guess)

Three verbs: remember, recall, forget. Recall only returns hits that clear its threshold. Compressed recall results carry a recovery handle, and reported token costs are inferred.

The order matters

A memory is never lost because the raw text is stored before anything else touches it.

  • Write is byte-safe. remember writes the full raw text to SQLite first. The engine is only consulted later, at recall time. If compression were to fail, the memory itself is already safe on disk.
  • Recall fails toward nothing. A query that scores below the threshold — or that has no term overlap with anything stored — recalls nothing. Cavemem returns an empty result rather than a low-confidence guess. Silence is the honest answer when nothing matches.
  • Compression is reversible. Each compressed recall hit carries a CCR recovery_handle. Recover returns the byte-exact original. Compression is transient; the raw memory underneath never changes.

The CLI

Build the binary and drive it directly. Every subcommand prints JSON.

terminal
go build -o cavemem ./public/mem/cmd/cavemem

./cavemem remember "the deploy key lives in vault under ops/deploy"
./cavemem recall "where is the deploy key" # { "hits": [...], "basis": "inferred" }
./cavemem forget mem_xxxxxxxx

recall takes an optional limit as a second argument. Recall hits are inferred — the tokens_added, the score, and the basis are all local estimates, never verified.

As an MCP server

Run the binary with no subcommand (or cavemem mcp) and it serves the same three operations as MCP tools over stdio, using the identical framing as caveman-mcp:

text
cavemem_remember(text: string)
cavemem_recall(query: string, limit?: number)
cavemem_forget(id: string)

Point an MCP host at the binary you built:

json
{
"mcpServers": {
"cavemem": {
"command": "/absolute/path/to/cavemem"
}
}
}

The thin clients

The JS and Python clients shell out to the same Go binary. Recall and scoring logic stay in Go. Set CAVEMEM_BIN if the binary is not on your PATH.

typescript
import { remember, recall, forget } from "cavemem";

await remember("the deploy key lives in vault under ops/deploy");
await recall("where is the deploy key", 5);
python
import cavemem

cavemem.remember("the deploy key lives in vault under ops/deploy")
cavemem.recall("where is the deploy key", limit=5)

A memory is never lost, and recall never bluffs

The raw memory is the source of truth, written before any compression. Recall ranks with deterministic BM25 and only returns hits that clear a conservative threshold — below it, you get nothing rather than a guess. Every figure it reports is inferred, and every compressed hit is recoverable to the byte through its recovery_handle.

Install names aren't live yet

The Go core is BSL; the JS and Python clients are MIT. Today the binary builds from source (go build …) and the clients shell out to it. The registry package names are reserved for launch and are not documented as working until they resolve to this project from a clean machine.