---
title: "Give an app agent memory"
description: "Let a support agent remember each customer's preferences, recall them into the next model call as data, keep tool-supplied facts quarantined, and forget a person with a signed receipt."
section: "guides"
status: "Building for 0.4"
spec: "memory"
canonical: "https://mainsdk.dev/docs/guides/give-an-agent-memory"
updated: "2026-10-28"
---

# Give an app agent memory

> Let a support agent remember each customer's preferences, recall them into the next model call as data, keep tool-supplied facts quarantined, and forget a person with a signed receipt.

Status: Building for 0.4 · Canonical: https://mainsdk.dev/docs/guides/give-an-agent-memory · Updated: 2026-10-28

Your support agent will remember what each customer tells it, such as how they like to be contacted, and use it in the next reply. Memories stay inside the customer's tenant, reach the model only as data, and are forgotten for real when the customer asks, with a receipt to show for it. It takes about 20 minutes.

> **Note:** `memory` is planned for 0.4 (spec `memory`) and has no code yet, so the steps below are the target shape and cannot be run today. Like everything in the app, it is free.

## You need

- A MainSDK app with `ai` set up and an agent under `agents` (see [Give an agent a budget](https://mainsdk.dev/docs/guides/govern-an-app-agent)).
- Sign-in, so each request has a person and a tenant.

## 1. Declare memory and the agent's grant

```yaml title="main.yaml"
memory:
  driver: db                       # local in development works too
  embed: { model: openai/text-embedding-3-small, feature: memory-embed }
  ttl: { event: 90d }
  from-tools: quarantine
agents:
  support-bot:
    budget: { spend: $5/day, calls: 500/day }
    memory: { read: own, write: true, forget: approve, recalls: 500/day, writes: 100/day }
```

`read: own` means the agent sees only what it wrote. `forget: approve` means a forget by the agent waits for a person.

## 2. Remember what the customer says

```ts title="lib/remember.ts"
import { memory } from "mainsdk/experimental/memory";

export async function rememberPreference(text: string) {
  return memory.remember(text, { kind: "preference" });   // about the person the agent acts for, in their tenant
}
```

Call it when the customer states a preference, for example from a `support.remember` action the agent can call.

## 3. Recall into the next reply, as data

```ts title="lib/reply.ts"
import { ai } from "mainsdk";
import { memory } from "mainsdk/experimental/memory";

export async function reply(user: { id: string }, message: string) {
  const ctx = await memory.context({ query: message, budget: 800 });
  const out = await ai.generate({
    model: "anthropic/claude-sonnet-4-5",
    messages: [
      { role: "user", content: ctx.text },   // one escaped <memory> block, never system text
      { role: "user", content: message },
    ],
    feature: "support-chat",
    agent: "support-bot",
    user,
  });
  return out.text;
}
```

If the store is down, `ctx.text` is an empty block and `ctx.degraded` is `true`; the reply still goes out.

## 4. Let a person confirm what a tool supplied

Facts the agent picked up from a tool or a web page are quarantined to their session. Show them to the customer and confirm the ones they agree with.

```ts title="app/api/memory/confirm/route.ts"
import { auth } from "mainsdk";
import { memory } from "mainsdk/experimental/memory";

export async function POST(req: Request) {
  await auth.require(req);
  const { id } = (await req.json()) as { id: string };
  return Response.json(await memory.revise(id, { trust: "confirmed" }, { reason: "customer confirmed" }));
}
```

## 5. Forget on request

```ts title="app/api/memory/forget/route.ts"
import { auth } from "mainsdk";
import { memory } from "mainsdk/experimental/memory";

export async function POST(req: Request) {
  const session = await auth.require(req);
  const receipt = await memory.forget({ about: session.user }, { reason: "customer request" });
  return Response.json({ receipt });   // signed by your project key; ids only, no content
}
```

## Verify

```text
$ pnpm mainsdk check
✓ memory: driver db, erase hard, regions eu, us
✓ agents.support-bot.memory: read own, write, forget approve
0 findings
```

In a test, remember a preference as one tenant and recall as another: the second gets nothing. Forget, then read the receipt: its signature verifies with your project's public key.

## If it fails

| You see | Do this |
| --- | --- |
| `MAIN-MEM-0005` | The agent has no grant. Add `memory` under `agents.<name>` |
| `MAIN-MEM-0001` | No person in context. Call inside a signed-in request, or pass `about` |
| `MAIN-MEM-0003` | The text looked like instructions. Store what the person said, not what a tool returned |
| `MAIN-MEM-0022` | You passed recalled text as `system`. Put it in a user message |
| `MAIN-MEM-0023` | A driver in `main.yaml` is named `memory`. Rename it `local` |

## For agents

```text
Give support-bot memory with MainSDK: add memory (driver db) and agents.support-bot.memory
(read own, write true, forget approve) to main.yaml. Store preferences with memory.remember,
pass memory.context() text as a user message (never system), confirm tool-supplied memories
with memory.revise(id, { trust: "confirmed" }) from a person, and add a forget route that
returns the memory.forget receipt. Run pnpm mainsdk check until it reports 0 findings.
```

## Next

- [Agent memory, the concept](https://mainsdk.dev/docs/concepts/agent-memory)
- [Agent memory reference](https://mainsdk.dev/docs/interfaces/memory)
- [Data and regions](https://mainsdk.dev/docs/concepts/data-and-regions)
