Skip to content

TypeScript SDK reference

@dotcraft/sdk is the Node.js SDK for AppServer applications. Start with the Quickstart for installation and a first run.

Package

FieldValue
Package@dotcraft/sdk
Module formatESM
RuntimeNode.js 20+

The package is published on npm. Runtime entry points belong in Node.js or Electron Main, not in browser or Electron Renderer code.

Entry points

Entry pointPublic surface
@dotcraft/sdkDotCraft, threads, runs, callbacks, input helpers, approval decisions, and high-level errors.
@dotcraft/sdk/contractsGenerated DTOs, method maps, registries, and protocol metadata.
@dotcraft/sdk/wireDotCraftWireClient, transports, lifecycle state, timeouts, typed methods, and raw extension APIs.
@dotcraft/sdk/hubHub discovery, AppServer management, process policy, events, and structured errors.
@dotcraft/sdk/app-bindingApp Binding handoff and result helpers.
@dotcraft/sdk/dynamic-toolsRuntime Dynamic Tool authoring helpers.
@dotcraft/sdk/testingTransport and protocol test surface.
@dotcraft/sdk/metaSDK, contract, protocol, and contract-hash metadata.

Contracts has no Node.js, WebSocket, or runtime I/O dependency, so Renderer code may import it for types.

Avatar package

@dotcraft/avatar/react provides the React 19 Avatar component for DotCraft's name-derived visual identity. Pass name and size, with optional state, motion, paused, eventSequence, and label props. Its ComposerMascot component accepts the host's applied light or dark theme through the optional theme prop, which defaults to dark. The framework-neutral package root exports deriveAppearance, which trims and NFC-normalizes the name before deriving an appearance. The same normalized name produces the same identity; an empty name produces the original DotCraft appearance.

High-level API

TaskAPI
ConnectDotCraft.local(), DotCraft.localChat(), DotCraft.remote()
Closedotcraft.close()
Threadsthreads.getOrCreate(), start(), resume(), list(), listPage(), read(), listTurns(), listItems()
Runrun(), runStreamed(), enqueue(), interrupt()
Thread statesnapshot(), refresh(), subscribe(), unsubscribe(), setMode(), archive(), delete()
Modelsmodels.list()
MCP runtimemcpRuntime.listStatus(), readResource(), callTool(), loginOAuth(), reload()
App BindingappBindings
Runtime toolsonToolCall()

Configure approvalHandler and userInputHandler in local or remote connection options. See Threads & runs and Tools & approvals for task flows.

Connect

MethodRequired optionConnection ownership
DotCraft.local(options)workspacePathUses Hub to ensure the workspace AppServer, then connects to it.
DotCraft.localChat(options?)NoneUses Hub to ensure the default Chat workspace AppServer.
DotCraft.remote(options)url; optional tokenConnects directly to an existing AppServer WebSocket.

All three option types accept client identity, approval and user-input handlers, and additional capabilities. Local options also accept executable selection, binary-match policy, Hub timeout, and home-directory overrides.

Option typeFields
DotCraftLocalOptionsRequired workspacePath; optional clientName, clientVersion, clientTitle, executable, expectedExecutable, binaryMatchPolicy, hubStartupTimeoutMs, homeDir, handlers, and capabilities.
DotCraftLocalChatOptionsThe local fields except workspacePath.
DotCraftRemoteOptionsRequired url; optional token, client identity, handlers, and capabilities.

A remote url points at the AppServer WebSocket endpoint, whose path ends in /ws. Pass the token in the token option instead of embedding it in the URL, and keep both out of logs. See AppServer mode for how the server listens.

Threads and runs

ThreadManager exposes these high-level operations:

ts
getOrCreate(options?: GetOrCreateThreadOptions): Promise<DotCraftThread>;
start(options?: StartThreadOptions): Promise<DotCraftThread>;
resume(threadId: string, options?: ResumeThreadOptions): Promise<DotCraftThread>;
list(options?: ListThreadOptions): Promise<ThreadSummary[]>;
listPage(options?: ListThreadOptions): Promise<ThreadListResult>;
read(threadId: string): Promise<SessionThread>;
listTurns(threadId: string, options?: ThreadHistoryPageOptions): Promise<ThreadTurnsListResult>;
listItems(threadId: string, options?: ThreadItemPageOptions): Promise<ThreadItemsListResult>;

Start options contain identity fields, display name, history mode, configuration, Runtime Dynamic Tools, and additional context. Resume options only rebind dynamic tools and additional context. List options add identity/workspace scope, archived filtering, text query, limit, and cursor.

