Skip to main content
Glama

umo-memory

Persistent memory for AI coding agents. Local-first. Zero cloud. Plug-and-play with Claude Code via MCP.

Tests Coverage Python License MCP

Stop losing context between sessions. umo-memory gives your AI agent a long-term brain that runs entirely on your laptop. Stored facts (preferences, decisions, conventions) survive across sessions and are recalled by semantic similarity — so the next time you ask Claude to "use my dark theme," it remembers without you re-explaining.

Built for Claude Code but works with any MCP-compatible client.


Why

Every Claude Code session starts cold. You re-explain your preferences, your project's conventions, your architecture decisions. After 50 sessions, you've typed the same context thousands of times.

umo-memory solves this with persistent memory:

  • Stored automatically by your agent via MCP tools (store, recall, etc.)

  • Recalled by semantic similarity (vector search, no exact-key matching)

  • Survives sessions, restarts, machines (single SQLite file)

  • 100% local — no API calls, no telemetry, no cloud lock-in

  • Battle-tested — 179 tests, 92% coverage (with branch tracking), real concurrency tests


Related MCP server: Tages

30-second quickstart

1. Install

pip install umo-memory

(First run downloads a ~80MB embedding model — one-time, then cached.)

2. Initialize the database

umo init

Creates ~/.local/share/umo-memory/memory.db.

3. Wire into Claude Code

Add to ~/.claude/mcp_servers.json (or .mcp.json in your project):

{
  "mcpServers": {
    "memory": {
      "command": "umo",
      "args": ["start"],
      "env": {"UMO_PATH": "~/.local/share/umo-memory/memory.db"}
    }
  }
}

4. Use it

Open Claude Code. It now has access to:

  • store — save a fact (preference, decision, convention)

  • recall — semantic search across stored facts

  • update / forget — mutate stored facts

  • recent / browse — inspect what's stored

Tell Claude: "Remember that I prefer dark mode in all my projects." Next session, it'll know.


First day with umo

A 5-minute walkthrough to prove the round-trip works:

$ umo init
Initialized umo-memory at ~/.local/share/umo-memory/memory.db

$ umo list
No memories yet. Run `umo init` then store something.

# Stash something via Python (or via Claude Code)
$ python -c "from umo import Memory; \
  m = Memory(); \
  m.store('I prefer dark mode in editors', 'fact', 0.8, subject_key='user.theme')"

$ umo list
  01KVF2CKW772  fact    imp=0.80  [user.theme] I prefer dark mode in editors

$ umo search "what theme does the user like"
  1. 01KVF2CKW772  fact    imp=0.80  [user.theme] I prefer dark mode in editors

$ umo show 01KVF2CKW772
Memory 01KVF2CKW772QQG4ZRPSDEH99E
  kind:         fact
  subject_key:  user.theme
  importance:   0.80
  source:       manual
  ...

  content:
    I prefer dark mode in editors

If you see this — Claude Code will too. The next session, just open Claude and ask "what theme does the user like?" — it'll know.


What's stored

Three kinds of memories:

Kind

Use for

Example

fact

User preferences, project facts, conventions

"User prefers dark mode"

event

Things that happened, dated context

"Migrated from Postgres to SQLite on 2026-01-15"

lesson

Procedural rules the agent should follow

"When using sqlite-vec, always include AND k = ?"

Each memory can have a subject_key (e.g. user.theme, project.db_choice) for deterministic lookup, plus metadata and importance (0.0–1.0).


Architecture

┌──────────────────────────────────────────────────┐
│  Claude Code (or any MCP client)                 │
│         │                                        │
│         │ MCP protocol (JSON-RPC over stdio)     │
│         ▼                                        │
│  ┌──────────────────────────────────────────┐    │
│  │  umo_memory mcp_server                      │    │
│  │  (9 tools: store, recall, update, …)      │    │
│  └──────────────┬───────────────────────────┘    │
│                 │                                │
│                 ▼                                │
│  ┌──────────────────────────────────────────┐    │
│  │  umo_memory core (Python)                   │    │
│  │  ┌──────────┐ ┌──────────┐ ┌─────────┐    │    │
│  │  │  Store   │ │ Recall   │ │ Embedder│    │    │
│  │  │ (SQLite) │ │(vec+fts) │ │  (sbert)│    │    │
│  │  └──────────┘ └──────────┘ └─────────┘    │    │
│  └──────────────┬───────────────────────────┘    │
│                 │                                │
│                 ▼                                │
│       SQLite + FTS5 + vec0  (~/.local/share/…)   │
└──────────────────────────────────────────────────┘

