Skip to main content
The @kyberon/memproof TypeScript SDK is a native library that implements the full Memproof control pipeline locally. It is not an HTTP client — it runs the same risk scoring, policy evaluation, and Trailproof audit trail logic as the Python SDK, directly in your Node.js process.

Installation

npm install @kyberon/memproof

Quick Start

import { Memproof } from "@kyberon/memproof";

const mp = new Memproof({ policy: "./memproof.yaml" });

const result = await mp.remember(
  "User prefers dark mode",
  { tenantId: "acme", projectId: "chatbot", agentId: "a1" },
  {
    actorType: "agent",
    actorId: "a1",
    source: "langgraph",
    timestamp: new Date(),
  },
);

console.log(result.status);      // "committed" or "pending_approval"
console.log(result.operationId); // "op-abc123..."

API Methods

The Memproof class exposes these methods:
MethodDescription
remember(content, scope, context)Create a new memory through the control path
get(memoryId)Retrieve a memory by ID
update(memoryId, context, options)Update a memory through the control path
forget(memoryId, context)Delete a memory through the control path
search(query, scope, context)Search memories through the control path
approve(operationId, actorId)Approve a pending operation
deny(operationId, actorId)Deny a pending operation
getOperationStatus(operationId)Check operation lifecycle status
verifyAuditTrail()Verify hash chain integrity of the audit trail
queryAuditTrail(options)Query audit trail events with filters
Every mutation method accepts an optional idempotencyKey parameter. If omitted, one is generated automatically.

Core Types

The SDK exports const enum objects and TypeScript types:

Enums

import {
  ActorType,
  DecisionAction,
  RiskLevel,
  OperationStatus,
  OperationType,
} from "@kyberon/memproof";

// Usage
const level = RiskLevel.HIGH;     // "high"
const action = DecisionAction.DENY; // "deny"

Key Interfaces

import type {
  MemoryScope,
  OperationContext,
  MemoryRecord,
  RiskAssessment,
  PolicyDecision,
  MemoryOperationResponse,
} from "@kyberon/memproof";
Properties use camelCase in TypeScript (e.g. tenantId, actorType, operationId). The SDK also accepts snake_case input for convenience when passing plain objects.

Error Handling

Failed operations throw typed error classes:
import {
  Memproof,
  PolicyDeniedError,
  QuarantinedError,
  NotFoundError,
  ConflictError,
} from "@kyberon/memproof";

try {
  await mp.get("nonexistent-id");
} catch (err) {
  if (err instanceof NotFoundError) {
    console.log(err.code);    // "NOT_FOUND"
    console.log(err.message); // "Memory nonexistent-id not found"
  }
}

Approval Workflow

// 1. Create a memory (may require approval depending on policy)
const result = await mp.remember("Sensitive data", scope, context);

if (result.status === "pending_approval") {
  // 2. Approve or deny via the operation ID
  const approved = await mp.approve(result.operationId, "reviewer-1");
  console.log(approved.status); // "committed"
}

Custom Adapters

You can implement custom memory adapters by implementing the MemoryAdapter interface:
import type { MemoryAdapter, MemoryRecord, MemorySearchHit } from "@kyberon/memproof";

class MyCustomAdapter implements MemoryAdapter {
  get providerName() { return "my_backend"; }

  async createMemory(memory: MemoryRecord): Promise<MemoryRecord> {
    // Your storage logic here
  }

  async updateMemory(memoryId: string, patch: Record<string, unknown>): Promise<MemoryRecord> {
    // ...
  }

  async deleteMemory(memoryId: string): Promise<boolean> {
    // ...
  }

  async getMemory(memoryId: string): Promise<MemoryRecord | undefined> {
    // ...
  }

  async searchMemories(
    query: string,
    scope: Record<string, unknown>,
    limit?: number,
  ): Promise<MemorySearchHit[]> {
    // ...
  }
}

Using Individual Components

You can use the risk engine, policy engine, and other components independently:
import { RiskEngine, PolicyEngine, loadPolicy, OperationType, ActorType } from "@kyberon/memproof";

const riskEngine = new RiskEngine();
const assessment = riskEngine.assess(
  OperationType.REMEMBER,
  "Some content with email user@example.com",
  { tenantId: "t1", projectId: "p1", agentId: "a1" },
  { actorType: ActorType.AGENT, actorId: "a1", source: "langgraph", timestamp: new Date() },
);

console.log(assessment.score);  // 0.48
console.log(assessment.level);  // "medium"
console.log(assessment.factors); // [{name: "content_pii", ...}, ...]
The TypeScript and Python SDKs use the same risk scoring algorithm, policy evaluation logic, and YAML policy format. A policy file works identically in both SDKs.