--- title: "Memory for LlamaIndex agents" description: "LlamaIndex Memory manages chat history and memory blocks per session. What it stores, its limits, and a FunctionTool that adds temporal memory over HTTP." canonical: https://past.dev/integrations/llamaindex last-updated: 2026-10-17 --- # Add memory to LlamaIndex agents Source: https://past.dev/integrations/llamaindex LlamaIndex documents a Memory class for agents: a short-term queue of recent chat messages that flushes into long-term memory blocks under a token budget. It is conversation memory, scoped to a session id and stored in a database the application configures. It models no fact validity or supersession. This page states what the documented system covers and shows a FunctionTool that connects any LlamaIndex agent to temporal memory over HTTP, where recall returns ranked documents with dates and verbatim source excerpts. ## What LlamaIndex memory covers The [memory guide](https://developers.llamaindex.ai/python/framework/module_guides/deploying/agents/memory/) documents a `Memory` class built around a FIFO queue of chat messages. `token_limit` caps what the object holds, `chat_history_token_ratio` sets the short-term share, and when the queue exceeds its budget, batches of `token_flush_size` tokens move into long-term memory blocks. A `session_id` names the conversation. The default backing store is an in-memory SQLite database; pointing the object at a database URI makes it persistent. Agents accept the object per run: `agent.run(question, memory=memory)`. Long-term memory is a set of blocks. `StaticMemoryBlock` holds fixed text such as a persona. `FactExtractionMemoryBlock` has an LLM extract fact lines from flushed messages, up to `max_facts`. `VectorMemoryBlock` writes flushed batches to a vector store and retrieves them by similarity. Each block carries a `priority`: zero is always kept, higher numbers are truncated first when the context budget fills. - **Flushing is budget-driven.** Messages reach long-term blocks when token limits overflow, so what persists depends on context pressure and on the extraction prompt rather than on a decision about the fact itself. - **Fact lines are undated.** An extracted fact records no event time, no validity window and no link to the fact it replaced. A January value and a March value are two lines of text, and similarity cannot say which one is current. - **Scope is the session you name.** Memory persists where its database lives and under the `session_id` the application passes. Sharing across agents, products and users is left to application design. ## The integration: a FunctionTool per endpoint LlamaIndex converts plain functions into tools. The [tools guide](https://developers.llamaindex.ai/python/framework/module_guides/deploying/agents/tools/) documents `FunctionTool.from_defaults`, which wraps a sync or async function, taking the name from the function and the description from its docstring. The [agent classes](https://developers.llamaindex.ai/python/framework/module_guides/deploying/agents/) (`FunctionAgent`, `ReActAgent`) accept a `tools` list. Two functions connect any of them to past.dev; the [API reference](/docs/memory-api/api-reference) documents all public operations. A tool whose first parameter is the workflow `Context` reads values from it, and the model never sees that parameter ([tools and state](https://developers.llamaindex.ai/python/framework/understanding/agent/state/)). ```python import os, requests from llama_index.core.agent.workflow import FunctionAgent from llama_index.core.tools import FunctionTool from llama_index.core.workflow import Context BASE = "https://api.past.dev/api/v1" HEADERS = {"Authorization": f"Bearer {os.environ['PAST_API_KEY']}"} async def remember(ctx: Context, text: str, happened_at: str) -> str: """Store timestamped source text, readable by the whole project, authored by the current user.""" r = requests.post(f"{BASE}/ingest", headers=HEADERS, json={"content": text, "timestamp": happened_at, "identity": await ctx.store.get("user_id")}).json() return r.get("sourceId", "stored") async def recall(ctx: Context, question: str) -> str: """Return ranked documents with source excerpts for the current user.""" r = requests.post(f"{BASE}/recall", headers=HEADERS, json={"query": question, "identity": await ctx.store.get("user_id")}).json() return str(r) agent = FunctionAgent( llm=llm, # any LlamaIndex LLM tools=[FunctionTool.from_defaults(remember), FunctionTool.from_defaults(recall)], system_prompt=( "Recall before answering questions about people, decisions or history. " "Remember durable source text with its original timestamp." ), ) async def ask(question: str, user_id: str): ctx = Context(agent) await ctx.store.set("user_id", user_id) # the signed-in user, set by your application return await agent.run(question, ctx=ctx) ``` Keep `Memory` on the run for conversational flow. The tools carry the durable record: facts stored at their original event time, recalled as ranked documents with dates and the verbatim source excerpts the agent can cite. > **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 `llama-index-tools-mcp` package provides `BasicMCPClient` and `McpToolSpec`. A URL that does not end in `/sse` uses Streamable HTTP ([MCP tools](https://developers.llamaindex.ai/python/framework/module_guides/mcp/llamaindex_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 os from llama_index.core.agent.workflow import FunctionAgent from llama_index.tools.mcp import BasicMCPClient, McpToolSpec client = BasicMCPClient(os.environ["PAST_MCP_URL"]) tools = await McpToolSpec(client=client).to_tool_list_async() agent = FunctionAgent( llm=llm, # any LlamaIndex LLM tools=tools, system_prompt="Call recall before you answer questions about people, decisions or history.", ) ``` 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. ## Routing on 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. An agent workflow can branch on the returned documents. Sufficient material becomes an answer with dates and source excerpts, disagreements are presented between named sources, insufficient material becomes a stated gap, and an HTTP failure triggers retry or fallback. ## A worked example: the budget that changed A client emails on January 8 that the renewal budget is 30k. A call on March 12 raises it to 45k. Inside `Memory`, both statements were flushed as text. `VectorMemoryBlock` retrieval returns both passages, because both are similar to the question, and neither passage carries the date it was true. A fact line extracted from either message is a sentence without a timeline. Ingested through the tool with their original timestamps and stable source ids, the two statements remain attributable to their sources. Recall returns ranked documents with dates and excerpts that the application can use to answer current or historical questions. The [quickstart](/docs/memory-api/quickstart) shows the public request flow, and the [benchmarks](/benchmarks) document how recall is measured. [Session memory](/glossary/session-memory) and [cross-session memory](/glossary/cross-session-memory) define the two layers this page separates. ## Frequently asked questions ### Does LlamaIndex have built in long term memory? Yes. The Memory class flushes older chat messages into long-term memory blocks: static text, LLM-extracted fact lines, or vector retrieval over past messages. The blocks live with the session and the database you configure. ### Do I still need the Memory class if I use a memory API? Yes. Memory carries the conversation so the agent can follow recent turns and references. The API carries timestamped source text and returns ranked documents with dated source excerpts across sessions, agents, and products. ### Can a LlamaIndex agent remember a user across sessions? Within the framework, persistence requires a database-backed Memory and a session design that maps to your users. A memory service moves that record outside the process, so any session or agent with the right key recalls the same user history. ## Related - [Memory for CrewAI](https://past.dev/integrations/crewai) - [Memory for LangGraph](https://past.dev/integrations/langgraph) - [Memory for the Vercel AI SDK](https://past.dev/integrations/vercel-ai-sdk) - [Memory for Haystack](https://past.dev/integrations/haystack) - [What is agent memory?](https://past.dev/what-is-agent-memory) - [Quickstart](https://past.dev/docs/memory-api/quickstart)