@memorynodeai/sdk
Typed client for the MemoryNode REST API — SDK/API to ship production AI memory. Source: packages/sdk/src/index.ts.
Make users feel remembered across sessions. See docs/PRODUCT.md.
| SDK | REST |
|---|---|
memory.remember(text, { ownerId }) | POST /v1/memories |
memory.recall(query, { ownerId }) | POST /v1/search |
memory.contextFor(query, { ownerId }) | POST /v1/context |
memory.prepareContext(query, { ownerId }) | POST /v1/context + formatting helpers |
injectContext(messages, contextText) | Merge into your LLM messages |
memory.saveFromTurn({ user, assistant, ownerId }) | Persist a chat turn after your LLM call |
Use ownerId = your app's logged-in user ID. For MCP while building in Cursor/Claude, see MCP_SERVER.md — not for production backends.
Adoption helpers
Add MemoryNode around your existing agent flow without new API routes:
| Helper | Purpose |
|---|---|
memory.prepareContext(query, { ownerId }) | contextFor + { contextText, systemBlock, citations } |
injectContext(messages, contextText, opts?) | Merge recalled text into OpenAI/Anthropic-shaped messages[] |
memory.saveFromTurn({ user, assistant?, saveAssistant?, ownerId }) | Persist a turn after your LLM call |
formatContextBlock(response) | Format context_text for custom prompts |
import { MemoryNode, injectContext } from "@memorynodeai/sdk";
const memory = new MemoryNode(process.env.MEMORYNODE_API_KEY!);
const ownerId = "user_123";
const { contextText } = await memory.prepareContext("How should the dashboard feel?", {
ownerId,
topK: 8,
});
const messages = injectContext(
[{ role: "user", content: "How should the dashboard feel?" }],
contextText,
{ preamble: "You are a SaaS copilot." },
);
// Pass `messages` to your existing OpenAI / Anthropic / Vercel AI client
await memory.saveFromTurn({
user: "How should the dashboard feel?",
assistant: "Use dark mode and weekly digests.",
ownerId,
saveAssistant: true,
});
Full stack examples: docs/INTEGRATION_RECIPES.md.
Install
npm install @memorynodeai/sdk
Quick start
import { MemoryNode } from "@memorynodeai/sdk";
const memory = new MemoryNode(process.env.MEMORYNODE_API_KEY!);
const ownerId = "user_123"; // same as your SaaS user id
await memory.remember("User prefers weekly email digests and dark mode.", { ownerId });
// LLM extraction is opt-in: pass { extract: true } when your plan allows it (default is off).
const results = await memory.recall("How should the dashboard feel for this user?", {
ownerId,
topK: 5,
explain: true,
});
console.log(memory.formatSearchDebug(results).join("\n"));
MemoryNode targets https://api.memorynode.ai with REST transport. Override with MEMORYNODE_BASE_URL for local Workers.
Full client (`MemoryNodeClient`)
import { MemoryNodeClient } from "@memorynodeai/sdk";
const client = new MemoryNodeClient({
baseUrl: "https://api.memorynode.ai",
apiKey: process.env.MEMORYNODE_API_KEY!,
transport: "rest", // default; use mcp | hybrid only for agent tooling
});
await client.addMemory({
ownerId: "user_123",
ownerType: "user",
text: "User prefers weekly email digests and dark mode.",
memory_type: "preference",
});
API key is sent as Authorization: Bearer <key>. For PayU billing behavior, plan limits, and rate limits, see docs/external/API_USAGE.md.
Automatic product behavior (dedupe, lifecycle ranking, contradiction handling, retrieval learning) needs no SDK flags — see docs/TWO_CALL_INTEGRATION.md and docs/INTEGRATION.md.
SaaS copilot demo
After Playground + examples/sdk-quickstart, run the flagship UI: starters/saas-copilot-nextjs.
Walkthrough: examples/sdk-quickstart · starters/saas-copilot-nextjs · docs/DEMOS.md
Client options
interface MemoryNodeClientOptions {
baseUrl?: string; // default http://127.0.0.1:8787
apiKey?: string;
timeoutMs?: number; // default 60_000
signal?: AbortSignal;
maxRetries?: number; // default 2
retryBaseMs?: number; // default 200
transport?: "mcp" | "rest" | "hybrid"; // default "rest"
}
Transports:
rest— direct HTTPS tobaseUrl(recommended for SaaS backends).mcp— hosted MCP Streamable HTTP at<baseUrl>/v1/mcp(editors/agents).hybrid— MCP for simple search; REST fallback for filters and advanced options.
Use rest for your app backend first. Reach for mcp or hybrid only when your tooling workflow actually needs it.
API surface tiers
Aligned with docs/external/API_USAGE.md §2:
- Tier A (customer):
remember/recall,addMemory,search,context,getUsageToday,health— start here. - Tier B (advanced):
ingest,addConversationMemory— optional write paths beyond Tier A; not part of public product marketing. - Tier C (operator / internal):
createWorkspace,createApiKey,listApiKeys,revokeApiKey— requireadminToken(x-admin-token). Not for SaaS app backends; customers create keys in the console App connection via dashboard routes, not/v1/api-keys.
Method map
Each method is a thin wrapper over an HTTP route in apps/api/src/router.ts. See docs/external/API_USAGE.md for request/response shapes.
Memories (Tier A / B)
| SDK method | REST route |
|---|---|
addMemory(input) | POST /v1/memories |
addConversationMemory(input) | POST /v1/memories/conversation |
ingest(input) | POST /v1/ingest |
listMemories(options?) | GET /v1/memories |
getMemory(id) | GET /v1/memories/:id |
deleteMemory(id) | DELETE /v1/memories/:id |
Search and context (Tier A)
| SDK method | REST route |
|---|---|
search(options) | POST /v1/search (or MCP search tool in hybrid/mcp) |
context(options) | POST /v1/context |
Usage
| SDK method | REST route |
|---|---|
getUsageToday() | GET /v1/usage/today |
Operator / internal only — Tier C
These helpers call operator routes (x-admin-token). They are for runbooks and automation, not for end-user apps. Customers should create keys in the console (App connection / /app-connection) which uses POST /v1/dashboard/api-keys — not exposed on MemoryNodeClient.
| SDK method | REST route | Notes |
|---|---|---|
createWorkspace(name, adminToken) | POST /v1/workspaces | Operator provisioning |
createApiKey(workspaceId, name, adminToken) | POST /v1/api-keys | Not the customer dashboard path |
listApiKeys(workspaceId, adminToken) | GET /v1/api-keys | Masked list; operator only |
revokeApiKey(apiKeyId, adminToken) | POST /v1/api-keys/revoke | Operator only |
Health
| SDK method | REST route |
|---|---|
health() | GET /healthz |
Owner identity
addMemory, addConversationMemory, search, context, and listMemories accept ownerId + ownerType (user | team | app). You may also pass userId as an alias for ownerId; both must match when provided together or the call throws MemoryNodeApiError with code INVALID_OWNER_ID.
Errors
All methods throw MemoryNodeApiError on non-2xx responses:
import { MemoryNodeApiError } from "@memorynodeai/sdk";
try {
await client.search({ ownerId: "u1", query: "..." });
} catch (err) {
if (err instanceof MemoryNodeApiError) {
console.log(err.code, err.message, err.status, err.requestId);
}
}
Codes mirror docs/external/API_USAGE.md §4.
Retry and timeouts
The REST transport (packages/sdk/src/internal-rest.ts) retries 429, 5xx, and fetch-level network errors with exponential backoff (retryBaseMs * 2^n, full jitter). timeoutMs bounds each individual attempt. signal aborts the combined call.
Re-exports
import {
MemoryNode,
MemoryNodeClient,
MemoryNodeApiError,
formatMemoryWriteDebug,
formatSearchDebug,
injectContext,
prepareContext,
saveFromTurn,
formatContextBlock,
MemoryNodeMcpTransport,
resolveMcpUrl,
MEMORYNODE_PRODUCTION_URL,
type ApiError,
} from "@memorynodeai/sdk";
Debugging: docs/DEBUGGING.md.