Jesse A. Green / notebook

Mem0 — User Guide

Generated June 2026 from mem0ai/mem0 at 74771b4

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Mem0 (pronounced "mem-zero") is a memory layer for AI agents and applications. It lets your LLM apps remember facts about users, agents, and conversations across sessions, so they stop forgetting everything the moment a chat ends.

You give Mem0 conversation messages; it uses an LLM to extract the durable facts ("User is allergic to peanuts", "User switched from almond to oat milk"), stores them as searchable memories, and returns the most relevant ones whenever you ask. The result is personalization that persists — without you stuffing an ever-growing transcript into every prompt.

This guide shows you how to install Mem0, store and search memories, scope them to users and agents, and wire Mem0 into real applications using Python, TypeScript, the REST API, or the command line. Configuration reference, deployment, and internals live in the companion Admin Guide.


Table of Contents

  1. Quick Start
  2. Choosing Your Path: Platform vs Open Source
  3. Installation
  4. Core Concepts
  5. Everyday Usage: The Memory Operations
  6. Scoping Memories: Users, Agents, Runs
  7. Searching and Filtering
  8. The Open Source Library in Depth
  9. The Platform Client in Depth
  10. The Mem0 CLI
  11. The LLM Proxy: Memory-Aware Chat in One Call
  12. The REST API
  13. OpenMemory: Your Private Memory Server
  14. Integrations
  15. Common Workflows (Recipes)
  16. How Mem0 Works (Concepts)
  17. Troubleshooting
  18. Frequently Asked Questions
  19. Reference

1. Quick Start

The fastest way to see Mem0 work is the managed Platform: get an API key, add a memory, search it back.

Python

pip install mem0ai
export MEM0_API_KEY="m0-your-api-key"
from mem0 import MemoryClient

client = MemoryClient()  # reads MEM0_API_KEY from the environment

# Store a conversation — Mem0 extracts the durable facts
client.add(
    [
        {"role": "user", "content": "I'm vegetarian and allergic to nuts."},
        {"role": "assistant", "content": "Got it — I'll keep that in mind."},
    ],
    user_id="alex",
)

# Later, in a different session, recall what matters
results = client.search("What can I cook for Alex?", filters={"user_id": "alex"})
for m in results["results"]:
    print(m["memory"])
Is vegetarian
Is allergic to nuts

TypeScript

npm install mem0ai
export MEM0_API_KEY="m0-your-api-key"
import MemoryClient from "mem0ai";

const client = new MemoryClient({ apiKey: process.env.MEM0_API_KEY });

await client.add(
  [
    { role: "user", content: "I'm vegetarian and allergic to nuts." },
    { role: "assistant", content: "Got it — I'll keep that in mind." },
  ],
  { user_id: "alex" }
);

const results = await client.search("What can I cook for Alex?", {
  filters: { user_id: "alex" },
});
console.log(results);

cURL

curl -X POST https://api.mem0.ai/v3/memories/add/ \
  -H "Authorization: Token m0-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "user", "content": "I am vegetarian and allergic to nuts."}
    ],
    "user_id": "alex"
  }'

Tip

Get a Platform API key from the Mem0 dashboard. Platform keys start with m0-. No infrastructure to run — Mem0 hosts the LLM, embeddings, and vector store for you.

Note

Prefer to run everything yourself with no external service? Skip to the Open Source Library. You only need an OpenAI (or other provider) key and a vector store — Mem0 handles the rest locally.


2. Choosing Your Path: Platform vs Open Source

Mem0 ships as one package with two ways to use it. Pick the one that fits your situation.

Platform (MemoryClient) Open Source (Memory)
Where memories live Mem0's managed cloud (api.mem0.ai) Your own vector store + database
What you provide A Mem0 API key LLM key + a vector store
Infrastructure to run None Vector store (Qdrant, pgvector, etc.)
Best for Shipping fast, scaling without ops Full data control, on-prem, air-gapped
Extra features Webhooks, exports, projects, feedback, graph memory Pluggable providers, local-first
Import (Python) from mem0 import MemoryClient from mem0 import Memory
Import (TS) import MemoryClient from "mem0ai" import { Memory } from "mem0ai/oss"

Important

The two share the same core verbs — add, search, get, get_all, update, delete, history — but their method signatures differ slightly (the Platform client accepts more options like app_id, webhooks, and exports). Examples in this guide are labelled so you always know which one you're looking at.

You can start on the Platform and move to self-hosted later (or vice versa); your application code barely changes because the verbs are the same.


3. Installation

Requirements

Requirement Platform Open Source
Python 3.10+ 3.10+
Node.js (for TS/JS or CLI) 18+ 18+
Mem0 API key Required —
LLM provider key (e.g. OPENAI_API_KEY) — Required
Vector store — Required (Qdrant by default)

Python

Platform only

pip install mem0ai

Open Source (with NLP extras)

pip install "mem0ai[nlp]"
python -m spacy download en_core_web_sm

Note

The open-source library uses spaCy for keyword lemmatization and entity extraction (part of its hybrid search). Installing the [nlp] extra and the en_core_web_sm model unlocks the full retrieval quality. If spaCy is missing, Mem0 still works — it falls back to semantic-only search.

TypeScript / JavaScript

