Developers · 10 of 11

Verify and build one

5 min

The reference packer, reader and verifier live in the engine package, @memoresse/engine (src/mem/memFile.ts). It exports MEM_VERSION ("1.0"), MEM_MIMETYPE, buildMemArchive, readMemArchive, verifyMemArchive, toManifest, computeManifestHash and manifestHashBytes (the 32-byte digest to hand to OpenTimestamps). It uses Web Crypto and one archive dependency, so it runs in Node 18+ and the browser.

Verify

import { verifyMemArchive } from "@memoresse/engine";

const bytes = new Uint8Array(await file.arrayBuffer());
const r = await verifyMemArchive(bytes);
// r.ok              every embedded asset re-hashes to its contentHash,
//                   and the manifest hash recomputes
// r.manifestHashOk  the package-level hash
// r.assets[]        { id, ref, embedded, hashOk }  (linked: hashOk null)
// r.anchor          { present, proofEmbedded, targetsManifestHash, status } | null

ok is false if any embedded asset fails its hash or the manifest hash does not recompute. Linked assets report hashOk: null because their bytes are not in the file; fetch and re-hash them yourself.

Read

import { readMemArchive } from "@memoresse/engine";

const reader = await readMemArchive(bytes);
reader.manifest.package.title;
reader.manifest.assets.map((a) => a.description);
await reader.getAssetBytes("media/<sha256>.jpg");
await reader.getAnchorProof();   // the .ots bytes, or null

Build

import { buildMemArchive } from "@memoresse/engine";

// pkg: a MEMPackage. resolveBytes: (asset) => Promise<Uint8Array | null>.
// Options: tier, profile, externalLocator, anchor, retrieval,
// presentation, redactDeclaredEmotion.
const { bytes, manifest } = await buildMemArchive(pkg, resolveBytes, {
  tier: "portable",
  profile: "bundled",
});

buildMemArchive takes a package, a function that resolves each asset’s bytes (from disk, a blob, a fetch, or null for a transcript-only asset), and options. tier defaults to portable and profile to bundled. externalLocator links some assets instead of embedding them. anchor folds in an OTS proof you obtained by stamping manifestHashBytes. redactDeclaredEmotion drops the owner’s note and sensitive contexts. toManifest is the same projection without the packing step.

Give an agent the memory

The format is meant to be built on, and there is a working example. In examples/memorial-site in the MEM repo, an SDK seed (sdk/mem.mjs, zero dependencies) turns an opened memory into pure data projections, and an MCP server (mcp/server.mjs, about ninety lines) exposes the same projections as tools any MCP client can call:

open_mem            title, summary, themes, who is in it, the provenance hash
get_emotional_arc   every dated moment in order with its weight: the shape
get_people_graph    roles and closeness (the file carries roles, not names)
get_timeline        day-level segments, each with its moments
get_themes          themes across the whole memory, by frequency
get_transcripts     the spoken-word corpus
list_media          each moment's media URL (linked profile)

Register it in Claude Code and ask the agent to open your memory and build a photo-book page; it calls get_timeline and get_emotional_arc itself. The example’s build.mjs does the same thing by hand and generates a living-memorial site without touching the schema, only the SDK. The chain is: a .mem file, the SDK projections, MCP tools, any agent building any app. It is an example, not a published package yet; chapter 10 says what is planned.