Agent Memory

SDKs (Node, Python, .NET)

Install the Node, Python, and .NET client libraries and run the basic memory loop.

The three client libraries use the same REST contract: recall, write, report the outcome, forget. This page covers installation and the basic loop.

SDKPackageExecution modelCoverage
Nodeagentmemory 0.4.0 (ESM, Node ≥ 18, no dependencies)All methods return a Promiseadd, search, get, update, share, delete, erasure, operation, explain, outcome, feedback
Pythonagentmemory 0.4.0 (Python ≥ 3.9, standard library only)SynchronousSame as Node
.NETAgentMemory.Client (project reference)Async + CancellationTokenAll of the above + consolidate, blocks

Consolidation and block operations are not in the Node/Python SDKs; use the MCP tools or the REST endpoints for these.

Installation

The packages are not published on the public npm/PyPI registries. Your service distributes them under /sdk/:

# Node
npm install $API/sdk/agentmemory-0.4.0.tgz

# Python
pip install $API/sdk/agentmemory-0.4.0-py3-none-any.whl

If you are working from the repository, you can also install from a local path: npm install ./clients/node, pip install ./clients/python.

Do not type just npm install agentmemory or pip install agentmemory: a different package with the same name on the public registry may be installed.

The SDKs do not read environment variables; you pass the address, key, and workspace from your code. Read the key from a secret store or an environment variable.

import { AgentMemoryClient } from 'agentmemory'

const memory = new AgentMemoryClient({
  apiKey: process.env.AGENT_MEMORY_API_KEY,
  baseUrl: process.env.AGENT_MEMORY_URL,      // e.g. https://memory.empecta.com
  workspaceId: process.env.AGENT_MEMORY_WS,
})

// write — if userId is an end user, the key needs the "act for users" permission
const { id, operationId } = await memory.add('The weekly report is sent as a PDF', {
  type: 'preference', userId: 'demo-user', runId: 'run-1', sourceKind: 'user',
  idempotencyKey: 'pref-weekly-report',
})
await memory.operation(operationId)            // { status: 'pending' | ..., effects: [...] }

// recall — keep the receiptId
const context = await memory.search('weekly report format', { userId: 'demo-user', runId: 'run-1' })
console.log(context.workspaceEntries.map(e => e.content))

// report the outcome — same runId and receiptId
await memory.outcome({ runId: 'run-1', buildSuccess: true, receiptId: context.receiptId })

// forget
const { status } = await memory.delete(id)      // 'deleted' | 'pending' | 'blocked' | 'not_found' | 'forbidden'
await memory.erasure(id)                        // { status: 'complete', ... }

Other methods: get(id), update(id, content, { ifMatch }), share(id, visibility), explain(id), feedback(report).

Common rules

  1. Do not send agentId. The agent your key is bound to performs the operation. If the key is bound to multiple agents and you want to pick another one, pass it; a name the key is not bound to returns 403.
  2. userId is a person, not an agent. Sending it requires the key's act for users permission; otherwise you get 403 policy_denied (identity-binding).
  3. A receipt belongs to a run. In outcome/feedback calls, use the same runId as the search that produced the receiptId; reporting a record the receipt did not deliver as "used" returns 400 RECEIPT_MISMATCH.
  4. Deletion can be pending. The record is blanked immediately; derived copies are cleaned up afterwards. Track it with erasure. A record with live derived records returns blocked; retry with cascade.
  5. Errors. Node and Python throw AgentMemoryError (status, body) for every unmapped HTTP error; .NET throws HttpRequestException.

Use agent, user, document, or import for sourceKind. tool and conversation, which appear in the Node type definitions, are not accepted by the server.

On this page