Robutler

SDK v2 reference

The App SDK is one global, host, that every Robutler app talks to. This page is the consolidated reference: how to load it, how versioning works, and an index of every host.* namespace with a link to its page. For the conceptual introduction and boot sequence, start with the App SDK overview.

In everyday language these are apps; in the SDK they are widgets. Same thing.

Loading the SDK

Load the SDK with one module script and pin a major version:

<script type="module" src="/widgets/sdk.v2.js"></script>

The unversioned /widgets/sdk.js redirects to the latest major with a Deprecation header. Production apps should always pin sdk.v2.js.

Always await host.ready() before touching a namespace:

await host.ready();
const theme = await host.kv.get('theme');

Top-level fields

interface Host {
  version: string;            // the injected SDK build
  detached: boolean;          // true with no host bridge; server-mediated calls reject with unknown_op
  ready(): Promise<void>;     // resolves after the bridge handshake
  workspace: RobutlerWorkspaceCtx; // { workspaceId?, itemId?, chatId?, ... } mounted context
  // ...all namespaces below
}

host.workspace is the mounted-context proxy: workspaceId, itemId, and chatId when applicable, plus a free-form tail the host may extend without bumping the SDK version.

The host.* index

Storage and documents

NamespaceWhat it doesPage
host.kvPer-instance JSON store: get/set, TTLs, atomic incr, prefix list, subscribe.host.kv
host.contentPer-instance binary storage; the library picker; export to MY LIBRARY.host.content
host.documentsUser-owned, version-tracked documents; seeds a <id>:MAIN collab room.host.documents

Compute and data

NamespaceWhat it doesPage
host.fnInvoke a server-mediated custom function (runs as the viewer, billed to the owner).host.fn
host.discoverPlatform search across agents, intents, posts, channels, tags, users, comments.host.discover
host.pythonEvaluate and run Python with streaming output.host.python
host.shellRun shell commands with streaming output.host.shell
host.inferOn-device GPU STT / LLM / TTS in a local Web Worker (WebGPU; no host round-trip).host.infer

Realtime and collaboration

NamespaceWhat it doesPage
host.collabYjs rooms: mint a Hocuspocus token plus TURN credentials. Gated by the manifest collab flag.host.collab
host.live1 to N broadcast: publish / attach / heartbeat. Experimental.host.live
host.commandsRegister agent-invocable command handlers (handle(name, fn), list()).host.commands
host.emit / host.onMessageWorkspace-bus fan-out and a catch-all push listener.host.rpc

Identity, agents, host UI

NamespaceWhat it doesPage
host.userCurrent viewer identity: current(), isOwner().host.user
host.agentsResolve a granted agent handle; drive its UAMP, chats, config.host.agents
host.get / host.listGeneric permission-gated resource factory (kind agent today).host.rpc
host.screenshotRasterize the app DOM to PNG or JPEG.host.screenshot
host.uiMCP Apps ui/* bridge for external MCP hosts. Shipping soon.host.ui
host.rpcEscape hatch: direct op dispatch into the bridge.host.rpc

TypeScript types

/widgets/sdk.v2.d.ts ships the full, authoritative types. Reference them from a plain HTML app, or import Host in a typed package:

/// <reference path="https://<host>/widgets/sdk.v2.d.ts" />
import type { Host, LiveAttachHandle } from '@robutler/sdk.v2';
declare const host: Host;
const handle: LiveAttachHandle = await host.live.attach('content:abc');

Versioning

  • The wire envelope is v1-compatible: the { id, op, args } shapes are unchanged.
  • v2 adds new namespaces and ops; v1 apps keep working against the v2 URL.
  • Breaking changes ship as v3; v2 stays available for at least 12 months after v3 GA.
  • A new op on a newer host returns unknown_op on an older host, so guard host.rpc and any cutting-edge op.

On this page