Everything in one SQLite file. SQLite gives ACID transactions, WAL for concurrent reads, and single-file backup. No Docker, no Postgres, no Redis.


Comparison

umo-memory

mem0

LangChain Memory

custom RAG

Local-first

✅ single file

❌ cloud default

❌ external DB

depends

MCP integration

✅ built-in

❌ DIY

❌ DIY

❌ DIY

No external services

depends

Vector search built-in

✅ sqlite-vec

depends

depends

FTS5 keyword fallback

Subject-key dedup

Setup time

30 sec

5 min

30 min

hours

Dependency footprint

7 packages

heavy

very heavy

DIY

When to use umo-memory: you want persistent memory that just works, runs on your laptop, doesn't phone home, and integrates with Claude Code in under a minute.

When NOT to use it: you need multi-tenant cloud storage, embeddings for non-text modalities, or 100k+ memories per user (vector search in SQLite caps out around there).


Backing up and restoring

Everything is in one SQLite file. To back up:

cp ~/.local/share/umo-memory/memory.db backup.db
# Or export to portable JSONL:
umo export ~/.local/share/umo-memory/memory.db > backup.jsonl

To restore:

# From a SQLite file:
cp backup.db ~/.local/share/umo-memory/memory.db
# From a JSONL file:
umo init ~/.local/share/umo-memory/memory.db --force
umo import_data ~/.local/share/umo-memory/memory.db backup.jsonl

Upgrading the embedding model

If you switch UMO_EMBEDDING_MODEL or upgrade sentence-transformers, old memories have embeddings in the old dimension. Run:

umo reembed

This re-encodes every memory using the current model. Without it, sqlite-vec queries on mixed-dim embeddings will crash.


Usage

CLI

umo init                              # create empty DB
umo verify                            # health check (8 checks)
umo stats                             # show counts, model, schema version
umo list                              # show recent memories (formatted)
umo show <id>                         # show one memory by id
umo search "query"                    # semantic search via CLI
umo start                             # run MCP server on stdio
umo export <path> > backup.jsonl      # export all memories to JSONL
umo import_data <path> <file.jsonl>   # import from JSONL backup
umo import <path> <pm-db-path>        # import from PMB-format DB
umo reembed                           # re-encode stale embeddings

Python API

from umo import Memory

mem = Memory(path="~/.local/share/umo-memory/memory.db")

# Store a fact (with subject_key for deterministic dedup)
mem.store(
    content="User prefers dark mode",
    kind="fact",
    importance=0.8,
    subject_key="user.theme",
)

# Semantic recall (results are MemoryRecord, sorted by relevance)
results = mem.recall("what theme does the user prefer?")
for r in results:
    print(f"[{r.kind}]  {r.content}")

# Update
mem.update(id=results[0].id, content="User prefers dark mode in editors, light in terminals")

# Forget
mem.forget(id=results[0].id)

# Browse by prefix
for item in mem.browse(subject_key_prefix="user."):
    print(item.content)

MCP tools

When running as an MCP server, these tools are exposed:

Tool

Purpose

store

Store a fact/event/lesson

recall

Semantic search across all memories

update

Update content/importance/metadata

forget

Soft-delete (archive)

recent

Browse recent memories

browse

List by subject_key prefix

stats

Counts, schema version, model info

store_many

Atomic batch insert

recall_many

Batch semantic search

For migration from PMB-format DBs, use the Python API: from umo_memory.importers.pmb import import_pmb.


Storage format

Single SQLite file with three tables:

  • memories — content + metadata (subject_key, kind, importance, source, timestamps)

  • memory_fts — FTS5 virtual table for keyword fallback

  • memory_vec — sqlite-vec virtual table for semantic search

Schema migrations: schema_version table tracks applied migrations; umo init upgrades existing DBs in place.


Testing

git clone https://github.com/yourname/umo-memory
cd umo-memory
pip install -e ".[dev]"
pytest                     # 179 tests, ~10 min on CPU
pytest --cov=umo_memory       # with coverage
ruff check src tests       # lint

Documentation


License

Apache 2.0. See LICENSE.


Credits

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A local, persistent memory system for AI coding assistants that stores decisions, patterns, and session context via MCP tools. It enables cross-session memory management using SQLite and optional vector search without external dependencies or cloud storage.
    18 npm
    64
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI coding agents to maintain persistent, cross-session memory of codebase architecture, naming conventions, and decisions through MCP tools. Eliminates repetitive project re-explanation by automatically injecting stored context into every session with local-first SQLite storage and optional team sharing capabilities.
    4
    MIT