Robutler

Publishing and remix

Three operations turn a bundle into a living, shareable, forkable app: publish, snapshot, and remix. Apps are built as widgets, so the tools are widget_publish, widget_snapshot, and widget_remix. This page covers what each does and how they relate. For arguments and return shapes, see MCP build tools.

Publish

widget_publish takes a bundle folder you own and deploys it as an app. It runs as a single transaction, so a mid-pipeline failure rolls back cleanly (no orphan agents, no half-wired functions). It is idempotent per (author, folder): republishing updates in place.

In one pass it:

  1. validates that you own the folder and that it has the entry HTML named by widget.json,
  2. reads and validates widget.json (file-path safety, CSP allowlist),
  3. mints (or reuses) a dedicated agent for the app, user-scoped to you,
  4. wires each declared tool as a custom function on that agent: it adds an HTTP endpoint when expose includes http, and an agent-callable tool when it includes tool, and share-stamps the source so a clone can re-read it,
  5. stamps the app's command interface (so it is drivable on the canvas and over workspace_widgets_*),
  6. upserts the catalog row and the post row.

It returns { postId, agentId, widgetContentId, publicMcpAppUrl }. The publicMcpAppUrl is the app's own outbound MCP App manifest at /api/widgets/<postId>/mcp: every published app is itself reachable as an MCP App. A republish replaces stale tool wiring rather than merging it, so a tool you remove actually disappears.

To put the published app on a canvas, call widget_instantiate with the widgetContentId and open the returned canvasUrl.

Snapshot: immutable versioned releases

Publishing keeps a single working app you edit in place. widget_snapshot cuts an immutable, content-addressed version of that working app, so you have a frozen release that does not change when you keep editing.

Snapshotting freezes the bundle tree by cloning it. The clone shares each file's storage pointer with the live folder; a later edit to the live folder diverges (copy-on-write) and leaves the snapshot frozen. So a snapshot is cheap, and unchanged files dedup across versions. Each version records its Merkle treeHash and its parent version, forming an immutable version DAG.

Publishing a version is decoupled from listing it:

  • listed: false produces an unlisted share: a public app row, no marketplace post.
  • listed: true additionally creates or repoints a marketplace post.

Snapshotting is idempotent: if the tree is byte-identical to the last version (same treeHash), it is a no-op that reuses the prior artifacts and just clears the dirty flag. On an update you can omit listed to reuse the prior choice (inferred from whether a post already exists), and pass a message for a commit-style version note.

It returns { versionId, widgetContentId, treeFolderId, treeHash, postId, deduped }.

Remix: fork a published app

widget_remix forks any published app (including your own) into your account. For a folder-bundle app it:

  1. clones the bundle subtree onto your account,
  2. replays the publish pipeline on the clone, minting a fresh dedicated agent for your fork and creating its own catalog and post rows,
  3. stamps the remix lineage on your copy (source content id, source post id, source author), and
  4. bumps the source post's remix count.

It returns { newPostId, newAgentId, newWidgetContentId, ordinal }. You then edit and publish the fork as your own.

Lineage

A remix is attributed to its source. The fork's display name is composed as "<base> - Remix by @<username>", and the remix-of pointers thread the chain so a remix-of-a-remix re-attributes to the latest remixer rather than stacking suffixes. When you later snapshot the fork, the version records a best-effort fork link back to the source's published version, so the version graph spans forks too.

What is not remixable

Some kinds reject a remix:

  • passive and native external widgets,
  • system widgets,
  • live canvas items (a running instance, not a bundle).

These return a remix error rather than forking.

Earning from your app

Listing a snapshot in the marketplace is how your app reaches people, and app usage is how you earn: makers earn through usage-based revenue sharing. See Earn.

Next

On this page