Skip to main content
oneMEM Logo

oneMEM

One memory. Every AI. You own it.

Local, structured memory for AI agents — in one SQLite file on your machine.

PyPI Python License: MIT Downloads Tests MCP Claude


oneMEM gives AI tools a shared local memory. It distills useful context into compact atomic facts and surfaces the minimum memory sufficient for a query. Every connected agent reads and writes the same SQLite file.

AI agents ───┐
Code editors ┼── MCP ── oneMEM ── ~/.onemem/onemem.db
Local tools ─┘

Why oneMEM?

Local & private One SQLite file. No server, no cloud, no account. Back it up by copying a file.
Deterministic retrieval No LLM in the read path. Same query returns the same result, always. Inspectable with SQL.
Append-only Events are never overwritten. Facts are only ever added. Corrections are new events.
MCP-native Two tools (onemem_recall + onemem_log) — works with Claude Code, Codex, Cursor, Windsurf.
BYOLLM OpenRouter, OpenAI, Anthropic, Gemini, Groq, xAI, Hugging Face, Ollama, or any OpenAI-compatible endpoint.
Local embeddings bge-base-en-v1.5 (768-d) runs locally. No embedding API, no extra key, no latency.

Quick Start

Requires Python 3.11+ and an API key for any LLM provider. Embeddings run locally.

# Install
uv tool install "onemem[all]"

# Setup (walks you through provider, key, model, capture, MCP wiring)
onemem init

# Try it
onemem add "Chose SQLite because it needs zero operations and one-file backups."
onemem ask "What storage did I choose, and why?"

Architecture

graph TB
    subgraph INPUTS ["Inputs"]
        CLI["CLI<br/>onemem &lt;command&gt;"]
        MCP["MCP Server<br/>onemem-mcp"]
        API["HTTP API<br/>FastAPI /events"]
        WATCH["Watch<br/>Claude Code / Codex transcripts"]
    end

    subgraph WRITE ["Write Path"]
        INTAKE["1. ingest_event()<br/>chunk - dedup by content hash - store"]
        EXTRACT["2. extract_entities()<br/>LLM reads event - atomic facts + named entities"]
        RECONCILE["3. reconcile + store<br/>normalize entities - link fact_entity_edges - store facts"]
        EMBED_W["4. embed_facts()<br/>bge-base-en-v1.5 768-d local embedding"]
    end

    subgraph SQLITE ["SQLite - ~/.onemem/onemem.db"]
        EVENTS[("events<br/>raw content, append-only")]
        EXTR[("extractions<br/>provenance ledger")]
        FACTS[("facts<br/>atomic claims")]
        ENTITIES[("entities<br/>canonical names")]
        EDGES[("fact_entity_edges<br/>which entities each fact mentions")]
        EMBED[("fact_embeddings<br/>sqlite-vec vec0, cosine")]
        FTS[("facts_fts<br/>FTS5 keyword index")]
    end

    subgraph READ ["Read Path"]
        PARAMS["1. LLM param extraction<br/>question - topic keywords + date range"]
        RETRIEVE["2. Deterministic Retrieval"]
        VECTOR["Vector Door<br/>cosine similarity"]
        KEYWORD["Keyword Door<br/>FTS5 BM25"]
        ENTITY_D["Entity Door<br/>fact_entity_edges"]
        FUSION["Fusion<br/>magnitude noisy-OR"]
        CUT["3. Adaptive Cut<br/>score-curve ratio, bounded 10 to limit"]
        COLLAPSE["Source Collapse<br/>if facts - raw event tokens - return raw"]
        SYNTH["4. LLM Synthesis<br/>optional natural-language answer"]
    end

    CLI --> INTAKE
    MCP --> INTAKE
    API --> INTAKE
    WATCH --> INTAKE

    INTAKE --> EVENTS
    EVENTS --> EXTRACT
    EXTRACT --> FACTS
    EXTRACT --> ENTITIES
    EXTRACT --> EXTR
    RECONCILE --> EDGES
    EMBED_W --> EMBED
    FACTS --> FTS

    CLI --> PARAMS
    MCP --> PARAMS

    PARAMS --> RETRIEVE
    RETRIEVE --> VECTOR
    RETRIEVE --> KEYWORD
    RETRIEVE --> ENTITY_D
    VECTOR --> FUSION
    KEYWORD --> FUSION
    ENTITY_D --> FUSION
    FUSION --> CUT
    CUT --> COLLAPSE
    COLLAPSE --> SYNTH

    EMBED --> VECTOR
    FTS --> KEYWORD
    EDGES --> ENTITY_D