npm install mem0ai
# or
pnpm add mem0ai
# or
yarn add mem0ai

The npm package mem0ai exposes the Platform client at the root and the open-source implementation under the mem0ai/oss subpath:

import MemoryClient from "mem0ai";        // Platform
import { Memory } from "mem0ai/oss";        // Open Source

Command Line

npm install -g mem0ai   # installs the `mem0` command (via @mem0/cli)

See The Mem0 CLI for usage.

Setting your keys

macOS / Linux

export MEM0_API_KEY="m0-your-api-key"     # Platform
export OPENAI_API_KEY="sk-..."            # Open Source default LLM/embedder

Windows (PowerShell)

setx MEM0_API_KEY "m0-your-api-key"
setx OPENAI_API_KEY "sk-..."

Python (.env)

from dotenv import load_dotenv
load_dotenv()  # loads MEM0_API_KEY / OPENAI_API_KEY from a .env file

4. Core Concepts

A handful of ideas appear everywhere in Mem0. Learn them once.

Memory : A single durable fact extracted from conversation, e.g. "User is allergic to nuts". Each memory has an id, the memory text, a hash, timestamps, and any metadata you attached. Memories are stored as vectors so they can be searched by meaning.

Messages : The input you feed add(). Either a plain string ("I love hiking") or a list of chat messages ([{"role": "user", "content": "..."}]). Mem0 reads these and decides what's worth remembering.

Inference : By default (infer=True), Mem0 sends your messages to an LLM that extracts only the memorable facts — not the whole transcript. Set infer=False to store messages verbatim with no LLM processing.

Scope (entity IDs) : Every memory belongs to at least one of user_id, agent_id, or run_id (the Platform also supports app_id). These keep one user's memories separate from another's. You must provide at least one when adding or searching.

Search : A meaning-based lookup. You give a query like "What does Alex eat?" and Mem0 returns the most relevant memories, ranked by a hybrid of semantic similarity, keyword matching, and entity overlap.

Tip

Think of add() as "tell Mem0 what happened" and search() as "ask Mem0 what it knows." You typically call add() after each conversation turn and search() before composing your next LLM prompt.


5. Everyday Usage: The Memory Operations

Every Mem0 surface — library, client, REST, CLI — exposes the same set of operations. Here they are with the Platform Python client; later sections show the open-source and other variants.

Add a memory

from mem0 import MemoryClient
client = MemoryClient()

# From a conversation
client.add(
    [
        {"role": "user", "content": "Book me a window seat when I fly."},
        {"role": "assistant", "content": "Noted — window seats going forward."},
    ],
    user_id="alex",
)

# From a single string
client.add("Alex prefers morning meetings", user_id="alex")
{'results': [{'id': '0b3f...', 'memory': 'Prefers window seats on flights', 'event': 'ADD'},
             {'id': '7a21...', 'memory': 'Prefers morning meetings', 'event': 'ADD'}]}

Each result carries an event describing what happened: ADD (new memory created), and on the Platform UPDATE/DELETE/NONE when an incoming fact revises or duplicates an existing one.

Search memories

results = client.search("travel preferences", filters={"user_id": "alex"})
for m in results["results"]:
    print(m["memory"], "→ score", round(m["score"], 3))
Prefers window seats on flights → score 0.71

Get all memories for a scope

all_mem = client.get_all(filters={"user_id": "alex"}, page=1, page_size=50)
print(all_mem["results"])

Get one memory by ID

mem = client.get("0b3f...")
print(mem["memory"])

Update a memory

client.update("0b3f...", text="Prefers aisle seats on long flights")
{'message': 'Memory updated successfully!'}

Delete a memory

client.delete("0b3f...")
{'message': 'Memory deleted successfully!'}

Delete all memories for a scope

client.delete_all(user_id="alex")

Caution

delete_all() removes every memory matching the filter you pass. There is no undo. To wipe everything for the whole account/instance, use reset() instead — and be equally careful.

View a memory's history

for change in client.history("0b3f..."):
    print(change["event"], change.get("old_memory"), "→", change.get("new_memory"))
ADD None → Prefers window seats on flights
UPDATE Prefers window seats on flights → Prefers aisle seats on long flights

Note

History is an audit trail of how a memory changed over time — when it was added, updated, or deleted. It's invaluable for debugging "why does the agent think X?"


6. Scoping Memories: Users, Agents, Runs

Scope is how Mem0 keeps memories from leaking between people, agents, and sessions. You must always supply at least one scope identifier.

Scope ID Meaning Typical use
user_id An end user / person "What does this customer like?"
agent_id An AI agent identity An agent's own learned behaviors and config
run_id A single session / conversation run Short-lived, per-conversation memory
app_id An application (Platform only) Group memory by product or app

Per-user memory (most common)

client.add(messages, user_id="alex")
client.search("preferences", filters={"user_id": "alex"})

Agent memory

When you add messages that include assistant turns and pass an agent_id, Mem0 can extract facts about the agent itself (its recommendations, configured behaviors, learned style):

client.add(
    [
        {"role": "user", "content": "Be concise from now on."},
        {"role": "assistant", "content": "Understood — I'll keep answers short."},
    ],
    agent_id="support-bot",
)

Combining scopes

You can scope to several IDs at once to narrow precisely:

