Skip to main content

A privacy-first, scope-isolated local memory store for AI agents, with a CLI and an MCP server.

Project description

Memory Unlocked

A privacy-first, scoped local memory for AI agents. Memory Unlocked gives agents durable, project-scoped memory without leaking secrets or letting one project's context bleed into another.

It is installable today as a dependency-free Python package with:

  • durable local JSONL and SQLite stores,
  • a practical CLI (memory-unlocked),
  • a dependency-free MCP stdio server (memory-unlocked-mcp),
  • lifecycle/governance commands for candidate review, archival, and forgetting,
  • token-budgeted context assembly and offline recall/privacy evals,
  • a deterministic semantic graph layer for typed agent context,
  • audit events for writes, recalls, updates, forgets, and rejections,
  • tests and CI for the privacy/scope guarantees.

The core stays deliberately small so teams can audit it, ship it locally, and adapt it to their own database, vector index, or hosted service later.

v1 local-isolation contract: every installation starts with an empty local store. It does not include sample memories, connect to a maintainer database, or share data with any other installation. Each user owns their own JSONL/SQLite files. See the student quickstart.


Why this exists

Long-running agents need to remember things between sessions — decisions, conventions, gotchas, references. But naive "just dump everything into a vector store" memory has two failure modes:

  1. Secret leakage — credentials, tokens, customer data, and PII end up persisted and later surfaced in unrelated contexts.
  2. Scope bleed — memory from Project A contaminates answers about Project B.

Memory Unlocked treats both as first-class concerns. Every memory is scoped to a namespace, every write passes a redaction/policy gate, and recall is filtered by scope before anything reaches the model.


Who it is for

  • Builders of multi-project agent systems who need isolated memory per scope.
  • Teams that want auditable, reviewable writes instead of a black-box store.
  • Anyone who wants a readable reference architecture they can port to their own database, vector index, or MCP server.

Quickstart

pipx install memory-unlocked
# or: uv tool install memory-unlocked

From source:

git clone https://github.com/josenaicipa/memory-unlocked.git
cd memory-unlocked
python -m pip install -e '.[dev]'
python -m pytest -q

Write and recall a memory from the CLI:

memory-unlocked --path ./mem init
memory-unlocked --path ./mem write \
  --tenant acme --project billing \
  --title "Refunds run through the async queue" \
  --body "Refund requests are enqueued and processed by a worker, not inline." \
  --source docs/refunds.md \
  --tags billing,architecture
memory-unlocked --path ./mem context \
  --tenant acme --project billing --query refund --token-budget 200

Review candidate memories and run governance/eval checks:

memory-unlocked --path ./mem write \
  --tenant acme --project billing \
  --title "Candidate fact" --body "Needs human approval." \
  --source docs/review.md --status candidate
memory-unlocked --path ./mem review --tenant acme --project billing
memory-unlocked --path ./mem audit --json
memory-unlocked eval examples/evalset/basic.json

Use SQLite for a more production-like local backend:

memory-unlocked --backend sqlite --path ./mem-sqlite init
memory-unlocked --backend sqlite --path ./mem-sqlite doctor

Extract semantic graph context and the public-safe graph reports:

memory-unlocked --path ./mem write \
  --tenant acme --project billing \
  --title "Graph demo" \
  --body "Billing service owns refunds. Worker depends on Redis." \
  --source docs/graph.md
memory-unlocked --path ./mem graph-context \
  --tenant acme --project billing --token-budget 200
memory-unlocked --path ./mem graph-temporal \
  --tenant acme --project billing --json
memory-unlocked --path ./mem graph-lineage \
  --tenant acme --project billing --json
memory-unlocked --path ./mem graph-effective-backend \
  --tenant acme --project billing --json

The extra graph reports are read-only and public-safe: graph-lineage emits opaque handles instead of raw memory ids/source refs, graph-temporal derives relation validity from source-memory timestamps, and graph-effective-backend returns the scoped graph as the canonical memory_unlocked backend payload for agent/MCP consumers.

