@takk/mnemosyne
v1.0.0
Published
Persistent, portable, shared memory for Massive Intelligence (IM) agents: pluggable stores, a deterministic 256-dimensional identity seed that stays stable across model swaps, masking and residency, and Ed25519-signed, SHA-256-chained tamper-evident acces
Maintainers
Readme
Mnemosyne
Open, local-first, portable memory for Massive Intelligence (IM) agents. Give a pool of agents one persistent, shared memory, with pluggable stores, a deterministic 256-dimensional identity seed that stays stable across model swaps, field-level masking and data residency, and Ed25519-signed, SHA-256-chained tamper-evident access logs, all running on your own infrastructure with your own keys.
Mnemosyne is the open memory layer for non-human entities, delivered as a zero-runtime-dependency NPM library that runs in your process, not someone else's. Context today is fragmented: every agent has its own short memory, state is lost at the handoff between agents, and a persona drifts over a long session and breaks the moment you swap the model. The market answer so far is to either bolt memory into one closed agent runtime that you cannot inspect or carry, or pin checkpoints to a single framework you then cannot leave. Mnemosyne takes the third path: a pluggable store any agent shares, a memory that is versioned, content-addressed, and inspectable, and an identity that projects to the same vector byte for byte no matter which model is answering. Your agent's identity seed is identical under GPT or Claude, a deterministic persona fingerprint that never depends on the model, so you can prove the identity you configured is unchanged. The fingerprint tracks the persona definition, not the model's behavior: it certifies the identity seed survived the swap, it does not assert that a different model will respond the same way.
Core promise: zero required runtime dependencies, two-line setup, a pluggable store so the same memory runs in-memory, on the edge, or on disk without a line of caller change, a deterministic 256-dimensional identity seed that is stable across model swaps and whose persona-definition drift is measurable rather than assumed, field-level masking with redact, hash, and partial plus a residency tag, a tamper-evident SHA-256 audit chain and Ed25519-signed snapshots over Web Crypto, a node-free core that runs in Node, edge runtimes, and the browser, ESM plus CJS dual distribution, and memory exposed as a Model Context Protocol resource with no hard dependency.
Why Mnemosyne
Shared memory for a pool of agents is a state problem with a portability constraint. You want every agent to read and write one durable memory, and you want an entity's identity to stay fixed as the model behind it changes, without locking that memory inside an endpoint or a framework you cannot leave. The two reflexive answers both fail. Baking memory into a closed agent runtime gives you state you cannot inspect, carry, or run on your own infrastructure. Pinning checkpoints to a single framework couples your memory to that framework's lifecycle and shape. Mnemosyne uses the correct primitive: a pluggable store behind one async interface, a namespaced shared context any agent in the pool touches, and a model-independent identity projection, over infrastructure you control.
What sets it apart from a closed memory built into an agent runtime:
- Portable and inspectable. Memory is a plain, versioned, content-addressed record in a store you choose, not a hidden blob behind an endpoint. Export a namespace as a snapshot and move it between infrastructures whenever you want.
- Stable identity across model swaps. A persona projects to a deterministic 256-dimensional vector seeded only by the persona itself, never by a model. Swap the provider and the fingerprint is identical, so the identity holds and any real drift is a measurable cosine distance, not a guess.
- Local-first and sovereign. It runs in your process, on your infrastructure, with your data. The core never reaches the network. It works on the edge and inside the EU, where a closed endpoint may be blocked.
- Masking and residency by construction. Field-level rules redact, hash, or partially mask sensitive data deterministically before it crosses a boundary, and a residency tag travels with the record.
- Provable access. A tamper-evident SHA-256 hash-chained log of every remember, recall, forget, snapshot, and restore, plus Ed25519-signed snapshots, the evidence a review or a regulator asks for.
- Pluggable everywhere. One
MemoryStoreinterface, with an in-memory reference, an edge key-value adapter, a Node file store, and a generic key-value bridge, so the same memory runs anywhere with identical semantics. - MCP-native. Memory is exposed as Model Context Protocol tools and a resource, so any agent runtime can remember and recall through the protocol it already speaks.
Install
pnpm add @takk/mnemosyne
# or: npm install @takk/mnemosyne
# or: yarn add @takk/mnemosyne
# or: bun add @takk/mnemosyneThe core has zero required runtime dependencies. Every @takk sibling is an optional peer; install only what you compose with.
Quickstart
import { Mnemosyne } from "@takk/mnemosyne";
// A pool of agents shares one namespace.
const memory = new Mnemosyne({ namespace: "support-thread" });
// Any agent writes a memory. Writes are versioned and content-addressed.
await memory.remember({ key: "user/name", value: "Ada", kind: "fact", tags: ["profile"] });
await memory.remember({ key: "ticket/intent", value: "refund", kind: "semantic", author: "triage-agent" });
// Any other agent reads it back, no state lost at the handoff.
console.log(await memory.get("user/name")); // "Ada"
// The shared context is the hippocampus of the swarm.
const context = memory.context();
console.log(await context.contributors()); // ["triage-agent", ...]
const window = await context.window({ maxRecords: 20 });
console.log(`${window.records.length} memories fit the budget`);Stable identity across a model swap
The signature feature: a persona projects to the same 256-dimensional identity seed, byte for byte, regardless of the model. Swap providers and the fingerprint does not move. This is a deterministic fingerprint of the persona definition, so it proves the identity you configured is unchanged across the swap; it is not a behavioral guarantee that a different model answers identically, and the cosine distance measures drift in the persona definition, not in model output.
import { definePersona, deriveIdentity, identityDistance } from "@takk/mnemosyne/identity";
import { personaGuard } from "@takk/mnemosyne/adapter";
const persona = definePersona("atlas", {
tone: "precise",
curiosity: 0.8,
domain: "engineering",
});
// Two derivations stand in for the same persona projected under two different models.
const underGpt = await deriveIdentity(persona);
const underClaude = await deriveIdentity(persona);
console.log(underGpt.dimensions); // 256
console.log(underGpt.fingerprint === underClaude.fingerprint); // true
console.log(identityDistance(underGpt, underClaude)); // 0, no drift
// Guard the identity across a swap in one call.
const guard = await personaGuard(underGpt, persona);
console.log(guard.stable, guard.distance); // true 0Pluggable stores
One interface, every runtime. The same Mnemosyne facade runs on each without a caller change.
import { Mnemosyne, InMemoryStore } from "@takk/mnemosyne";
import { fileMemoryStore } from "@takk/mnemosyne/node";
import { edgeKvStore } from "@takk/mnemosyne/edge";
// In memory, the default.
const ephemeral = new Mnemosyne({ store: new InMemoryStore() });
// On disk, local-first and durable across restarts. Single-process: agents sharing this file in one process are
// safe (writes are serialized and atomic); for a concurrent multi-process pool, use kvMemoryStore with a real
// database that provides transactions or locking.
const onDisk = new Mnemosyne({ store: fileMemoryStore("./mnemosyne-store/memory.json") });
// On the edge, over a Cloudflare Workers KV binding (or any lookalike).
const onEdge = new Mnemosyne({ store: edgeKvStore(env.MEMORY_KV) });A MemoryStore is a small async interface, put, get, getByKey, delete, list, and clear. Bring any backend through kvMemoryStore, which adapts a minimal async key-value store and reuses the exact query and ordering semantics of the in-memory reference.
Masking and residency
Redact, hash, or partially mask sensitive fields deterministically before memory leaves a boundary, and stamp a residency tag.
import { maskRecord } from "@takk/mnemosyne/masking";
const policy = {
rules: [
{ match: "value", pattern: "@", strategy: "hash" }, // emails -> stable digest
{ match: "key", pattern: "token", strategy: "partial" }, // keep edges only
{ match: "key", pattern: "ssn", strategy: "redact" }, // remove entirely
],
residency: "eu",
};
const masked = await maskRecord(record, policy);
// masked.value.email === "sha256:..." (the same email always hashes to the same digest)
// masked.residency === "eu"Tamper-evident audit and sealed snapshots
Turn on the audit chain and every access is recorded into a hash-linked log that detects any later edit. Export a namespace as an Ed25519-signed snapshot that moves between infrastructures.
import { Mnemosyne } from "@takk/mnemosyne";
import { verifyChain } from "@takk/mnemosyne/audit";
import { generateSigningKeyPair, verifySnapshotSignature } from "@takk/mnemosyne/signing";
const memory = new Mnemosyne({ namespace: "regulated", audit: true });
await memory.remember({ key: "decision/loan-42", value: "approved", author: "underwriter" });
await memory.recall("decision/loan-42");
const trail = memory.auditTrail();
console.log((await verifyChain(trail)).valid); // true; any tamper flips this to false
const keyPair = await generateSigningKeyPair();
const sealed = await memory.sealedSnapshot(keyPair);
console.log(await verifySnapshotSignature(sealed)); // trueMemory as an MCP resource
Expose remember, recall, and query as Model Context Protocol tools, and the namespace as a readable resource, with no SDK dependency.
import { Mnemosyne } from "@takk/mnemosyne";
import { createMemoryTools, createMemoryResource } from "@takk/mnemosyne/mcp";
const memory = new Mnemosyne({ namespace: "agent-pool" });
const [remember, recall, query] = createMemoryTools(memory);
const resource = createMemoryResource(memory); // uri: mnemosyne://agent-pool
await remember.handler({ key: "fact/1", value: "the sky is blue", kind: "fact" });
const view = await recall.handler({ key: "fact/1" });Entry points
Each subpath is independently importable, so you pull in only what you use. Every entry point is dual ESM and CJS with type definitions.
| Import | What it provides |
| --- | --- |
| @takk/mnemosyne | The node-free barrel: facade, record, store, identity, context, masking, audit, signing, MCP, adapters. |
| @takk/mnemosyne/mnemosyne | The Mnemosyne facade and createMnemosyne. |
| @takk/mnemosyne/record | MemoryRecord construction, validation, and content addressing. |
| @takk/mnemosyne/store | InMemoryStore, matchesQuery, orderRecords. |
| @takk/mnemosyne/identity | The deterministic 256-dimensional persona projection and comparisons. |
| @takk/mnemosyne/context | SharedContext, the budgeted window, and the typed handoff. |
| @takk/mnemosyne/masking | Field-level masking and residency. |
| @takk/mnemosyne/audit | The tamper-evident SHA-256 audit chain. |
| @takk/mnemosyne/signing | Ed25519 snapshot signing over Web Crypto. |
| @takk/mnemosyne/mcp | Memory as MCP tools and a resource. |
| @takk/mnemosyne/adapter | The key-value bridge, the persona guard, and the conversation recorder. |
| @takk/mnemosyne/edge | The edge key-value store, plus the re-exported node-free core. |
| @takk/mnemosyne/node | The file-backed store, the only surface that touches node:fs. |
CLI
# Store a memory, then recall it. Values are parsed as JSON, or kept as strings.
mnemosyne remember user/name Ada --kind fact --tags profile
mnemosyne recall user/name
# Derive the deterministic 256-dimensional identity for a persona.
mnemosyne identity atlas '{"tone":"precise","curiosity":0.8}'
# Export a portable snapshot, then restore it elsewhere.
mnemosyne snapshot --out snapshot.json
mnemosyne restore snapshot.json --store other-store.json
# Generate an Ed25519 signing key pair, and verify a tamper-evident audit chain.
mnemosyne keygen --out key.json
mnemosyne audit-verify chain.jsonThe CLI persists to a Node file store by default (mnemosyne-store/memory.json, overridable with --store or MNEMOSYNE_STORE), so memory written in one invocation is recalled by the next. Exit codes are stable: 0 success, 2 usage error, 10 not found, 20 invalid input, 21 verification failed.
How it works, in one paragraph
A memory is a content-addressed record: its hash is the SHA-256 of its canonical value, so the same value always addresses the same memory. Records live in a namespace, the shared room a pool of agents reads and writes, and each write of a key increments a version while preserving the original creation time. A persona projects to a 256-dimensional vector by seeding an SHA-256 counter-mode expansion with the canonical persona, never with a model, so the projection is byte-for-byte reproducible and the identity seed is stable across model swaps, and drift in the persona definition is a cosine distance you can measure. Masking traverses a value and applies deterministic rules to its leaves, so sensitive data is redacted, hashed, or partially masked before it crosses a boundary. The audit chain hashes each access together with the previous entry's hash, so any edit, reorder, or deletion breaks the linkage. Snapshots are signed with Ed25519 over Web Crypto. Nothing reaches the network; the store is the only thing that persists, and you choose it.
What the examples show
Run any with node examples/<name>.mjs after pnpm build.
remember-and-recallwrites and reads memory with automatic versioning.shared-context-handoffpasses a typed baton between agents with no lost state.stable-identityshows a persona projects to the same identity seed across a model swap.sealed-snapshotexports, signs, moves, and verifies a memory snapshot.masking-and-residencymasks sensitive fields deterministically and tags residency.audited-memoryrecords a tamper-evident access trail and detects a tamper.
The benchmark in benchmarks/memory-benchmark.mjs runs against the built package and reports real numbers: 100% projection determinism, the same persona yields the same fingerprint with zero drift, 100% distinct fingerprints across distinct personas, and the in-memory store throughput.
Quality
- 141 tests across 16 suites, green on Node 20, 22, and 24.
- Coverage 93.92% statements, 85.63% branches, 96.93% functions, 93.79% lines.
- Zero required runtime dependencies. The core is node-free: Ed25519 and SHA-256 run over Web Crypto, never
node:crypto. - Dual ESM and CJS with types for both, validated by
publintandattw, with a per-export size budget enforced bysize-limit. - SLSA provenance attestation on every npm release, published through a two-step, review-required CI/CD flow.
FAQ
Is this a vector database? No. Mnemosyne is the portable memory substrate: a versioned, content-addressed, namespaced store with a deterministic identity. Semantic recall over embeddings is a roadmap item, not a 1.0 feature, and you can layer a vector index on top of any store.
Does it call a model or the network? Never. The core has zero runtime dependencies and makes no network calls. It is memory logic over a store you provide.
How is the identity stable across model swaps? The 256-dimensional vector is seeded only by the canonical persona, through an SHA-256 expansion, so it does not depend on any model. Two derivations of the same persona always produce the same fingerprint, and the distance is exactly zero. To be precise, this is a deterministic fingerprint of the persona definition, not a measurement of model behavior: it proves the identity seed you configured is unchanged across a swap, and the cosine distance detects edits to the persona definition, not whether a different model responds differently under the same persona.
Where does memory actually live? In the store you choose: in memory, an edge key-value namespace, a file on your disk, or any backend you bridge through kvMemoryStore. The library never persists anywhere you did not configure.
Can I run it on the edge? Yes. The core is node-free, so it runs on Cloudflare Workers, Vercel Edge, Deno, Bun, and the browser. The @takk/mnemosyne/edge entry adapts a Workers KV namespace directly.
Contributing
Contributions are welcome. Please read .github/CONTRIBUTING.md and the Code of Conduct. The full gate is pnpm run verify, and changes must stay green on Node 20, 22, and 24.
Community and support
- Issues and feature requests: github.com/davccavalcante/mnemosyne/issues
- Security reports: see SECURITY.md
- Site: takk.ag
Author
David C Cavalcante, Product Engineer, AI Engineer, ML Engineer, LLM Engineer, LLM Architect, and Artificial Intelligence Researcher at Takk Innovate Studio.
- Email: [email protected]
- GitHub: github.com/davccavalcante
- LinkedIn: linkedin.com/in/hellodav
- X: x.com/davccavalcante
Mnemosyne is part of the open multi-agent ecosystem for Massive Intelligence (IM): a transport layer, a verification layer, this memory layer, observability, and cost control, each publishable on its own and designed to compose.
Privacy
Mnemosyne is local-first and node-free. The core makes no network calls and ships no telemetry. Memory lives only in the store you configure, and field-level masking plus residency tagging let you protect sensitive data before it crosses any boundary. See PRIVACY.md.