client.add(messages, user_id="alex", agent_id="support-bot", run_id="ticket-8842")
client.search("open issues", filters={"user_id": "alex", "run_id": "ticket-8842"})

Important

In search() and get_all(), entity IDs must go inside filters={...}, not as top-level arguments. client.search(query, user_id="alex") raises an error in current versions; use client.search(query, filters={"user_id": "alex"}). In add() and delete_all(), they remain top-level arguments (user_id="alex"). This split is deliberate — it keeps "where to store" separate from "what to query."


7. Searching and Filtering

Search is where Mem0 earns its keep. Beyond a plain query, you can filter on metadata, use comparison operators, and combine conditions with boolean logic.

client.search("dietary restrictions", filters={"user_id": "alex"})

Limit results and set a threshold

client.search(
    "favorite foods",
    filters={"user_id": "alex"},
    top_k=5,           # return at most 5 memories
    threshold=0.3,     # drop matches below this similarity score (0–1)
)

Metadata filters with operators

When you store memories with custom metadata, you can filter on it using rich operators. Pass the operator as a nested dict:

# Memories tagged with a category, created this year, excluding archived ones
client.search(
    "project notes",
    filters={
        "user_id": "alex",
        "category": {"in": ["work", "planning"]},
        "year": {"gte": 2026},
        "status": {"ne": "archived"},
    },
)

Supported operators (open-source and Platform):

Operator Meaning Example
eq equals {"tier": {"eq": "pro"}}
ne not equals {"status": {"ne": "archived"}}
gt / gte greater than / or equal {"year": {"gte": 2026}}
lt / lte less than / or equal {"score": {"lte": 5}}
in value in list {"tag": {"in": ["a", "b"]}}
nin value not in list {"tag": {"nin": ["spam"]}}
contains substring match {"note": {"contains": "urgent"}}
icontains case-insensitive substring {"note": {"icontains": "Urgent"}}
"*" wildcard (any value present) {"category": "*"}

Boolean logic: AND / OR / NOT

client.search(
    "travel",
    filters={
        "user_id": "alex",
        "OR": [
            {"category": "flights"},
            {"category": "hotels"},
        ],
        "NOT": [{"status": "cancelled"}],
    },
)

Tip

Keep user_id/agent_id/run_id at the top level of filters even when you use AND/OR/NOT — those entity IDs always scope the search, while the boolean blocks refine within that scope.

Reranking for higher precision

Set rerank=True to re-score the top candidates with a dedicated reranker model for sharper ordering (slower, but more accurate):

client.search("what to pack for the trip", filters={"user_id": "alex"}, rerank=True)

Note

On the open-source library, reranking requires you to configure a reranker provider (Cohere, a sentence-transformer model, etc.) — see the Admin Guide. On the Platform, rerank=True just works.


8. The Open Source Library in Depth

The open-source Memory class runs entirely on your own infrastructure. You bring an LLM, an embedder, and a vector store; Mem0 orchestrates extraction, storage, and hybrid retrieval locally.

Zero-config start (Python)

With just OPENAI_API_KEY set, the defaults give you OpenAI for extraction and embeddings plus a local Qdrant store:

from mem0 import Memory

m = Memory()  # uses default config

m.add(
    [{"role": "user", "content": "I run every morning before work."}],
    user_id="alex",
)

print(m.search("exercise habits", filters={"user_id": "alex"}))
{'results': [{'id': '...', 'memory': 'Runs every morning before work',
              'score': 0.62, 'created_at': '2026-06-03T...', 'updated_at': '...'}]}

The full open-source API

Method Signature Returns
add add(messages, *, user_id=None, agent_id=None, run_id=None, metadata=None, infer=True, memory_type=None, prompt=None) {"results": [...]}
search search(query, *, top_k=20, filters=None, threshold=0.1, rerank=False) {"results": [...]}
get get(memory_id) memory dict or None
get_all get_all(*, filters=None, top_k=20) {"results": [...]}
update update(memory_id, data, metadata=None) {"message": "..."}
delete delete(memory_id) {"message": "..."}
delete_all delete_all(user_id=None, agent_id=None, run_id=None) {"message": "..."}
history history(memory_id) list of change records
reset reset() None (wipes the store)
close close() releases DB connections

Important

In the open-source search() and get_all(), the entity IDs go inside filters, and at least one of user_id/agent_id/run_id is required. Passing user_id="alex" as a top-level keyword to search() raises a ValueError telling you to use filters={"user_id": "alex"} instead.

Storing raw messages without inference

m.add(
    [{"role": "user", "content": "Order #4471 shipped on 2026-06-01"}],
    user_id="alex",
    infer=False,   # store the message text directly, skip LLM extraction
)

Tip

Use infer=False for structured records you want stored verbatim (order numbers, logs, IDs) where you don't want an LLM paraphrasing them. Use the default infer=True for natural conversation where you want clean, deduplicated facts.

Async usage

Every method has an async twin via AsyncMemory:

import asyncio
from mem0 import AsyncMemory

async def main():
    m = await asyncio.to_thread(AsyncMemory)
    await m.add([{"role": "user", "content": "I prefer dark mode"}], user_id="alex")
    print(await m.search("ui preferences", filters={"user_id": "alex"}))

asyncio.run(main())

Configuring providers