Run the MCP server for an agent runner:

MEMORY_UNLOCKED_TENANT=acme \
MEMORY_UNLOCKED_PROJECT=billing \
MEMORY_UNLOCKED_HOME="$HOME/.memory_unlocked" \
  memory-unlocked-mcp

Use the core package directly:

from memory_unlocked import (
    Memory, Source, Namespace, MemoryStore, ContextAssembler, PolicyError,
)

store = MemoryStore()

store.add(Memory(
    namespace=Namespace("acme", "billing"),
    title="Refunds run through the async queue",
    body="Refund requests are enqueued and processed by a worker, not inline.",
    source=Source(kind="doc", ref="docs/refunds.md"),
    tags=["billing", "architecture"],
))

# Recall is scope-filtered: only memories in the requested namespace come back.
assembler = ContextAssembler(store)
context = assembler.assemble(Namespace("acme", "billing"), query="refund")
print(context)

Writes that contain obvious secrets, or that lack a verifiable source, are rejected at the gate:

store.add(Memory(
    namespace=Namespace("acme", "billing"),
    title="API key",
    body="AWS_SECRET_ACCESS_KEY=AKIA...",   # raises PolicyError
    source=Source(kind="doc", ref="notes.md"),
))

Core concepts

Concept What it is
Memory One atomic fact, with a title, body, tags, and a required source.
Source Provenance for a memory (a file, URL, ticket, or run id). No source → no write.
Namespace A tenant / project scope. Recall never crosses namespaces.
Policy / redaction A gate every write passes before it is stored.
Context assembler Builds a scope-filtered, ranked context block for the agent.
Event An append-only record of writes and recalls for auditability.

Privacy-first guardrails

These are the defaults, not opt-ins:

  • Never store secrets. Writes are scanned for credential-shaped content and rejected. See docs/privacy-and-redaction.md.
  • Every memory needs a source. Unattributed claims are rejected so memory stays verifiable.
  • Scope isolation by default. A recall in tenant/project cannot return a memory written under any other scope.
  • No raw transcripts, no PII, no customer/lead data. Store durable, stable facts — not transient progress or personal information.
  • Writes are reviewable. Every write and recall emits an event so you can audit what the memory fabric learned and surfaced.

Documentation


License

MIT — see LICENSE.

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

memory_unlocked-1.0.0.tar.gz (79.7 kB view details)

Uploaded Source

Built Distribution

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

memory_unlocked-1.0.0-py3-none-any.whl (53.8 kB view details)

Uploaded Python 3

File details

Details for the file memory_unlocked-1.0.0.tar.gz.

File metadata

  • Download URL: memory_unlocked-1.0.0.tar.gz
  • Upload date:
  • Size: 79.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for memory_unlocked-1.0.0.tar.gz
Algorithm Hash digest
SHA256 9aaf95e374b57a4706431e29a0e8bdf5c4411bba15861d3f1beaa4a0c7cea0da
MD5 3dca51786fd03d34122f7f0cb8b7e36a
BLAKE2b-256 1d17cb37161977d833ec28bd7382e567936b38053b309d8ecac94d5690cf48d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for memory_unlocked-1.0.0.tar.gz:

Publisher: publish.yml on josenaicipa/memory-unlocked

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file memory_unlocked-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: memory_unlocked-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 53.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for memory_unlocked-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4c555396a024999551a6c4ea90b672d9e41f8dfbc4df3392b6a42aa39bc26c34
MD5 b60a651bdce283280b226078e3bf9eb5
BLAKE2b-256 9597d556a0b8932be7c59c9f110520a8f35ca31be962c931546f0dd101e36a7b

See more details on using hashes here.

Provenance

The following attestation bundles were made for memory_unlocked-1.0.0-py3-none-any.whl:

Publisher: publish.yml on josenaicipa/memory-unlocked

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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