Skip to main content

memstrand

PyPI Python License: MIT

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.

30-second demo

No Docker. No server. No LLM. pip install is the entire setup:

from memstrand import Category, Memory, Provenance

mem = Memory.in_memory()

# A fact scoped to one task...
mem.remember(
    "Playwright installed as an agent-testing task dependency",
    category=Category.fact,
    provenance=Provenance.explicit_statement,
    task_id="playwright-test",
)

# ...and a global preference
mem.remember(
    "Chiran prefers a natural, unstylized look in AI portraits",
    category=Category.preference,
    provenance=Provenance.explicit_statement,
    confidence=0.95,
)

# An unrelated session asks about testing setup.
# The Playwright fact does NOT leak across the task boundary:
for hit in mem.recall("testing setup"):
    print(hit["category"], "-", hit["content"])
# preference - Chiran prefers a natural, unstylized look in AI portraits

# Same query WITH the task scope sees it:
for hit in mem.recall("testing setup", task_id="playwright-test"):
    print(hit["category"], "-", hit["content"])
# fact - Playwright installed as an agent-testing task dependency

Typed. Scoped. Provenance on every atom. The hot path (remember/recall) never touches an LLM — embeddings are local ONNX, the graph is embedded Kuzu, sessions are SQLite.

Why

Flat vector memory has three failure modes, and every agent hits all three:

  1. No types — a preference, a decision, and a guess all look the same to cosine similarity.
  2. No scope — a fact learned while testing Playwright leaks into an unrelated Mac disk-cleanup session. (This actually happened. It's why this exists.)
  3. 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).

Persistent setup

in_memory() is ephemeral — data dies with the process. For real use:

docker compose up -d          # Qdrant (vectors); Kuzu + SQLite are embedded, zero setup
pip install memstrand
mem = Memory()  # Docker Qdrant + on-disk Kuzu/SQLite

For the session-distillation pass (mem.improve()), point at any OpenAI-compatible local endpoint:

export MEMSTRAND_LLM_BASE_URL=http://localhost:8081/v1

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.

How it compares

memstrand Mem0 Cognee raw vector RAG
Local-first, no API keys ✅ OSS self-host option ✅ ✅
Typed memory schema ✅ 13 categories ✅ notes ✅ ontology ❌
Scope enforcement (hard filter) ✅ ❌ ❌ ❌
Graph + vector joint writes ✅ ✅ ✅ ❌
Contradictions as edges, not deletes ✅ ❌ ✅ ❌

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 (needs local LLM)
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):

  1. Remember me in a brand-new chat without re-pasting anything.
  2. Search by meaning, not keywords.
  3. 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.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for memstrand 0.1.2
File Size Uploaded
memstrand-0.1.2.tar.gz 20.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for memstrand 0.1.2
File Interpreter ABI Platform
memstrand-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 44.5 kB

Release files / memstrand-0.1.2.tar.gz

Download URL memstrand-0.1.2.tar.gz
Size 20.9 kB
Tags Source
SHA-256 checksum
How to use checksums
636299fb564d8c91e5ec92da107844cb244a2d2b275244abe174184a45b3b8a6
BLAKE2b-256 checksum
How to use checksums
2d87571c7a1fe271af9054233301a3af4cb4c46f8729a7dc3f5b10e46f46e52a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / memstrand-0.1.2-py3-none-any.whl

Download URL memstrand-0.1.2-py3-none-any.whl
Size 23.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
11680797136a853409cfb313f375eeda786ab90e1028b531089781d741620578
BLAKE2b-256 checksum
How to use checksums
059cc1cb1e30536451e0e2167d7d2d213a1ce2a92b2665ac3c330f4852b3708f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

0.2.1

2 release files

0.2.0

2 release files

0.1.3

2 release files

This release

0.1.2 This release

2 release files

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page