read() and a Thread handle's refresh() return the current Thread header without persisted Turns or Items. listTurns() reads Turn metadata; listItems() reads Items across the Thread or for the optional turnId. Both accept cursor, limit, and sortDirection, and return data plus an opaque nextCursor. Thread handles expose the same two pagination methods without the threadId argument.

run() and runStreamed() accept text, InputPart[], or { input, sender }. Run options are sender, collectRawEvents, abortSignal, and enqueueIfBusy. A buffered result contains thread, optional terminal turn, merged text, items, optional usage, optional raw events, and any queued-input result.

Models, MCP, and App Binding

ManagerOperations
modelslist() returns the model catalog visible to this AppServer.
mcpRuntimelistStatus(), readResource(), callTool(), loginOAuth(), reload().
appBindingsApp discovery, connection, surfaces, thread bindings, social bindings, and principal operations.

The TypeScript high-level surface lists models but does not currently provide a model-configuration convenience method. Use the typed Wire request map for thread/config/update when an application must change the complete thread configuration, and preserve fields it does not own. See MCP runtime and DotCraft App for task-oriented flows.

The MCP manager signatures are:

ts
listStatus(params?: McpServerStatusListParams): Promise<McpServerStatusListResult>;
readResource(params: McpServerResourceReadParams): Promise<McpServerResourceReadResult>;
callTool(params: McpServerToolCallParams): Promise<McpServerToolCallResult>;
loginOAuth(params: McpServerOAuthLoginParams): Promise<McpServerOAuthLoginResult>;
reload(): Promise<McpServerReloadResult>;

Callbacks and Runtime Dynamic Tools

ts
type ApprovalHandler =
  (request: Record<string, unknown>) => Promise<ApprovalDecision> | ApprovalDecision;
type UserInputHandler =
  (request: Record<string, unknown>) => Promise<Record<string, unknown>> | Record<string, unknown>;
type DynamicToolHandler =
  (request: DynamicToolCallRequest) => Promise<DynamicToolCallResult> | DynamicToolCallResult;

thread.onToolCall(namespace: string | null, name: string, handler: DynamicToolHandler): Unsubscribe;

Handlers execute in the application process. Register them before starting work that can call the tool, validate arguments in the handler, and dispose registrations when their owning scope ends.

Typed and raw Wire API

Use the typed method map for cataloged AppServer methods:

ts
const result = await wire.request("thread/list", params);
const dispose = wire.on("thread/started", ({ thread }) => console.log(thread.id));

Use raw APIs only for third-party or not-yet-cataloged extensions:

ts
const value = await wire.requestRaw("ext/example/read", { id: "42" });
const dispose = wire.onRaw("ext/example/changed", console.log);

DotCraftWireClient owns JSON-RPC and connection state. It does not approve requests, answer user input, or rebuild thread and tool resources.

Connection lifecycle

Wire state is connecting, initializing, ready, disconnected, reconnecting, reconnectError, or closed.

  • Local and remote high-level connections reconnect automatically.
  • Raw Wire connections do not reconnect unless autoReconnect is enabled.
  • Ordinary requests default to a 30-second timeout.
  • Reconnect uses exponential backoff and queues at most 1024 new calls.
  • In-flight calls fail and are never replayed.
  • Initialization completes before queued calls are released.
  • Handler registrations survive reconnect. Thread subscriptions, active runs, and runtime tool resources do not.

Reconnect does not rebuild those resources for the application. Read or resume the thread, subscribe again, and re-register runtime tool handlers before continuing.

Closing a local high-level client closes its WebSocket connection. It does not stop Hub or the Hub-managed AppServer.

Errors

All SDK errors derive from DotCraftError and carry a stable code.

ErrorCondition
JsonRpcErrorAppServer returned a JSON-RPC error. Preserves rpcCode and data.
InitializationErrorConnection initialization failed.
TurnInProgressErrorThe thread already has an active turn.
ThreadNotFoundError / ThreadNotActiveErrorThe target thread is missing or cannot run.
TurnFailedError / TurnCancelledErrorA buffered run reached a failed or cancelled terminal state.
ApprovalTimeoutErrorAppServer reports approval timeout.
ProtocolViolationErrorA known message does not match its contract.

JsonRpcError and the transport-level errors TransportError, TransportClosed, RequestTimeoutError, and ReconnectQueueFullError are exported from the Wire entry point.

Hub API

HubClient discovers or starts Hub, validates the local lock, resolves a workspace AppServer, and supports ensure, restart, stop, list, status, events, and shutdown operations.

Hub errors preserve code, message, and details. Do not log Hub tokens or full token-bearing WebSocket URLs.