Skip to main content

Local-first AI memory — semantic retrieval over your own SQLite + HNSW index.

Project description

Mnemonics

/nɪˈmɒnɪks/, ni-MON-iks (the "m" is silent, like "memories" with an N).

Local-first AI memory with tier-aware decay.

Mnemonics is a small memory layer that stores text, retrieves it with semantic search, and decays old entries the way a brain does, slowly for the things you use often, faster for ambient noise. No cloud, no telemetry, no daemon required.

Why

Most AI memory tools push your conversations to a hosted service. Mnemonics doesn't. Your index, your DB, your machine. The library is small enough to read in one sitting, and every retrieval is fully transparent: you see the raw cosine score, the decay factor, the age, and the tier on every result, so nothing is silently demoted behind your back.

Install

pip install mnemonics

CLI alias: both mnemonics and the shorter mnem are available after install.

Quick start

# Store something
mnem ingest "The Eiffel Tower is 330 meters tall and located in Paris."

# Retrieve (decay applied by default)
mnem retrieve "how tall is the Eiffel Tower"
#   [0.912] [raw=0.912 decay=1.00 age=0d tier=def] The Eiffel Tower is 330 meters tall ...

Tiers and decay

Every memory has a tier that controls how aggressively its score fades over time:

Tier Label Half-life Use for
0 pinned no decay decisions, key facts, things you must keep
1 default 90 days general notes (the default)
2 ambient 14 days low-confidence observations, chit-chat

Final score on every retrieval is:

score = raw_cosine × exp(-ln(2) × age_days / half_life)

Pinned (tier 0) entries always score at full weight. Tier-1 entries lose half their weight after 90 days, tier-2 after 14. Disable decay anytime with --no-decay (CLI) or decay=false (REST/MCP).

mnem pin <id>             # tier=0, never decays
mnem tier <id> 2          # tier=2, ambient (fast decay)
mnem retrieve "..." --no-decay   # show raw cosine scores

Every retrieval bumps access_count and last_accessed for the rows it returned, which sets up future reinforcement scoring without any caller action.

Python API

from mnemonics.store import Store
from mnemonics.ingest import ingest
from mnemonics.retrieve import retrieve

store = Store("~/.mnemonics")

ingest(["Paris is the capital of France.", "Rome is the capital of Italy."], store)

result = retrieve("what is the capital of France", store, top_k=3)
for r in result["results"]:
    print(f"[{r['score']:.3f}] tier={r['tier']} age={r['age_days']:.0f}d  {r['text']}")

store.pin(id) and store.set_tier(id, tier) change a memory's tier directly.

REST server

mnem serve --port 7810

The server binds to 127.0.0.1 only, no external interface, no telemetry.

Method Path Body
POST /ingest {"texts": [...], "ns": "default"}
POST /retrieve {"query": "...", "top_k": 5, "decay": true}
GET /health
GET /namespaces
GET /count?ns=default
DELETE /memory/<id>

MCP (Claude Code / Cursor / Metis)

mnem mcp
{
  "mcpServers": {
    "mnemonics": {
      "command": "mnem",
      "args": ["mcp"]
    }
  }
}

Tools exposed:

  • mnemonics_ingest
  • mnemonics_retrieve (decay-aware, supports decay: false for raw cosine)
  • mnemonics_forget
  • mnemonics_pin
  • mnemonics_tier
  • mnemonics_gc
  • mnemonics_stats

Namespaces

Isolate memories by project, user, or any key:

mnem ingest "project notes..." --ns work
mnem retrieve "deadlines" --ns work

Architecture

texts -> chunk (200w / 40w overlap) -> embed (all-MiniLM-L6-v2)
      -> hnswlib cosine index (per namespace)
      -> SQLite metadata store (id, ns, text, meta, created,
                                tier, last_accessed, access_count)

retrieve -> embed query -> knn search -> tier-aware decay -> ranked results
         -> UPDATE last_accessed, access_count on retrieved rows

Storage layout under ~/.mnemonics:

memories.db        SQLite (text, meta, tier, access counters, timestamps)
index_<ns>.bin     hnswlib index for each namespace

Privacy

  • The REST server binds to 127.0.0.1 only. There is no 0.0.0.0 flag.

  • The mnemonics package contains no outbound HTTP, no telemetry, no analytics.

  • First-run network: sentence-transformers downloads the all-MiniLM-L6-v2 model (~90 MB) from Hugging Face Hub on the first ingest or retrieve. The model caches under ~/.cache/huggingface/. After that first download, you can pin the package fully offline:

    export TRANSFORMERS_OFFLINE=1
    export HF_HUB_OFFLINE=1
    
  • DB encryption-at-rest (SQLCipher) is not currently enabled. The SQLite file at ~/.mnemonics/memories.db is plaintext on disk; protect it with full-disk encryption (FileVault on macOS) until first-class encryption support lands.

License

MIT

Project details


Download files

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

Source Distribution

mnemonics-0.2.1.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

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

mnemonics-0.2.1-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file mnemonics-0.2.1.tar.gz.

File metadata

  • Download URL: mnemonics-0.2.1.tar.gz
  • Upload date:
  • Size: 21.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for mnemonics-0.2.1.tar.gz
Algorithm Hash digest
SHA256 722dc784441e6c29cadffeaa13faced130f8213d821300114ccd5e971e7a4fd8
MD5 bab639de5f5fe226e4962f683a7051a2
BLAKE2b-256 34a61773f80eca66f736eb5a8ab1afc12a70c9c745fd131eebdaa4d4565170a6

See more details on using hashes here.

File details

Details for the file mnemonics-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: mnemonics-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 14.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for mnemonics-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 28ac5c51d52dbb6583d6c15d04fbb3d993c938c7267fcd9e8d4fda77f42f7661
MD5 827db0cfe6081c57fcd33977267054fa
BLAKE2b-256 3f2d7dcc70c34f552d85c248218fc8892fa7a1d29a222b87b99e80c8cbeeccb4

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 Pingdom Monitoring Sentry Error logging StatusPage Status page