SDKsTypeScript

TypeScript SDK

pnpm add @mnemosyne/client-ts

Construct

import { MnemosyneClient } from "@mnemosyne/client-ts";
 
const mnemo = new MnemosyneClient({
  baseUrl: "http://localhost:3000",
  apiKey: process.env.MNEMO_KEY!,
  // optional — defaults below
  fetch: globalThis.fetch,
  retries: { max: 3, baseMs: 200 },
});

The five tools

// Recall
const { hits, debug } = await mnemo.recall({
  query: "coffee preferences",
  topK: 3,
});
 
// Remember
const fact = await mnemo.facts.create({
  content: "user prefers espresso",
  tags: ["coffee"],
});
 
// Forget
await mnemo.facts.forget(fact.id, { reason: "user said they switched to tea" });
 
// Pin
await mnemo.facts.pin(fact.id, { pinned: true });
 
// Timeline
const timeline = await mnemo.timeline({
  from: new Date(Date.now() - 7 * 86400_000),
  to: new Date(),
  types: ["event", "episode"],
});

Streaming pagination

for await (const fact of mnemo.facts.list({ pageSize: 100 })) {
  console.log(fact.id, fact.content);
}

The iterator handles cursor-based paging transparently — no manual cursor juggling.

Typed errors

import { MnemoConflictError, MnemoRateLimitError } from "@mnemosyne/client-ts";
 
try {
  await mnemo.facts.create({ content: "redis is at 6.2" });
} catch (e) {
  if (e instanceof MnemoConflictError) {
    console.log("Conflicting fact:", e.conflicts[0].id);
  } else if (e instanceof MnemoRateLimitError) {
    await wait(e.retryAfterMs);
  } else {
    throw e;
  }
}

Idempotency

await mnemo.facts.create(
  { content: "user prefers espresso" },
  { idempotencyKey: crypto.randomUUID() },
);

Same key + same body within 24h returns the cached response.

Embedded usage

If you don’t want the network hop, use @mnemosyne/core directly — same method names, in-process function calls.

import { createMnemoClient, createDrizzleStorage } from "@mnemosyne/core";
 
const mnemo = createMnemoClient({
  storage: createDrizzleStorage({ databaseUrl: process.env.DATABASE_URL! }),
});
 
await mnemo.recall({ workspaceId: "demo", query: "coffee" });

The @mnemosyne/client-ts and @mnemosyne/core clients are API-compatible. You can switch from in-process to over-the-wire (or vice versa) without rewriting your code.

@mnemosyne/client-ts is ESM-only and runs on any modern JS runtime — Node, Bun, Deno, Cloudflare Workers, and browsers. (@mnemosyne/core, the in-process client, needs a direct Postgres connection and is server-side only.)