Node.js SDK

Embed zot rpc in Node.js and TypeScript apps.

@patriceckhart/zot-sdk-javascript is a TypeScript SDK that embeds zot rpc in Node.js applications. It starts a long-lived zot rpc child process and talks newline-delimited JSON over stdin/stdout, so you get streaming output without hand-rolling the protocol.

Server runtimes only

The SDK spawns a child process. Use it in Node-compatible server runtimes only. Do not import it in browser components or edge runtimes.

Install

shell
npm install @patriceckhart/zot-sdk-javascript
# or: pnpm add / yarn add / bun add @patriceckhart/zot-sdk-javascript

On install, a postinstall step detects your OS and CPU. If zot is already on PATH it uses that; otherwise it downloads the matching GitHub release asset, verifies checksums.txt, and stores the binary under the package vendor/ directory.

Bun lifecycle scripts

Bun may block the postinstall and print Blocked 1 postinstall. Trust the package with Bun, or run the installer manually: node node_modules/@patriceckhart/zot-sdk-javascript/scripts/install-zot.js. If zot is already on your PATH, no download is needed.

Environment controls: ZOT_SKIP_INSTALL=1 skips the download, ZOT_FORCE_INSTALL=1 downloads even when zot exists, ZOT_VERSION=v0.2.31 pins a release tag, and ZOT_BINARY=/path/to/zot selects a specific binary at runtime.

Stream a prompt

ts
import { ZotClient } from "@patriceckhart/zot-sdk-javascript";

const zot = new ZotClient({
  provider: "anthropic",
  model: "claude-sonnet-4-5",
  cwd: process.cwd(),
});

for await (const event of zot.promptStream("Explain this project in 3 bullets")) {
  if (event.type === "text_delta") process.stdout.write(event.delta);
  if (event.type === "tool_call") console.log("\ntool:", event.name, event.args);
}

zot.close();

One-shot prompt

ts
import { createZotClient } from "@patriceckhart/zot-sdk-javascript";

const zot = await createZotClient({ provider: "openai", cwd: process.cwd() });
const result = await zot.prompt("Write a tiny README for this app");
console.log(result.text);
zot.close();

Framework usage

zot rpc is stateful, so keep one client per chat session on the server. The SDK works in any Node-compatible framework that can spawn child processes (Next.js route handlers with runtime = "nodejs", Nuxt server routes, Express, and others), but not in browser code or edge runtimes.

API

ts
const client = new ZotClient(options);
await client.start();
await client.hello();
await client.ping();
await client.prompt("message");
client.promptStream("message");
await client.abort();
await client.compact();
await client.getState();
await client.getMessages();
await client.clear();
await client.setModel("model-id");
await client.getModels();
client.close();

Key options: binary (defaults to ZOT_BINARY or zot); provider, model, cwd, apiKey, baseUrl, systemPrompt, appendSystemPrompt, reasoning, maxSteps, noTools, and tools map to zot rpc flags; rpcToken sends the initial hello token when ZOTCORE_RPC_TOKEN is set on the child process.

State changes while busy

Call clear() and setModel() only when the agent is idle. The RPC runtime rejects clear, set_model, and set_reasoning with an agent is busy error during prompt preparation, model/tool execution, or compaction. State is unchanged and these commands are not queued. Wait for completion, or abort the active operation, wait for it to finish, and retry. An abort() acknowledgement alone does not mean the active operation has finished.

Auth and lifecycle

Use normal zot auth: run zot and /login, or pass provider keys through environment variables such as ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, or KIMI_API_KEY.

  • One ZotClient wraps one zot rpc process, cwd, model, and session.
  • Only one prompt or compact operation should be active per client at a time.
  • For multiple projects or concurrent chats, create multiple clients.
  • The process exits when closed or when stdin closes.

Source and full docs: https://github.com/patriceckhart/zot-sdk-javascript.