TypeScript SDK

npm install @mnueron/sdk — Node, Deno, Bun, Workers, browsers.

The TypeScript SDK is the lightest way to use mnueron from any JS runtime. Zero runtime dependencies, dual ESM + CommonJS builds, works in Node 18+, Deno, Bun, Cloudflare Workers, and browsers (CORS permitting).

Install

npm install @mnueron/sdk

Quick start

import { Mnueron } from '@mnueron/sdk';

const m = new Mnueron({ apiKey: 'mnu_...' });   // or set MNUERON_API_KEY env

// Save
const mem = await m.save('User prefers concise replies', {
  namespace: 'my-app',
  tags: ['preferences'],
});

// Full-text search (BM25 server-side)
const hits = await m.search('how does the user like responses?', {
  namespace: 'my-app',
  k: 5,
});
for (const r of hits) console.log(r.content, r.score);

// Partial update — metadata MERGED (pass null in values to delete a key)
await m.update(mem.id, {
  tags: ['preferences', 'tone'],
  metadata: { confidence: 0.9 },
});

await m.delete(mem.id);

Configuration

Set the env var once and the constructor picks it up automatically:

export MNUERON_API_KEY=mnu_xxxxxxxxxxxxxxxxxxxxx
# Optional — default is https://www.mnueron.com
export MNUERON_API_URL=https://www.mnueron.com
const m = new Mnueron();   // reads env

Date + metadata filters

Date values are epoch milliseconds. metadata_filter is passed to Postgres' @> jsonb containment operator.

const yesterday = Date.now() - 24 * 60 * 60 * 1000;
const recent = await m.list({
  namespace: 'my-app',
  created_after: yesterday,
  metadata_filter: { speaker: 'sarah' },
});

Up to 25 queries in one HTTP round-trip:

const results = await m.bulkSearch(
  ['onboarding', 'billing edge cases', 'JWT setup'],
  { namespace: 'work', k: 5 },
);

for (const r of results) {
  console.log(r.query, '→', r.hits.length, 'hits');
}

Webhooks

Register a delivery endpoint:

const hook = await m.createWebhook('https://example.com/mnueron-hook', {
  events: ['memory.saved', 'memory.deleted'],
  description: 'forward saves into our event bus',
});
console.log('Store this once — won\'t appear again:', hook.secret);

Verify incoming deliveries — works in Node, Workers, Deno, Bun. The verifier uses Node's node:crypto when available and falls back to Web Crypto everywhere else, so the same code runs in any runtime.

import { verifyWebhookSignature } from '@mnueron/sdk';

// Express
app.post('/mnueron-hook',
  express.raw({ type: 'application/json' }),
  async (req, res) => {
    const sig = req.header('X-Mnueron-Signature');
    const ok = await verifyWebhookSignature(secret, req.body, sig);
    if (!ok) return res.status(401).end();
    // ... handle payload
    res.status(200).end();
  },
);

// Next.js App Router
export async function POST(req: Request) {
  const raw = new Uint8Array(await req.arrayBuffer());
  const sig = req.headers.get('x-mnueron-signature');
  if (!(await verifyWebhookSignature(secret, raw, sig))) {
    return new Response('invalid signature', { status: 401 });
  }
  // ... handle JSON.parse(new TextDecoder().decode(raw))
  return new Response(null, { status: 204 });
}

Combine with an LLM client

import OpenAI from 'openai';
import { Mnueron } from '@mnueron/sdk';

const m = new Mnueron();
const llm = new OpenAI();

const context = await m.search(userMessage, { namespace: 'user-123', k: 5 });
const promptContext = context.map((r) => r.content).join('\n');

const reply = await llm.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [
    { role: 'system', content: `Relevant context:\n${promptContext}` },
    { role: 'user', content: userMessage },
  ],
});

// Opt into v0.2.9 fact extraction on this save
await m.save(reply.choices[0].message.content!, {
  namespace: 'user-123',
  source: 'auto',
  metadata: { extract_facts: true },
});

Same shape works with @anthropic-ai/sdk, Mistral, Gemini, or any other client.

Edge runtimes

The SDK is bundler-friendly and ships no Node-only code in the import path. It runs unmodified in:

  • Cloudflare Workers
  • Vercel Edge Functions
  • Deno Deploy
  • Bun's edge-style handlers
  • Modern browsers (set apiKey explicitly — no process.env there)

API reference

MethodReturnsNotes
save(content, opts?)MemorySingle insert. Fires memory.saved webhooks.
search(query, opts?)Memory[]BM25 search with stacking filters.
bulkSearch(queries, opts?)BulkSearchResult[]Up to 25 queries per batch.
list(opts?)Memory[]Newest-first; supports date + metadata filters.
get(id)Memory | nullReturns null on 404.
update(id, patch)MemoryPartial; metadata is merged.
delete(id)voidFires memory.deleted webhooks.
namespaces()string[]All namespaces in your org.
health(){ ok: true }Liveness probe.
listWebhooks() / createWebhook() / getWebhook() / updateWebhook() / deleteWebhook()Full CRUD over webhook subscriptions.
verifyWebhookSignature(secret, body, sigHeader)Promise<boolean>Constant-time HMAC-SHA256 check. Exported as a standalone function too.

Throws a typed MnueronError on non-2xx responses with the server's error message attached.

Source

github.com/randi2160/mnueron/tree/main/sdks/typescript

Last updated 2026-05-26edit