Skip to main content

SDK Quickstart

Agent index: llms.txt

Install, initialize, and make your first ingest and search, with MemoryClient wired to a running atomicmemory-core.

Prerequisites

  • Node.js 22+ (FOC/Filecoin storage paths require Node 24+)
  • A running atomicmemory-core, follow the Core Quickstart if you have not yet brought one up; we assume http://localhost:3050 below

Step 1, Install

npm install @atomicmemory/sdk

Also works with pnpm add / yarn add.

Step 2, Initialize

MemoryClient needs one thing: a providers map telling it which memory backend(s) to use and how to reach them.

import { MemoryClient } from '@atomicmemory/sdk';

const memory = new MemoryClient({
providers: {
atomicmemory: { apiUrl: 'http://localhost:3050' },
},
});

await memory.initialize();

The atomicmemory key is the provider id the client uses to route calls; the nested object is the provider adapter's config. See Using the atomicmemory backend for the full config shape (apiKey, timeout, apiVersion).

If you configure more than one provider, pass defaultProvider to pick which one receives un-qualified calls:

new MemoryClient({
providers: {
atomicmemory: { apiUrl: 'http://localhost:3050' },
mem0: { apiUrl: 'http://localhost:8888', pathPrefix: '' },
},
defaultProvider: 'atomicmemory',
});

Step 3, Ingest a memory

await memory.ingest({
mode: 'text',
content: 'JavaScript closures capture variables from their lexical scope.',
scope: { user: 'demo-user' },
provenance: { source: 'manual' },
});

Or from a conversation:

await memory.ingest({
mode: 'messages',
messages: [
{ role: 'user', content: 'I prefer aisle seats.' },
{ role: 'assistant', content: 'Noted.' },
],
scope: { user: 'demo-user' },
});

ingest takes a single IngestInput. Any capture-gating policy ("should this conversation be saved at all?") lives in your application, not in the SDK.

const page = await memory.search({
query: 'How do closures work?',
scope: { user: 'demo-user' },
limit: 5,
});

for (const { memory: record, score } of page.results) {
console.log(score.toFixed(3), record.content);
}

Similarly, search takes a single SearchRequest. Injection-gating ("should this result ever be shown on this site?") is also an application-layer concern.

This is the whole round trip

initializeingestsearch. Every other method (get, delete, list, package, capabilities, getExtension, getProviderStatus) is reachable on the same memory object. Backend-specific admin, lifecycle reset, audit trails, lesson lists, agent trust, is reachable via the atomicmemory namespace handle:

const handle = memory.atomicmemory;
if (handle) {
await handle.lifecycle.resetSource('demo-user', 'manual');
const stats = await handle.lifecycle.stats('demo-user');
}

For the full surface, see the API Reference overview.

What next