npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@memra-client/client

v0.3.0

Published

Persistent memory for AI agents — official JS/TS client

Readme

@memra-client/client

Persistent memory for AI agents. Give your LLM apps long-term memory — save conversations, retrieve semantically relevant context, and manage memory across sessions.

Installation

npm install @memra-client/client

Quick Start

import MemoryClient from '@memra-client/client'

const client = new MemoryClient({
  apiKey: 'mk_live_...',
  // Default: https://memra-rho.vercel.app/api
  // Override for self-hosted deployments:
  // baseUrl: 'https://your-memra-instance.com/api'
})

Self-hosting? Pass baseUrl to point the client at your own Memra deployment. All methods use this base URL for every API call.

Usage

Save a Conversation Turn

After every AI response, save the exchange to memory:

await client.save(
  'user_123',           // userId
  'What is TypeScript?', // user message
  'TypeScript is...',    // AI reply
  { agentId: 'my-bot' } // optional
)

Get an AI Response (with memory)

Send a message and get an AI reply — Memra automatically injects relevant memory context:

const { reply } = await client.respond(
  'What did we talk about yesterday?',
  { userId: 'user_123', agentId: 'my-bot' }
)
console.log(reply)

Get Relevant Context

Before sending a prompt to your LLM, fetch context — includes recent conversation history, semantically relevant memories, and the backwards-compatible context array:

const { context, recentHistory, relevantMemories, count, latencyMs } = await client.getContext(
  'user_123',
  'TypeScript questions',
  { limit: 5, recentLimit: 10 }
)

// recentHistory — last N messages in chronological order
// Fixes the "what's my name?" problem: the AI can see recent conversation flow
recentHistory.forEach(m => console.log(`${m.role}: ${m.content}`))

// relevantMemories — semantically similar past messages (deduplicated against recent)
relevantMemories.forEach(m => console.log(`[${m.similarity}] ${m.content}`))

// context — same as before, for backwards compatibility
context.forEach(memory => {
  console.log(memory.content)
  console.log(memory.role)
  console.log(memory.similarity)
  console.log(memory.createdAt)
})

Get Full Conversation History

Retrieve paginated chat history for a user — no need to store conversations in your own database:

const { history, total, count, hasMore, cursors } = await client.getHistory(
  'user_123',
  { limit: 50, order: 'desc' }
)

// Paginate through older messages using cursors
if (hasMore) {
  const older = await client.getHistory('user_123', {
    limit: 50,
    before: cursors.before,
  })
}

Forget / Delete Memory

Wipe all memory for a user:

const { success, deleted } = await client.forget(
  'user_123',
  { agentId: 'my-bot' } // optional
)

Error Handling

All methods throw descriptive errors that include the API error code when available:

try {
  await client.save('user_123', 'hello', 'hi')
} catch (err) {
  // e.g. "Memra save failed: 403 — WRONG_KEY_TYPE"
  // e.g. "Memra respond failed: 429 — RATE_LIMIT"
  console.error(err.message)
}

API Reference

new MemoryClient(options)

| Option | Type | Required | Description | |--------|------|----------|-------------| | apiKey | string | ✅ | Your Memra API key | | baseUrl | string | ❌ | API base URL (default: https://memra-rho.vercel.app/api). Override for self-hosted deployments. |


client.save(userId, userMessage, aiReply, options?)

Saves a conversation turn (user message + AI reply) to memory.

| Parameter | Type | Description | |-----------|------|-------------| | userId | string | Unique identifier for the user | | userMessage | string | The message sent by the user | | aiReply | string | The AI's response | | options.agentId | string | Agent identifier (default: "default") |

Returns { success: boolean, saved: number }


client.respond(message, options)

Sends a message to the Memra chat endpoint and returns an AI reply with memory-augmented context. Requires an API key.

| Parameter | Type | Description | |-----------|------|-------------| | message | string | The user's message | | options.userId | string | Unique identifier for the user (required) | | options.agentId | string | Agent identifier (default: "default") |

Returns { reply: string }


client.getContext(userId, query, options?)

Retrieves recent history and semantically relevant memories for a query. Use this to inject past context into your LLM prompt.

| Parameter | Type | Description | |-----------|------|-------------| | userId | string | Unique identifier for the user | | query | string | Search query to find relevant memories | | options.agentId | string | Agent identifier (default: "default") | | options.limit | number | Max semantic results to return (default: 5) | | options.recentLimit | number | Max recent messages to return (default: 10) |

Returns: | Field | Type | Description | |-------|------|-------------| | context | Memory[] | Backwards-compatible semantic matches | | recentHistory | Memory[] | Recent messages in chronological order | | relevantMemories | Memory[] | Semantic matches, deduplicated against recent history | | count | number | Total number of results | | latencyMs | number | Client-measured round-trip latency |


client.getHistory(userId, options?)

Retrieves paginated conversation history for a user. Use this to build chat UIs or store conversations without needing your own database.

| Parameter | Type | Description | |-----------|------|-------------| | userId | string | Unique identifier for the user | | options.agentId | string | Filter by agent identifier | | options.limit | number | Max messages to return (default: 50, max: 100) | | options.order | 'asc' \| 'desc' | Sort order (default: 'desc') | | options.before | string | ISO date cursor — get messages before this date | | options.after | string | ISO date cursor — get messages after this date |

Returns: | Field | Type | Description | |-------|------|-------------| | history | Memory[] | Array of messages | | total | number | Total messages available | | count | number | Messages returned in this page | | hasMore | boolean | Whether more pages exist | | cursors | { before, after } | Cursors for pagination |


client.forget(userId, options?)

Deletes all stored memory for a user.

| Parameter | Type | Description | |-----------|------|-------------| | userId | string | Unique identifier for the user | | options.agentId | string | Agent identifier (default: "default") |

Returns { success: boolean, deleted: number }


Memory Object

Every memory returned has this shape:

{
  id: string         // unique memory ID
  content: string    // the message content
  role: string       // 'user' or 'assistant'
  createdAt: string  // ISO timestamp
  similarity?: number // relevance score (only in getContext)
}

Full Example — LLM with Memory

import MemoryClient from '@memra-client/client'

const memory = new MemoryClient({ apiKey: 'mk_live_...' })
const userId = 'user_123'
const userMessage = 'Tell me about black holes'

// Step 1 — get context (recent history + relevant memories)
const { recentHistory, relevantMemories } = await memory.getContext(userId, userMessage)

// Step 2 — build prompt with both recent and relevant context
const prompt = `
  Recent conversation:
  ${recentHistory.map(m => `${m.role}: ${m.content}`).join('\n')}

  Relevant past memories:
  ${relevantMemories.map(m => `${m.role}: ${m.content}`).join('\n')}

  User: ${userMessage}
`

// Step 3 — call your LLM (any provider)
const aiReply = await yourLLM.complete(prompt)

// Step 4 — save the exchange to memory
await memory.save(userId, userMessage, aiReply)

License

MIT © Memra