Skip to main content
Glama
README.md
# 蛙 kaeru

`kaeru` is a **cross-agent cognitive engine** for LLM agents — a typed graph that agents think in, plus a recollection layer for long-term ideas and outcomes. Local-first for each agent, with an optional shared cloud tier so a whole team of agents and people build on one another's memory.

Designed for **multi-session, multi-agent continuity**: when an agent opens a project, it has full context of what was being thought about, can follow provenance chains, can consolidate outcomes into stable long-term knowledge, and can pull in what the rest of the team has shared.

Inspired by the LLM-wiki pattern (Karpathy, gist `442a6bf555914893e9891c11519de94f`), the bi-temporal knowledge graph approach of Graphiti / Zep, the curator-driven knowledge engine of Cognee, and the reasoning-based hierarchical-summary navigation pattern from PageIndex. Two-tier design grounded in the hippocampus / cortex split.

Name: 蛙 (*kaeru*, "frog"; homophonic with 帰る "to return" and 変える "to change") — the agent that returns, recalls, and reshapes.

![A kaeru vault rendered as a live knowledge galaxy by kaeru-viz](kaeru-viz/galaxy.gif)

<sub>A kaeru vault rendered by [`kaeru-viz`](kaeru-viz/) — each project a constellation of stars around its core, sized by memory layer, with ochre cross-project bridges, reasoning-chain replay, and a time-lapse of how the knowledge grew. Hover a node to trace its neighbours; click to pin them.</sub>

## Overview

![A kaeru vault rendered as a knowledge galaxy by kaeru-viz](kaeru-viz/screenshot.png)

`kaeru` is built around a typed property graph stored in CozoDB. Two tiers, biological analogy:

- **cognitive (operational / hippocampus)** — high-velocity working graph where the agent actively thinks: episodes, scratch, drafts, hypotheses, experiments, audit events.
- **recollection (archival / cortex)** — settled ideas, outcomes, summaries, references; mostly read.

Every node and edge is **bi-temporal** — the substrate stores assertion / retraction history natively, so time-travel queries are out of the box and conflict resolution is non-destructive (the old version is invalidated, not deleted).

Per-initiative subgraphs through a junction-relation pattern: one substrate, many initiatives, multi-membership. An agent working on project A asks "what was I doing here last time?" and gets an answer scoped to A. The same node can belong to several initiatives at once.

`kaeru` is a **facilitator, not an enforcer**. The curator API exposes ~70 primitives (`awake`, `recall`, `drill`, `claim`, `synthesise`, `at`, `history`, `settle`, …) as available tools. The agent and user choose when to invoke them; the daemon hints but doesn't block.

## Features

