SDK quickstart
Install the universal TypeScript SDK, store one memory, and recall it.
Install
Use the package manager for your runtime:
npm install @fishmem/sdk
# or: pnpm add @fishmem/sdk
# or: bun add @fishmem/sdkDeno imports the same npm package:
import { FishMem } from "npm:@fishmem/sdk";Create a client
Keep API keys on the server. Cloud keys begin with fm_.
import { FishMem } from "@fishmem/sdk";
const fishmem = new FishMem({
apiKey: process.env.FISHMEM_API_KEY!,
});For a self-hosted deployment:
const fishmem = new FishMem({
apiKey: process.env.FISHMEM_API_KEY!,
baseUrl: "https://memory.example.com",
});Store a memory
Every write must have at least one scope: user_id, agent_id, or run_id.
Use an idempotency key when a write may be retried.
const added = await fishmem.memories.addAndWait(
{
content: "Alex prefers concise answers with runnable examples.",
user_id: "alex",
metadata: { source: "onboarding" },
},
{ idempotencyKey: "alex-answer-style-v1" },
);
console.log(added.results[0]);With the default infer: true, FishMem queues a durable task, calls the
configured LLM once in the worker, and stores only refined canonical records.
addAndWait polls the Event API for this example. Use addAsync when your
application wants the event_id immediately, or events.wait(event_id) when
you persist the receipt yourself.
Use memories.add({ ..., infer: false }) when content is already distilled
or must be stored verbatim with zero LLM calls; that path returns synchronously.
Recall it
Search with the same scope used on write:
const { results } = await fishmem.memories.search({
query: "How should I answer Alex?",
user_id: "alex",
top_k: 5,
});
const context = results.map((item) => `- ${item.memory}`).join("\n");Never put a FishMem API key in browser code, a public environment variable, or a client-side bundle. Call FishMem from your server, Worker, or edge function.