Agent-readable docs index: /docs/llms.txt. Full docs in one file: /docs/llms-full.txt. Download /docs/docs.zip to grep all markdown files locally.

Concepts

Events

An event is a raw record: a message, a tool call, a file, a commit. remember appends events to a stream. Each event gets a sequence number and a hash:
hash = sha256(prevHash || canonical(event))
The canonical form follows RFC 8785 (JSON Canonicalization Scheme), and it commits to a digest of the payload, not the payload itself. That is what lets a payload be purged later without breaking the chain. Anyone with read access can recompute it. The CLI does this with kaibo verify.
Every event carries an idempotency key, unique per project. Sending the same key again returns the original event and appends nothing.

Memories

A memory is a statement derived from events, with a type (fact, decision, task, preference, procedure, episode), a validity range, a confidence, and the ids of the events it came from.
A newer statement does not overwrite an older one. When an event says something replaces, moves, reassigns or cancels an earlier memory, the old memory becomes superseded or canceled, its validTo is set, and the two are linked. Nothing is lost, and recall answers from what is current.
Writing is asynchronous. remember returns a job id; pass wait to block until the memory is searchable. A model structures what you wrote, so three things follow:
  • One event can become several memories, and the wording can change. "Move the release target from July 13 to July 17" might yield the decision itself and a rewritten fact with the year added. explain shows the chain that led to each one.
  • A memory's id and type can change after structuring. Right after remember you may see a quick provisional memory; a few seconds later it is replaced by the structured one, with a new id and a better type. Use wait: true before you store or compare ids.

Recall

recall takes a question and a token budget and returns the smallest set of memories that answers it. Each item is either a verbatim quote or a short summary, and each has citations. Results are scored on stemmed term matches, filtered to what was valid at asOf (default now), de-duplicated for diversity, then packed into the budget.
If nothing citable matches, the response has abstain.abstained: true and a reason. Treat that as "I do not know". With Accept: text/event-stream the same call streams candidates, packed and final events.
Recall is lexical today. A question phrased with none of the words in the memory will miss it.

Explain

explain takes a memory id (or a recalled item) and returns the chain of memories it replaced (oldest first), each with the text it said, and the source events with sequence numbers and hashes. Use it to show a user why an agent believes something:
const why = await kaibo.explain(pack.top); for (const version of why.chain) console.log(version.status, version.validFrom, version.content);

Forget

forget takes a memory id or a query, and a reason. The memory is tombstoned immediately and the text is purged after a grace window (24 hours). A receipt points at an entry in a hash-chained deletion ledger; verify recomputes it and checks the memories are gone. The ledger stores a digest of the reason, not the reason.
A query matches superseded memories as well as current ones, so a preview (dryRun) can list more than you stored statements: the old versions and any memories derived from the same events. Read it before you confirm.
A receipt cannot prove that a copy you made earlier is gone. Subscribe to the memory.forgotten webhook to clean up your own copies.

Retrieved text is untrusted

Memory is text someone wrote earlier. It can contain instructions aimed at your agent. Put it in prompts as data, not as instructions. The MCP server wraps recall output in delimiters with a random value per response for this reason.