Encrypted · portable · offline

Own your AI memory.

Import a chat export or your notes, search it locally, seal it into an encrypted .keepsake vault, and let any agent recall it over MCP. No server, no account, no network call.

bunx github:srivtx/keepsake#main --help

Run it once with Bun, or install the keepsake binary with the one-line script. It is not on npm.

keepsake
$ keepsake import notes.md export.json --out memory.keepsakesealed 5 cell(s) into memory.keepsakemerkle  230b272ae6653e4619e67e37f616eb9d56c0d7482ebf4a3ef9ceac97a174f895$ keepsake search "staging database" --vault memory.keepsake1. [json · assistant · 2026-09-20T13:21:37.431Z]  #demoNoted: the staging database is cart-staging, reset nightly.

Browser app

Import, search, seal, and open a vault without leaving the page. Everything runs in this tab; nothing is uploaded.

Local only

Runs entirely in your browser. Nothing is uploaded.

Import

A chat export, a notes file, or a few lines. A ChatGPT conversations.json is recognized automatically. A memory-pack.md pack is verified against its hashes and Merkle root before its cells are imported.

No cells imported yet.

Search

Exact, lexical BM25 ranking by default, with optional on-device embeddings you can load in card 6. The keepsake/v1 file itself stores no embeddings.

Import something, then search it.

Seal a vault

AES-256-GCM under a PBKDF2-SHA256 key, then a download of YYYY-MM-DD-keepsake.keepsake. The passphrase is never stored.

Nothing sealed yet.

A memory pack is a different, lossless Markdown copy of the cells for another tool. It is plaintext and not encrypted — anyone who has the file can read it.

No memory pack downloaded yet.

Open a vault

Pick a .keepsake file and its passphrase. A wrong passphrase fails the authentication tag and reports an error.

No vault opened.

Context pack

A task-scoped, token-budgeted Markdown projection of the cells. Built in memory and never written to disk.


                  

Import something, then build a pack.

Semantic recall

Rank cells by meaning, not just exact words. The model is self-hosted on this site (about 23 MB, downloaded once), runs entirely in your browser, and no memory or query ever leaves the machine.

On-device model

Model not loaded. Lexical BM25 search works without it.

Embeddings are rebuilt in the background after an import, a forget, or an opened vault. They never leave this tab and are never written to a vault.


Integrity

No cells yet.

Search results

No search run yet.

Cells

No cells forgotten.

Stats

How it works

Seven steps, all on your machine. The vault is a file you can copy, back up, and hand to another tool.

Import
A chat export, a notes file, or free text becomes cells. One message, note, or line is one cell with a stable id and a content hash.
Search
Recall is exact and lexical over the plaintext you hold. Version 0.1 has no embeddings and no model inference.
Context pack
A task-scoped, token-budgeted Markdown projection of the matching cells. Built in memory for an agent and never written to disk.
Forget
Cells matching a query, tag, source, or id are dropped, and the vault is rewritten from what remains.
Seal
The cells are canonicalized, encrypted with AES-256-GCM under a PBKDF2-SHA256 key, and written to one .keepsake file.
Memory pack
A plaintext, lossless, agent-readable Markdown projection you can hand to another tool and import back. It is not encrypted.
Recall
Any MCP-capable agent opens the vault over stdio and reads the cells in process. No server holds the only copy.

The format in brief

A memory is a Cell; a vault is one JSON file that holds the cells sealed, plus a Merkle root committing to the exact plaintext.

{
  "format": "keepsake/v1",
  "createdAt": "2026-03-01T12:00:00.000Z",
  "cells": 3,
  "kdf": { "name": "PBKDF2-SHA256", "iterations": 250000, "salt": "…base64…" },
  "cipher": { "name": "AES-GCM", "iv": "…base64…" },
  "ciphertext": "…base64, includes the 16-byte GCM tag…",
  "merkle": "4e540078fb922de39e689dcf86a9828e4e274986fd6fe5a03da2333724c96d2d"
}
Cell
An id, text, source, role, timestamp, tags, and a SHA-256 hash over the canonical payload. Text is UTF-8, normalized to NFC, and must be non-empty.
Canonical JSON
Object keys sorted by code point, no insignificant whitespace. The exact bytes that are hashed and encrypted, so two implementations agree.
Merkle root
A SHA-256 hash tree over the sorted cell hashes. It commits to the set of cells and does not depend on their order.
Vault
Seven members: format, createdAt, cells, kdf, cipher, ciphertext, and merkle. Transport is the file itself.

Read the normative format specification for the byte-level rules.

Documentation

The landing page is the pitch. The details live on four short pages.

Spec
The normative keepsake/v1 format: the Cell, canonical JSON, hashing, the Merkle root, the vault container, and the KDF and AEAD parameters.
Usage
Install, the CLI commands, the passphrase rule, exit codes, and the MCP server configuration.
Conformance
The three conformance levels, run in your browser against the published test vectors.
FAQ
Scope, security posture, honest limits of version 0.1, and the roadmap.