Skip to content

TypeScript

The xmemory npm package is a lightweight TypeScript client for the xmemory API. Zero dependencies — it uses native fetch only.

For MCP-based integration, see the MCP guide. For framework-specific setup, see Mastra AI.

API key: To use xmemory APIs or integrations, you need an API key. Please register your interest at https://xmemory.ai and we will reach out to give access. Copy and securely store the key. Never share your API key publicly.


Terminal window
npm install xmemory

import { XmemoryClient, SchemaType } from "xmemory";
// Connect (reads XMEM_API_URL and XMEM_AUTH_TOKEN from env)
const xm = new XmemoryClient({ token: "your-token" });
// Get a handle for an existing instance
const inst = xm.instance("your-instance-id");
// Write some information
await inst.write("Alice Johnson works at Acme Corp. Her email is alice@acme.com.");
await inst.write("Bob Lee is a designer at Globex. He joined last Monday.");
// Read it back
const result = await inst.read("What is Alice's email?");
console.log(result.reader_result);
// → {"answer": "alice@acme.com"}

Three options, depending on whether you want a health check:

import { XmemoryClient, xmemoryInstance } from "xmemory";
// Factory function — runs a health check automatically
const xm = await xmemoryInstance({ url: "https://api.xmemory.ai", token: "..." });
// Static method — same behavior
const xm = await XmemoryClient.create({ url: "https://api.xmemory.ai", token: "..." });
// Constructor — no health check
const xm = new XmemoryClient({ url: "https://api.xmemory.ai", token: "..." });
OptionEnv varDefaultDescription
tokenXMEM_AUTH_TOKENundefinedBearer token for authentication
urlXMEM_API_URLhttps://api.xmemory.aiAPI base URL
timeoutMs60000Default request timeout in milliseconds

All three forms resolve token and url from environment variables when not passed. Only xmemoryInstance() and XmemoryClient.create() perform a health check on construction.


Use xm.instance(id) to get a scoped handle for data operations:

const inst = xm.instance("your-instance-id");
// All data operations go through the handle
await inst.write("Carol is a senior engineer at Initech.");
const result = await inst.read("Who works at Initech?");
console.log(result.reader_result);

Send free-form text — xmemory extracts structured objects according to your schema and merges them into the knowledge graph.

const resp = await inst.write("Carol is a senior engineer at Initech.");
console.log(resp.write_id);
console.log(resp.cleaned_objects);
console.log(resp.trace_id); // request trace id when available

Control the speed/accuracy tradeoff:

await inst.write("...", { extractionLogic: "fast" });
ValueWhen to use
"deep"Important or complex information (default)
"regular"Balanced speed and accuracy
"fast"High-volume, low-stakes writes

For latency-sensitive code, enqueue a write and return immediately:

const { write_id } = await inst.writeAsync("Dave manages the London office.");
console.log(write_id); // use this to poll for completion

write() and read() responses include trace_id, which is useful for correlating client calls with API logs.

Then check the status:

const status = await inst.writeStatus(write_id);
console.log(status.write_status);
// → "queued" | "processing" | "completed" | "failed" | "not_found"

Do not call read immediately after writeAsync — the data may not be committed yet. Poll with writeStatus until "completed", or use write (synchronous) when you need to read right after.


Ask questions in natural language:

const resp = await inst.read("Who works at Acme Corp?");
console.log(resp.reader_result);
console.log(resp.trace_id);
// Plain-text answer (default)
const resp = await inst.read("What is Alice's email?", { readMode: "single-answer" });
// Structured objects and relations
const resp = await inst.read("Show all contacts", { readMode: "xresponse" });
// Raw SQL result sets
const resp = await inst.read("List all contacts", { readMode: "raw-tables" });

Preview what xmemory would extract from a piece of text, without storing anything:

const resp = await inst.extract("Dave manages the London office.");
console.log(resp.objects_extracted);
console.log(resp.trace_id);

Accepts the same extractionLogic option as write.


The describe() method returns agent-facing tool descriptions enriched with the instance’s actual schema. Use it to tell an LLM what tools are available and how to call them.

