One call. Any agent.

Install nmemo-sdk, retrieve a grounded context package, and pass it to the model or framework you already use.

Install

Published publicly as nmemo-sdk.

npm

npm install nmemo-sdk

createEngine

import { createEngine } from "nmemo-sdk"

const engine = createEngine({
  apiKey: process.env.NMEMO_API_KEY!,
  // baseUrl defaults to https://api.nmemo.cloud
})

Create the engine once on your server and reuse it for every turn. Keep the API key out of browser code. Current release: nmemo-sdk@0.1.0.

The idea

Context in. Agent out.

Your agent already knows how to talk, use tools, and call a model. What it usually lacks is the right context for this user, this workspace, this question.

That is what nmemo provides. One call returns a ready prompt, the context your agent should see, plus citations you can show next to the answer.

The flow

General pattern for every turn.

  1. 01

    User talks to your agent

    A chat message, a support ticket, a voice turn, whatever your product already handles.

  2. 02

    Ask nmemo for context

    Call getContext() with the query and who is asking. We pull from the sources in your workspace and assemble what matters.

  3. 03

    Give context to the agent

    Pass context.prompt as the agent’s instructions / system context. Keep the user message as the user message.

  4. 04

    Agent answers as usual

    Your model, tools, and orchestration stay yours. nmemo does not replace the agent, it feeds it.

  5. 05

    Show sources, remember the turn

    Use citations in the UI. Write the exchange back to memory so the next turn is smarter.

Core pattern

Framework-agnostic on purpose.

Give context to the agent

import { createEngine } from "nmemo-sdk"

const engine = createEngine({
  apiKey: process.env.NMEMO_API_KEY!,
})

// 1. Get context for this turn
const context = await engine.getContext({
  query: userMessage,
  userId,
  workspaceId,
  conversationId,
})

// 2. Give that context to your agent
const reply = await yourAgent.run({
  instructions: context.prompt, // what the agent should know
  input: userMessage,           // what the user just said
})

// 3. Optionally remember the turn
await engine.writeMemory({
  userId,
  workspaceId,
  messages: [
    { role: "user", content: userMessage },
    { role: "assistant", content: reply },
  ],
})

// 4. Show sources in your UI
return { reply, citations: context.citations }

yourAgent.run is a stand-in. Swap it for OpenAI, Anthropic, the Vercel AI SDK, LangChain, Mastra, LlamaIndex, or a custom loop, the nmemo part stays the same.

How you pass context in

Every stack has a place for “what the agent should know.” That place is where context.prompt goes.

Same idea, different APIs

// OpenAI-style
messages: [
  { role: "system", content: context.prompt },
  { role: "user", content: userMessage },
]

// Anthropic-style
{ system: context.prompt, messages: [{ role: "user", content: userMessage }] }

// AI SDK / LangChain / custom
agent.run({ system: context.prompt, prompt: userMessage })
// or
llm.invoke([system(context.prompt), human(userMessage)])

Works with any agent stack

If it takes instructions, it takes nmemo.

  • Chat agents

    Support bots, copilots, internal assistants, context before each reply.

  • Tool-using agents

    Give grounded context first, then let tools run on top of that.

  • Voice agents

    Use getContextFast() so each utterance still gets useful context.

  • Multi-agent systems

    Each agent can request context with its own agent label and the same workspace.

  • Any model

    OpenAI, Anthropic, Google, open models, if it reads a system prompt, you’re fine.

  • Any framework

    AI SDK, LangChain, LangGraph, Mastra, LlamaIndex, or plain fetch + messages[].

getContext

IDs you pass every turn.

  • queryWhat the user said this turn, the question the agent must answer.
  • userIdWho is asking in your product. Scopes personal memory, use your app’s user id.
  • workspaceIdWhich workspace’s sources to use. Copy it from Settings or Keys in the dashboard.
  • conversationIdOptional. One id per chat/thread/call so turns stay linked.
  • agentOptional. Name of the agent asking, useful when many agents share a workspace.

What you get back

Give prompt to the agent. Keep the rest for your product.

GetContextResult

type GetContextResult = {
  prompt: string       // give this to the agent
  memories: ...
  documents: ...
  sources: ...
  citations: ...       // show these in the UI
  tokenUsage: ...
  diagnostics: ...     // use these while building
}
  • promptContext for the agent, pass this as instructions / system.
  • citationsSources to show next to the answer.
  • memories / documentsStructured hits if you want to render or debug them yourself.
  • sourcesWhich connected sources were queried and how they performed.
  • tokenUsageHow much context budget this turn used.
  • diagnosticsWhy things were kept or dropped, for you while building, not end users.

Do and don't

Do

  • Give context.prompt to the agent as instructions / system context.
  • Keep the user’s message as the user message.
  • Call getContext() once per turn, before the agent runs.
  • Pass stable userId + workspaceId every time.
  • Show citations with the answer.
  • Write the turn to memory after the agent replies.

Don't

  • Don’t paste context into a fake user message.
  • Don’t rebuild your own retrieval on top of the same sources.
  • Don’t skip userId or mix conversationIds across users.
  • Don’t call getContext() after the agent already answered.
  • Don’t put API keys in the browser.
  • Don’t show raw diagnostics to end users.

Remember the turn

So the next ask has context too.

writeMemory

await engine.writeMemory({
  userId,
  workspaceId,
  messages: [
    { role: "user", content: userMessage },
    { role: "assistant", content: reply },
  ],
})

After the agent answers, store the exchange. The next getContext() can use it.

Faster path

Same idea, less wait, for voice and live turns.

getContextFast

const context = await engine.getContextFast({
  query: userMessage,
  userId,
  workspaceId,
  conversationId,
})

// Still: give context.prompt to the agent

Next

See a live result in the playground, then wire the same context.prompt into your agent.