localmem
Local-first multi-agent memory MCP server. Persistent storage for LLM agents — hybrid (dense + sparse) vector search, behavioral pattern graphs, temporal knowledge triples, layered wake-up context, lifecycle management, and a read-only browser dashboard. All on-device, no cloud dependencies.
Exposes its functionality over the Model Context Protocol (SSE transport), so any MCP-capable client — Claude Code, Cursor, Continue, custom agents — can read and write memory through a single shared server.
Why
Most "memory" for LLM agents is either a flat key-value store or a single-agent knowledge graph. Real agent systems need more:
- Per-agent namespaces. Each agent's notes, decisions, and observations
stay in its own wing. A reserved
sharedwing carries cross-agent context. - Hybrid retrieval. Dense embeddings catch semantic matches, sparse BM25 catches exact terms, RRF fuses both. Either signal alone misses too much.
- Behavioral graphs. Some relationships live in entries; others live in the connections between them — co-occurrence, sequence, community structure.
- Temporal knowledge. Facts change. Knowledge triples track validity windows and surface contradictions automatically.
- Graceful forgetting. Three-tier lifecycle (hot → warm summaries → cold compressed archive) keeps the working set fast without losing history.
- Token-aware loading. Layered wake-up context (L0 manifest → L1 critical → L2 scoped search → L3 verbatim) gives an agent ~170 tokens of high-signal context without pulling the whole store.
Quick start
Use a virtualenv. Recent macOS / Homebrew / Debian Python installs are "externally managed" (PEP 668) and
pip install localmemdirectly will refuse. A dedicated venv also keeps thelocalmemconsole script onPATHautomatically when activated.
# 1. Create a venv (use Python 3.13 — 3.14 + Apple Silicon has a known
# sentence-transformers shutdown issue, see Known issues below)
python3.13 -m venv ~/.venvs/localmem
source ~/.venvs/localmem/bin/activate
# 2. Install from PyPI
pip install 'localmem[dashboard,analytics]'
# 3. Scaffold a working config + data directory
mkdir -p ~/localmem-data && cd ~/localmem-data
localmem init --wing my_assistant --dashboard
# 4. Start the MCP server (SSE on http://localhost:8781)
localmem -c localmem.yaml serve
Connect any MCP client to http://localhost:8781/sse and the 22 tools below
become available.
Dashboard (optional, read-only):
# In another terminal (venv active):
localmem -c localmem.yaml dashboard # REST + WS on http://localhost:8782
# The prebuilt React frontend isn't shipped on PyPI yet. To get the UI:
git clone https://github.com/jordanaftermidnight/localmem.git ~/localmem-source
cd ~/localmem-source/dashboard
npm install
VITE_API_URL=http://localhost:8782 VITE_WS_URL=ws://localhost:8782/ws npm run build
cd dist && python3 -m http.server 8785
Then open http://localhost:8785.
Headless / always-on (macOS LaunchAgents):
For a server that survives logout, reboot, and crashes, generate + load the LaunchAgents in one command (after the Quick start above is working):
git clone https://github.com/jordanaftermidnight/localmem.git ~/localmem-source 2>/dev/null
python3 ~/localmem-source/deploy/setup-launchd.py --load
launchctl list | grep localmem
Three services come up: com.localmem.serve (:8781), com.localmem.dashboard
(:8782), com.localmem.frontend (:8785). All have RunAtLoad=true and
KeepAlive=true — they auto-start on login and respawn on crash. Combined
with Docker Desktop's "start on login" + --restart unless-stopped on the
Qdrant container (see docs/DEPLOY.md when written), the
stack runs entirely headless.
Working from source (contributing or pinning a specific commit):
git clone https://github.com/jordanaftermidnight/localmem.git
cd localmem
python3.13 -m venv .venv && source .venv/bin/activate
pip install -e '.[dev,dashboard,analytics]'
MCP tools
| Group | Tool | Purpose |
|---|---|---|
| Memory (6) | localmem_store, localmem_search, localmem_retrieve, localmem_update, localmem_pin, localmem_unpin |
Entry CRUD + hybrid search |
| Graph (5) | localmem_graph_add_node, localmem_graph_add_edge, localmem_graph_query, localmem_graph_neighbors, localmem_graph_communities |
Behavioral pattern graph |
| Knowledge (3) | localmem_triple_assert, localmem_triple_query, localmem_triple_contradictions |
Temporal triples with contradiction detection |
| System (3) | localmem_wake, localmem_health, localmem_metrics |
Layered wake-up + observability |
| Intelligence (3) | localmem_intel_detect, localmem_intel_alerts, localmem_intel_report |
Pattern detection (opt-in via config) |
| Operations (2) | localmem_prune, localmem_archive |
Retention triggers |
Storage stack
- Qdrant — embedded by default (path-backed,
single-writer). Switch to a remote Qdrant via
storage.qdrant_mode: serverstorage.qdrant_urlto unblock live embedding migrations and multi-process writers.
- NetworkX — in-process directed multigraph with multi-hop traversal and Louvain community detection.
- SQLite (WAL) — temporal triples, agent diaries, wing/room taxonomy, importance scoring with time-decay.
Configuration
localmem.yaml at the repo root is the single source of truth. The shipped
defaults run locally with zero edits — set wings: to name your agents and
you're done. See inline comments for every section. Highlights:
wings: [list]— your agent namespaces.sharedis implicit.embedding.model—all-MiniLM-L6-v2(384d, fast) or BGE-large (1024d, quality). Switch live withlocalmem migrate-embeddings --to <model>.retention.enabled: true— opt in to the three-tier lifecycle.dashboard.auth_enabled: true+ bearer key for remote dashboard access.intelligence.detectors.*— each pattern detector is off until you point it at a specific wing/room (or node selector for the graph cluster detector). Nothing runs you didn't ask for.
Any string value supports ${VAR} or ${VAR:-default} env-var
interpolation, so secrets stay out of YAML on disk.
Dashboard
A read-only browser UI under dashboard/ (Vite + React + dockview). 10
panels: Health, Entries, Metrics, Alerts, Graph, Wings/Rooms, Triples,
Diaries, Logs, Admin. Pin/unpin and lifecycle triggers live in Admin.
Localhost-only by default; flip on bearer auth to expose it remotely.
Observability
localmem healthandlocalmem_healthMCP tool — per-wing entry counts, store connectivity, embedding device, retention worker status.localmem_metricsMCP tool — per-tool call counts, p50/p95/p99 latency, error counts (rolling window)./metricsPrometheus exposition endpoint on the dashboard sidecar (text/plain; version=0.0.4). See docs/DASHBOARD.md for the metric reference and example scrape config.- Structured logging (text or JSON) with optional
RotatingFileHandler. See docs/LOGGING.md for Loki + Promtail and ELK + Filebeat shipping configs.
Deployment
deploy/ contains installer scripts for the three major platforms — each
generates a config dir, sets up a service (systemd / launchd / Scheduled
Tasks), and writes an api_key to a perms-restricted env file:
deploy/setup-ubuntu.sh --auth --qdrant-server http://qdrant:6333
deploy/setup-macos.sh --auth
deploy/setup-windows.ps1 -Auth
Documentation
docs/ARCHITECTURE.md— full specificationdocs/DASHBOARD.md— dashboard panels, auth, metricsdocs/LIFECYCLE.md— retention / consolidation / archivedocs/MIGRATIONS.md— schema and embedding migrationsdocs/LOGGING.md— log shipping recipes
Project layout
localmem/
├── src/localmem/ # Package source
├── dashboard/ # React + dockview frontend
├── deploy/ # Installers + service units
├── docs/ # Architecture, dashboard, lifecycle, migrations, logging
├── manifests/ # Per-agent wake-up manifests
├── tests/ # 300+ tests
├── localmem.yaml # Default configuration
└── pyproject.toml
Known issues
- Python 3.14 + Apple Silicon + sentence-transformers: the
lokyprocess pool used by sentence-transformers can crash silently at shutdown on Python 3.14 / arm64 macOS. Python 3.13 and earlier are unaffected. Either use Python 3.13 (verified end-to-end on this build) or switch to the sparse-only retrieval path viaembedding.model: "Qdrant/bm25".
License
MIT. See LICENSE.
Metadata
Release files for localmem 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| localmem-0.1.2.tar.gz | 502.2 kB | With provenance | Details for localmem-0.1.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| localmem-0.1.2-py3-none-any.whl | Python 3 | none | any | Details for localmem-0.1.2-py3-none-any.whl |
Total release size: 591.0 kB
Release files / localmem-0.1.2.tar.gz
| Download URL | localmem-0.1.2.tar.gz |
|---|---|
| Size | 502.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c10a9ba1b3a08890f182bfdaf9179759a6cbd6c90c07a023453641b89e8e3e18
|
|
BLAKE2b-256 checksum How to use checksums |
6643956c0cc00b4e160348c862e292880682a3f284f99bcfb5331024b88d4366
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 28, 2026.
Transparency logRelease files / localmem-0.1.2-py3-none-any.whl
| Download URL | localmem-0.1.2-py3-none-any.whl |
|---|---|
| Size | 88.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e68a5517bfb961b5b684c2b7c5510886dfa8a3879c112f11f018adb41c563c5a
|
|
BLAKE2b-256 checksum How to use checksums |
2c71547dc154253962386b32f80dc0ebe8ce983f6f6be27d1b53c1027206042c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 28, 2026.
Transparency logSecurity for localmem 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for localmem-0.1.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 28, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.