Skip to content
rmbr.dev

Local-first memory
for AI agents.

What SQLite is to Postgres, rmbr aims to be to hosted memory services: one file, three lines, no infrastructure. It gives you hybrid search, safe multi-agent isolation, and full offline support as a plain Python dependency, not a service you have to run.

memory.py
1pip install rmbr
2from rmbr import Memory
3mem = Memory("agents.db")
4mem.remember("likes dark mode")
5mem.recall("preferences")
rmbrSRock44
A
license
A
quality
A
maintenance
PythonMIT License
One file
A SQLite .db file you can commit, diff, and roll back like any other file.
No infra
The memory and retrieval path makes zero network calls by default.
Hybrid search
BM25 keyword search plus semantic search, with an embedding cache built in.
Safe isolation
MCP tools are pinned to one namespace, and Policy denies cross-agent access by default.
Built with rmbr

Projects

rmbr is still early. The runnable example below ships in the repo, and this section is here for community projects as they show up.

History

Changelog

v0.2.7
2026-08-03
  • +Fixed a second FastEmbedEmbedder-sharing crash, this time in AnnIndex itself, unrelated to the embedder sharing fixed in v0.2.6 despite surfacing in the identical "one Memory per namespace" pattern as #18.
  • +Root cause: usearch (>=2.9, confirmed through 2.26.0) leaves a tombstoned node in its HNSW graph after remove(), even once the index is back down to zero vectors.
  • +Serializing that state and reloading it in a fresh process — exactly what happens the moment a second Memory/Index opens the same .db file/collection after any prior remember()+forget(), add_text()+delete(), or dedupe-triggered update — segfaulted the next add() on that reload.
  • +Fix: AnnIndex now rebuilds itself from its surviving vectors before every serialize whenever a remove() happened since the last one, so a reloaded index never carries a tombstone into a fresh process.
v0.2.6
2026-08-03
  • +Fixed Memory(embedder=None)/Index(embedder=None) (the default) constructing a brand-new FastEmbedEmbedder — a fresh fastembed.TextEmbedding/onnxruntime InferenceSession — on every call, with no sharing across instances.
  • +Apps opening one Memory/Index per namespace against a shared .db file (the pattern Policy.allow(read=[...]) exists to support) piled up redundant onnxruntime sessions per process, which could reliably crash the process (native heap corruption, worse when another native library shared the process).
  • +Fix: make_embedder() now shares one FastEmbedEmbedder per model name via a lock-guarded module-level cache, so the default path is safe without callers needing to pass a shared embedder in explicitly.
v0.2.5
2026-07-31
  • +Memory.bulk() and Index.bulk() defer vector-index reserialization to one write per batch, instead of on every remember()/add_text() call. Up to 35.6x faster at 40,000-item namespaces.
  • +PDF and DOCX ingestion for Index.add_files() via optional rmbr[pdf] and rmbr[docx] extras.
  • +New bench scripts: scale.py, mcp_latency.py, http_latency.py. Real MCP-subprocess and HTTP-socket round-trip numbers, not just the in-process API.
  • +Glama.ai MCP quality pass: real ToolAnnotations on all three tools, and tool descriptions rewritten to disclose search-vs-recall guidance and eviction behavior.
v0.2.4
2026-07-31
  • +A LangGraph BaseStore adapter (as_store()) and a mem0-API-compatible Memory drop-in, reimplemented from scratch with no mem0ai dependency.
  • +An optional HTTP server (serve_http and build_app): Starlette and uvicorn, zero new dependencies, namespace-pinned like MCP, with opt-in bearer-token auth.
  • +Memory.get() and Memory.update() for direct record access by id.
  • +CI hardening: a ruff lint gate, real subprocess and socket integration tests, Dependabot, CodeQL, and a SECURITY.md.
v0.2.3
2026-07-31
  • +Per-parameter JSON Schema descriptions on every MCP tool argument, closing a gap Glama.ai’s quality scoring caught: a tool-calling model sees the schema, not the docstring.
v0.2.2
2026-07-31
  • +Glama.ai MCP directory listing, verified live.
  • +An MCP resource template (rmbr://examples/{pattern}) serving short, runnable snippets for common usage patterns.
  • +Fixed serve_mcp() reporting an empty version string in serverInfo.
v0.2.1
2026-07-31
  • +A py.typed marker, so mypy and pyright now trust rmbr’s type hints.
  • +ToolSpec.call() validates arguments against the tool’s own schema and raises a clear ToolCallError instead of a bare TypeError when a model hallucinates an argument.
  • +Memory and Index gained stats() and integrity_check().
  • +remember(..., pinned=True) exempts specific memories from max_memories eviction.
v0.2.0
2026-07-31
  • +Similarity-based memory dedupe and update (dedupe_threshold), plus bounded retention (max_memories, forget_older_than).
  • +Recency-weighted ranking for Memory.recall() and Index.search().
  • +Richer where= filtering ($gt, $gte, $lt, $lte, $in, $nin, $ne), and a real confidence gate on raw cosine similarity (min_similarity).
  • +An optional local cross-encoder reranker (rerank=True), remember_turn() for conversation memory, and tool-calling export (as_tool()/as_tools()) for hand-rolled agent loops.
  • +LangChain and LlamaIndex retriever adapters, plus VoyageEmbedder and CohereEmbedder alongside OpenAIEmbedder.
v0.1.0
2026-07-30
  • +Memory, Policy, and Index: hybrid BM25 and vector search, with metadata filtering.
  • +Embedding and semantic query caches, plus namespace-pinned MCP support.
  • +CI across Linux, Windows, and macOS, and an async API surface (a-prefixed methods).
  • +PyPI trusted publishing, a uvx-launchable console script, and a listing on the official MCP registry.