The open, self-hostable memory layer for AI agents. MCP-native, local-first, research-grade.
Project description
Memry
memry.tech - the open, self-hostable memory layer for AI agents. One pip install, zero services,
plugged into any agent over MCP - with the intelligence layer (extraction, reconciliation,
temporal invalidation, decay, context construction) as first-class, replaceable research code.
pip install memry
memry mcp # ← your agent now has long-term memory
- MCP-native - works with Claude Code, Claude Desktop, Cursor, Windsurf, Codex, and any other MCP client, over stdio or streamable HTTP.
- Local-first - a single SQLite file. No vector DB, no Postgres, no cloud. Works with
zero API keys (FTS5 BM25 + deterministic hash embeddings), gets smarter the moment you
set
ANTHROPIC_API_KEY/OPENAI_API_KEY. - Real memory, not a vector dump - LLM extraction distills conversations into discrete
facts; reconciliation deduplicates, merges, and supersedes contradicted memories instead
of deleting them (bi-temporal:
valid_from/invalid_at/superseded_by). - Explainable retrieval - hybrid vector + BM25 with reciprocal-rank fusion, boosted by recency and importance; every result carries its score signals.
- Provenance & audit - raw episodes are stored immutably; every memory links to its
source episodes; every mutation is an event you can inspect (
history). - Forgetting built in - importance decays with a half-life; a decay sweep soft-forgets stale trivia (invalidated, never destroyed).
- Entities, disambiguated - mentions become first-class entities, and a name match is never enough to merge: unclear cases stay separate ("three Jonases") with a merge proposal you (or the system, once evidence is clear) confirm or reject later.
- Category filters -
search(categories=["diet"]),memry search -c diet,?categories=on REST,categorieson the MCP search tool. - Scales when you need it - optional usearch HNSW index (
memry[ann]) for vector search at scale, and a PostgreSQL + pgvector backend (memry[postgres]) for multi-writer deployments. SQLite stays the zero-ops default. - Multi-tenant ready - per-tenant API keys with transparent namespacing and strict
isolation on the self-hosted server (
MEMRY_TENANTS), plus an admin key. - Research-grade - a built-in eval harness (recall@k, MRR, latency) with a synthetic dataset, plus a pluggable backend interface with an optional Mem0 adapter so you can benchmark against it under identical conditions.
Apache-2.0. Your agents. Your memories. Your infrastructure.
Quickstart
1. As an MCP server (any agent)
// Claude Desktop / Cursor / Windsurf config
{
"mcpServers": {
"memry": {
"command": "memry",
"args": ["mcp"],
"env": { "ANTHROPIC_API_KEY": "sk-ant-..." } // optional but recommended
}
}
}
# Claude Code
claude mcp add memry -- memry mcp
The server exposes: save_memories, search_memories, get_memory_context,
list_memories, update_memory, delete_memory, memory_history, memory_stats.
2. As a Python library
from memry import MemoryStore
store = MemoryStore()
# write: extraction + reconciliation (or infer=False to store verbatim)
store.add(
[{"role": "user", "content": "I'm Ada, a data engineer in Berlin. I prefer uv over pip."}],
user_id="ada",
)
# read: hybrid search with explainable scores
for hit in store.search("what tooling does the user prefer?", user_id="ada"):
print(hit.score, hit.memory.content, hit.signals)
# or a ready-to-inject, token-budgeted context block
ctx = store.reconstruct_context("help me set up a new project", user_id="ada", token_budget=1200)
print(ctx.text)
3. Self-hosted server (REST + dashboard + MCP)
memry serve --host 0.0.0.0 --port 8787
# dashboard: http://localhost:8787/
# REST API: http://localhost:8787/api/v1/...
# MCP (HTTP): http://localhost:8787/mcp
Or with Docker:
docker compose up -d # see docker-compose.yml
Or on a fresh VPS (Ubuntu/Debian) with automatic HTTPS - one command, any provider (guide):
curl -fsSL https://raw.githubusercontent.com/cosmin-novac/memry/main/deploy/install.sh \
| MEMRY_DOMAIN=memory.example.com bash
Set MEMRY_API_KEY to require Authorization: Bearer <key> on the API.
4. CLI
memry add "I moved to Amsterdam and joined ASML" -u ada
memry search "where does ada work" -u ada
memry context "plan a commute" -u ada
memry history <memory_id> # full audit trail
memry sweep # decay: soft-forget stale memories
memry eval --dataset evals/datasets/synthetic_v1.jsonl
How it works
flowchart LR
A[conversation] --> E[episodes<br/><i>immutable raw log</i>]
A --> X[extraction<br/><i>LLM distills facts</i>]
X --> R{reconcile}
R -- new --> ADD[ADD memory]
R -- overlaps --> UPD[UPDATE in place]
R -- contradicts --> SUP[invalidate old<br/>supersede with new]
R -- duplicate --> NONE[skip]
ADD & UPD & SUP --> M[(memories<br/>FTS5 + vectors + events)]
Q[agent query] --> H[hybrid retrieval<br/>RRF + recency + importance]
M --> H --> C[token-budgeted<br/>context block]
- Episodes first. Every message is stored verbatim before anything is derived from it. Memories are an index; episodes are the source of truth - you can re-run a better extraction pipeline over them later.
- Extraction (Mem0-style phase 1): an LLM distills discrete, self-contained facts with type (semantic / episodic / procedural), importance, categories, and entities. Without an LLM, messages are stored verbatim so the system still works.
- Reconciliation (phase 2, with Zep-style temporal semantics): each fact is compared to its most similar existing memories - duplicates are skipped, refinements rewrite in place, and contradictions invalidate the old memory and link it to its successor.
- Retrieval: BM25 + cosine similarity fused with RRF, then boosted by recency (half-life) and importance. Keyword-only when no embedder is configured.
- Forgetting: effective importance decays over time;
memry sweepinvalidates memories that decayed below threshold.
Configuration
Everything works with defaults. Override via env vars, ~/.memry/config.json, or Config(...):
| Env var | Default | Notes |
|---|---|---|
MEMRY_DB_PATH |
~/.memry/memry.db |
single SQLite file |
MEMRY_BACKEND |
local |
local | mem0 (needs memry[mem0]) |
MEMRY_DEFAULT_USER |
default |
user scope when the agent doesn't pass one |
MEMRY_LLM_PROVIDER |
auto | anthropic | openai | ollama | none - auto-detected from ANTHROPIC_API_KEY / OPENAI_API_KEY |
MEMRY_LLM_MODEL |
per provider | claude-opus-4-8 / gpt-5-mini / llama3.1 (use claude-haiku-4-5 for a cheaper extraction model) |
MEMRY_EMBEDDING_PROVIDER |
auto | openai | ollama | voyage | hash | none |
MEMRY_API_KEY |
- | bearer token for the REST/MCP HTTP server |
Anthropic extraction requires the optional SDK: pip install "memry[anthropic]".
Evaluation
memry eval --dataset evals/datasets/synthetic_v1.jsonl -k 5
The harness ingests each case through the full write path, then scores retrieval (recall@k, MRR, latency p50/p95) - deterministic and offline, so it runs in CI. Format LoCoMo/LongMemEval into the same JSONL schema to compare providers, configs, and backends (including the Mem0 adapter) under identical conditions. See docs/research/competitive-analysis.md for the landscape survey behind the design.
Project layout
src/memry/
models.py # Episode / Memory / MemoryEvent (bi-temporal, provenance)
config.py # env + file config, provider auto-detection
store.py # MemoryStore - the public API
retrieval.py # hybrid search: RRF + recency + importance
backends/ # storage interface, local SQLite engine, Mem0 adapter
intelligence/ # extraction, reconciliation, decay, context building
providers/ # LLMs (Anthropic/OpenAI/Ollama) & embeddings (+hash fallback)
mcp_server.py # MCP tools (stdio + streamable HTTP)
rest.py # REST API + dashboard + /mcp mount
evals/ # retrieval eval harness
Development
pip install -e ".[dev]"
pytest
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file memry-0.2.0.tar.gz.
File metadata
- Download URL: memry-0.2.0.tar.gz
- Upload date:
- Size: 52.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
869484598aff2c39e52c44fa2a1801158d3d8e02e2c5004e6bc284f59ec8bde7
|
|
| MD5 |
c5173ad0563a3c3c4feff67135318036
|
|
| BLAKE2b-256 |
bc44a5c30094d5a3083d09b11325cc032813e363a74ea0654f5a560dec4027a0
|
Provenance
The following attestation bundles were made for memry-0.2.0.tar.gz:
Publisher:
publish.yml on cosmin-novac/memry
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memry-0.2.0.tar.gz -
Subject digest:
869484598aff2c39e52c44fa2a1801158d3d8e02e2c5004e6bc284f59ec8bde7 - Sigstore transparency entry: 2199589121
- Sigstore integration time:
-
Permalink:
cosmin-novac/memry@881741db7887ad31f0302ab43e098d1b242cb9ac -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/cosmin-novac
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@881741db7887ad31f0302ab43e098d1b242cb9ac -
Trigger Event:
release
-
Statement type:
File details
Details for the file memry-0.2.0-py3-none-any.whl.
File metadata
- Download URL: memry-0.2.0-py3-none-any.whl
- Upload date:
- Size: 64.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16e595b68dd2ca00283e6481642b25e6a1968d6c4aa027e6004ad4d015fc5040
|
|
| MD5 |
c81164c516e56ba41d8341a5be5e31c6
|
|
| BLAKE2b-256 |
3539c86e5717ef19b83f9f26f201b0487b5eeaf41681af5253e2dd08b2a8fa5b
|
Provenance
The following attestation bundles were made for memry-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on cosmin-novac/memry
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memry-0.2.0-py3-none-any.whl -
Subject digest:
16e595b68dd2ca00283e6481642b25e6a1968d6c4aa027e6004ad4d015fc5040 - Sigstore transparency entry: 2199589167
- Sigstore integration time:
-
Permalink:
cosmin-novac/memry@881741db7887ad31f0302ab43e098d1b242cb9ac -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/cosmin-novac
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@881741db7887ad31f0302ab43e098d1b242cb9ac -
Trigger Event:
release
-
Statement type: