Koda Docs
Home Coordination Download
Docs / KodaMemory

KodaMemory

A shared knowledge graph for your agents. As sessions work, they record durable project knowledge — decisions, gotchas, where-things-live pointers — as linked nodes. When a new session starts, Koda recalls the memory relevant to its task, not just the last few notes, so what your agents learn compounds instead of getting relearned.

Included in your trial and ProKodaMemory rides the same local MCP coordination bus. Writing and querying memory (koda_memory_note, koda_memory_query) and graph-based recall are part of the 7-day free trial and stay on with Pro.

Overview

CLI agents are turn-based and forgetful: each new session starts cold, and anything a previous agent figured out — a subtle build flag, why a decision was made, which file really owns a behavior — is gone unless someone wrote it down. The legacy fix was a flat list of the last handful of "learnings," surfaced by recency. That doesn't scale: the note you need is rarely one of the last five.

KodaMemory replaces recency with relevance. Knowledge is stored as a graph of typed nodes connected by typed relationships, and recall ranks that graph against the task in front of the agent. The result is that a session picks up the decisions and gotchas that actually bear on its work — with the links between them attached — the moment it starts.

Coordination vs. memoryCoordination keeps agents in sync in the moment — who's doing what, right now. KodaMemory keeps what they learn across time — durable knowledge that outlives any single session. Same bus, same .koda/coord/ folder, two different jobs.
Project memory vs. your Second BrainKodaMemory is per-workspace and about the project. What Koda knows about you — your goals, preferences, and writing style — lives in a separate per-user graph, the AI Second Brain, which follows you across every workspace.

The graph model

Everything in KodaMemory is either a node (a thing worth remembering) or an edge (a relationship between two things). Both use a small, fixed vocabulary so the graph stays consistent and dedupable.

Node types

TypeWhat it captures
componentA subsystem or module — a coherent part of the codebase.
fileA where-things-live pointer — the file that really owns a behavior.
decisionWhy something was done a particular way.
gotchaA pitfall, sharp edge, or hard-won fix.
entityAn external service, API, or concept the project touches.
taskA unit of work, linked back to the board card it came from.

Edge relations

Edges connect nodes by name using a closed set of relationships, so the graph reads like a set of plain-English facts:

RelationMeaning
depends_onA needs B to work.
relates_toA and B are connected (the general-purpose link).
caused_byA gotcha or failure was caused by B.
supersedesA replaces B — B is now obsolete (see compaction).
implementsA implements B (e.g. a file implements a decision).
blocksA blocks B from proceeding.
learned_fromA was learned from B (a card, an investigation).
Names are the join keyAn edge points at another node by its name. If that node doesn't exist yet, Koda creates a lightweight stub for it, so you can assert a relationship before — or without — writing the full node. Name the same thing the same way and it deduplicates automatically.

Writing memory

There are two ways knowledge enters the graph.

Structured notes

An agent calls koda_memory_note to assert a node — its type, a stable name, a one- or two-sentence summary, optional tags, and optional edges to other nodes. This is the right tool when the knowledge has a clear subject and/or relates to other things.

koda_memory_note → memory-events.jsonl
{
  "kind": "node",
  "type": "gotcha",
  "name": "stripe portal needs a live config id",
  "summary": "The billing portal 500s until a live billing_portal config is created in the dashboard.",
  "tags": ["stripe", "billing", "portal"],
  "cardId": "cmr1o9bdm-4-985160",
  "by": "4",
  "ts": 1782886553745
}

Quick learnings

koda_record_learning is the lightweight path: a one-line text learning with no subject or edges. It's ideal for a fast "note to future sessions." Under the hood Koda still turns it into a gotcha node, so quick learnings flow into the same graph as everything else.

It happens as agents workKoda's agent instructions prompt every session to save non-obvious discoveries. You don't run a separate "index" step — the graph fills in as your agents build, and each note is attributed to the pane and board card it came from.

Recall & ranking

Memory is only useful if the right piece shows up at the right time. KodaMemory surfaces knowledge two ways.

At session start

On the first prompt of a session, Koda ranks the whole graph against the task (the prompt plus the card title) and injects the top matches — with their one-hop relationships — straight into the agent's context. It's the same hook that auto-announces the card, so it's automatic and needs no tool call.

injected into a new session
Relevant project memory (KodaMemory knowledge graph):
  - stripe portal needs a live config id [gotcha]
      caused_by → missing billing_portal config
  - surface the real Stripe error, not the wrapper [decision]
  - supabase/functions/portal/index.ts [file]
      implements → surface the real Stripe error

Ranking is deterministic and dependency-free — a keyword score over each node's name, tags and summary, boosted by how often the node has been mentioned and how recently it was seen. Nodes that have been superseded are penalized, and if nothing matches the query, Koda still surfaces the most important recent nodes so a session is never handed an empty slate.

Mid-task queries

When an agent wants to look something up while working — before it investigates a subsystem or changes a behavior — it calls koda_memory_query with a natural-language query and an optional type filter. It returns the matching nodes with their summaries, tags and one-hop edges, ranked the same way.

