memstrand
Local-first typed memory for AI agents. Zero API keys.
Two strands, like DNA: one strand holds facts (vectors), the other holds relationships (graph). Every write joins them base-pair by base-pair — a memory is never stored without its connections, and never retrieved without its scope.
pip install memstrand → remember() → recall() → done. Everything runs on your machine: no cloud, no keys, no telemetry.
Why
Flat vector memory has three failure modes, and every agent hits all three:
- No types — a preference, a decision, and a guess all look the same to cosine similarity.
- No scope — a fact learned while testing Playwright leaks into an unrelated Mac disk-cleanup session. (This actually happened. It's why this exists.)
- No provenance — nobody knows whether a memory was said, inferred, or corrected, or how confident the agent was.
memstrand fixes all three: every memory is typed (13 categories), scoped (session/task/host), and carries provenance (how it was learned, confidence, expiry).
Quickstart
docker compose up -d # Qdrant (vectors); Kuzu + SQLite are embedded, zero setup
pip install memstrand
export MEMSTRAND_LLM_BASE_URL=http://localhost:8081/v1 # any OpenAI-compatible local endpoint
from memstrand import Memory, Category
mem = Memory()
mem.remember(
"Chiran prefers a natural, unstylized look in AI portraits",
category=Category.preference,
provenance="explicit_statement",
confidence=0.95,
)
for hit in mem.recall("what do I know about portrait preferences?"):
print(hit.content, hit.score)
Architecture
Seven layers, deterministic write routing, scoped retrieval:
| Layer | What lives there | Scope |
|---|---|---|
| L0 working | live transcript + task/host scope; outranks everything | task |
| L1 session cache | fast raw Q&A, no extraction, TTL'd | session |
| L2 episodic | distilled session learnings | task + host |
| L3 semantic | typed facts, vector-embedded | global |
| L4 consolidated | curated cross-session synthesis | global |
| L5 graph | typed edges over everything above | global |
| L6 procedural | action sequences, workflow patterns, lessons | global |
Write path (the session-commit loop): during a session, writes land in L1 with zero extraction cost. At session end (or pre-compact hook), an async distillation pass extracts Memanto-typed atoms via your local LLM, dedups by content hash, checks for conflicts — contradictions become contradicts edges, never deletions — and promotes into L2/L3/L5.
Read path: scope filter first (session/task/host is a hard filter, not a ranking signal), then tiered abstracts before full content, graph traversal for multi-hop, and a grounded_answer() primitive that answers only from stored memory.
Memory dynamics (stolen fair and square, see below): per-fact FSRS strength with a review queue, Hebbian edge weights (use strengthens, disuse decays), and replay consolidation that prunes weak edges but never facts.
API
mem.remember(content, category=..., provenance=..., confidence=..., ttl_days=...)
mem.recall(query, session_id=..., task_id=..., limit=...) # scope-aware
mem.improve(session_ids=[...]) # distill sessions → permanent memory
mem.forget(memory_id) # provenance-chain cleanup, never silent
mem.grounded_answer(question) # answer ONLY from stored memories
MCP server included: python -m memstrand.mcp_server exposes the same surface to Claude Code, Cursor, and friends over stdio.
Acceptance test
Any memory system should pass these three before you trust it (rubric adapted from a Cognee ad, because it was right):
- Remember me in a brand-new chat without re-pasting anything.
- Search by meaning, not keywords.
- Connect facts across sessions — and don't leak facts across unrelated tasks (the Playwright test).
Acknowledgments
Standing on shoulders, with credit:
- Memanto (moorcheh-ai/memanto) — the 13-category typed schema, provenance, and confidence model. Their product is cloud-only; this is the schema reimplemented local-first.
- Cognee (topoteretes/cognee) — the pipeline patterns: fast session cache → distillation, joint graph+vector writes, contradictions as additive edges.
- ZenBrain (zensation-ai/zenbrain) — per-fact FSRS, deterministic write routing, replay consolidation, Hebbian edges.
- Mem0 — the ADD/UPDATE/DELETE/NONE extraction resolution pattern.
Roadmap
- Schema + store interfaces + scaffold
- Session-commit distillation loop (extract → dedup → judge → promote)
- Scoped retrieval (task/host hard filters; unscoped queries see globals only)
- Graph neighbor hydration + Hebbian strengthen/decay
- FSRS + replay consolidation pass (math is in
pipeline/consolidate.py, not yet scheduled) - MCP server tools (remember/recall/forget)
-
memstrand import— adopt an existing Markdown memory file - Benchmarks: the 3-test rubric, automated (
tests/test_memory_flow.py)
License
MIT — see LICENSE.
Metadata
Release files for memstrand 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| memstrand-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / memstrand-0.1.0-py3-none-any.whl
| Download URL | memstrand-0.1.0-py3-none-any.whl |
|---|---|
| Size | 22.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
44fedc5bd5709dadcc0125e99b8e887ec6b196128455946d006fb09cc1d767be
|
|
BLAKE2b-256 checksum How to use checksums |
41779ac87b6bd6a9b7b5c129d26c21a87604d72e5c81a21cea027098565b79ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|