memory-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@memory-mcpremember that I adopted a beagle named Biscuit"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
๐ง Agent Memory Engine: long-term memory for AI agents
Give an AI assistant a memory that survives across conversations, keeps track of what changed, and knows when it doesn't know. Claude extracts facts from conversations, decides whether each one is new, an update or already known, and stores them with their history. A hybrid recall layer finds the right memories later. It ships as an MCP server, so Claude Code or any MCP-capable agent can use it, and it comes with a benchmark against three ways of answering without it.
Agent memory is one of the most active areas in open-source AI right now (mem0 is at ~67k GitHub stars). This project builds the core ideas from scratch, then measures them: does structured memory beat pasting the whole history into the prompt, and what does each part contribute?
Results
Six synthetic users, 8 conversations each, 72 questions. Every method uses the same answering prompt and model (Claude Haiku 5.5); only the context differs.
Method | Overall | Single fact | Knowledge update | History | Multi-session | Graph | Abstention | Input tokens / question | Cost / question |
No memory | 17% | 0% | 0% | 0% | 0% | 0% | 100% | 433 | $0.00007 |
Chunk RAG (BM25 over raw messages) | 25% | 25% | 0% | 0% | 0% | 0% | 100% | 501 | $0.00010 |
Full context (whole history in the prompt) | 100% | 100% | 100% | 100% | 100% | 100% | 100% | 1,957 | $0.00029 |
Memory engine | 100% | 100% | 100% | 100% | 100% | 100% | 100% | 628 | $0.00010 |
Memory engine, no graph hop (ablation) | 99% | 100% | 100% | 100% | 100% | 83% | 100% | 587 | $0.00009 |
Longer histories (24 extra small-talk conversations per user, 32 in total, same 72 questions):
Method | Overall | Input tokens / question | Cost / question |
Full context | 100% | 5,459 (2.8ร more than with 8 conversations) | $0.00066 |
Memory engine | 100% | 616 (flat) | $0.00009 |
What this shows, honestly:
Same accuracy as brute force, at a fraction of the context. With 8 conversations the memory engine uses 3ร fewer input tokens than pasting the history; with 32 it's 9ร fewer, and the gap keeps growing because recall always returns at most 8 memories.
Memory isn't free to build. Extraction plus decisions cost $0.0415 for 6 users ร 32 conversations (~$0.007 per user). At these prices it pays for itself after about 12 questions per user; after that every question is cheaper.
At this scale, full context is a perfectly good answer. Haiku read 5,000 tokens of chat without missing anything. Memory wins on cost and on histories too long for a context window, not on accuracy here.
Naive RAG over chat logs fails badly (25%). "What's my pet called?" shares no words with "we adopted a beagle puppy and named him Biscuit", and "which city do I live in" retrieves the colleague who moved. Turning chats into enriched, standalone memories is what fixes it. (A dense-embedding chunk retriever would do better than this BM25 baseline; it is not included yet.)
The graph hop barely matters now, and that's a finding. Once the extractor sees the known people ("Diego = husband"), relationships are resolved when the memory is written, so recall rarely needs the graph. Without the graph, one answer out of 72 hedged.
Two bugs the benchmark caught in my own work: the extractor stored "the user's friend Diego" before known-entity context was added, and my test data called a tabby a breed. Claude answered "tabby is a coat pattern, not a breed", which was right, so I fixed the data rather than the model.
Total API cost for all the runs above: about $0.25.
Related MCP server: PseudoLife-MCP
How it works
conversation โโโบ 1. EXTRACT Claude turns it into standalone memories
"The user's husband Diego started a new job as a veterinarian."
+ keywords (work, career, occupation) + entities (Diego: person)
+ KNOWN PEOPLE AND PETS from memory, so a bare "Diego" is resolved
โโโบ 2. DECIDE for each candidate, Claude sees the related existing memories:
ADD (new) ยท UPDATE (replaces an outdated memory, kept as history) ยท SKIP (known)
โโโบ 3. STORE SQLite: memories + entities + links, superseded rows keep valid_until
question โโโโโโบ 4. RECALL BM25 over memory text + LLM-written keywords, one hop through the
entity graph, current facts ranked above history (no LLM call, ~1 ms)
โโโบ 5. ANSWER Claude answers from recalled memories only, cites memory ids,
and returns known=false instead of guessingDesign choice | Why |
History, not overwrite | "We moved to Berlin" supersedes "lives in Pune" but keeps it, with the date. The engine answers both "where do I live?" and "where did I live before?". |
Write-time enrichment instead of a vector DB | The extractor attaches synonyms and categories (a beagle gets dog, pet, puppy), so plain BM25 matches paraphrased questions. Recall needs no embedding model and no LLM call. |
Known-entity context at extraction | Without it, "Diego started a new job" in a later conversation was stored as "the user's friend Diego": a wrong memory. Showing the extractor who's already known fixed it. |
Structured outputs everywhere | Extraction, decisions and answers are JSON-schema constrained, so nothing has to be parsed out of free text. |
Abstention is a first-class answer |
|
Right to be forgotten |
|
The benchmark
Synthetic users talk to an assistant over 8 weekly conversations (plus optional small-talk-only conversations to grow the history). Generated deterministically, no LLM involved, so every answer is known. Question types follow long-term-memory benchmarks such as LongMemEval and LoCoMo:
Type | Example | What makes it hard |
single fact | "What's my pet called?" | Worded differently from "we adopted a beagle puppy and named him Biscuit"; a friend's dog is also mentioned |
knowledge update | "Which city do I live in these days?" | The city, job and diet all change later; only the newest is right |
history | "Where was I living before the move?" | Needs the superseded memory, not the current one |
multi-session | "Which countries have I travelled to recently?" | Three trips in three different conversations; all must be listed |
graph | "What does my husband do for work?" | "My husband Diego" and "Diego started as a vet" are weeks apart and share only a name |
abstention | "What's my sister's name?" | Never mentioned; the right answer is "I don't know" |
Scoring is deterministic string matching on the expected values; no LLM judge. Persona 0 was used while developing the prompts and retrieval; the reported numbers use personas 1-6, which were never looked at during development.
Use it from Claude Code (MCP)
pip install -e .
claude mcp add memory -- memory-mcp # database at ~/.agent-memory.dbTool | What it does | LLM calls |
| extract + decide + store | 2 (Haiku 5.5 by default, |
| ranked memories, each marked current or "no longer true since โฆ" | 0 |
| everything stored about a user | 0 |
| people, pets, places and organisations, with memory counts | 0 |
| permanent delete | 0 |
Quick start
git clone https://github.com/abpandey-dev/agent-memory-engine.git && cd agent-memory-engine
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
memory show-data --persona 1 # see a synthetic user's conversations and questions (free)
pytest -q # 19 tests, scripted fake model, no API key neededWith Claude (needs ANTHROPIC_API_KEY; real calls cost money):
memory demo --persona 0 --model claude-haiku-5-5 # ~$0.005: build memory, answer 12 questions
memory bench --model claude-haiku-5-5 --personas 6 # ~$0.08: the full comparison
memory bench --model claude-haiku-5-5 --filler 24 --methods full_context memory # long historiesReal output of memory demo --persona 0 (Haiku 5.5), lightly trimmed. History is kept, and Claude decided on its own that going vegetarian replaces "comfort food is lamb kebabs":
priya-s04: +1 added, 1 updated [('m-0004', 'm-0009')], 0 skipped
priya-s06: +1 added, 1 updated [('m-0003', 'm-0013')], 0 skipped
priya-s07: +1 added, 1 updated [('m-0002', 'm-0014')], 0 skipped
m-0003 The user is based in Izmir. [superseded 2026-07-06 by m-0013]
m-0004 The user's comfort food is lamb kebabs, which they could eat every week. [superseded 2026-06-22 by m-0009]
m-0005 The user is married to a husband named Diego.
m-0009 The user has decided to become vegetarian, mostly for health reasons, as of June 2026.
m-0011 The user's husband Diego recently started a new job as a veterinarian with intense shifts.
m-0013 The user moved to Berlin, Germany in late June 2026, and their new flat was full of boxes shortly after.
โ Where was I living before the move?
You were living in Izmir before the move to Berlin. (memories: m-0003, m-0013)
โ Which countries have I travelled to recently? List them all.
Iceland (a trip for a friend's wedding, returning around June 2026), Peru (a two-week trip returning in
early June 2026), and Kenya (a long weekend trip, returning July 12, 2026). (memories: m-0010, m-0006, m-0015)
โ What does my husband do for work?
Your husband Diego recently started a new job as a veterinarian with intense shifts. (memories: m-0011, m-0005)
โ What's my sister's name?
I don't know your sister's name; your memories don't mention a sister. (memories: -)
12/12 correct; 27 calls, 23,541+4,009 tokens, $0.0044Project layout
src/agent_memory/
store.py # SQLite: memories, entities, links, supersede history, forget
retrieval.py # BM25 + stemming, entity-graph hop, history down-weighting
engine.py # extract -> decide -> store; recall -> answer (prompts + JSON schemas)
llm.py # structured-output calls, token and cost accounting, refusal handling
mcp_server.py # 5 MCP tools over stdio (MCP Python SDK 2.x)
dataset.py # synthetic multi-session users with known answers
bench.py # the four methods + ablation, deterministic scoring
cli.py # `memory` command
tests/ # scripted fake Claude client, in-process MCP client
docs/ # architecture and results diagrams (SVG)Limits and next steps
Synthetic data. Conversations are templated, so they are cleaner than real chat logs. The next step is running the public LongMemEval set.
Lexical recall. Write-time keywords did the job here, but a dense-embedding retriever (and a dense chunk-RAG baseline, which would beat the BM25 one shown here) should be compared at larger scale.
One user per question. Shared memory across a team (and access control on it) is not covered.
Decay and consolidation. Old, low-importance memories are kept forever; a consolidation pass that merges and summarises them is the next feature.
Built with synthetic data only. No real personal data is used.
Available Tools
5 toolsforgetA
Permanently delete one memory (for example when the user asks to be forgotten).
| Name | Required | Description | Default |
|---|---|---|---|
| memory_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses irreversibility ('permanently delete'), which is the key trait for a destructive tool, but says nothing about confirmation requirements, permissions, or behavior on an invalid/nonexistent memory_id.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence, front-loaded with the action and irreversibility, with the example parenthetically appended. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be described. For a one-parameter destructive tool, the main missing piece is how to source the memory_id and any confirmation/error semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the description never mentions memory_id, so it adds no meaning about the identifier's format or where to obtain it (recall/list_memories). The single parameter is self-explanatory by name, preventing a lower score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Permanently delete one memory.' The word 'one' distinguishes it from bulk/list siblings like list_memories, though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives one triggering example ('when the user asks to be forgotten'), which clarifies intent, but offers no conditions for when not to use it or which sibling to use instead (e.g., recall to find the ID first).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_entitiesB
People, pets, places and organizations in the user's memory, with how many memories mention each.
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It helpfully discloses that results include mention counts per entity, but it omits pagination, result limits, sorting, and authentication/scoping behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, waste-free sentence that front-loads the entity categories. It is efficient, though it does not lead with an explicit verb like 'List'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. For a simple one-parameter list tool, the description covers the resource adequately, but gaps in usage guidance and user_id semantics keep it from being fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sole parameter user_id has 0% schema description coverage, so the description should compensate. It implies user scoping via 'the user's memory' but never mentions the parameter, its default, or accepted format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the resource precisely: people, pets, places, and organizations in the user's memory, plus mention counts. It is clear what the tool enumerates, but it does not explicitly distinguish itself from siblings like list_memories or recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus siblings such as list_memories, recall, or remember. The retrieval context is implied by 'user's memory,' but no alternatives or exclusions are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_memoriesA
Everything remembered about a user (current facts only unless include_history is true).
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | default | |
| include_history | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. It usefully states the default behavioral trait that only current facts are returned unless include_history is true, but it does not mention read-only status, permissions, pagination, or other operational traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with zero wasted words. It efficiently conveys the core resource and the key default scope caveat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with two parameters and an output schema, so the description needn't explain return values. Still, it leaves gaps around user_id semantics and when to choose this tool versus recall, which are relevant given the sibling-tool context and zero schema description coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies the meaning of include_history and the default current-facts behavior, but it does not explain user_id beyond the phrase 'about a user,' leaving the identifier semantics only partially covered.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool returns everything remembered about a user, with a default current-facts-only scope. It does not explicitly distinguish itself from sibling tools like recall, but the purpose is specific enough for an agent to understand the resource being listed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool by saying it returns everything remembered about a user, and it explains that history is included only when include_history is true. However, it gives no explicit guidance about when to prefer this over siblings such as recall or list_entities.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallB
Find memories relevant to a query. Each result says whether it is current or no longer true.
| Name | Required | Description | Default |
|---|---|---|---|
| k | No | ||
| query | Yes | ||
| user_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It usefully discloses that each result indicates whether it is current or no longer true, but it omits other behavioral context such as read-only nature, permissions, or result limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core purpose and no wasted wording. The description is appropriately sized for the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return values need not be explained, but with no annotations and 0% schema coverage the description leaves key gaps. It does not address sibling alternatives, parameter meanings, or user scoping.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, but it does not. It only implies the query parameter and leaves k and user_id unexplained, including their defaults and scoping role.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: "Find memories relevant to a query." It is clear what the tool does, but it does not explicitly distinguish itself from siblings like list_memories or list_entities.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives such as list_memories, remember, or forget. It implies retrieval use but provides no exclusions or decision criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rememberA
Store what the user said about themselves. Facts that replace older ones (a new city, a new job) are recorded as updates and the old fact is kept as history.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| user_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose a genuinely non-obvious behavior: superseded facts (new city, new job) are recorded as updates and the old value is retained as history, so nothing is destructively overwritten. It omits other behavioral context such as per-user scoping or duplicate handling, but the key mutation semantics are covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste, with the core action front-loaded and the update/history caveat following immediately. Nothing is repeated from the name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the tool is a simple two-parameter write. However, the unexplained user_id scoping and the absence of any routing guidance against forget/recall leave gaps for an agent operating in a memory-tool cluster.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and largely doesn't. It never explains what 'text' should contain (a sentence? a fact tuple?) nor what 'user_id' scopes, even though its 'default' value implies multi-user partitioning that an agent could easily get wrong.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (store) and a specific resource (facts the user shares about themselves), which clearly separates it from retrieval siblings like recall and list_memories. It stops short of naming any sibling explicitly, so differentiation is inferred from the verb rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer it should call this when the user reveals personal facts, but there is no explicit 'use when' framing, no guidance on when to prefer forget or recall, and no mention of how this interacts with list_entities/list_memories.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
forget - First observed
list_entities - First observed
list_memories - First observed
recall - First observed
remember
TDQS
Scored across 5 tools
Each tool has a clearly distinct role: remember writes, recall does query-based retrieval, list_memories enumerates all facts, list_entities enumerates people/places, and forget deletes. The recall vs. list_memories boundary (search vs. full listing) is explicitly spelled out in the descriptions, leaving no real overlap.
All names are imperative lowercase verbs, which gives a readable, predictable style. However, the pattern is not strictly verb_noun: remember/recall/forget omit the object while list_memories/list_entities include one, a minor inconsistency but not confusing.
Five tools is well-scoped for a personal memory store: one write, three read shapes, and one delete. Every tool earns its place with no redundant or speculative operations.
The lifecycle is essentially covered: remember implicitly handles updates with history, and forget handles deletion. Minor gaps exist, such as bulk deletion of all of a user's data (beyond one memory at a time) and no way to remove or merge entities explicitly.
Maintenance
Related MCP Connectors
Persistent memory for AI agents across Claude, ChatGPT and any MCP client.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Hosted agent memory: store, search, and recall facts across sessions from any MCP client.
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceGives AI persistent personal memory with hybrid search, temporal decay, and knowledge graph. Works with Claude and any MCP client.7 npm10MIT

PseudoLife-MCPofficial
AlicenseAqualityBmaintenanceEnables persistent long-term memory for Claude Code across sessions, with tools for storing, searching, and managing facts, knowledge graphs, and procedural lessons.381,774 PyPI6Apache 2.0- AlicenseNot gradedqualityBmaintenanceEnables AI agents to persist and retrieve structured memory across sessions and models via MCP tools for cataloging, searching, and saving facts, with automatic supersession and scope filtering.MIT
- AlicenseNot gradedqualityCmaintenanceEnables all local Claude Code sessions, subagents, and other MCP clients to read and write one shared long-term memory over HTTP on localhost, so facts retained by one agent can be recalled by another. It extracts atomic facts, entities, and observations into an embedded local Postgres with ONNX embeddings and reranking, requiring no API key.MIT