Memory.from_config() takes a plain dict that selects your LLM, embedder, and vector store:

from mem0 import Memory

config = {
    "llm": {"provider": "anthropic", "config": {"model": "claude-sonnet-4-5", "temperature": 0.1}},
    "embedder": {"provider": "openai", "config": {"model": "text-embedding-3-small"}},
    "vector_store": {"provider": "qdrant", "config": {"host": "localhost", "port": 6333}},
}
m = Memory.from_config(config)

The library supports a broad provider matrix out of the box:

  • LLMs: OpenAI, Anthropic, Gemini, Groq, Together, AWS Bedrock, Azure OpenAI, DeepSeek, MiniMax, xAI, Sarvam, Ollama, LM Studio, vLLM, LiteLLM, LangChain.
  • Embedders: OpenAI, Ollama, Hugging Face, Azure OpenAI, Gemini, Vertex AI, Together, LM Studio, AWS Bedrock, FastEmbed, LangChain.
  • Vector stores: Qdrant, Chroma, pgvector, Milvus, Pinecone, Redis, Valkey, Weaviate, FAISS, Elasticsearch, OpenSearch, MongoDB, Supabase, Azure AI Search, Databricks, Vertex AI Vector Search, Upstash, S3 Vectors, Cassandra, Baidu, Neptune Analytics, Turbopuffer, plus Azure MySQL.

Note

The exact config keys for each provider (hosts, models, API-base overrides, environment variables) are catalogued in the Admin Guide → Configuration Reference. As a user, you mainly need to know that switching providers is a one-line change in the config dict.

TypeScript open-source

import { Memory } from "mem0ai/oss";

const memory = new Memory({
  embedder: { provider: "openai", config: { apiKey: process.env.OPENAI_API_KEY } },
  llm: { provider: "openai", config: { apiKey: process.env.OPENAI_API_KEY, model: "gpt-4o" } },
  vectorStore: { provider: "memory", config: { collectionName: "memories" } },
});

await memory.add("The sky is blue", "alex");
const results = await memory.search("What color is the sky?", "alex");

Note

The TypeScript open-source build ships with sensible defaults (OpenAI embeddings + GPT-4 + an in-memory vector store + SQLite history), so a new Memory() with just an API key works for quick experiments. Production deployments should pick a persistent vector store (pgvector, Qdrant, Redis).


9. The Platform Client in Depth

The Platform client (MemoryClient / AsyncMemoryClient) talks to Mem0's hosted API. Beyond the core verbs, it unlocks features that need server-side infrastructure.

Initialization

from mem0 import MemoryClient

client = MemoryClient(api_key="m0-...")        # or rely on MEM0_API_KEY env var
# Custom host (e.g. EU region or self-hosted Platform):
client = MemoryClient(api_key="m0-...", host="https://api.mem0.ai")
import MemoryClient from "mem0ai";
const client = new MemoryClient({ apiKey: "m0-..." });

Platform-only capabilities

Batch operations — update or delete many memories in one call:

client.batch_update([
    {"memory_id": "id-1", "text": "Updated fact one"},
    {"memory_id": "id-2", "metadata": {"reviewed": True}},
])
client.batch_delete([{"memory_id": "id-1"}, {"memory_id": "id-2"}])

Entities (users/agents/runs) — list and manage every entity that has memories:

client.users()                       # all users, agents, runs with memories
client.delete_users(user_id="alex")  # delete a specific entity's footprint

Memory exports — request a structured export defined by a JSON schema:

client.create_memory_export(schema=my_json_schema, user_id="alex")
export = client.get_memory_export(user_id="alex")

Summaries — get a narrative summary of a user's memories:

client.get_summary(filters={"user_id": "alex"})

Feedback — tell Mem0 a retrieved memory was good or bad to improve future results:

client.feedback(memory_id="id-1", feedback="POSITIVE")
client.feedback(memory_id="id-2", feedback="NEGATIVE", feedback_reason="outdated")

Valid feedback values: POSITIVE, NEGATIVE, VERY_NEGATIVE.

Webhooks — get notified when memories change:

client.create_webhook(
    url="https://example.com/hooks/mem0",
    name="memory-events",
    project_id="proj_123",
    event_types=["memory.add", "memory.update"],
)
client.get_webhooks(project_id="proj_123")

Projects — manage project-wide settings like custom instructions and categories:

client.project.update(
    custom_instructions="Focus on travel preferences and dietary restrictions.",
    custom_categories=["travel", "food", "work"],
)

Tip

Custom instructions steer what the extraction LLM remembers. If your app only cares about, say, support-ticket context, set instructions accordingly and Mem0 will stop storing irrelevant chit-chat — improving precision and lowering noise.

Deleting superseded memories — when a newer memory supersedes an older one, delete the whole chain at once:

client.delete("id-current", delete_linked=True)

Async Platform client

import asyncio
from mem0 import AsyncMemoryClient

async def main():
    async with AsyncMemoryClient() as client:
        await client.add("I love jazz", user_id="alex")
        print(await client.search("music taste", filters={"user_id": "alex"}))

asyncio.run(main())

10. The Mem0 CLI

The mem0 command brings memory to your terminal and to coding agents. It talks to the Mem0 Platform.

Setup

npm install -g mem0ai
mem0 init            # interactive: paste your API key or log in via email

