--- title: "Memory for the OpenAI Agents SDK" description: "The OpenAI Agents SDK persists conversation history through sessions. Add durable temporal memory with dated evidence through the past.dev API." canonical: https://past.dev/integrations/openai-agents-sdk last-updated: 2026-10-17 --- # Add memory to the OpenAI Agents SDK Source: https://past.dev/integrations/openai-agents-sdk The OpenAI Agents SDK persists conversation history through sessions: a session stores the items of one conversation and prepends them to the next run's input. Handoffs pass that history between agents. The SDK does not document a cross-session fact model. A function tool that calls past.dev over HTTP adds timestamped ingestion and grouped recall documents with source excerpts. ## OpenAI Agents SDK memory scope The [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) ships session memory: a [session](https://openai.github.io/openai-agents-python/sessions/) stores the items of one conversation (user messages, assistant responses, tool calls), prepends them to the next run's input and appends what the run produced. Backends include `SQLiteSession`, `RedisSession`, `SQLAlchemySession` and `OpenAIConversationsSession`, which keeps the history server-side through the [Conversations API](https://developers.openai.com/api/docs/guides/conversation-state). A [handoff](https://openai.github.io/openai-agents-python/handoffs/) delegates the conversation to another agent. By default the receiving agent sees the entire previous conversation history; an `input_filter` can trim what it receives. - Scope is one conversation. A new session id starts empty, and the SDK documents no cross-session or cross-user fact model. - Sessions store raw conversation items. There is no entity resolution, no fact validity dates and no change query over what they hold. - Server-side storage has retention rules: [response objects are saved for 30 days by default](https://developers.openai.com/api/docs/guides/conversation-state), while conversation objects carry no 30-day TTL. Either way the stored unit is a transcript rather than structured facts. ## The integration: two function tools, two endpoints Define two function tools that call past.dev over HTTP. Store observations with their original timestamps, and recall before answering questions that depend on history. All public operations are documented in the [API reference](/docs/memory-api/api-reference). ```python import os, requests from dataclasses import dataclass from agents import Agent, RunContextWrapper, Runner from agents.decorators import tool BASE = "https://api.past.dev/api/v1" HEADERS = {"Authorization": f"Bearer {os.environ['PAST_API_KEY']}"} @dataclass class CurrentUser: identity: str # the signed-in user, set by your application @tool def remember(wrapper: RunContextWrapper[CurrentUser], text: str, happened_at: str) -> dict: """Store timestamped source text, readable by the whole project, authored by the current user.""" return requests.post(f"{BASE}/ingest", headers=HEADERS, json={ "content": text, "timestamp": happened_at, "identity": wrapper.context.identity, }).json() @tool def recall(wrapper: RunContextWrapper[CurrentUser], question: str) -> dict: """Return ranked documents with source excerpts for the current user.""" return requests.post(f"{BASE}/recall", headers=HEADERS, json={ "query": question, "identity": wrapper.context.identity, }).json() agent = Agent[CurrentUser]( name="Assistant", instructions="Call recall before you answer questions about people, decisions or history.", tools=[remember, recall], ) result = Runner.run_sync(agent, "What did we decide about the Q4 budget?", context=CurrentUser("demo-user")) ``` The SDK builds each schema from the function signature and takes the descriptions from the docstring ([tools documentation](https://openai.github.io/openai-agents-python/tools/)). The `RunContextWrapper` parameter carries the run's context, which the SDK never sends to the model ([context](https://openai.github.io/openai-agents-python/context/)). Pass the signed-in user as `context` on each run, and tell the agent in its instructions when to use the tools: remember durable facts about people and decisions, recall before answering questions about history. > **Identity** > > The application sets the identity. The model never chooses it. Recall returns what the identity in the request may read, so take the identity from the signed-in user in code, and keep it out of every value that the model fills. ## Or connect the MCP server The SDK's `MCPServerStreamableHttp` from `agents.mcp` connects to a remote server over Streamable HTTP, and an agent takes it through `mcp_servers` ([MCP guide](https://openai.github.io/openai-agents-python/mcp/)). The project's end-user MCP server then gives the agent `recall`, `answer` and `who_am_i`, plus `remember` while the project's write toggle is on, with no tool code to write. 1. Turn on the project's end-user MCP server on **Build › MCP server** in the console. 2. Mint an access link there, or with the account server's `create_mcp_access_link` tool. The link has the form `https://api.past.dev/mcp//link/`. It is one URL that is one identity, and the server answers it with no sign-in step. 3. Keep the link in a secret store, such as the `PAST_MCP_URL` environment variable that the code below reads. The secret in its path is the credential. ```python import asyncio, os from agents import Agent, Runner from agents.mcp import MCPServerStreamableHttp async def main(): async with MCPServerStreamableHttp( name="past", params={"url": os.environ["PAST_MCP_URL"]}, ) as server: agent = Agent( name="Assistant", instructions="Call recall before you answer questions about people, decisions or history.", mcp_servers=[server], ) result = await Runner.run(agent, "What did we decide about the Q4 budget?") print(result.final_output) asyncio.run(main()) ``` Every call through the link runs as its identity, with that identity's audiences. Mint one link per install, so that a revoked link stops one agent only. When the agent serves several people, mint one link per end user, and connect each request with the link of the user who makes it. Never share one link between users. `remember` writes to the identity's own private audience, and only that identity recalls it. Send data that the whole project must recall through the ingest call. The [end-user server documentation](/docs/mcp/serving-your-own-users) describes the tools, the links and revocation. ## How an agent uses recall results Recall returns ranked documents with dates and source excerpts. The application decides whether those documents support an answer, contain a disagreement, or are insufficient; HTTP failures are handled separately. Define behavior for the returned documents and for HTTP failures separately. Answer with dates and source excerpts when the material is sufficient, present documents that disagree, decline when it is insufficient, and retry or fall back when the request fails. ## Sessions and past.dev side by side | Requirement | Sessions | past.dev via tool | | --- | --- | --- | | Continue one conversation across runs | Yes | No | | Facts shared across sessions, users and agents | No | Yes | | Current value after a fact changes | The model rereads the transcript | Supersession with both values queryable | | What was true on a date | No query for it | [Point-in-time recall](/glossary/point-in-time-recall) | | Recall result | Conversation items | Grouped documents with dated source excerpts | The two layers run together: the session carries the current conversation while the API holds timestamped source text that authorized identities can recall. The [quickstart](/docs/memory-api/quickstart) shows how to ingest, wait until ingestion completes, and recall. The [benchmarks](/benchmarks) document how recall quality is measured. ## Frequently asked questions ### Do OpenAI Agents SDK sessions remember users across conversations? A session replays the conversation items stored under its session id. A new session id starts empty, so memory across conversations requires the application to load history itself or to query an external memory service. ### Can I keep using sessions if I add a memory API? Yes. Sessions handle the transcript of the current conversation. The memory API keeps durable facts with dates and sources that any session, agent or application can query. ### What happens to memory during a handoff? By default the receiving agent sees the entire previous conversation for that run. Facts stored through the memory tools are independent of handoffs: any agent with the same key can recall them, during the run or after it. ## Related - [Memory for the Vercel AI SDK](https://past.dev/integrations/vercel-ai-sdk) - [Memory for the Claude Agent SDK](https://past.dev/integrations/claude-agent-sdk) - [Memory for Pydantic AI](https://past.dev/integrations/pydantic-ai) - [Memory for LangGraph](https://past.dev/integrations/langgraph) - [Session memory](https://past.dev/glossary/session-memory) - [Quickstart](https://past.dev/docs/memory-api/quickstart)