artifact-capabilities
Artifact runtime capabilities
A published Artifact page can declare runtime capabilities — abilities the claude.ai viewer grants the page at open time — by passing capabilities: {name: config} to the Artifact tool. The control plane is the authority on valid names and config shapes. Declaration gestures: omitting capabilities on a redeploy carries the stored declaration forward unchanged (and preserves the artifact's stored contract pin); an empty object {} is the explicit clear-all; a non-empty object is a full-set declaration (anything stored but not restated is revoked). Moving a republished artifact's runtime version is a deliberate gesture — pass contract: 'latest' to upgrade, or a specific version to pin or roll back — never a side effect of editing.
A page that republishes itself through the artifact capability sends its whole document in exactly the shape the Artifact tool publishes, so a later publish from the tool recognizes and replaces the skeleton instead of nesting it: <!doctype html><html><head><meta charset=utf8><meta name=viewport content="width=device-width,initial-scale=1,viewport-fit=cover"><style> the same small reset the tool's description names </style></head><body> — no whitespace between those tags and nothing else in the head — then the page content exactly as it was written for the tool (its <title> and <style> first, inside the body, regenerated from the page's state), then </body></html>.
Available capabilities: artifact, assets, comments, db, downloads, files, mcp, room, sample, self, user — the complete set of capability names you may declare; built in on every page, called without declaring (never pass these in capabilities): permissions. Anything not listed is unavailable to this user.
Tool spelling in this session: the
Artifacttool'saction: "read_db"/"write_db"with adb_opare theArtifactDatatool, whoseactionis thatdb_op("get", "list", "query", "set", "update", "str_replace", "delete", "batch") with the other fields unchanged — load it with ToolSearch when you first need it. Read the steps below with that substitution.
Runtime contract 0.2.91
Capability namespaces live behind claude.use(name): const db = await claude.use("db") resolves the capability's namespace, or null when this view cannot run it (not served, not granted, or failed to load — indistinguishable by design). Branch on null and design for absence. window.claude carries only use: no window.claude.db, .room, or .artifact member is ever promised, so never read one — render the page without them and light features up when the promise resolves (later, never within your script's first run, and unordered with DOMContentLoaded; null after 10 s when no viewer answers). The resolved namespace is frozen and platform-owned: call its functions and keep the reference; never assign to it, defineProperty on it, or replace a member (wrap it for your own helpers). Permission stays on the calls: a consent prompt, rate limit, or policy refusal arrives on the first call, never from use(). Awaiting use("db") again is free (memoized); an unknown name resolves null.
--- capability: artifact ---
Use artifact for pages that should remember what people do with them: polls, sign-up sheets, checklists, trackers, boards — the page is the record; data kept server-side, or seeded or read back by Claude, is db. Declare capabilities: {artifact: {}}; const artifact = await claude.use("artifact"), then await artifact.publish(html) saves html (a complete document, doctype first) as the new version, and every open view, this one included, reloads to it. Nothing a viewer types, ticks or drags is kept unless the page publishes it. So embed the shared state as data in the HTML you publish and render the page from it; when an interaction completes, update the state, regenerate the document and publish it — never serialize the live DOM; batch rapid edits into one publish; publish only after a viewer acts, never on load. conflict is routine (every view reloads to the winner, dropping this edit): no retry. For read-only viewers publish rejects not_granted/not_writer — render a read-only view.