init writes config to ~/.mem0/config.json (permissions 0600). You can also pass flags:

mem0 init --api-key m0-... --user-id alex
mem0 init --email [email removed]   # login via emailed verification code

Core commands

# Add memory (string or piped messages)
mem0 add "I prefer TypeScript over JavaScript" --user-id alex
mem0 add --file conversation.json --user-id alex

# Search
mem0 search "language preferences" --user-id alex
mem0 search "preferences" --user-id alex --output table

# Retrieve / list
mem0 get <memoryId>
mem0 list --user-id alex --page 1

# Update / delete
mem0 update <memoryId> "Now prefers Rust"
mem0 delete <memoryId>
mem0 delete --all --user-id alex --confirm   # wipe a user's memories
mem0 delete --all --user-id alex --dry-run   # preview what would be deleted

# Import a JSON export
mem0 import memories.json --user-id alex

# Status & config
mem0 status
mem0 whoami
mem0 config show
mem0 config get platform.base_url
mem0 config set defaults.user_id alex

Add options worth knowing

Flag Effect
--user-id, --agent-id, --app-id, --run-id Scope the memory
--metadata <json> Attach custom metadata
--immutable Prevent the memory from being updated later
--no-infer Store raw, skip LLM extraction
--expires <YYYY-MM-DD> Auto-expire the memory
--categories <list> Tag with categories (JSON array or comma-separated)
--output <format> text, json, or quiet

Search options

Flag Effect
--rerank Enable reranking (Platform)
--keyword Use keyword search
--filter <json> Advanced filter expression
--fields <list> Return only specific fields
--output <format> text, json, or table

Agent / scripting mode

Every command accepts a global --json flag that emits a machine-readable envelope, ideal for use inside AI coding agents and scripts:

mem0 search "preferences" --user-id alex --json
{"status":"ok","command":"search","data":{"results":[ ... ]}}

Tip

The CLI auto-detects when it's running inside an AI coding assistant (Claude Code, Cursor, Codex, Cline, Continue, Aider, Goose, Windsurf) and switches to a quiet, JSON-friendly "agent mode" so its output is easy to parse. Set NO_COLOR=1 to disable ANSI colors anywhere.

CLI environment variables

Variable Purpose
MEM0_API_KEY API key (overrides config file)
MEM0_BASE_URL API base URL
MEM0_USER_ID / MEM0_AGENT_ID / MEM0_APP_ID / MEM0_RUN_ID Default scope IDs
NO_COLOR Disable colored output

11. The LLM Proxy: Memory-Aware Chat in One Call

The Mem0 proxy wraps an OpenAI-compatible chat completion so memory retrieval and storage happen automatically — you make a normal chat call, and Mem0 injects relevant memories into the prompt and saves new ones in the background.

from mem0.proxy.main import Mem0

# Use the Platform...
mem0_chat = Mem0(api_key="m0-...")
# ...or the open-source library:
# mem0_chat = Mem0(config={"vector_store": {...}, "llm": {...}})

response = mem0_chat.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What restaurant should I book tonight?"}],
    user_id="alex",
)
print(response.choices[0].message.content)

What happens under the hood:

  1. Mem0 searches the user's memories using the last few messages as the query.
  2. It injects the relevant memories into a system prompt.
  3. It calls the model (via LiteLLM, so any supported model works).
  4. In a background thread, it stores the new turn as memory.

Note

The proxy requires a model that supports function calling and at least one of user_id, agent_id, or run_id. It installs litellm on first use if it isn't already present.

Tip

The proxy is the lowest-effort way to add memory to an existing chatbot: replace your openai.chat.completions.create(...) with mem0.chat.completions.create(..., user_id=...) and you instantly get personalization across sessions.


12. The REST API

If you self-host the Mem0 REST server (see [Admin Guide → Deployment]), or want to call the Platform over HTTP directly, the memory operations are available as plain HTTP endpoints.

Self-hosted server endpoints

Method Path Purpose
POST /memories Create memories
GET /memories List memories (optionally filtered by user_id/agent_id/run_id)
GET /memories/{memory_id} Get one memory
POST /search Search memories
PUT /memories/{memory_id} Update a memory
GET /memories/{memory_id}/history Memory change history
DELETE /memories/{memory_id} Delete a memory
DELETE /memories Delete all for a scope
POST /reset Reset all memories
GET/POST /configure View / set the runtime config

Example: add and search over HTTP

# Add
curl -X POST http://localhost:8000/memories \
  -H "X-API-Key: $MEM0_KEY" \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"I love spicy food"}],"user_id":"alex"}'
# Search
curl -X POST http://localhost:8000/search \
  -H "X-API-Key: $MEM0_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"food preferences","filters":{"user_id":"alex"}}'

Important

On /search, pass entity IDs inside filters (e.g. "filters": {"user_id": "alex"}). Passing user_id at the top level still works but is deprecated and logs a warning. The self-hosted server's interactive API docs live at /docs (Swagger UI) once it's running.

Platform HTTP API

The Platform exposes versioned endpoints under https://api.mem0.ai (e.g. POST /v3/memories/add/, POST /v3/memories/search/, GET /v1/memories/{id}/). Authenticate with Authorization: Token m0-your-api-key. Most users reach these through the SDKs rather than raw HTTP.