- **Two-tier graph** — operational (cognitive / hippocampus) for active thinking; archival (recollection / cortex) for settled knowledge. `settle` promotes across the boundary, preserving provenance.
- **Bi-temporal** — native assertion / retraction history. `at` reads a node in full as it is now or as-of any past moment; conflicts are non-destructive (the old version is invalidated, not deleted).
- **Per-initiative scoping + layered re-entry** — one substrate, many projects. `awake` restores a project's working set by memory layer (Core → Hot → Warm) and surfaces the archival **cortex** (settled knowledge) alongside it, so durable facts re-enter every session; `surface` reaches the archived Cold / Frozen on demand.
- **Reasoning chains** — `chain` saves the load-bearing weighted path between two nodes as a recallable trail with an agent-authored summary; `why` reads a trail — give it a chain for its ordered steps, or any node to reach the chain it belongs to. Duplicates are folded at creation, and `rechain` refreshes a trail after the graph changes (re-links, re-weights).
- **Self-maintenance** — `reflect` computes a tidy-up work-list: orphan nodes to link, overdue tasks, chains gone stale, settled work to promote into cortex, and shared/cloud items whose rebalancing is escalated to the user. The agent calls it at the end of a piece of work; layer tidying runs on its own in the background (`hygiene`).
- **Role slots** — `slot` gives an initiative a role held by exactly one live node (`handoff`, `entrypoint`, `queue`). Filling it archives the previous holder to Cold and links `supersedes` from the new holder to it, so a project cannot drift into three "current" handoffs. Nothing is deleted; the predecessor stays reachable through `at` / `surface`.
- **It tells you when you are behind** — the daemon asks GitHub once a day whether a newer kaeru exists, and if so the next `awake` opens with what the gap is costing: the running version, how many releases back it is, that release's own one-line reason, and the upgrade command for the way this binary was actually installed (installer script, `.mcpb` bundle, or a source checkout). The agent is the updater and asks before running it. One public GET, no identifiers, nothing about your vault; `KAERU_MCP_UPDATE_CHECK=0` turns it off entirely. A warning in a daemon log nobody reads is the same as no warning at all.
- **Automatic hygiene** — a background pass keeps a project's layers honest: old unreferenced journal entries move to Cold, untouched unreferenced Core nodes drop one step, heavily-referenced nodes rise one step. It triggers on accumulation (writes, Core growth, elapsed time) rather than on a schedule, runs off the reactor in batches so it never stalls a tool call, and only ever changes a node's layer — every move reverses with one `layer` call. On by default since 0.7.3: set `KAERU_MCP_HYGIENE_ENABLE=0` to turn it off (embedding via `kaeru-rig`? hygiene stays opt-in there — a library must not sweep a vault its embedder didn't ask it to; `KaeruMemory::with_hygiene()` starts it). `hygiene <initiative>` shows exactly what the next pass would move without moving it — worth a look on a vault you care about.
- **Cross-agent sharing** — local-first by default; an optional `kaeru-cloud` tier lets a trusted team share settled knowledge through two safety gates (initiative policy, which names both *whether* an initiative may leave and *which clouds* it may reach, plus a deterministic secret guard). `cloud_recall` searches the shared tier, `unshare` withdraws a mistake, and with several clouds configured an unnamed call is refused rather than routed to a default. See [Local & cloud](#local--cloud--sharing-memory-across-a-team).
- **Structural recall** — exact name lookup, typed `walk` / `drill` / `trace`, `between`, FTS fuzzy fallback. Every read carries when each node was asserted, and a read that stops short points at the verb that goes further: an excerpt names `at`, a changed node names `history`, a node inside a saved trail names `why`. A name that fails to resolve says which of three things happened — it lives in another initiative, something close exists, or it is nowhere.
- **Read-back on re-entry** — `awake` restores what was *touched* and also what is still *owed*: open tasks with overdue ones first, claims awaiting a verdict, and the saved trails with their summaries. On a shared initiative it says the local answer may be incomplete.
- **Initiative management** — `rename` / `delete` an initiative (locally or team-wide), or `attach` a node to another initiative to repair fragmentation after the fact.
- **Markdown export** — Obsidian-friendly snapshot of any initiative.

## Architecture Notes

- **Substrate is CozoDB** with RocksDB backend; bi-temporal `Validity` is native to the substrate, not bolted on.
- **Edges carry operational semantics** — each edge type is something the curator API responds to. `derived_from` powers provenance and explainability; `contradicts` triggers a non-destructive `under_review` flow; `supersedes` retracts the previous version through the bi-temporal substrate, and runs one way — from the replacement to what it replaced. Edges are not just associations.
- **`audit_event` is a first-class node type** — every mutation writes an audit node, so changes to memory themselves become reasoning surface for the agent. Substrate-level history (`Validity`) and operational audit (audit-event nodes) stay separate: the substrate tracks *what was*, the audit nodes track *who did it and why*.
- **Per-initiative scope through junction relations** rather than column filtering — RocksDB prefix-scan gives O(log n + k) on the active initiative.
- **Retrieval is structural-first** — explicit name lookup, typed graph traversal, summary views. Cozo FTS for fuzzy fallback when an exact name is forgotten. No vector/embedding layer today: Cozo supports HNSW, but kaeru wires none of it — a vector fallback is possible future work, not a current feature.
- **Two-tier with explicit promotion** — `settle <name>` moves a node that stopped changing into the archival tier as a deliberate, logged operation, carrying its name, body and manual tags over unchanged (`unsettle` mirrors it back). Provenance (`derived_from`) survives the tier boundary.
- **Single binary, embedded substrate** — the substrate runs in-process with the daemon; the vault is a local file tree, not a service. The daemon speaks MCP to the agent and, optionally, HTTP to a `kaeru-cloud`. Vault on disk under a platform-specific default (Linux `$XDG_DATA_HOME/kaeru`, macOS `~/Library/Application Support/ai.lamantin.kaeru`, Windows `%LOCALAPPDATA%\ai.lamantin.kaeru`); override with `KAERU_VAULT_PATH`.

## Layout

```
kaeru/
├── Cargo.toml                  ← workspace root
├── kaeru-core/                 ← library: substrate, schema, primitives
├── kaeru-mcp/                  ← binary `kaeru-mcp`: Model Context Protocol server (the agent's surface)
├── kaeru-cloud/                ← binary `kaeru-cloud`: shared cloud tier (Axum REST over kaeru-core)
├── kaeru-rig/                  ← library: `rig` Tools that give a rig agent kaeru memory
└── skills/
    └── kaeru-skill/            ← portable agent skill (Claude Code / etc.)
```

`kaeru-rig` is the [rig](https://github.com/0xPlaygrounds/rig) framework adapter — the full curator verb set as discrete rig `Tool`s over an embedded `Arc<Store>`, so a rig agent reads and writes one vault. Future: `kaeru-langchain` (Python bridge), not yet started.

## Install

> **Pre-1.0 alpha.** Substrate schema may change between minor versions —
> export to markdown if you need to keep notes around.

See [QUICK_START.md](QUICK_START.md) for source builds, MCP daemon setup, and the re-entry ritual.

## Quick tour (MCP tools)

```
# See what projects exist:
initiatives

# Re-entry ritual: process state + epistemic state.
awake (initiative: "auth-rewrite")
overview (initiative: "auth-rewrite")

# Capture (auto-named):
jot (initiative: "auth-rewrite", body: "noticed token expiry differs across platforms")

# Fuzzy lookup when you forgot the exact name:
search (initiative: "auth-rewrite", query: "expiry")

# Drill into something:
drill (initiative: "auth-rewrite", name: "noticed-token-expiry-differs-across-...")

# Hypothesis cycle:
# You normally reach memory AFTER the check has run, so record the verdict
# with the claim — one call, and the status lands where every read can see it:
claim (initiative: "auth-rewrite", text: "platform-aware policy is correct",
       verdict: "supported", by: "<evidence>")
# Or the prospective path, when the question is genuinely still open:
claim (initiative: "auth-rewrite", text: "platform-aware policy is correct", about: "<node>")
evidence (initiative: "auth-rewrite", hypothesis: "<hyp>", method: "compared iOS / Android TTL")
confirm (initiative: "auth-rewrite", hypothesis: "<hyp>", by: "<experiment>")

# Time-travel:
at (initiative: "auth-rewrite", name: "<name>", when: "5m")
history (initiative: "auth-rewrite", name: "<name>")

# Knowledge chains — strongest weighted path between two nodes
# (link the load-bearing edges with strong: true first):
path (initiative: "auth-rewrite", from: "<a>", to: "<b>")    # preview the trail
chain (initiative: "auth-rewrite", from: "<a>", to: "<b>")   # save it as a recallable chain
why (initiative: "auth-rewrite", name_or_id: "<a>")          # read the trail a node sits in

# Roles — one live node each. Writing the next handoff archives the last one:
slot (initiative: "auth-rewrite", slot: "handoff", name: "handoff-tuesday")
slots (initiative: "auth-rewrite")

# What the next hygiene pass would move, and why:
hygiene (initiative: "auth-rewrite")

# Snapshot to an Obsidian-friendly markdown vault:
export (initiative: "auth-rewrite", path: "/tmp/auth-snapshot")
```


## Building without network access

Some machines cannot reach crates.io. The dependencies for each release are
vendored into a separate repository, [`LamantinAI/kaeru-vendor`](https://github.com/LamantinAI/kaeru-vendor),
one tag per release:

```bash
git checkout v0.7.3
./contrib/offline/fetch-vendor.sh     # ~600 MB, needs network once
# carry the whole directory across, then:
cargo build --release --offline -p kaeru-mcp
```

Rust alone is not enough on either side of that line — cozo builds RocksDB from
C++ and zstd/lz4 from C, so a C++ toolchain and `libclang` are needed whether or
not you are offline. See [docs/offline-build.md](docs/offline-build.md) for the
per-platform requirements and the Windows line-ending trap that fails every
checksum at once.

## Connecting to an MCP-aware agent

`kaeru-mcp` is a long-lived HTTP service: **one daemon per machine** owns the substrate, any number of agent sessions (Claude Code, Opencode, Cursor, …) connect concurrently. This is intentional — RocksDB is single-writer, so a stdio MCP that forks a subprocess per session would hit lock contention. See `kaeru-mcp/README.md` for systemd / launchd unit templates and the full HTTP config.

Run the daemon (or set up the systemd user unit from `contrib/install/`):

```bash
kaeru-mcp                                            # foreground, Ctrl-C to stop
```

Then point your agent at it:

- **Claude Code**: `claude mcp add --transport http kaeru http://127.0.0.1:9876/mcp` — see `skills/kaeru-skill/` for the portable system-prompt rules.
- **Check memory before asking** (Claude Code and Codex): `contrib/hooks/kaeru-first/` is a harness hook for the moment the agent is about to ask the user something — if kaeru was not read recently, it sends the agent to search first, once, and then asks it to capture the user's answer. Stdlib Python, fails open. See its README.
- **Opencode**: `bash contrib/opencode/install-opencode.sh` — wires the daemon, drops `AGENTS.kaeru.md` rules into `~/.config/opencode/`, and installs `/kaeru` / `/lesson` / `/recall` slash commands. Designed to coexist with your existing OSS-model provider config (Qwen / DeepSeek / GLM / Ollama). See `contrib/opencode/README.md`.
- **Cursor and other runtimes**: paste the body of `skills/kaeru-skill/SKILL.md` into your agent's rules / system-prompt section. For MCP-aware clients the daemon URL above works directly.

After restart the agent sees tools like `awake`, `drill`, `claim`, `at` natively. Each tool takes an optional `initiative` parameter.

## Local & cloud — sharing memory across a team

`kaeru` runs **local-first**: your vault lives on your machine and nothing leaves it by default. A second, optional tier — `kaeru-cloud` — is a shared store for a trusted group (a team, a family). Each initiative carries a sticky `share_policy`:

- `private` (default) — nothing ever leaves; personal projects.
- `team` — nodes you explicitly mark `shared` may sync to the cloud.

Sharing is never automatic and passes two gates: the initiative policy, and a deterministic **pre-share secret guard** that blocks anything looking like an API key, token, or private key. The guard is silent on clean content and only interrupts on a real hit.

Verbs (over MCP): `policy` (mark an initiative `team`), `share` (push a node), `cloud_recall` (see what the team has), `pull` (bring a shared node into your local graph), `link_cloud` / `cloud_links` (reference cloud nodes without copying), and `sync_review` (batch-review still-local nodes). Capture verbs (`episode` / `jot` / `cite`) take `visibility: shared` to capture-and-share in one call.

A single daemon can also reach **several named clouds** (e.g. a `family` and a `work` cloud) via a `clouds.toml` file; the cloud verbs then take an optional `cloud: <name>` and soft links remember which cloud they point at. See [`kaeru-mcp/README.md`](kaeru-mcp/README.md#configuration) for the file format.

Per-user / per-org isolation (multi-tenant) is a future addition; today each cloud is one shared space scoped by initiative. See [`kaeru-cloud/README.md`](kaeru-cloud/README.md).

## Roadmap

- **Initiative onboarding** — a generated "what is this initiative, and what's in it" briefing the first time an agent enters a project, in the spirit of the `import` guide — an instruction over the collected context, not graph machinery.
- **PostgreSQL backend** — a server-mode substrate alongside the embedded RocksDB default.
- **Multi-tenant + isolation** — per-user / per-org separation in the shared cloud.
- **Cross-initiative links** — opt-in edges and recall that *traverse* between initiatives. Per-initiative scoping is deliberate, not a gap — and `attach` already gives a node membership in several initiatives at once; this adds boundary-crossing edges/recall on top of it.

## Status

Pre-1.0. Implemented and covered by a green test suite: the substrate and curator API, memory layers with layered re-entry — an operational working set plus an archival **cortex** that re-enters every session (`awake` / `surface`), bi-temporal time-travel with assertion time surfaced in every read (`at` / `history`), per-initiative scoping with `rename` / `delete` / `attach` (additive multi-membership), knowledge chains (weighted shortest-path, agent-authored summaries, creation-time dedup, `rechain`), a `reflect` maintenance pass, forward-only schema migrations, the MCP server, the shared `kaeru-cloud` tier (sharing, recall, soft links, sync-review) including multi-cloud, the `kaeru-rig` framework adapter (full curator toolset as rig Tools), and markdown export. What still needs hardening:

- **Multi-tenant.** The cloud is one shared space scoped by initiative; per-user / per-org isolation isn't built yet.
- **MCP concurrency.** Concurrent sessions share one `Store`; the per-call initiative scope is serialized through `Store::scoped`, so two sessions can't corrupt each other's scope. What remains is ordering — when an agent batch-fires async calls, a read can still land before a not-yet-applied write.
- **Whole-second `Validity` resolution.** Two opposing mutations on the same node/edge within one second (e.g. `link` then an immediate `unlink`, or a `forget` right after a write) resolve ambiguously. Interactive use is fine — human pacing always crosses the boundary; the test suite sleeps between such operations.
- **Audit events** aren't attached to the initiative junction yet (export filters them by `affected_refs` intersection — a working workaround).
- **Rig adapter shipped, LangChain not yet.** `kaeru-rig` gives a [rig](https://github.com/0xPlaygrounds/rig) agent the full memory toolset; a Python / LangChain bridge is still to come.
- **Migrations are forward-only and add-only.** A `migration_journal` runs schema additions (new relations / columns) on open; there is no down-migration or destructive-change path yet. Snapshot via `export` before a major upgrade is still prudent pre-1.0.

## Contributing

Discussion and design feedback through issues. PRs welcome on the open items above and anywhere the agent-facing surface feels rough — the verb taxonomy (`awake`, `drill`, `claim`, `flag`, `settle`, …) is meant to map to natural agent thinking, not just expose graph operations.

## License

**Business Source License 1.1** — see [`LICENSE`](LICENSE), with a plain-language
summary in [`LICENSING.md`](LICENSING.md).

kaeru is *source-available*: read it, modify it, run it in production, and embed
it as a component or tool inside your own systems and products — including what
you sell. The one thing you may not do is operate kaeru itself as a hosted /
managed / SaaS platform for third parties. Each released version converts to the
**Apache License 2.0** four years after it ships. Contributions are accepted
under the [Contributor License Agreement](CLA.md).

Versions up to and including v0.7.0 were released under the MIT License and
remain available under it.

TDQS

B3.3/5.0

Scored across 71 tools

Disambiguation4/5

There is heavy thematic overlap in the read family (at vs recall vs search vs tagged; drill vs neighbours vs between; path vs chain vs why) and in the write/lifecycle family (jot vs episode; settle vs synthesise; link vs link_cloud; reflect vs lint), but the descriptions go to unusual lengths to draw explicit boundaries ('drill follows only derived_from and part_of; neighbours follows all twelve'). An agent can tell them apart with care, though the sheer number of near-parallel verbs invites occasional misselection.

Naming Consistency3/5

Casing and separators are consistent (all lowercase snake_case), but predicate style is mixed: bare imperative verbs (link, settle, pin, search), verb_noun compounds (set_status, close_review, merge_initiative, cloud_recall), and bare nouns (board, slots, ideas, outcomes, history, config). No camelCase chaos, but no single predictable convention either.

Tool Count2/5

71 tools is far beyond any comfortable surface, and the rubric flags 25+ as heavy and 50+ as extreme. The domain (bi-temporal graph, tiers, layers, chains, roles, reviews, initiatives, multi-cloud sync) genuinely justifies more than a typical server, so it is not a pure mismatch, but the count is still excessive for reliable tool selection.

Completeness5/5

Coverage is remarkably exhaustive for a knowledge substrate: capture (jot/episode/cite/claim/task/evidence), layered read (at/recall/search/tagged/drill/neighbours/between/path/trace/why/history/surface), graph editing (link/unlink/reweight/chain/rechain), lifecycle (settle/unsettle/supersede/revise/synthesise/forget), task board, reviews/verdicts, roles, initiative management, cloud sync, and maintenance (reflect/lint/hygiene) plus export/import. Almost no dead ends in the domain flow.

Maintenance

ActivityActive
ResponsivenessWithin a week