Skip to content

Memory Bank

The Memory Bank is the vault’s long-term memory: what its agents and workflows have learned, and how each run builds on the ones before it. It belongs to the vault, so it belongs to the customer. Agents come and go; the Memory Bank stays.

What it holds

A graph of records and relations.

Record field Meaning
id Stable id you choose. Writing the same id again updates the record.
type What kind of thing it is, e.g. fact, decision, principle, note.
title, body The content.
scope Where it lives: the vault scope that governs who may read it.
privacy How sensitive it is: public, internal, private, or restricted.

A relation is a directed, typed edge from one record (in) to another (out). It carries its own scope and privacy, because a link can be more sensitive than the records it joins.

Records also move through review states (proposed, accepted, rejected, superseded). Reads return accepted records unless they ask for other states.

Two axes of access

Every read is gated twice:

  • Scope decides where a reader may look. A reader sees only scopes their grants reach. An ungranted scope returns no rows, never an error.
  • Privacy decides how sensitive a fact a reader may see. A vault member can hold a privacy ceiling (Public, Internal, Private, or Restricted).

A run reads with the permissions of the person who started it.

How data gets in

Writes come from agents and workflows only. Your app reads the Memory Bank but cannot write to it.

Writer How
A workflow remember (file a record) and relate (link two records) steps.
A code agent ctx.memory.upsert(record), .update(id, patch), .setPrivacy(id, privacy), .delete(id), .relation(edge).

privacy is required on every write and never defaulted. Before filing anything, answer: who reads this later, and does each row need its own visibility?

await ctx.memory.upsert({
id: `decision:${ticketId}`,
type: "decision",
title: "Refunds over 500 need a second approver",
body: "Agreed after the March audit.",
scope: "finance",
privacy: "internal",
});
await ctx.memory.relation({
in: `decision:${ticketId}`,
out: "principle:four-eyes",
type: "applies",
scope: "finance",
privacy: "internal",
});

Work in progress belongs in a cubby. File only what the organization should keep.

How agents and workflows read it

Reader How
A workflow recall step: search, then read each hit’s body.
A code agent ctx.memory.search(match, { limit }), .get(id), .neighbours(id, { limit }), .countByType(). Rows come back as plain objects.
A widget A named query with tool: "search" | "get" | "neighbours" | "countByType". See Widgets.
Your app vault.memory.search, .list, .get, .neighbours, .countByType in the Vault SDK.
An LLM agent The vault’s MCP endpoint (below).
const hits = await ctx.memory.search("refund approval", { limit: 5 });

From your app

The Vault SDK returns rows exactly as the vault sends them: a columns list and positional rows, plus a cursor when more rows exist.

const page = await vault.memory.search("refund approval", { scope: "finance", limit: 20 });
// page.columns: id, type, title, scope, privacy, rank, snippet
const next = page.cursor
? await vault.memory.search("refund approval", { scope: "finance", cursor: page.cursor })
: undefined;

Read neighbours rows by position: the far record’s type and the edge’s type share a column name.

From an LLM agent: MCP

The vault serves its Memory Bank as read-only MCP tools at:

POST /api/v1/vaults/:vaultId/mcp

It is a stateless Streamable HTTP server, authenticated like any vault read. During a run, an LLM agent that receives the run’s execution token presents it, so it searches with the permissions of the person who started the run. See Authentication.

Tool Arguments Limits
search query, optional domains, types, statuses, limit limit default 10, at most 25
get ids, optional body_chars, offset 1 to 10 ids; body_chars default 4000, at most 8000
neighbours id, optional edge_type, direction, limit limit default 10, at most 25

Search matches words of three or more letters by stem, ranks records that match more and rarer words first, and returns ids, titles, and a snippet; call get for full text. Tool failures come back as MCP tool errors the model can act on; authentication failures stay HTTP 401 or 403.

In ROC

The Memory Bank page shows the vault behind the selected Agent Service, and only what your grants reach.

Tab Shows
Overview Ask a question and get an answer drawn from the records only; knowledge and run counts, knowledge by type, recently changed records.
Journeys Runs for one domain and subject, step by step, with key takeaways; compare a run with others.
Browse Search and open records; filter to Needs review; Show run entries to include the runs’ own bookkeeping.
Outcomes What a workflow wrote and what a person decided afterwards.

Memory Bank Overview tab with the Ask box and knowledge counts