[{"title":"Start here","url":"/","group":"start","description":"Memory and context for AI products — Playground proof, SDK/API to ship, MCP to build.","headings":["Recommended path","1. Prove recall in Playground","2. Ship with SDK/API","3. SaaS copilot starter (optional UI)","4. MCP for builders (optional)","The four-step ship flow","Owner id matters","What to skip at first","Next reads"],"text":"Start here Memory and context for AI products. SDK/API to ship. MCP to build. Prove it with a SaaS copilot in 5 minutes. Make users feel remembered — add MemoryNode around your existing AI stack: save what matters, recall the right context, inject into your prompt. Your model stack stays the same. Recommended path Follow this order: Playground — prove save → recall → context (~5 min, no API key) Create API key — App connection after Playground proof Two-call integration — wire REST/SDK in production SDK quickstart — fastest code path SaaS copilot starter — full in-app UX with Memory used badge MCP setup — only if building inside Cursor or Claude (not your production backend) 1. Prove recall in Playground Sign in to the console . Setup creates your workspace automatically. Open Playground (no API key needed — the console uses your signed-in session). Save a preference, e.g. User prefers weekly email digests and dark mode on the dashboard. Ask a different question , e.g. How should the dashboard feel for this user? Click Build context and confirm Context ready shows prompt-ready text (or use Search recall for ranked hits). Copy context_text — that is what you inject into your LLM system prompt. Playground uses default-user by default. That is fine for proof. Create an API key on App connection when you run code below. Playground proves memory and context — it does not chat with an LLM on your behalf. 2. Ship with SDK/API After Playground works, run the SDK quickstart : export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; export MEMORYNODE_USER_ID= &quot;user_42&quot; node examples/sdk-quickstart/index.mjs TypeScript: import { MemoryNode } from &quot;@memorynodeai/sdk&quot; ; const memory = new MemoryNode (process. env . MEMORYNODE_API_KEY !); const ownerId = process. env . MEMORYNODE_USER_ID ?? &quot;user_42&quot; ; await memory. remember ( &quot;User prefers weekly email digests and dark mode.&quot; , { ownerId }); const { context_text : contextText } = await memory. contextFor ( &quot;How should the dashboard feel for this user?&quot; , { ownerId, topK : 8 }, ); // Inject contextText into your existing LLM messages 3. SaaS copilot starter (optional UI) Open the Next.js SaaS copilot starter : save a preference, ask a different question, watch Memory used on the reply. The starter uses OpenAI for the reply step — Playground does not. 4. MCP for builders (optional) Use MCP only when prototyping in Cursor or Claude Desktop . MCP is for building, not your production SaaS backend. Same API key, same memories. The four-step ship flow Step What you do API / SDK 1. Save Store what your app learned POST /v1/memories · memory.remember() 2. Recall Ranked hits (optional if you use context) POST /v1/search · memory.recall() 3. Build context Prompt-ready pack + citations POST /v1/context · memory.contextFor() 4. Inject Merge into your system/user message Your OpenAI / Anthropic code — unchanged Minimum proof: save + search (two API calls). Production prompts: prefer save + context . Owner id matters Memories are scoped by owner_id (SDK alias: userId ). Pass your SaaS app&#39;s logged-in user ID on every write and read. Session 1 and session 2 must use the same value. What to skip at first Custom ranking tuning or large eval harnesses Get save + recall (or context) working first. Ship with SDK/API before MCP. Next reads Two-call integration Integration recipes Demos Pricing API usage","excerpt":"Start here Memory and context for AI products. SDK/API to ship. MCP to build. Prove it with a SaaS copilot in 5 minutes. Make users feel remembered — add MemoryNode around your existing AI stack: save what matters, recal"},{"title":"Two-call integration","url":"/two-call-integration/","group":"start","description":"Ship path: POST /v1/memories + POST /v1/context with owner_id as your SaaS user ID.","headings":["Concepts you need","Authentication","SaaS copilot example","cURL","Node / TypeScript","Python","Wire it in your app (save → recall → inject)","Context pack (recommended for prompts)","Common errors","Not needed for first recall","Next reads"],"text":"Two-call integration Add per-user memory to your SaaS copilot in two API calls. Persistent memory without rebuilding your AI pipeline. Save what matters, recall the right context, inject into your prompt, and keep using your existing model stack. Your AI app forgets users between sessions. Fix it with POST /v1/memories (save what you learn) and POST /v1/search or POST /v1/context (recall before the next reply). Use the same owner_id as your SaaS app&#39;s logged-in user ID. For stack-specific copy-paste (OpenAI, REST, MCP), see Integration recipes . Base URL: https://api.memorynode.ai (or your self-hosted Worker URL). Concepts you need Concept What it means Workspace Your MemoryNode project. One API key belongs to one workspace. Create keys in the console under App connection . API key Authorization: Bearer mn_live_… (or x-api-key: mn_live_… ). Required on every product route. owner_id Your SaaS app&#39;s user ID — the same string you use for user_id in the API body. Session 1 and session 2 must use the same value or recall looks empty. POST /v1/memories Saves what your copilot learned about a user (preferences, habits, account facts). POST /v1/search Recalls ranked memory hits before you generate the next AI reply. POST /v1/context Same recall pipeline, plus assembled context_text for your LLM (recommended for prompts). Playground default is default-user . In production, replace it with your real user ID. Authentication Authorization: Bearer mn_live_…your_key… Content-Type: application/json Every response includes x-request-id — log it for support and debugging. SaaS copilot example Session 1 — user tells your copilot how they work: \"I prefer weekly email digests and dark mode on the dashboard.\" Session 2 — user asks a different question: \"How should the dashboard feel for this user?\" MemoryNode recalls the preference. Your LLM answers without re-asking. cURL export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; export OWNER_ID= &quot;user_42&quot; # your SaaS user id # Session 1 — remember curl -sS -X POST &quot;https://api.memorynode.ai/v1/memories&quot; \\ -H &quot;Authorization: Bearer $MEMORYNODE_API_KEY &quot; \\ -H &quot;Content-Type: application/json&quot; \\ -d &#x27;{ &quot;user_id&quot;: &quot;&#x27; &quot; $OWNER_ID &quot; &#x27;&quot;, &quot;text&quot;: &quot;User prefers weekly email digests and dark mode on the dashboard.&quot;, &quot;extract&quot;: false }&#x27; # Session 2 — recall before the reply curl -sS -X POST &quot;https://api.memorynode.ai/v1/search&quot; \\ -H &quot;Authorization: Bearer $MEMORYNODE_API_KEY &quot; \\ -H &quot;Content-Type: application/json&quot; \\ -d &#x27;{ &quot;user_id&quot;: &quot;&#x27; &quot; $OWNER_ID &quot; &#x27;&quot;, &quot;query&quot;: &quot;How should the dashboard feel for this user?&quot;, &quot;top_k&quot;: 5, &quot;namespace&quot;: &quot;default&quot;, &quot;search_mode&quot;: &quot;hybrid&quot; }&#x27; Save the x-request-id header from the search response. Node / TypeScript npm install @memorynodeai/sdk export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; import { MemoryNode } from &quot;@memorynodeai/sdk&quot; ; const ownerId = &quot;user_42&quot; ; // same as your SaaS logged-in user id const memory = new MemoryNode (process. env . MEMORYNODE_API_KEY !); // Session 1 await memory. remember ( &quot;User prefers weekly email digests and dark mode on the dashboard.&quot; , { ownerId }, ); // Session 2 const { results } = await memory. recall ( &quot;How should the dashboard feel for this user?&quot; , { ownerId, topK : 5 , explain : true , }); console . log (results?.[ 0 ]?. text ); Runnable: examples/sdk-quickstart Python pip install httpx export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; export OWNER_ID= &quot;user_42&quot; import os import httpx BASE = &quot;https://api.memorynode.ai&quot; KEY = os.environ[ &quot;MEMORYNODE_API_KEY&quot; ] OWNER = os.environ.get( &quot;OWNER_ID&quot; , &quot;user_42&quot; ) headers = { &quot;Authorization&quot; : f&quot;Bearer {KEY} &quot; , &quot;content-type&quot; : &quot;application/json&quot; } with httpx.Client(base_url=BASE, headers=headers, timeout= 30.0 ) as client: client.post( &quot;/v1/memories&quot; , json={ &quot;user_id&quot; : OWNER, &quot;text&quot; : &quot;User prefers weekly email digests and dark mode on the dashboard.&quot; , &quot;extract&quot; : False , }, ).raise_for_status() hits = client.post( &quot;/v1/search&quot; , json={ &quot;user_id&quot; : OWNER, &quot;query&quot; : &quot;How should the dashboard feel for this user?&quot; , &quot;top_k&quot; : 5 , &quot;namespace&quot; : &quot;default&quot; , &quot;search_mode&quot; : &quot;hybrid&quot; , }, ).raise_for_status().json() print (hits.get( &quot;results&quot; , [{}])[ 0 ].get( &quot;text&quot; )) Wire it in your app (save → recall → inject) Save — after each user message (or session end), call POST /v1/memories with facts your app should remember. Recall — before each AI reply, call POST /v1/context with the current question as query (or POST /v1/search if you assemble the prompt yourself). Inject — merge context_text (or joined search hit texts) into your LLM system or user message. Your OpenAI / Anthropic / Vercel AI / LangChain code stays the same. Keep your stack — MemoryNode is a memory layer; you still call your existing model provider. Keep user_id / owner_id identical to your auth user id across sessions. Context pack (recommended for prompts) curl -sS -X POST &quot;https://api.memorynode.ai/v1/context&quot; \\ -H &quot;Authorization: Bearer $MEMORYNODE_API_KEY &quot; \\ -H &quot;Content-Type: application/json&quot; \\ -d &#x27;{ &quot;user_id&quot;: &quot;&#x27; &quot; $OWNER_ID &quot; &#x27;&quot;, &quot;query&quot;: &quot;How should the dashboard feel for this user?&quot;, &quot;top_k&quot;: 8, &quot;namespace&quot;: &quot;default&quot; }&#x27; Use the returned context_text in your system prompt. SDK: memory.contextFor(query, { ownerId }) . Runnable REST example: examples/integrations/rest-node . Prove recall in the console Playground first — save one memory, then Build context . See START_HERE . Common errors HTTP Typical error.code Fix 401 UNAUTHORIZED Missing or invalid API key. 400 BAD_REQUEST Validation failed — check user_id , text , query . 402 daily_cap_exceeded , monthly_cap_exceeded , ENTITLEMENT_REQUIRED , trial expired Upgrade via console billing (PayU INR) or wait for cap reset. 429 rate_limited Back off and retry; see plan RPM limits. Full reference: API_USAGE.md · OpenAPI Not needed for first recall Skip these until you have working write + search in production: MCP — builder tools only (Cursor/Claude); ship with REST/SDK first ( MCP_SERVER.md ) Brain / rerank tuning — defaults work for first recall Eval sets — add after you ship Next reads START_HERE — Playground-first activation path INTEGRATION_RECIPES — REST, OpenAI, MCP, stack patterns INTEGRATION — advanced capabilities (dedupe, lifecycle, feedback) TROUBLESHOOTING — empty search, auth, 402 Pricing — trial and PayU (INR)","excerpt":"Two-call integration Add per-user memory to your SaaS copilot in two API calls. Persistent memory without rebuilding your AI pipeline. Save what matters, recall the right context, inject into your prompt, and keep using "},{"title":"Integration","url":"/integration/","group":"start","description":"Advanced capabilities after first recall — dedupe, lifecycle, context assembly.","headings":["Context-pack-first workflow","Archive vs forget","What you get without extra code","TypeScript SDK","Deeper reference"],"text":"MemoryNode integration Start here: Two-call integration — the canonical developer path for POST /v1/memories and POST /v1/search . Stack recipes: Integration recipes — save → recall → inject into your existing LLM (REST/OpenAI/Anthropic for production app flows; MCP only for Cursor/Claude build path). That doc covers authentication, owner_id , copy-paste examples (cURL, TypeScript, Python), the SaaS copilot session 1 → session 2 proof, and what you can skip for first recall. This page covers what runs automatically once the two calls are already wired and working. Context-pack-first workflow After POST /v1/memories and POST /v1/search work, use POST /v1/context when you want a single payload for the model: ranked memories and citations assembled as context_text . Recommended flow: Save what you learned ( POST /v1/memories ). Recall with search when you only need ranked hits ( POST /v1/search ). Build context when you are ready to answer ( POST /v1/context ) — paste the returned pack into your chat prompt. The console Playground follows this order: save → build context → copy context_text . Archive vs forget Action API / console Effect Archive POST /v1/memories/:id/archive · Memories → Archive Hides the memory from active recall; keeps the row for audit and optional review. Forget (delete) DELETE /v1/memories/:id · Memories → Forget Hard delete with chunks and links removed. Use archive when a fact is outdated but you may want history; use forget when the user or policy requires removal. What you get without extra code These run on every write/search; you do not configure separate services for them. Capability What it means for your app Lifecycle intelligence Confidence, volatility, expiry, and supersession are applied on ingest and reflected in ranking — not a separate “lifecycle API”. Semantic dedupe Near-duplicate text or embeddings can return { deduped: true, memory_id, dedupe_kind } instead of a second row. Contradiction handling Conflicting facts are resolved on write; check intelligence.conflict_state on new memories. SQL recall + Worker ranking Postgres returns candidates; business ranking (lifecycle, learning, freshness) runs in the Worker after fusion. Retrieval ranking Postgres returns candidates; ranking (lifecycle, freshness) runs in the Worker after fusion. Worker-side LLM (operator) Extraction and evolution on ingest use CHAT_PROVIDER on the MemoryNode Worker (OpenAI, Anthropic, or Gemini). This is not “use Claude in your app” — your product still calls your own model; MemoryNode only uses these keys for optional extract/evolve on write. Embeddings stay OpenAI/stub with per-chunk version metadata. Details: API_USAGE.md §4 (lifecycle, providers, retrieval architecture). TypeScript SDK @memorynodeai/sdk wraps the same routes with retries, typed errors, and explain for ranking debug. See DEBUGGING.md . Deeper reference docs/INTEGRATION_RECIPES.md — copy-paste per stack docs/TWO_CALL_INTEGRATION.md — start here for first recall docs/external/openapi.yaml — product OpenAPI (generated; excludes operator routes) docs/external/API_USAGE.md — full HTTP reference docs/MCP_SERVER.md — MCP to build in Cursor/Claude (not for production backends)","excerpt":"MemoryNode integration Start here: Two-call integration — the canonical developer path for POST /v1/memories and POST /v1/search . Stack recipes: Integration recipes — save → recall → inject into your existing LLM (REST/"},{"title":"Integration recipes","url":"/integration-recipes/","group":"start","description":"SDK/API to ship — save, recall, inject into OpenAI, Anthropic, and more.","headings":["The four-step flow (every stack)","Recipe index","REST (Node fetch)","REST (Python httpx)","TypeScript SDK (with helpers)","OpenAI Chat Completions","MCP for builders","Anthropic Messages API","Vercel AI SDK","LangChain","What runs automatically","Next reads"],"text":"Integration recipes Persistent memory without rebuilding your AI pipeline. SDK/API to ship production memory: save what matters, recall the right context, inject into your prompt. MCP to build in Cursor or Claude while prototyping — not your production backend. This page is the recipe index. Each path uses the TypeScript SDK helpers ( prepareContext , injectContext , saveFromTurn ) or the equivalent REST calls below. The four-step flow (every stack) Step What you do MemoryNode API 1. Save Persist facts from the user or your app POST /v1/memories · memory.remember() 2. Recall Fetch what matters for this turn POST /v1/search · memory.recall() — or skip if you only need a prompt pack 3. Build context Get prompt-ready text + citations POST /v1/context · memory.contextFor() 4. Inject Merge context_text into your LLM system or user message Your OpenAI / Anthropic / Vercel AI / LangChain code — unchanged After reply Optionally save the turn POST /v1/memories again Owner id: pass the same user_id / owner_id as your SaaS logged-in user on every call. See Two-call integration . Prove the flow in the console Playground first: save → Build context → copy context_text . Recipe index Stack When to use Runnable example REST (Node) Any backend, no SDK examples/integrations/rest-node REST (Python) Python services examples/integrations/rest-python TypeScript SDK Node / TS backends examples/sdk-quickstart OpenAI Chat Completions Already on OpenAI HTTP or SDK examples/integrations/openai MCP (Cursor / Claude Desktop) Editor or agent IDE MCP_SERVER.md · examples/cursor-mcp-config.json Anthropic Messages API Claude in your app examples/integrations/anthropic Vercel AI SDK Next.js streamText / generateText examples/integrations/vercel-ai LangChain Chains / retrievers examples/integrations/langchain Canonical activation path remains START_HERE → Two-call integration . REST (Node fetch) Save → context → inject → LLM reply (requires OPENAI_API_KEY in the demo script — Playground does not run this step). export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; export MEMORYNODE_USER_ID= &quot;user_42&quot; node examples/integrations/rest-node/demo.mjs Core calls: // 1. Save await fetch ( ` ${BASE} /v1/memories` , { method : &quot;POST&quot; , headers : authHeaders, body : JSON . stringify ({ user_id : ownerId, text : &quot;User prefers weekly digests and dark mode.&quot; , }), }); // 2. Build context (prompt-ready) const ctxRes = await fetch ( ` ${BASE} /v1/context` , { method : &quot;POST&quot; , headers : authHeaders, body : JSON . stringify ({ user_id : ownerId, query : &quot;How should the dashboard feel for this user?&quot; , top_k : 8 , }), }); const { context_text : contextText } = await ctxRes. json (); // 3. Inject into your LLM (example: OpenAI-shaped messages) const messages = [ { role : &quot;system&quot; , content : &quot;You are a SaaS copilot.\\n\\nRecalled user context:\\n&quot; + (contextText || &quot;(none yet)&quot; ), }, { role : &quot;user&quot; , content : userQuestion }, ]; // 4. Your existing model call — unchanged stack // await openai.chat.completions.create({ model: &quot;gpt-4o-mini&quot;, messages }); Full script: examples/integrations/rest-node/demo.mjs . REST (Python httpx) Same four steps with httpx : pip install httpx export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; export MEMORYNODE_USER_ID= &quot;user_42&quot; python examples/integrations/rest-python/demo.py See examples/integrations/rest-python/demo.py . TypeScript SDK (with helpers) import { MemoryNode , injectContext } from &quot;@memorynodeai/sdk&quot; ; const memory = new MemoryNode (process. env . MEMORYNODE_API_KEY !); const ownerId = &quot;user_42&quot; ; await memory. remember ( &quot;User prefers weekly digests and dark mode.&quot; , { ownerId }); const userQuestion = &quot;How should the dashboard feel for this user?&quot; ; const { contextText, systemBlock } = await memory. prepareContext (userQuestion, { ownerId, topK : 8 , }); const messages = injectContext ( [{ role : &quot;user&quot; , content : userQuestion }], contextText, ); // Your existing OpenAI / Anthropic / Vercel AI call with `messages` await memory. saveFromTurn ({ user : userQuestion, assistant : &quot;Use dark mode and weekly digests.&quot; , ownerId, saveAssistant : true , }); Lower-level API (no helpers): memory.contextFor() returns the raw ContextResponse . Runnable: examples/sdk-quickstart . UI starter: starters/saas-copilot-nextjs . OpenAI Chat Completions Use MemoryNode helpers; keep OpenAI for generation. export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; export OPENAI_API_KEY= &quot;sk-...&quot; node examples/integrations/openai/demo.mjs Pattern: memory.remember(...) memory.prepareContext(question, { ownerId }) injectContext(messages, contextText) → OpenAI messages memory.saveFromTurn({ user, assistant, saveAssistant: true }) Details: examples/integrations/openai/README.md . MCP for builders Production SaaS: integrate with REST or @memorynodeai/sdk first. MCP is for Cursor, Claude Desktop, and other agent IDEs — safe, policy-gated tools on the same backend. Use case Path In-product copilot REST / SDK — Two-call integration Cursor / Claude Desktop Hosted MCP or stdio — MCP_SERVER.md Agent flow: Configure MCP ( examples/cursor-mcp-config.json ). Before answering, call the context tool with the user’s question. Paste the returned bundle into the agent prompt — your agent framework stays the same. Call memory only for durable, user-confirmed facts. Do not replace the two-call REST path in product docs with MCP-only integration. Anthropic Messages API export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; export ANTHROPIC_API_KEY= &quot;...&quot; node examples/integrations/anthropic/demo.mjs Uses prepareContext → systemBlock on the Anthropic system field → saveFromTurn . Details: examples/integrations/anthropic/README.md . Vercel AI SDK Copy route.example.ts into your Next.js app, or run the memory-layer demo: node examples/integrations/vercel-ai/demo.mjs streamText works the same — build system from prepareContext before you stream. Details: examples/integrations/vercel-ai/README.md . LangChain node examples/integrations/langchain/demo.mjs Uses memory-node-retriever.mjs — wire getRelevantDocuments into your prompt template; keep your chain and LLM. Details: examples/integrations/langchain/README.md . What runs automatically Dedupe, lifecycle ranking, and retrieval learning run on the Worker — no extra integrator services. After first recall, see Integration for links and archive/forget. Next reads START_HERE — Playground proof TWO_CALL_INTEGRATION — auth, owner_id , errors INTEGRATION — context pack, lifecycle API reference · SDK · MCP","excerpt":"Integration recipes Persistent memory without rebuilding your AI pipeline. SDK/API to ship production memory: save what matters, recall the right context, inject into your prompt. MCP to build in Cursor or Claude while p"},{"title":"Why MemoryNode","url":"/why-memorynode/","group":"guides","description":"Two-lane memory infrastructure — Playground proof, INR billing, India-first.","headings":["Who it is for","The problem","What MemoryNode gives you","Why founders choose it","Fastest path to proof","Two lanes, one backend","India trust","When to use MemoryNode","What we are not","Proof to show"],"text":"Why MemoryNode? Make users feel remembered — memory and context infrastructure for AI products. Who it is for Primary: SaaS founders and small AI product teams, especially India-first builders , shipping AI chat or copilot into their product. Prove the SaaS copilot path first (save → recall → context in Playground). The same API works for other remembered-user products later. The problem Your users come back, but your AI does not remember them. They repeat preferences every session. The product feels generic even when the user already told you what matters. What MemoryNode gives you Surface What you get Proof Playground — see recall in ~5 minutes, no API key Ship REST + SDK — remember , prepareContext , injectContext , saveFromTurn Build MCP for Cursor/Claude — same backend while prototyping Lane rule: MCP is for building in Cursor and Claude. SDK/API is for shipping production apps. Same memory, same API key. Why founders choose it Fastest path to proof The first milestone is the recall/context panel filling in Playground — not architecture. Two lanes, one backend Ship with SDK/API in production. Use MCP while building in your IDE. One workspace, one API key. India trust INR billing through PayU, hard caps, no surprise bills. Built for Indian self-serve founders. When to use MemoryNode Use it when: your product has or is shipping AI chat or a copilot users return across sessions with stable accounts you map your app user ID to owner_id you want proof before building custom memory infra What we are not Not a RAG platform. Not an agent framework. Not a no-code studio. PayU INR only — no international self-serve checkout yet. Proof to show Start here — Playground-first Demos — SaaS copilot walkthrough Two-call integration — ship path Pricing — Trial + Build, PayU INR","excerpt":"Why MemoryNode? Make users feel remembered — memory and context infrastructure for AI products. Who it is for Primary: SaaS founders and small AI product teams, especially India-first builders , shipping AI chat or copil"},{"title":"Demos","url":"/demos/","group":"guides","description":"Prove memory recall in Playground — SaaS copilot save → context in 5 minutes.","headings":["Fastest proof: Playground","Playground walkthrough (film this)","Flagship code demos","Before / after","More examples"],"text":"Demos Prove memory recall in minutes. Show one story: a SaaS copilot remembers a user in session 1, then answers a different question in session 2 without asking again. Fastest proof: Playground Start here — open Playground first. No terminal, no API key. Flow: Save memory → Search recall → Build context . Playground shows Context ready (prompt-ready text). It does not run an LLM reply — that is what your app or the SaaS copilot starter does. Playground walkthrough (film this) Same story everywhere: session 1 save → session 2 ask → visible recall . Step What to show Copy 1 Open Playground (no API key) &quot;Prove your AI product can remember users.&quot; 2 Turn 1 — Save &quot;User prefers weekly email digests and dark mode UI.&quot; 3 Turn 2 — Ask &quot;How should the dashboard feel for this user?&quot; 4 Build context Context ready panel fills with prompt-ready text 5 Optional Copy context_text — that goes into your LLM prompt Do not search the exact same text you just saved on turn 1. Do show the context panel and recalled preferences. Do not lead with architecture, embeddings, or MCP tool catalogs. Flagship code demos Link SDK quickstart examples/sdk-quickstart Next.js starter starters/saas-copilot-nextjs Film script SAAS_COPILOT_DEMO_SCRIPT.md export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; node examples/sdk-quickstart/index.mjs Map ownerId to your app&#39;s logged-in user ID. Before / after Before After Empty recall / context panel Non-empty context with user preferences Generic AI reply (in your app) Reply shaped by recalled context More examples Integration recipes — REST, OpenAI, Anthropic, MCP for builders REST (Node) · REST (Python) Two-call integration","excerpt":"Demos Prove memory recall in minutes. Show one story: a SaaS copilot remembers a user in session 1, then answers a different question in session 2 without asking again. Fastest proof: Playground Start here — open Playgro"},{"title":"SaaS copilot demo script","url":"/saas-copilot-demo-script/","group":"guides","description":"60–90s film script: Playground save, context ready panel, SDK ship path.","headings":["Story","Shot list","Do not","Do","Local replay","Sync checklist"],"text":"SaaS copilot demo script (60–90s) Film this for README proof and founder demos. Users feel remembered when session 2 answers without re-asking session 1. Video status: not published yet. Until it is, this file and docs/DEMOS.md are the source of truth. Story A SaaS founder added AI chat to their product. Users kept repeating preferences every session. MemoryNode fixes that: prove recall in Playground, ship with SDK/API. Shot list # Duration Visual Narration 1 5s README or console Home &quot;Memory and context for AI products.&quot; 2 10s Sign in → Open Playground &quot;Prove it with a SaaS copilot in five minutes. No API key needed.&quot; 3 15s Playground — Save &quot;User prefers weekly email digests and dark mode UI.&quot; 4 20s Playground — Ask &quot;How should the dashboard feel for this user?&quot; 5 20s Build context → Context ready panel &quot;Different question. Same user. Prompt-ready context — inject into your LLM.&quot; 6 10s Code snippet: remember + contextFor with ownerId &quot;Ship with SDK/API. Same owner_id as your app&#39;s user ID.&quot; Playground does not show an LLM reply. For a full copilot UX with OpenAI reply, use the SaaS copilot starter . Do not Search the exact same text you just saved on turn 1 Lead with embeddings, architecture diagrams, or MCP tool lists Show Playground as a chat app with model replies Do Show the Context ready panel and recalled preferences Use stable owner_id / default-user in Playground Keep the story on continuity, not infrastructure Local replay export MEMORYNODE_API_KEY= &quot;mn_live_...&quot; node examples/sdk-quickstart/index.mjs # Full UI: cd starters/saas-copilot-nextjs &amp;&amp; pnpm dev (requires OPENAI_API_KEY) Sync checklist README walkthrough links stay accurate docs/DEMOS.md walkthrough table matches this script Console Playground copy matches save → context flow","excerpt":"SaaS copilot demo script (60–90s) Film this for README proof and founder demos. Users feel remembered when session 2 answers without re-asking session 1. Video status: not published yet. Until it is, this file and docs/D"},{"title":"Debugging","url":"/debugging/","group":"guides","description":"Debug ranking, dedupe, and retrieval with x-request-id and explain mode.","headings":["Always log x-request-id","After a write (POST /v1/memories)","SDK helper","After a search (POST /v1/search)","SDK","Empty search results","MCP / agents"],"text":"Debugging MemoryNode You do not need a special dashboard to understand what the API did. Use response bodies , x-request-id , and optional explain on search. Always log `x-request-id` Every success and error includes x-request-id (and request_id in JSON errors). Log it in your app and send it with support requests. There is no public POST /v1/feedback endpoint in v1. After a write (`POST /v1/memories`) Signal Meaning deduped: true Near-duplicate text; existing memory_id reused superseded_memory_id You passed replaces_memory_id ; old row superseded intelligence.conflict_state Contradiction handling ( candidate , resolved , superseded , …) extraction.status skipped / degraded / run — not a hard failure SDK helper import { MemoryNode , formatMemoryWriteDebug } from &quot;@memorynodeai/sdk&quot; ; const res = await memory. remember ( &quot;...&quot; ); console . log ( formatMemoryWriteDebug (res). join ( &quot;\\n&quot; )); // or: memory.formatWriteDebug(res) After a search (`POST /v1/search`) Pass explain: true to attach ranking_reason string codes on each hit (REST only). curl -sS -X POST &quot;https://api.memorynode.ai/v1/search&quot; \\ -H &quot;Authorization: Bearer $MEMORYNODE_API_KEY &quot; \\ -H &quot;Content-Type: application/json&quot; \\ -d &#x27;{&quot;query&quot;:&quot;preferences&quot;,&quot;top_k&quot;:5,&quot;explain&quot;:true}&#x27; SDK const hits = await memory. recall ( &quot;preferences&quot; , { explain : true }); console . log (memory. formatSearchDebug (hits). join ( &quot;\\n&quot; )); Codes map to plain language via RANKING_REASON_LABELS in @memorynodeai/sdk . Empty search results Confirm the same owner ( user_id / owner_id ) and namespace as ingest. Wait a few seconds after first write (embedding/index path). Try search_mode: &quot;keyword&quot; once to verify text is stored. Check plan usage: GET /v1/usage/today . MCP / agents Hosted MCP tools return the same memory IDs; enable logging in your MCP client and correlate with x-request-id from REST calls in the same session.","excerpt":"Debugging MemoryNode You do not need a special dashboard to understand what the API did. Use response bodies , x-request-id , and optional explain on search. Always log `x-request-id` Every success and error includes x-r"},{"title":"Troubleshooting","url":"/troubleshooting/","group":"guides","description":"Fix auth errors, empty search, 402 quota, and MCP vs REST differences.","headings":["401 Unauthorized","402 Payment required / quota","429 Rate limited","Search returns nothing","MISSINGOWNERID (SDK)","MCP search differs from REST","Local Worker vs production","Still stuck?"],"text":"Troubleshooting 401 Unauthorized Use Authorization: Bearer mn_… or header x-api-key: mn_… Key must be active (not revoked) — check console → App connection No extra spaces when pasting the key 402 Payment required / quota Daily read/write caps for your plan — GET /v1/usage/today Upgrade via console billing (PayU checkout) 429 Rate limited Per-workspace concurrency or rate limits — retry with backoff (SDK does this automatically on REST) Search returns nothing Check Action Wrong user/namespace Use the same user_id / owner_id on write and search. API + SDK default is default-user when omitted (console onboarding uses this id). Too soon Retry after 2–5s on first memory Query mismatch Try keywords from the stored sentence min_score too high Lower or omit Degraded entitlements Response ENTITLEMENT_DEGRADED — use search_mode: &quot;keyword&quot; temporarily See DEBUGGING.md . `MISSING_OWNER_ID` (SDK) Provide ownerId (or userId ) on remember / recall / addMemory / search . The simplified MemoryNode class defaults to MEMORYNODE_USER_ID or default-user . MCP search differs from REST Default SDK transport is rest on both MemoryNode and MemoryNodeClient . Use transport: &quot;rest&quot; (or omit the option) for production. Set transport: &quot;mcp&quot; or hybrid only when you intentionally call hosted MCP from the SDK. Local Worker vs production Local: BASE_URL=http://127.0.0.1:8787 and a dev API key Production: https://api.memorynode.ai — MemoryNode constructor sets this automatically Still stuck? Note x-request-id from the failing call Open DEBUGGING.md Re-run with the same owner_id , capture the exact request body, and compare against TWO_CALL_INTEGRATION.md","excerpt":"Troubleshooting 401 Unauthorized Use Authorization: Bearer mn_… or header x-api-key: mn_… Key must be active (not revoked) — check console → App connection No extra spaces when pasting the key 402 Payment required / quot"},{"title":"Pricing","url":"/pricing/","group":"guides","description":"Trial + Build plans, PayU INR checkout, hard caps via the console.","headings":["Self-serve plans (INR)","What the caps mean","Trial behavior","What gets metered","Same backend on every plan"],"text":"Pricing Make users feel remembered without surprise billing. MemoryNode bills through the console via PayU (INR) . Hard caps, no automatic overages, no international self-serve checkout outside INR. Source of truth: plan limits live in packages/shared/src/plans.ts and are enforced through workspace entitlements . Self-serve plans (INR) Plan Price Period Memory writes Memory retrievals Storage Best for Trial ₹0 14 days 100 500 100 MB Prove first recall in Playground Build ₹1,499 30 days 1,000 2,500 1 GB Ship your SaaS copilot There is no permanent free tier . New workspaces start on a 14-day trial . Upgrade to Build via console → Billing . What the caps mean Hard stop at cap each billing period. No automatic overages. Plan Embed tokens Gen tokens Trial 50,000 0 Build 500,000 150,000 Writes and search consume embed tokens. The core promise: reliable write + recall in two calls. Trial behavior Trial ends when either happens first: 14 days pass since signup Trial usage limits are reached When trial ends without a paid plan, quota-consuming API calls return HTTP 402 with error.code: &quot;TRIAL_EXPIRED&quot; . What gets metered Action Metering POST /v1/memories Write + optional embed POST /v1/search Read + query embedding POST /v1/context Read + embedding Usage visibility: GET /v1/usage/today or SDK getUsageToday() . Same backend on every plan REST and SDK use the same API key and workspace caps. MCP (builder tools) uses the same key too — ship with SDK/API in production; use MCP only while building in Cursor or Claude.","excerpt":"Pricing Make users feel remembered without surprise billing. MemoryNode bills through the console via PayU (INR) . Hard caps, no automatic overages, no international self-serve checkout outside INR. Source of truth: plan"},{"title":"API reference","url":"/api/","group":"reference","description":"Canonical HTTP reference for the MemoryNode API Worker.","headings":["1. Authentication","1.1 Auth quick reference (which client uses what)","2. API surface tiers","Tier A — Customer activation (OpenAPI + quickstart)","Tier B — Power-user (Worker + this doc; not quickstart-first)","Tier C — Internal / operator only (not in public OpenAPI)","3. Middleware order","4. Error envelope","5. Rate limits, concurrency, quotas","Trial gate (quota-consuming routes)","Chat completions provider (Worker)","Memory lifecycle intelligence (automatic)","6. Plans","7. Routes (tenant-facing)","7.1 Memories","7.2 Search and context","Search request fields (POST /v1/search, POST /v1/context)","Owner identity (ownerid / userid)","7.3 Usage","7.5 Workspaces and API keys","7.6 Billing","7.7 Dashboard","7.8 Health","7.9 Admin","7.10 MCP (secondary)","8. Canonical flows","8.1 POST /v1/memories","8.2 POST /v1/search","8.3 POST /v1/billing/checkout","8.4 POST /v1/billing/webhook","9. Client headers you may see","10. Operator and internal routes (not in OpenAPI)","11. Changes and drift"],"text":"MemoryNode API usage Canonical HTTP reference for the memorynode-api Cloudflare Worker. Source of truth for behavior is code in apps/api/src/ . The regenerated docs/external/openapi.yaml documents the public product surface (run pnpm openapi:gen ) — internal, operator, and advanced routes may still exist in the Worker but are omitted from that contract. Production base: https://api.memorynode.ai Hosted MCP base: https://mcp.memorynode.ai (same Worker) Staging base: https://api-staging.memorynode.ai Local dev: http://127.0.0.1:8787 Product focus: make users feel remembered for Indian SaaS founders shipping AI chat or copilots inside their product ( PRODUCT.md ). Advanced surfaces (connectors read settings, audit exports, pruning metrics, admin routes, etc.) may exist on the Worker for operators; they are omitted from the published OpenAPI contract — see section 10. OpenAPI is a subset: openapi.yaml covers Tier A memory/search/context/usage only. Dashboard session routes, billing, and hosted MCP are documented in this file (§7) — not in OpenAPI. Do not generate a client from OpenAPI alone for console setup or PayU checkout. 1. Authentication Dispatched in apps/api/src/auth.ts and apps/api/src/lifecycle/handleRequestImpl.ts . Mode Trigger Validation Uses API key (K) Authorization: Bearer &lt;key&gt; or x-api-key: &lt;key&gt; SHA-256 of key + API_KEY_SALT then authenticate_api_key(p_key_hash) RPC All /v1/* tenant routes Dashboard session (S) Cookie: mn_dash_session=&lt;opaque&gt; + x-csrf-token Row in dashboard_sessions + CSRF double-submit /v1/* tenant routes from browser Admin (A) x-admin-token Equality against MASTER_ADMIN_TOKEN or HMAC-SHA256 signed form; optional IP allowlist ( ADMIN_ALLOWED_IPS ); ADMIN_BREAK_GLASS /admin/* , /v1/admin/* PayU webhook (H) form body Reverse SHA-512 over PayU response fields using PAYU_MERCHANT_SALT (see payuReconcile.ts ) POST /v1/billing/webhook only Internal MCP (I) x-internal-mcp: 1 + x-internal-secret: &lt;MCP_INTERNAL_SECRET&gt; Constant-time compare Internal hosted-MCP → REST subrequests Public (P) — — /healthz , /ready , /v1/health Customers: create and revoke keys only via the console dashboard routes ( POST /v1/dashboard/api-keys , GET /v1/dashboard/api-keys , POST /v1/dashboard/api-keys/revoke ) while signed in — see §6.7. Do not use /v1/api-keys in app code or quickstarts. Operators: POST /v1/api-keys , GET /v1/api-keys , and POST /v1/api-keys/revoke require x-admin-token ( MASTER_ADMIN_TOKEN ). They are internal/operator-only and are not in the generated OpenAPI contract. All API keys are rate-limited at 15 RPM for the first 48 h after api_keys.created_at ; after that the default is 60 RPM per key. See packages/shared/src/plans.ts . Webhook forwarding uses internal headers after signature verification, but that internal token path is route-bound to POST /v1/memories and is not accepted as a general-purpose auth bypass on other routes. 1.1 Auth quick reference (which client uses what) You are building… Use Do not use Production SaaS backend (Node, Python, etc.) API key (K) on POST /v1/memories and POST /v1/search Dashboard session cookie from the browser MemoryNode console (Playground, setup) Dashboard session (S) — POST /v1/dashboard/init then cookie + CSRF on mutating calls Pasting a live API key into Playground Creating keys for your app Dashboard session → POST /v1/dashboard/api-keys POST /v1/api-keys (operator x-admin-token only) Cursor / Claude Desktop / agent IDE API key (K) via REST/SDK first; optional MCP ( MCP_SERVER.md ) MCP as the only integration path for your product backend PayU billing callback PayU webhook (H) on POST /v1/billing/webhook API key or session On-call / cron / hygiene Admin (A) on /admin/* Customer-facing docs or quickstarts Integrator rule: ship with REST + @memorynodeai/sdk ( transport: &quot;rest&quot; default). Use the same owner_id as your app&#39;s logged-in user id. Contributor map (monorepo layers, not customer copy): docs/internal/ARCHITECTURE.md . 2. API surface tiers Use this map when writing docs, SDK examples, and console copy. Tier A is what new developers should see first. Tier B is for advanced integrations. Tier C is operator-only — never put Tier C routes in customer quickstarts. Tier A — Customer activation (OpenAPI + quickstart) Route Purpose POST /v1/memories Save memory POST /v1/search Recall memory POST /v1/context Assembled context for prompts GET /v1/usage/today Plan caps vs usage POST /v1/dashboard/init Console one-shot setup (session cookie + workspace) GET /v1/dashboard/workspaces List workspaces for signed-in user POST /v1/dashboard/api-keys Create API key (plaintext returned once) GET /v1/dashboard/api-keys List masked keys POST /v1/dashboard/api-keys/revoke Revoke a key GET /v1/billing/status Entitlement / plan status POST /v1/billing/checkout PayU checkout form GET /v1/health , GET /healthz Health GET /v1/memories , GET/DELETE /v1/memories/:id List / read / delete Hosted MCP ( /v1/mcp ) Secondary — 7 tools; see MCP_SERVER.md (not in OpenAPI v1) Tier B — Power-user (Worker + this doc; not quickstart-first) Route Purpose POST /v1/ingest Advanced ingest dispatch POST /v1/memories/conversation Transcript ingest Tier C — Internal / operator only (not in public OpenAPI) Route family Auth Notes /admin/* , /v1/admin/* x-admin-token Webhook reprocess, usage reconcile, session cleanup, memory hygiene/retention, billing health POST /v1/workspaces Admin API key or operator tooling Legacy workspace create GET/POST /v1/api-keys , POST /v1/api-keys/revoke x-admin-token Operator key management — not for customers POST /v1/billing/webhook PayU signature Server-to-server only GET /v1/dashboard/overview-stats Dashboard session Console-only metrics 3. Middleware order From handleRequestImpl in apps/api/src/lifecycle/handleRequestImpl.ts (health short-circuit in healthRoutes.ts ): Request-id resolve, CORS + security headers ensemble. Short-circuit health endpoints ( /healthz , /ready , /v1/health ). CORS deny if Origin is not in ALLOWED_ORIGINS (except hosted MCP paths). enforceRuntimeConfigGuards and ensureRateLimitDo . OPTIONS short-circuit. assertBodySize (bounded by MAX_BODY_BYTES / MAX_IMPORT_BYTES ). KNOWN_PATH_ALLOWED_METHODS 405 gate with Allow: header. Production dashboard ALLOWED_ORIGINS gate. createSupabaseClient(env) + db_access_path_selected log. Hosted MCP path → IP rate limit → handleHostedMcpRequest . Dashboard session POST/logout inline. Enforce route-level auth and handler dispatch via route() . Build handlerDeps , instantiate factories, call route() . 404 if route() returns null. Catch: ApiError -shaped response with error_code ; else 500 INTERNAL . Finally: emitAuditLog and request_completed structured log. 4. Error envelope Errors emitted by the outer catch in handleRequestImpl ( apps/api/src/lifecycle/handleRequestImpl.ts ) use: { &quot;error&quot; : { &quot;code&quot; : &quot;STRING_CODE&quot; , &quot;message&quot; : &quot;human readable&quot; } } Typical codes: BAD_REQUEST , UNAUTHORIZED , FORBIDDEN , NOT_FOUND , PAYLOAD_TOO_LARGE , RATE_LIMITED , CAP_EXCEEDED , TRIAL_EXPIRED , COST_BUDGET_EXCEEDED , INTERNAL . Correlate responses with the x-request-id header. 5. Rate limits, concurrency, quotas All defined in apps/api/src/auth.ts , apps/api/src/usage/quotaReservation.ts , and packages/shared/src/plans.ts . Control Default Source Per-key RPM 60 (15 for new keys, 48 h) RATE_LIMIT_MAX , RATE_LIMIT_RPM_NEW_KEY Per-workspace RPM 120 (300 for scale ) WORKSPACE_RPM_DEFAULT , WORKSPACE_RPM_SCALE Per-workspace in-flight 8 WORKSPACE_CONCURRENCY_MAX , TTL 30000 ms Cost/minute burst 15 INR WORKSPACE_COST_PER_MINUTE_CAP_INR Daily and period caps atomic via Postgres reserve_usage_if_within_cap / commit_usage_reservation Global AI cost budget fail-closed (prod) AI_COST_BUDGET_INR , 60 s cache When entitlement verification is unavailable, quota-consuming routes move into temporary read-only degradation ( ENTITLEMENT_DEGRADED , HTTP 503) until billing chec","excerpt":"MemoryNode API usage Canonical HTTP reference for the memorynode-api Cloudflare Worker. Source of truth for behavior is code in apps/api/src/ . The regenerated docs/external/openapi.yaml documents the public product surf"},{"title":"TypeScript SDK","url":"/sdk/","group":"reference","description":"SDK/API to ship — prepareContext, injectContext, saveFromTurn.","headings":["Adoption helpers","Install","Quick start","Full client (MemoryNodeClient)","SaaS copilot demo","Client options","API surface tiers","Method map","Memories (Tier A / B)","Search and context (Tier A)","Usage","Operator / internal only — Tier C","Health","Owner identity","Errors","Retry and timeouts","Re-exports"],"text":"@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&#39;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 &quot;@memorynodeai/sdk&quot; ; const memory = new MemoryNode (process. env . MEMORYNODE_API_KEY !); const ownerId = &quot;user_123&quot; ; const { contextText } = await memory. prepareContext ( &quot;How should the dashboard feel?&quot; , { ownerId, topK : 8 , }); const messages = injectContext ( [{ role : &quot;user&quot; , content : &quot;How should the dashboard feel?&quot; }], contextText, { preamble : &quot;You are a SaaS copilot.&quot; }, ); // Pass `messages` to your existing OpenAI / Anthropic / Vercel AI client await memory. saveFromTurn ({ user : &quot;How should the dashboard feel?&quot; , assistant : &quot;Use dark mode and weekly digests.&quot; , ownerId, saveAssistant : true , }); Full stack examples: docs/INTEGRATION_RECIPES.md . Install npm install @memorynodeai/sdk Quick start import { MemoryNode } from &quot;@memorynodeai/sdk&quot; ; const memory = new MemoryNode (process. env . MEMORYNODE_API_KEY !); const ownerId = &quot;user_123&quot; ; // same as your SaaS user id await memory. remember ( &quot;User prefers weekly email digests and dark mode.&quot; , { ownerId }); // LLM extraction is opt-in: pass { extract: true } when your plan allows it (default is off). const results = await memory. recall ( &quot;How should the dashboard feel for this user?&quot; , { ownerId, topK : 5 , explain : true , }); console . log (memory. formatSearchDebug (results). join ( &quot;\\n&quot; )); MemoryNode targets https://api.memorynode.ai with REST transport. Override with MEMORYNODE_BASE_URL for local Workers. Full client (`MemoryNodeClient`) import { MemoryNodeClient } from &quot;@memorynodeai/sdk&quot; ; const client = new MemoryNodeClient ({ baseUrl : &quot;https://api.memorynode.ai&quot; , apiKey : process. env . MEMORYNODE_API_KEY !, transport : &quot;rest&quot; , // default; use mcp | hybrid only for agent tooling }); await client. addMemory ({ ownerId : &quot;user_123&quot; , ownerType : &quot;user&quot; , text : &quot;User prefers weekly email digests and dark mode.&quot; , memory_type : &quot;preference&quot; , }); API key is sent as Authorization: Bearer &lt;key&gt; . 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 ?: &quot;mcp&quot; | &quot;rest&quot; | &quot;hybrid&quot; ; // default &quot;rest&quot; } Transports: rest — direct HTTPS to baseUrl (recommended for SaaS backends). mcp — hosted MCP Streamable HTTP at &lt;baseUrl&gt;/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 — require adminToken ( 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 &quot;@memorynodeai/sdk&quot; ; try { await client. search ({ ownerId : &quot;u1&quot; , query : &quot;...&quot; }); } 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 &quot;@memorynodeai/sdk&quot; ; Debugging: docs/DEBUGGING.md .","excerpt":"@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.rem"},{"title":"MCP server","url":"/mcp/","group":"reference","description":"MCP to build in Cursor and Claude — not for production backends.","headings":["When to use REST vs MCP","Safe MCP for builders","Policy (single source)","Production configuration","Hosted MCP","Endpoints","Default activation tools (always on)","Advanced tools (not in v1)","Session lifecycle and 409 handoff","Safety notes","stdio MCP","Install","Required environment","Tool surface","Upstream constraints"],"text":"MemoryNode MCP server **MCP to build.** Use MCP in Cursor, Claude Desktop, or agent IDEs while prototyping. **SDK/API to ship** in production — `POST /v1/memories` and `POST /v1/context` (see [Two-call integration](./TWO_CALL_INTEGRATION.md)). **MCP is for building in Cursor and Claude. SDK/API is for shipping production apps.** Same memory, same API key. MemoryNode exposes two MCP surfaces: Hosted MCP — Streamable HTTP JSON-RPC at POST /v1/mcp and POST /mcp ( https://mcp.memorynode.ai/mcp or https://api.memorynode.ai/v1/mcp ) stdio MCP — local binary memorynode-mcp from @memorynodeai/mcp-server Both call the same REST backend ( /v1/memories , /v1/search , /v1/context , …) and enforce the same quota, plan, and rate-limit rules as direct REST. When to use REST vs MCP Use case Choose Production SaaS backend (chat, copilot, workflows) REST or @memorynodeai/sdk — two-call remember → recall Cursor, Claude Desktop, local agent editors Hosted MCP or stdio MCP Explicit schemas, idempotency keys, server-side retries REST first Billing and usage in production REST or console — not MCP MCP must not replace the two-call REST flow in product docs, quickstarts, or console onboarding. Safe MCP for builders Use MCP when a builder tool (Cursor, Claude Desktop, agent IDE) needs memory — not as your production SaaS backend. Step Action 1 Prove REST/SDK in Playground first 2 Configure stdio or hosted MCP ( Integration recipes ) 3 Call context before the agent answers 4 Call memory only for durable, user-confirmed facts Policy defaults deny unsafe writes; see Policy below. Full agent recipe: Integration recipes — MCP for builders . Policy (single source) Hosted and stdio MCP both use McpPolicyEngine from @memorynodeai/shared ( packages/shared/src/mcpPolicy.ts ). Policy contract version: MCP_POLICY_VERSION (currently 2026-04-19.1 ; see SUPPORTED_MCP_POLICY_VERSIONS ). Hosted MCP negotiates via optional request header x-mcp-policy-version (comma-separated client list). Tool denials return stable action_id , policy_version , and error codes — same engine for stdio and hosted. Implementation packages: @memorynodeai/mcp-core (hosted tool registry), @memorynodeai/mcp-server (stdio adapter). There is no separate forked policy for stdio vs hosted. Production configuration Variable Production Purpose MCP_INTERNAL_SECRET Required (secret) Authenticates hosted MCP internal fetch to /v1/* ; never expose to browsers MCP_ADVANCED_TOOLS_ENABLED Optional Extended hosted tools are not registered in v1 MEMORYNODE_REST_ORIGIN Optional REST origin for MCP worker subrequests (default https://api.memorynode.ai on mcp.memorynode.ai ) MCP_AUDIT_LOG_REQUIRES_TEAM Optional Operator-only; extended hosted tools are not registered in v1 MCP_CONNECTOR_SETTINGS_REQUIRES_TEAM Optional Operator-only; not part of the public MCP catalog MCP_SESSION_DO Binding (Wrangler) Durable Object for session registry metadata; transport may still be in-process per isolate MCP_ADVANCED_TOOLS_ENABLED is not set in apps/api/wrangler.toml production [vars] . Enable only deliberately for operator workflows. Hosted MCP Endpoints Method Path Purpose POST /v1/mcp , /mcp JSON-RPC request ( initialize , tools/list , tools/call ) GET /v1/mcp , /mcp Browser landing or SSE subscription DELETE /v1/mcp , /mcp Close session Authentication uses the same API key as REST ( Authorization: Bearer &lt;key&gt; or x-api-key ). Default activation tools (always on) P1 / activation tools are registered without MCP_ADVANCED_TOOLS_ENABLED : Tool REST equivalent Purpose memory / memory_save POST /v1/memories Store durable memory memory_list GET /v1/memories List memories for scope memory_forget (policy-gated) Request forget / archive flow memory_forget_confirm (policy-gated) Confirm forget after policy check recall / search POST /v1/search Retrieve relevant memories context / context_pack POST /v1/context Prompt-ready context pack whoAmI / identity_get scope resolution Inspect workspace and owner scope Canonical v1 names: memory_save , memory_list , memory_forget , memory_forget_confirm , search , context_pack , identity_get (see HOSTED_V1_PUBLIC_TOOL_NAMES in @memorynodeai/mcp-core ). Use the same owner_id / user_id as REST. Omitting owner fields resolves to default-user (demos only). Advanced tools (not in v1) Extended hosted tools beyond the seven public tools are not registered in the current Worker build. Use REST or the console for billing and usage. Session lifecycle and 409 handoff Hosted MCP uses an in-process transport per Worker isolate plus a Durable Object session registry. Clients should send mcp-session-id after initialize . HTTP Meaning Client action 409 Session exists in registry but transport is on another isolate ( mcp_session_handoff_required ) Reinitialize: DELETE optional, then initialize again, store new mcp-session-id , retry pending tools/call 404 Unknown session ( not_found ) or idle TTL exceeded ( expired ) Reinitialize MCP session; do not reuse old session id 401 API key mismatch for session Fix key; reinitialize with correct key 409 response shape (JSON-RPC envelope, HTTP 409): { &quot;jsonrpc&quot; : &quot;2.0&quot; , &quot;error&quot; : { &quot;code&quot; : -32000 , &quot;message&quot; : &quot;Session transport unavailable on this isolate. Reinitialize MCP session.&quot; } , &quot;id&quot; : null } Safe retry pattern after 409 or 404: Drop the stored mcp-session-id . Send JSON-RPC initialize (same API key and protocol version). Read the new mcp-session-id from response headers. Retry tools/list / tools/call — use idempotent writes ( request_id on REST-backed saves where applicable). Cross-isolate routing is expected on Cloudflare Workers; re-init is the supported recovery — not a Durable Object transport upgrade in the current release. Safety notes Hosted MCP goes through policy checks and rate limits identical to REST. Trial write gates match REST behavior. Responses include x-request-id for support. Advanced billing, audit, and connector tools are opt-in only. stdio MCP Install npm install -g @memorynodeai/mcp-server memorynode-mcp Required environment Variable Required Purpose MEMORYNODE_API_KEY yes Bearer key for REST calls MEMORYNODE_BASE_URL yes REST API base URL, e.g. https://api.memorynode.ai MEMORYNODE_USER_ID no Default owner id for tool calls MEMORYNODE_NAMESPACE no Default namespace MEMORYNODE_TIMEOUT_MS no Per-request timeout Tool surface The stdio binary keeps the tool set intentionally small: recall context memory whoAmI Legacy aliases such as memory_search , memory_context , and memory_insert are removed; use canonical tools only. Upstream constraints top_k is capped at 10 for recall / search containerTag is capped at 128 chars Policy can deny unsafe repetition or forbidden scopes REST remains the canonical integration surface for app backends For package layout, see packages/mcp-server/README.md . For HTTP facts, see docs/external/API_USAGE.md . For deploy secrets, see docs/internal/DEPLOYMENT.md .","excerpt":"MemoryNode MCP server **MCP to build.** Use MCP in Cursor, Claude Desktop, or agent IDEs while prototyping. **SDK/API to ship** in production — `POST /v1/memories` and `POST /v1/context` (see [Two-call integration](./TWO"},{"title":"Security","url":"/security/","group":"legal","description":"Authentication modes, controls, and customer responsibilities.","headings":["Authentication modes","Core controls","Secrets","Customer responsibilities"],"text":"Security posture MemoryNode runs as a single Cloudflare Worker with Supabase as the data plane. This document captures the current launch security model. Authentication modes API routes use x-api-key (hashed at rest). Dashboard routes use session cookie + CSRF token. Admin routes use x-admin-token and optional ADMIN_ALLOWED_IPS allowlist. Billing webhook routes verify PayU callbacks via reverse SHA-512 (or HMAC-SHA256 fallback) using PAYU_MERCHANT_SALT . Core controls Per-key and per-route rate limits. Workspace concurrency caps for write-heavy routes. Cost guardrails for AI-heavy operations. Request ID and audit event logging for privileged operations. Tenant isolation checks on memory read/write/search paths. Webhook internal token auth is route-bound to POST /v1/memories only (not accepted as a general alternate auth mode across routes). Secrets Production secrets are configured in your deployment platform (Cloudflare Worker secrets for the API). Never commit secrets to git. Required production configuration is validated before release ( pnpm check:config in CI). Local examples use *.example env templates only. Customer responsibilities Rotate API keys from the console if a key may have leaked. Scope memories per end-user with explicit user_id / owner_id in production (default default-user is for quickstarts only). Restrict dashboard access to trusted team members; session cookies are HttpOnly + CSRF-protected.","excerpt":"Security posture MemoryNode runs as a single Cloudflare Worker with Supabase as the data plane. This document captures the current launch security model. Authentication modes API routes use x-api-key (hashed at rest). Da"},{"title":"Privacy Policy","url":"/privacy/","group":"legal","description":"MemoryNode privacy policy.","headings":["What we collect","Why we use it","Processors and infrastructure","Retention","Your choices","Billing region","Contact","Changes"],"text":"Privacy Policy Last updated: May 2025 MemoryNode (&quot;we&quot;, &quot;us&quot;) operates the MemoryNode API and console at memorynode.ai . This policy describes how we handle personal data. What we collect Account data: email address and authentication identifiers (e.g. via Google, GitHub, or magic link). API and memory content: text and metadata you store through the API (memories, search queries, embeddings-derived indexes). Usage data: request counts, quotas, billing period usage, and operational logs (including x-request-id for support). Why we use it Provide and secure the memory API and console. Enforce plan limits, billing, and abuse protection. Improve reliability and support. Processors and infrastructure We use subprocessors to run the service, including: Supabase (database, authentication) Cloudflare (API hosting, Pages for console and docs) OpenAI (embeddings and optional AI features when enabled on your plan) Data is stored in the region configured for your Supabase project. Contact us if you need the current production region. Retention We retain account and memory data while your account is active and as needed for billing, security, and legal obligations. You may request deletion by contacting support@memorynode.ai . Your choices Rotate or revoke API keys in the console. Sign out and stop using the service. Email us to request access, correction, or deletion where applicable. Billing region Self-serve checkout is PayU in INR via the console . Contact support@memorynode.ai Changes We may update this policy. Material changes will be reflected on this page with an updated date.","excerpt":"Privacy Policy Last updated: May 2025 MemoryNode (&quot;we&quot;, &quot;us&quot;) operates the MemoryNode API and console at memorynode.ai . This policy describes how we handle personal data. What we collect Account data"},{"title":"Terms of Service","url":"/terms/","group":"legal","description":"MemoryNode terms of service.","headings":["The Service","Accounts and API keys","Acceptable use","Plans, trial, and billing","Your content","Disclaimers","Limitation of liability","Termination","Governing law","Contact","Changes"],"text":"Terms of Service Last updated: May 2025 These Terms govern your use of MemoryNode&#39;s API, console, and related services (&quot;Service&quot;). By creating an account or using the Service, you agree to these Terms and our Privacy Policy . The Service MemoryNode provides memory and context infrastructure for AI applications: persistent user-scoped memory and prompt-ready context. Production apps integrate via REST API and TypeScript SDK. MCP is for building in Cursor and Claude only — not a production backend. Accounts and API keys You are responsible for your account credentials and API keys. Do not share keys in public repositories or client-side code. You are responsible for activity under your workspace and keys. Acceptable use You agree not to: Violate applicable law or third-party rights. Upload unlawful, abusive, or infringing content. Attempt to bypass quotas, authentication, or security controls. Resell or overload the Service without written agreement. We may suspend or terminate access for violations. Plans, trial, and billing New workspaces receive a free trial (14 days or trial usage limits, whichever comes first). Self-serve paid plan: Build , billed in INR via PayU through the console. Higher tiers ( Deploy , Scale ) require written agreement and are not available in self-serve checkout. Usage caps are enforced per billing period; there is no automatic overage billing unless separately agreed. Refunds and cancellations follow PayU and our billing policies communicated at checkout. Your content You retain rights to content you submit. You grant us the rights necessary to host, process, and display that content to provide the Service (including embeddings and search indexes). Disclaimers THE SERVICE IS PROVIDED &quot;AS IS&quot; WITHOUT WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WE DO NOT GUARANTEE UNINTERRUPTED OR ERROR-FREE OPERATION. Limitation of liability TO THE MAXIMUM EXTENT PERMITTED BY LAW, MEMORYNODE AND ITS OPERATORS WILL NOT BE LIABLE FOR INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, OR ANY LOSS OF PROFITS, DATA, OR GOODWILL. OUR AGGREGATE LIABILITY FOR CLAIMS RELATING TO THE SERVICE IS LIMITED TO THE AMOUNTS YOU PAID US IN THE TWELVE (12) MONTHS BEFORE THE CLAIM, OR INR 10,000, WHICHEVER IS GREATER. Termination You may stop using the Service at any time. We may suspend or terminate access for breach, risk, or discontinuation of the Service with reasonable notice where practicable. Governing law These Terms are governed by the laws of India . Courts in India have exclusive jurisdiction, subject to mandatory consumer protections in your jurisdiction. Contact support@memorynode.ai — billing inquiries: billing@memorynode.ai Changes We may update these Terms. Continued use after the updated date constitutes acceptance of the revised Terms.","excerpt":"Terms of Service Last updated: May 2025 These Terms govern your use of MemoryNode&#39;s API, console, and related services (&quot;Service&quot;). By creating an account or using the Service, you agree to these Terms and "}]