13. OpenMemory: Your Private Memory Server

OpenMemory is a self-hosted, Dockerized memory server with a web dashboard and a built-in MCP (Model Context Protocol) server, so MCP-aware clients (Claude Desktop, Cursor, etc.) can read and write your memories. Everything stays on your machine.

One-line install

curl -sL https://raw.githubusercontent.com/mem0ai/mem0/main/openmemory/run.sh \
  | OPENAI_API_KEY=your_api_key bash

This script:

  • Verifies Docker and Docker Compose are installed.
  • Picks a vector store (default Qdrant; override with VECTOR_STORE=... — qdrant, chroma, pgvector, redis, weaviate, milvus, elasticsearch, faiss).
  • Starts the backend API on http://localhost:8765 and the dashboard UI on http://localhost:3000 (next free port up to 3010).
# Choose a different vector store
curl -sL .../openmemory/run.sh | OPENAI_API_KEY=sk-... VECTOR_STORE=pgvector bash

What you get

  • A web UI to browse, search, create, and delete your memories and connected apps.
  • An MCP endpoint (/{client}/sse/{user_id}) you can register in any MCP client to give it long-term memory.
  • Your memories stored locally in the vector store of your choice.

Tip

OpenMemory is the best fit if you want a personal memory layer shared across all your AI tools, fully under your control, without sending data to a managed service. The only external dependency is the LLM/embedding provider key you supply (OpenAI by default).


14. Integrations

Mem0 plugs into the popular AI app frameworks. The pattern is always the same: search memories before the model call, add memories after.

Integration Package / entry point Notes
Vercel AI SDK @mem0/vercel-ai-provider Drop-in provider that adds memory to AI SDK apps
OpenAI Agents / tools mem0ai + OpenAI SDK Use Mem0 as a tool the agent can call
LangChain / LangGraph @mem0/community (mem0ai/community/langchain) Memory-backed chains and graphs
CrewAI, LlamaIndex, AutoGen mem0ai Search/add around agent steps
OpenClaw @mem0/openclaw-mem0 Mem0 memory backend for OpenClaw, platform or self-hosted
Claude Code Mem0 plugin (/plugin install mem0@mem0-plugins) Skills that add, search, and manage memory from Claude

Vercel AI SDK example

import { createMem0 } from "@mem0/vercel-ai-provider";
import { generateText } from "ai";

const mem0 = createMem0({ apiKey: process.env.MEM0_API_KEY });

const { text } = await generateText({
  model: mem0("gpt-4o", { user_id: "alex" }),
  prompt: "Recommend a dinner spot for me.",
});

Mem0 as an OpenAI tool

Expose search/add as tools your agent can call, then let the model decide when to remember or recall. The examples/openai-inbuilt-tools directory in the repo shows a complete pattern.

Note

Each integration ships runnable examples in the examples/ directory of the repository (multimodal chat, Vercel chat app, graph-DB demo, YouTube assistant Chrome extension, healthcare assistant, and more). They're the quickest way to see an end-to-end app.


15. Common Workflows (Recipes)

Recipe: Personalized chatbot

from mem0 import MemoryClient
client = MemoryClient()

def chat(user_id, user_message, llm_call):
    # 1. Recall
    memories = client.search(user_message, filters={"user_id": user_id}, top_k=5)
    context = "\n".join(m["memory"] for m in memories["results"])

    # 2. Compose prompt with memory context
    system = f"You are a helpful assistant. What you know about the user:\n{context}"
    reply = llm_call(system=system, user=user_message)

    # 3. Remember this turn
    client.add(
        [{"role": "user", "content": user_message},
         {"role": "assistant", "content": reply}],
        user_id=user_id,
    )
    return reply

Recipe: Long-running agent that learns

# Store agent-level lessons that persist across runs
client.add(
    [{"role": "assistant", "content": "When the user asks for code, default to Python."}],
    agent_id="dev-helper",
)
# Recall them at the start of each run
lessons = client.search("coding defaults", filters={"agent_id": "dev-helper"})

Recipe: Per-session scratch memory that you clean up

run_id = "session-2026-06-03-001"
client.add(messages, user_id="alex", run_id=run_id)
# ...use it during the session...
client.delete_all(user_id="alex", run_id=run_id)  # tidy up when done

Recipe: Tagging and filtered recall

client.add("Prefers Delta for transatlantic flights", user_id="alex",
           metadata={"category": "travel", "confidence": "high"})

client.search("airline preference", filters={
    "user_id": "alex",
    "category": "travel",
    "confidence": {"in": ["high", "verified"]},
})

Recipe: Bulk import existing user data

# infer=False stores facts verbatim — good for migrating known facts
for fact in known_user_facts:
    client.add(fact, user_id="alex", infer=False)

Tip

A reliable pattern for production chatbots: search before every model call, add after every model call, and keep top_k modest (3–7). This keeps prompts small while still surfacing the facts that matter.


16. How Mem0 Works (Concepts)

You don't need this section to use Mem0, but understanding the pipeline helps you debug and tune it.

What happens on add()