koda_memory_query("stripe portal error", ["gotcha"]) → result
{
  "ok": true, "count": 1, "matched": true,
  "nodes": [
    {
      "id": "n_a1b2", "type": "gotcha",
      "name": "stripe portal needs a live config id",
      "summary": "The billing portal 500s until a live config is created.",
      "tags": ["stripe", "billing"], "mentions": 3,
      "status": "active",
      "edges": [{ "rel": "caused_by", "to": "missing billing_portal config" }]
    }
  ]
}

Memory tools reference

KodaMemory adds three tools to the coordination server. Agents call them by their fully-qualified MCP names (e.g. mcp__koda-coord__koda_memory_note); they're documented here by their short names.

koda_memory_notewritePro

Adds a node to the graph, plus any edges from it. The dedup key is (type + normalized name), so re-asserting the same node merges tags, unions its card provenance, and bumps its mention count rather than duplicating it.

typecomponent, file, decision, gotcha, entity, or task.
name — a short, stable subject; the dedup key.
summary opt — one or two sentences (clamped to 500 chars).
tags opt — up to 12 lowercase keywords to aid ranking.
edges opt — an array of { to, rel } relationships to other nodes.
cardId opt — board card provenance; defaults to the card you've claimed.
koda_memory_queryreadPro

Searches the materialized graph and returns matching nodes with their summaries, tags, mention counts, status and one-hop edges — ranked by relevance plus importance and recency. Read-only.

query opt — natural-language terms; omit to get the most important nodes.
types opt — restrict to one or more node types.
limit opt — max nodes to return (default 8, max 25).
koda_record_learningwritealways on

Records a one-line learning for future sessions. Kept in an auditable learnings.jsonl log and also emitted as a gotcha node so it flows into the graph. Not gated — it keeps working even when your entitlement can't be verified.

text — the learning, distilled to one or two sentences (clamped to 500 chars).
cardId opt — board card provenance; defaults to the claimed card.

Architecture & storage

KodaMemory is built the same way as the rest of coordination: a zero-dependency server that only appends, and a single writer in Koda that materializes. That split is what keeps many agent panes writing concurrently without locks or corruption.

FileWritten byHolds
memory-events.jsonleach pane's MCP server (append-only)The source of truth — one node/edge event per line.
graph.jsonKoda main (single writer)The materialized snapshot: merged nodes and edges with rankings.
graph-cursor.jsonKoda mainByte offsets of what's already been materialized, for fast polling.

Agents never write graph.json directly — they only append events, which is race-safe across processes. Koda's main process tails the event log on each presence poll and rebuilds the graph: it merges duplicate assertions, upserts edges, recomputes mention and recency rankings, and marks superseded nodes. Every node carries its provenance — the pane that authored it and the board cards it traces back to — so the memory is auditable, not a black box.

Zero-dependency, all localThe server that agents talk to is plain Node with no packages, and the graph is just JSON on disk under .koda/coord/. There's no database to run and no service to reach.

Dedup & compaction

Left alone, an append-only log grows forever. KodaMemory keeps the graph tight in three ways:

Privacy & tiers

KodaMemory inherits coordination's stance: local files, no backend, no proxy.

Access gating is enforced at every layer and fails closed — if your trial or subscription can't be verified, the graph features pause and only the ungated basics keep working:

CapabilityUnverified accessTrial & Pro
koda_record_learning
Last-few learnings at session start
koda_memory_note / koda_memory_query
Graph materialization & relevance recall
Memory graph view in the Tasks panel

KodaMemory is active throughout your trial and on Pro. Everything it records lives locally in .koda/coord/, so nothing is lost between sessions — or between the trial and a subscription.

Limitations

KodaMemory is deliberately simple in v1. A few honest edges to know about:

Keyword ranking, not embeddings

Recall scores on keywords, tags and mentions — not semantic similarity. It's fast and dependency-free, but a query has to share words with a node to match it. Semantic search is on the roadmap.

Grows by distinct nodes

Log size is bounded by compaction, but the count of distinct nodes has no hard cap yet. In practice this stays small; heavy pruning of stale links is a future refinement.

Recall can lag a beat

The graph is rebuilt on Koda's presence poll, so a note written this turn may take one poll cycle to appear in a query. Session-start recall always reads the freshest snapshot.

Troubleshooting

Memory tools return "pro-required"

koda_memory_note and koda_memory_query need an active trial or Pro subscription. Sign in and make sure it's active; the gate fails closed, so a login that can't be verified is treated as unentitled.

A note isn't showing up in queries

The graph materializes on a poll cycle — give it a moment. Confirm coordination is On for the workspace, since memory rides the same bus.

Two notes I meant as one are separate

The dedup key is the node name. Name the same thing the same way and future assertions merge; small differences in wording create distinct nodes.

Old, wrong knowledge keeps surfacing

Don't delete it — supersede it. Write the corrected node with a supersedes edge to the old one, and the old node drops down the rankings while staying in the audit trail.