MemLibMemLib

Namespaces & Entities

How MemLib organizes memories with namespace and entity scoping

The Two-Level Scope

Every memory in MemLib belongs to a namespace and an entity. Together, these create a two-level hierarchy for organizing memories:

namespace: "my-app"
├── entity: "user-alice"
│   ├── "Prefers dark mode"
│   ├── "Uses TypeScript"
│   └── "Lives in Berlin"
├── entity: "user-bob"
│   ├── "Likes Python"
│   └── "Works at Acme Corp"
└── entity: "team-eng"
    └── "Sprint planning on Mondays"

Namespace

A namespace is the top-level scope — typically your application name, tenant ID, or project identifier.

  • All operations are scoped to a namespace
  • Memories in different namespaces are fully isolated
  • Think of it as a "database" within your MemLib project

Entity

An entity is the sub-scope within a namespace — typically a user ID, session ID, or agent ID.

  • Most operations require both namespace and entity
  • Recall searches within a single entity by default
  • Think of it as a "table" within a namespace

Setting Scope

You can set namespace and entity in two ways:

Constructor Defaults

Set them once when creating the client. All operations will use these defaults:

const mem = new MemLib({
  apiKey: "sk_...",
  namespace: "my-app",
  entity: "user-alice",
});

// These use namespace="my-app", entity="user-alice"
await mem.store({ content: "Likes hiking" });
await mem.recall({ query: "hobbies" });

Per-Call Overrides

Override the defaults for a specific operation:

// Store to a different entity
await mem.store({
  content: "Meeting with Alice at 2pm",
  namespace: "my-app",
  entity: "user-bob",
});

// Recall from a different namespace entirely
await mem.recall({
  query: "project deadlines",
  namespace: "work-tracker",
  entity: "team-eng",
});

Common Patterns

Per-User Memory

The most common pattern — each user has their own memory space:

const mem = new MemLib({
  apiKey: "sk_...",
  namespace: "my-chatbot",
  entity: `user-${userId}`,
});

Per-Session Memory

For applications that track conversational context per session:

const mem = new MemLib({
  apiKey: "sk_...",
  namespace: "my-app",
  entity: `session-${sessionId}`,
});

Multi-Agent Systems

Each agent maintains its own memory, scoped by agent name:

// Research agent
const researchMem = new MemLib({
  apiKey: "sk_...",
  namespace: "research-project",
  entity: "agent-researcher",
});

// Coding agent
const codeMem = new MemLib({
  apiKey: "sk_...",
  namespace: "research-project",
  entity: "agent-coder",
});

Shared Knowledge Base

Use a single entity for team-wide or global knowledge:

const shared = new MemLib({
  apiKey: "sk_...",
  namespace: "company",
  entity: "shared",
});

Scoping in the REST API

When using the REST API directly, namespace and entity are required fields in every request body:

curl -X POST https://mem.anishroy.com/api/v1/memory \
  -H "Authorization: Bearer sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "namespace": "my-app",
    "entity": "user-alice",
    "content": "Prefers dark mode"
  }'

For list operations, entity is optional — you can list all memories across entities in a namespace.


Important Notes

  • Namespace + entity = isolation boundary. Recall and prepare only search within a single namespace/entity pair.
  • No implicit sharing. Memories stored under one entity are never returned when querying a different entity.
  • Consolidation is scoped. Memory consolidation groups by (namespace, entity, category), so unrelated facts are never merged together.
  • Diff is scoped. The memory changelog only returns events within the specified namespace/entity.

On this page