When you add a conversation with inference enabled, Mem0 runs a multi-phase pipeline:

  1. Context gathering — pulls the recent messages for this scope to resolve pronouns and references.
  2. Existing-memory retrieval — embeds your messages and finds related memories already stored.
  3. LLM extraction — a single LLM call extracts self-contained, contextually rich facts from both user and assistant messages, deduplicating against what's already known and linking related memories.
  4. Embedding & dedup — each extracted fact is embedded; exact duplicates (by content hash) are skipped.
  5. Storage — new memories are written to the vector store, with a history record for each.
  6. Entity linking — named entities (people, places, titles) are extracted and linked so future searches can boost memories about the same entity.

The extraction model is careful: it preserves proper nouns, exact numbers, and dates; grounds relative time references ("last week") to absolute dates; never fabricates; and captures emotional and motivational context, not just bare facts.

The open-source library uses hybrid retrieval that blends three signals:

  1. Semantic search — vector similarity between your query and stored memories.
  2. Keyword (BM25) search — lexical matching using lemmatized text, so "running" matches "ran".
  3. Entity boosting — memories linked to entities mentioned in your query get a relevance boost.

These signals are combined into a single normalized score, filtered by your threshold, and ranked. Optionally a reranker model re-orders the top results for maximum precision.

Note

This is why installing the spaCy NLP extras matters for the open-source library: keyword matching and entity boosting both rely on spaCy. Without it, you still get semantic search, just not the full hybrid quality.

Memory types

Type How to create Use
Factual / conversational (default) add(messages, user_id=...) Everyday user/agent facts
Procedural add(messages, agent_id=..., memory_type="procedural_memory") A detailed summary of an agent's step-by-step execution history

Where data lives (open source)

  • Memories (vectors): your chosen vector store.
  • History (audit trail): a local SQLite database at ~/.mem0/history.db by default.
  • Working directory: ~/.mem0/ (override with the MEM0_DIR environment variable).

17. Troubleshooting

Error: Mem0 API Key not provided. Please provide an API Key.

Cause: The Platform client couldn't find an API key. Solution: Set MEM0_API_KEY in your environment or pass MemoryClient(api_key="m0-..."). Prevention: Keep the key in a .env file loaded at startup; never hard-code it in source.

Error: filters must contain at least one of: user_id, agent_id, run_id.

Cause: You called search() or get_all() without a scope inside filters. Solution: Add a scope, e.g. search(query, filters={"user_id": "alex"}). Prevention: Always decide a memory's scope up front; treat scope as required.

Error: Top-level entity parameters {...} are not supported in search()/get_all(). Use filters={'user_id': '...'} instead.

Cause: You passed user_id/agent_id/run_id/app_id as a top-level keyword to search() or get_all(). Solution: Move them inside filters={...}. Prevention: Remember the rule — top-level on add()/delete_all(), inside filters on search()/get_all().

Error: Invalid threshold: ... Must be between 0 and 1

Cause: threshold was outside the [0, 1] range, or top_k was negative. Solution: Use a threshold between 0 and 1 (default 0.1) and a non-negative integer top_k.

Error: Invalid 'memory_type'. Please pass procedural_memory ...

Cause: You passed a memory_type other than "procedural_memory". Solution: Only "procedural_memory" is supported; omit memory_type for normal memories.

Search returns nothing even though you added memories

Cause: Usually a scope mismatch (added under one user_id, searched under another), or the threshold is too high. Solution: Confirm you're searching the same scope you added to; lower threshold (try 0.1 or 0); call get_all(filters={"user_id": ...}) to confirm the memories exist. Prevention: Standardize your scope IDs across add and search.

Open-source search quality feels weak / "spaCy is not installed"

Cause: The spaCy NLP model isn't installed, so keyword and entity signals are disabled. Solution: pip install "mem0ai[nlp]" then python -m spacy download en_core_web_sm. Prevention: Install the NLP extras as part of your environment setup.

add() returns an empty results list

Cause: The extraction LLM found nothing worth remembering (e.g. pure greetings), or all extracted facts were duplicates of existing memories. Solution: This is expected for non-informational messages. Verify with content that contains real facts; check get_all() to see what's already stored.

Self-hosted server returns 401 Authentication required

Cause: The server has auth enabled but no credentials were supplied. Solution: Pass a valid X-API-Key or Bearer token; for local development only, the operator can set AUTH_DISABLED=true. See the Admin Guide for auth setup.

Self-hosted server: LLM provider 'X' is not bundled in this image

Cause: You configured a provider whose Python package isn't included in the prebuilt server image. Solution: The default server image bundles OpenAI, Anthropic, and Gemini (LLM) and OpenAI/Gemini (embedder). To use another, the operator must install its package and rebuild — see the Admin Guide.

Rate limit / provider errors (provider_rate_limited, provider_timeout)

Cause: The upstream LLM/embedding provider throttled or timed out. Solution: Retry with backoff; on the Platform, catch RateLimitError and wait. Reduce request volume or upgrade your provider tier.


18. Frequently Asked Questions

Q: Do I need to choose Platform or Open Source forever? No. They share the same verbs, so you can prototype on the Platform and self-host later (or run both). Your add/search calls barely change.

Q: What does Mem0 actually store — the whole conversation? By default, no. With infer=True it stores only the extracted facts (e.g. "Is vegetarian"), not the raw transcript. Use infer=False if you want messages stored verbatim.