const desc = await inst.describe();
// Plain text — inject into a system prompt
console.log(desc.asText());
// Anthropic tool-use format
const tools = desc.asAnthropicTools();
// OpenAI function-calling format
const tools = desc.asOpenaiTools();

Results are cached locally for 5 minutes. To force a refresh (e.g. after updating the schema):

inst.clearDescribeCache();
const desc = await inst.describe();

asText() shows tools as method signatures by default. Pass { includeHttp: true } to also show HTTP method and path for raw REST callers.


All management operations live on xm.admin:

const clusters = await xm.admin.listClusters();
const clusterId = clusters[0].id;
const schema = await xm.admin.generateSchema(
clusterId,
"Track contacts with name, email, company, and notes.",
);
console.log(schema.data_schema);
import { SchemaType } from "xmemory";
const inst = await xm.admin.createInstance(
clusterId,
"contacts",
schemaYml,
SchemaType.YML,
{ description: "User contacts" },
);
// inst is a bound InstanceHandle — use inst.write(), inst.read(), etc.
await inst.write("Alice joined the team.");
await xm.admin.updateInstanceSchema(instanceId, newSchemaYml, SchemaType.YML);
const instances = await xm.admin.listInstances();
const info = await xm.admin.getInstance(instanceId);
await xm.admin.deleteInstance(instanceId);

All errors throw XmemoryAPIError with an optional .status property containing the HTTP status code.

import { XmemoryAPIError, XmemoryHealthCheckError } from "xmemory";
try {
const xm = await XmemoryClient.create({ token: "..." });
} catch (e) {
if (e instanceof XmemoryHealthCheckError) {
console.error("Server unreachable:", e.message);
}
}
try {
await inst.write("...");
} catch (e) {
if (e instanceof XmemoryAPIError) {
console.error(`Error (HTTP ${e.status}): ${e.message}`);
}
}

MethodReturnsDescription
new XmemoryClient(options?)XmemoryClientCreate a client (no health check)
XmemoryClient.create(options?)Promise<XmemoryClient>Create a client with health check
xmemoryInstance(options?)Promise<XmemoryClient>Factory with health check (same as .create())
xm.instance(instanceId)InstanceHandleGet a handle for data operations on an instance
xm.checkHealth()Promise<void>Raises XmemoryHealthCheckError if unreachable
MethodReturnsDescription
listClusters(options?)Promise<ClusterInfo[]>List clusters
getCluster(clusterId, options?)Promise<ClusterInfo>Get a cluster by ID
generateSchema(clusterId, description, options?)Promise<GenerateSchemaResult>Generate a schema from a description
createInstance(clusterId, name, schemaText, schemaType, options?)Promise<InstanceHandle>Create an instance; returns a bound handle
listInstances(options?)Promise<InstanceInfo[]>List instances
getInstance(instanceId, options?)Promise<InstanceInfo>Get an instance by ID
deleteInstance(instanceId, options?)Promise<string[]>Delete an instance
getInstanceSchema(instanceId, options?)Promise<InstanceSchemaInfo>Get an instance’s schema
updateInstanceSchema(instanceId, schemaText, schemaType, options?)Promise<InstanceInfo>Update an instance’s schema
updateInstanceMetadata(instanceId, name, description, options?)Promise<InstanceInfo>Update instance name and description
MethodReturnsDescription
write(text, options?)Promise<WriteResult>Extract and persist objects from text
writeAsync(text, options?)Promise<AsyncWriteResult>Enqueue a write; returns write_id immediately
writeStatus(writeId, options?)Promise<WriteStatusResult>Poll the status of an async write
read(query, options?)Promise<ReadResult>Query the instance in natural language
extract(text, options?)Promise<ExtractResult>Extract objects without writing them
getSchema(options?)Promise<InstanceSchemaInfo>Get this instance’s schema
describe(options?)Promise<DescribeResult>Get agent-facing tool descriptions (cached 5 min)
clearDescribeCache()voidForce next describe() to fetch fresh data
idstringThe instance ID (property)
type ExtractionLogic = "fast" | "regular" | "deep";
type ReadMode = "single-answer" | "raw-tables" | "xresponse";
type WriteQueueStatus = "queued" | "processing" | "completed" | "failed" | "not_found";
const SchemaType = { YML: 0, JSON: 1 } as const;