@memorynodeai/sdk
Typed client for the MemoryNode REST API and hosted MCP. Source: packages/sdk/src/index.ts.
MemoryNode is currently optimized for workflow outcomes in three primary use clusters:
- SaaS personalization copilots
- AI companion products
- Creator tools with persistent audience context
Developer agents are a secondary segment in the current roadmap.
Install
npm install @memorynodeai/sdk
Quick start
import { MemoryNodeClient } from "@memorynodeai/sdk";
const client = new MemoryNodeClient({
baseUrl: "https://api.memorynode.ai",
apiKey: process.env.MEMORYNODE_API_KEY!,
// transport: "hybrid" (default) | "mcp" | "rest"
});
await client.addMemory({
ownerId: "user_123",
ownerType: "user",
text: "Prefers answers in bullet points.",
memory_type: "preference",
});
const results = await client.search({
ownerId: "user_123",
query: "how does the user like answers?",
topK: 5,
});
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/INTEGRATION.md § What you get without extra code.
Starter templates (three only)
Use one of these templates first for faster activation:
- AI companion memory starter: save preferences + relationship context.
- SaaS personalization starter: per-user continuity for product experiences.
- Creator personalization starter: durable audience context and intent memory.
This phase intentionally keeps starter scope to these three templates.
Runnable references in this repo:
examples/support-bot-minimal(AI companion memory)examples/nextjs-middleware(SaaS personalization continuity)examples/node-quickstart(creator personalization baseline)
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 "hybrid"
}
Transports:
rest— direct HTTPS tobaseUrl.mcp— calls the hosted MCP Streamable HTTP at<baseUrl>/v1/mcp(requiresapiKey).hybrid— attempts MCP for simplesearchcalls; falls back to REST whenever the request uses filters,search_mode,min_score,retrieval_profile,page, orpage_size, or when MCP itself errors.
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
| 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
| SDK method | REST route |
|---|---|
search(options) | POST /v1/search (or MCP search tool in hybrid/mcp) |
listSearchHistory(limit?) | GET /v1/search/history |
replaySearch({ queryId }) | POST /v1/search/replay |
context(options) | POST /v1/context |
sendContextFeedback(options) | POST /v1/context/feedback |
getPruningMetrics() | GET /v1/pruning/metrics |
Usage and audit
| SDK method | REST route |
|---|---|
getUsageToday() | GET /v1/usage/today |
listAuditLog({ page?, limit? }) | GET /v1/audit/log |
Admin (needs adminToken per call, sent as x-admin-token)
| SDK method | REST route |
|---|---|
createWorkspace(name, adminToken) | POST /v1/workspaces |
createApiKey(workspaceId, name, adminToken) | POST /v1/api-keys |
listApiKeys(workspaceId, adminToken) | GET /v1/api-keys |
revokeApiKey(apiKeyId, adminToken) | POST /v1/api-keys/revoke |
Health
| SDK method | REST route |
|---|---|
health() | GET /healthz |
Owner identity
addMemory, addConversationMemory, search, context, and listMemories accept ownerId + ownerType (user | team | app). Legacy userId / entityId / entityType are accepted for back-compat; entityType: "agent" is normalized to "app". All provided ids must match 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 §3.
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 {
MemoryNodeClient,
MemoryNodeApiError,
MemoryNodeMcpTransport,
resolveMcpUrl,
type ApiError,
} from "@memorynodeai/sdk";