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.
Installation
Section titled “Installation”npm install xmemoryQuick start
Section titled “Quick start”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 instanceconst inst = xm.instance("your-instance-id");
// Write some informationawait 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 backconst result = await inst.read("What is Alice's email?");console.log(result.reader_result);// → {"answer": "alice@acme.com"}Creating a client
Section titled “Creating a client”Three options, depending on whether you want a health check:
import { XmemoryClient, xmemoryInstance } from "xmemory";
// Factory function — runs a health check automaticallyconst xm = await xmemoryInstance({ url: "https://api.xmemory.ai", token: "..." });
// Static method — same behaviorconst xm = await XmemoryClient.create({ url: "https://api.xmemory.ai", token: "..." });
// Constructor — no health checkconst xm = new XmemoryClient({ url: "https://api.xmemory.ai", token: "..." });| Option | Env var | Default | Description |
|---|---|---|---|
token | XMEM_AUTH_TOKEN | undefined | Bearer token for authentication |
url | XMEM_API_URL | https://api.xmemory.ai | API base URL |
timeoutMs | — | 60000 | Default 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.
Instance handle
Section titled “Instance handle”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 handleawait inst.write("Carol is a senior engineer at Initech.");const result = await inst.read("Who works at Initech?");console.log(result.reader_result);Writing
Section titled “Writing”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 availableExtraction logic
Section titled “Extraction logic”Control the speed/accuracy tradeoff:
await inst.write("...", { extractionLogic: "fast" });| Value | When to use |
|---|---|
"deep" | Important or complex information (default) |
"regular" | Balanced speed and accuracy |
"fast" | High-volume, low-stakes writes |
Async writes
Section titled “Async 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 completionwrite() 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.
Reading
Section titled “Reading”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);Read modes
Section titled “Read modes”// Plain-text answer (default)const resp = await inst.read("What is Alice's email?", { readMode: "single-answer" });
// Structured objects and relationsconst resp = await inst.read("Show all contacts", { readMode: "xresponse" });
// Raw SQL result setsconst resp = await inst.read("List all contacts", { readMode: "raw-tables" });Extracting (without writing)
Section titled “Extracting (without writing)”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.
Describing (agent tool discovery)
Section titled “Describing (agent tool discovery)”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 promptconsole.log(desc.asText());
// Anthropic tool-use formatconst tools = desc.asAnthropicTools();
// OpenAI function-calling formatconst 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.
Cluster and instance management
Section titled “Cluster and instance management”All management operations live on xm.admin:
Listing clusters
Section titled “Listing clusters”const clusters = await xm.admin.listClusters();const clusterId = clusters[0].id;Generating a schema
Section titled “Generating a schema”const schema = await xm.admin.generateSchema( clusterId, "Track contacts with name, email, company, and notes.",);console.log(schema.data_schema);Creating an instance
Section titled “Creating an instance”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.");Updating a schema
Section titled “Updating a schema”await xm.admin.updateInstanceSchema(instanceId, newSchemaYml, SchemaType.YML);Listing and deleting instances
Section titled “Listing and deleting instances”const instances = await xm.admin.listInstances();const info = await xm.admin.getInstance(instanceId);
await xm.admin.deleteInstance(instanceId);Error handling
Section titled “Error handling”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}`); }}Reference
Section titled “Reference”Client
Section titled “Client”| Method | Returns | Description |
|---|---|---|
new XmemoryClient(options?) | XmemoryClient | Create 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) | InstanceHandle | Get a handle for data operations on an instance |
xm.checkHealth() | Promise<void> | Raises XmemoryHealthCheckError if unreachable |
Admin methods (xm.admin)
Section titled “Admin methods (xm.admin)”| Method | Returns | Description |
|---|---|---|
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 |
Instance methods (xm.instance(id))
Section titled “Instance methods (xm.instance(id))”| Method | Returns | Description |
|---|---|---|
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() | void | Force next describe() to fetch fresh data |
id | string | The 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;