Q: Which LLM and embedder does the open-source library use by default? OpenAI for both — a chat model for extraction and text-embedding-3-small for embeddings — with a local Qdrant vector store. You only need OPENAI_API_KEY set. Swap any of them via config.

Q: Can I run Mem0 fully offline / air-gapped? Yes — use the open-source library with local providers like Ollama (LLM + embeddings) and a local vector store (Qdrant, FAISS, pgvector). No data leaves your machine.

Q: How is a memory different from just logging the chat? A memory is a deduplicated, self-contained fact that's been reconciled against what's already known (added, updated, or skipped as a duplicate) and made searchable by meaning. Raw logs aren't searchable by meaning and grow without bound.

Q: How do I keep one user's memories from leaking to another? Always scope with user_id (and/or agent_id/run_id). Searches only return memories matching the scope in filters. Two users with different user_ids never see each other's memories.

Q: What's the difference between delete_all() and reset()? delete_all() removes memories for a specific scope (a user, agent, or run). reset() wipes the entire store and recreates it. Both are irreversible.

Q: Can I attach my own metadata and filter on it? Yes. Pass metadata={...} on add(), then filter with operators (eq, in, gte, contains, etc.) and boolean logic (AND/OR/NOT) on search().

Q: Does search use embeddings only? The open-source library uses hybrid retrieval: semantic similarity + BM25 keyword matching + entity boosting, combined into one score. Optionally a reranker sharpens the top results.

Q: What is "procedural memory"? A special memory type for agents: a detailed, verbatim-preserving summary of an agent's step-by-step execution history. Create it with memory_type="procedural_memory" and an agent_id.

Q: Can I use Mem0 from the command line or inside a coding agent? Yes. The mem0 CLI provides every operation, auto-detects coding-agent environments, and offers a --json mode for scripting.

Q: Is there a way to add memory to my chatbot without rewriting it? Use the LLM proxy (mem0.proxy.main.Mem0). Swap your chat.completions.create(...) call for the proxy's and pass a user_id — memory retrieval and storage become automatic.

Q: How do I see why the agent "knows" something? Call history(memory_id) to see the full add/update/delete trail of any memory.

Q: Does Mem0 collect telemetry? The open-source library and self-hosted server send anonymous usage telemetry by default. Opt out by setting MEM0_TELEMETRY=false.


19. Reference

Memory operations (at a glance)

Operation Open Source (Memory) Platform (MemoryClient)
Add add(messages, user_id=...) add(messages, user_id=...)
Search search(q, filters={...}) search(q, filters={...})
Get one get(memory_id) get(memory_id)
Get all get_all(filters={...}) get_all(filters={...})
Update update(memory_id, data) update(memory_id, text=...)
Delete delete(memory_id) delete(memory_id, delete_linked=...)
Delete all delete_all(user_id=...) delete_all(user_id=...)
History history(memory_id) history(memory_id)
Reset reset() reset()
Batch update/delete — batch_update([...]), batch_delete([...])
Entities — users(), delete_users(...)
Exports / summary — create_memory_export(...), get_summary(...)
Feedback — feedback(memory_id, "POSITIVE")

Key environment variables (user-facing)

Variable Used by Purpose
MEM0_API_KEY Platform client, CLI Authenticate with the Mem0 Platform
OPENAI_API_KEY Open source (default) Default LLM + embeddings
MEM0_DIR Open source Working dir for history DB (default ~/.mem0)
MEM0_TELEMETRY Open source, server Set false to opt out of anonymous telemetry
MEM0_BASE_URL CLI Override the API base URL
MEM0_USER_ID / MEM0_AGENT_ID / MEM0_APP_ID / MEM0_RUN_ID CLI Default scope IDs
NO_COLOR CLI Disable colored output

Packages

Package Ecosystem What it is
mem0ai PyPI Python library (Platform + Open Source)
mem0ai npm TypeScript SDK (mem0ai = Platform, mem0ai/oss = Open Source)
@mem0/cli npm The mem0 command-line tool
@mem0/vercel-ai-provider npm Vercel AI SDK provider
@mem0/community npm Community integrations (LangChain)
@mem0/openclaw-mem0 npm OpenClaw memory backend

Supported providers (open source)

  • LLMs: OpenAI, Anthropic, Gemini, Groq, Together, AWS Bedrock, Azure OpenAI, DeepSeek, MiniMax, xAI, Sarvam, Ollama, LM Studio, vLLM, LiteLLM, LangChain.
  • Embedders: OpenAI, Ollama, Hugging Face, Azure OpenAI, Gemini, Vertex AI, Together, LM Studio, AWS Bedrock, FastEmbed, LangChain.
  • Vector stores: Qdrant, Chroma, pgvector, Milvus, Pinecone, Redis, Valkey, Weaviate, FAISS, Elasticsearch, OpenSearch, MongoDB, Supabase, Azure AI Search, Databricks, Vertex AI Vector Search, Upstash, S3 Vectors, Cassandra, Baidu, Neptune Analytics, Turbopuffer, Azure MySQL.
  • Rerankers: Cohere, sentence-transformer, ZeroEntropy, LLM-based, Hugging Face.

Where to go next

  • Configuration reference, deployment, security, internals → the companion Mem0 Admin Guide.
  • Runnable examples → the examples/ directory in the repository.
  • Official documentation → docs.mem0.ai.