---
title: "Memory for the Vercel AI SDK"
description: "The Vercel AI SDK leaves memory persistence to the application. Add temporal memory to an AI SDK agent with one fetch-based tool pair and two endpoints."
canonical: https://past.dev/integrations/vercel-ai-sdk
last-updated: 2026-09-02
---
# Add memory to the Vercel AI SDK

Source: https://past.dev/integrations/vercel-ai-sdk

The Vercel AI SDK runs the agent loop and manages the message array within a run. It does not provide native memory persistence: chat history storage is implemented by the application, and the memory guide lists provider-defined tools, memory providers and custom tools as the ways to add more. A custom tool whose execute function calls past.dev over HTTP adds temporal memory with dated evidence and a status value on every recall.

## Vercel AI SDK memory scope

The [AI SDK](https://ai-sdk.dev/docs/agents) treats an agent as a model calling tools in a loop, with `ToolLoopAgent` managing the loop, the message array and the stopping conditions for one run. Persistence sits with the application: the [message persistence guide](https://ai-sdk.dev/docs/ai-sdk-ui/chatbot-message-persistence) has you implement chat saving and loading against your own database.

For memory beyond the transcript, the [memory guide](https://ai-sdk.dev/docs/agents/memory) states that the SDK provides no native memory persistence and documents three approaches: provider-defined tools, external memory providers and custom tools. The recipe below is the custom-tool path.

- `useChat` manages client-side message state; storing and reloading chats is application code in your route handlers.
- `runtimeContext` carries shared state through one agent loop, for `prepareStep` and lifecycle callbacks. It is run-scoped state rather than durable memory.
- A saved transcript stays unstructured: nothing in it resolves entities, dates facts or marks which value is current.

## The integration: one tool pair, two endpoints

Define a [tool](https://ai-sdk.dev/docs/foundations/tools) per endpoint: a `description`, an `inputSchema` and an `execute` function that calls `fetch`. The wire format is small: `content` plus `timestamp` on ingest, `query` on recall ([API reference](/docs/memory-api/api-reference)).

```typescript
import { tool } from "ai";
import { z } from "zod";

const BASE = "https://api.past.dev/api/v1";
const headers = {
  Authorization: `Bearer ${process.env.PAST_API_KEY}`,
  "Content-Type": "application/json",
};

export const rememberFact = tool({
  description: "Store a durable fact with the time it actually happened.",
  inputSchema: z.object({
    text: z.string(),
    happenedAt: z.string().describe("ISO 8601 event time"),
  }),
  execute: async ({ text, happenedAt }) => {
    const r = await fetch(`${BASE}/ingest`, {
      method: "POST",
      headers,
      body: JSON.stringify({ content: text, timestamp: happenedAt }),
    });
    return r.json();
  },
});

export const recallMemory = tool({
  description: "Return dated evidence and a status value for a question.",
  inputSchema: z.object({ question: z.string() }),
  execute: async ({ question }) => {
    const r = await fetch(`${BASE}/recall`, {
      method: "POST",
      headers,
      body: JSON.stringify({ query: question }),
    });
    return r.json();
  },
});
```

Pass both through the `tools` parameter of `generateText`, `streamText` or a `ToolLoopAgent`. The model decides when to store and when to recall from the tool descriptions. Keep your existing chat persistence for resuming conversations; route durable facts through the API.

## Routing on recall status

Applications can route on `status`. `Supported` means the evidence establishes the answer. `Conflicted` returns evidence from credible sources that disagree. `NoKnownSupport` means the stored evidence does not establish an answer. `UnknownBecauseDegraded` means retrieval could not complete and should be treated as an unknown result.

In an AI SDK app the status arrives as the tool result, so the model can state it directly, and a lifecycle callback or your route handler can branch on it: send `Conflicted` answers to a person with the evidence from both sides, or have `NoKnownSupport` trigger a clarifying question instead of a guess.

## When to use which layer

| Requirement | Chat persistence you build | past.dev via tool |
| --- | --- | --- |
| Resume a conversation in useChat | Yes | No |
| Facts shared across chats, users and apps | Only by rereading transcripts | One recall call |
| Current value after a change | The model rereads the transcript | Supersession with both values queryable |
| Backfilled history on original dates | No | Timestamped ingestion |
| Insufficient evidence distinguished from a miss | No | NoKnownSupport and UnknownBecauseDegraded |

The [quickstart](/docs/memory-api/quickstart) reaches a first recall in four calls. The [benchmarks](/benchmarks) document how recall is measured, and [choosing a memory system](/guides/choose-memory-system) compares the wider field of options.

## Frequently asked questions

### Does the Vercel AI SDK have built-in memory?

No. The AI SDK documents memory as something the application adds through provider-defined tools, an external memory provider, or custom tools. Chat history persistence is also implemented by the application.

### Do I need a database to give an AI SDK agent memory?

You need storage somewhere. A transcript store you build covers resuming conversations, and a memory API adds structured facts with dates, supersession and a status value on recall without new infrastructure on your side.

### Does this work with useChat and streamText?

Yes. The tools execute inside your route handler wherever generateText or streamText runs, and useChat on the client is unchanged.

## Related

- [Memory for the OpenAI Agents SDK](https://past.dev/integrations/openai-agents-sdk)
- [Memory for LangChain](https://past.dev/integrations/langchain)
- [Memory for n8n](https://past.dev/integrations/n8n)
- [Cross-session memory](https://past.dev/glossary/cross-session-memory)
- [Quickstart](https://past.dev/docs/memory-api/quickstart)