Key design principles:

  • Append-only — raw events are never overwritten; facts are only ever added
  • Deterministic retrieval — no LLM in the read path; same query always returns the same result
  • Small models at the edges — LLM only at write time (distill) and optionally at read time (synthesize)

User Flow

%%{ init: { 'theme': 'dark', 'themeVariables': { 'actorBkg': '#7C3AED', 'actorTextColor': '#fff', 'actorBorder': '#9F67FF', 'signalColor': '#E2E8F0', 'signalTextColor': '#E2E8F0', 'noteBkgColor': '#1E293B', 'noteTextColor': '#E2E8F0', 'noteBorderColor': '#475569', 'rectBkgColor': '#0F172A', 'rectBorderColor': '#334155', 'rectTextColor': '#E2E8F0', 'sequenceNumberColor': '#fff' } }%%
sequenceDiagram
    actor User
    participant CLI as CLI / MCP
    participant Core as oneMEM Core
    participant LLM as LLM Provider
    participant DB as SQLite

    rect rgb(15, 23, 42)
        Note over User, DB: Write — ingest and distill
        User ->> CLI: onemem add "note"
        CLI ->> Core: ingest_event()
        Core ->> DB: store raw event
        Core ->> LLM: extract facts + entities
        LLM -->> Core: ExtractionResult
        Core ->> DB: store facts, entities, edges
        Core ->> Core: embed facts (768-d, local)
        Core -->> CLI: event_ids
    end

    rect rgb(15, 23, 42)
        Note over User, DB: Read — retrieve and answer
        User ->> CLI: onemem ask "question?"
        CLI ->> LLM: extract search params
        LLM -->> CLI: {text, start, end}
        CLI ->> Core: retrieve(text, start, end)
        Core ->> DB: vector + keyword + entity search
        DB -->> Core: matched facts
        Core ->> Core: fusion then adaptive cut
        Core -->> CLI: facts with scores
        CLI ->> LLM: synthesize answer from facts
        LLM -->> CLI: AskAnswer
        CLI -->> User: natural language answer
    end

    rect rgb(15, 23, 42)
        Note over User, DB: MCP — agent background write
        User ->> CLI: AI agent conversation
        CLI ->> Core: onemem_log(content)
        Core ->> DB: store raw event
        Note right of Core: background processor<br/>extracts facts later
    end

Command Flow

oneMEM Command Flow


Commands

Command Purpose Path
onemem init Interactive setup wizard (provider, key, model, capture, MCP) --
onemem add "text" Store a note directly write
onemem ask "question" Retrieve matching facts + optional LLM synthesis read
onemem import <path> Bulk-import .txt / .md files (parallel batch) write
onemem process Process all pending events (extract facts) write
onemem watch Capture Claude Code / Codex sessions in real-time write
onemem watch --start Start background capture service write
onemem watch --stop Stop background capture service write
onemem status Event / fact / entity counts + staleness detection read
onemem doctor Health check (DB, sqlite-vec, LLM, write path) read
onemem list events Browse events (--since, --until, --source) read
onemem show event N Full event detail + extraction provenance read
onemem sql "SELECT..." Read-only SQL query against the memory read
onemem tables List all DB tables with row counts read
onemem config set Interactively change provider, API key, model config
onemem config show Show active config safely (never exposes full key) read

MCP Setup

oneMEM works with any MCP client that supports local stdio servers.

# Claude Code
claude mcp add --scope user onemem -- "$(command -v onemem-mcp)"

# Codex
codex mcp add onemem -- "$(command -v onemem-mcp)"

onemem init automatically detects and wires Claude Code and Codex during setup.

MCP Tools

Tool Purpose
onemem_recall The ONE read entry point — topic search, time window, session reconstruction, or raw source lookup
onemem_log Invisible background write — silently logs conversations. No announcement, no permission, no waiting.

Supported Providers

Provider Key Env Var Notes
OpenRouter OPENROUTER_API_KEY One key, hundreds of models
OpenAI OPENAI_API_KEY Direct GPT access
Anthropic ANTHROPIC_API_KEY Native Claude API
Google Gemini GEMINI_API_KEY Direct Gemini access
Groq GROQ_API_KEY Fast inference, open-weight models
xAI XAI_API_KEY Grok access
Hugging Face HF_TOKEN Open-weight models via Inference Providers
Ollama no key needed Free, runs locally
Custom base_url + api_key_env Any OpenAI-compatible endpoint

Embeddings always use bge-base-en-v1.5 (768-d) running locally — no API key needed.


Benchmarks

Measured on a 100-instance stratified sample of LongMemEval-S:

Metric Result
Retrieval recall 0.89
Context reduction 99.1%
End-to-end answer accuracy 72%

Configuration

Edit ~/.onemem/config.toml (or use onemem config set):

[model]
provider = "openrouter"
model = "google/gemini-3.5-flash-lite"

[spend]
max_run_cost_usd = 20.0    # hard ceiling per batch import

[retrieval]
default_limit = 30         # max facts returned per recall
neighbour_max = 20         # neighbour facts gathered around a match

[ingestion]
concurrency = 20           # parallel LLM workers during bulk import

Where data lives

Path Contents
~/.onemem/onemem.db Events, facts, entities, embeddings — back this up
~/.onemem/config.toml Active provider, model, runtime settings
~/.onemem/.env Provider API keys

Development

git clone https://github.com/shashank-tomar0/onemem.git
cd onemem
uv sync --all-extras
uv run pytest -q                    # 144 passing
./scripts/dev-onemem doctor         # run with isolated dev home

Project Structure

onemem/
├── cli/                  # Click CLI (init, add, ask, watch, ...)
├── api/                  # FastAPI HTTP API
├── providers/            # LLM + embedding implementations
│   ├── openai_compat.py      # OpenAI-compatible endpoints
│   ├── anthropic.py          # Anthropic native API
│   └── local_embedding.py    # bge-base-en-v1.5
├── mcp_server.py         # MCP server (onemem_recall + onemem_log)
├── fact_retrieval.py     # Deterministic hybrid search
├── pipeline.py           # Ingest + process orchestration
├── entity_extractor.py   # LLM-based entity + fact extraction
├── schema.sql            # SQLite schema
└── config.py             # All tunable settings

License

MIT — Based on Meniscus by magic_bubblez.


oneMEM — Your memory, your machine, your AI.

Get Started · Report Bug · View Design · PyPI

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

onemem-0.1.7.tar.gz (13.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

onemem-0.1.7-py3-none-any.whl (72.2 kB view details)

Uploaded Python 3

File details

Details for the file onemem-0.1.7.tar.gz.

File metadata

  • Download URL: onemem-0.1.7.tar.gz
  • Upload date:
  • Size: 13.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.7

File hashes

Hashes for onemem-0.1.7.tar.gz
Algorithm Hash digest
SHA256 396df6e97ba0d3ed6e93a0c6e92c9392ce933917bc70d1ccefd0724ce17afe65
MD5 a6b1e60fef56c146bb70ad67e7b49c00
BLAKE2b-256 526feb9a8fefddb964e9417b6583320bced1ef85bd3a76ae6c166e208b5acef6

See more details on using hashes here.

File details

Details for the file onemem-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: onemem-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 72.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.7

File hashes

Hashes for onemem-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 c045e57834a97bd6950493c74214963824a3f5b8158244b43f36fffe6331b709
MD5 add00b2b2a558d8b1cb68d4678971d49
BLAKE2b-256 bd32b572708494cf1a51d989fef19cafebc3b0468f025122f7a4c35f8e357e69

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page