# Tools for Hedy Deck 2.0 agents

Use [Studio](/studio) and the `hedy2_*` catalogue for new editable decks. Authoring operations run in the visitor's browser, with no Hedy admin connector or account. The optional `hedy2_handoff` operation explicitly uploads one source snapshot to temporary server storage. The [source specification](/docs/hedydeck-v2.md) describes the document model; the [JSON Schema](/schemas/hedydeck-v2.schema.json) describes its structure.

## Access

- **WebMCP:** discover the page's registered tools when your browser and agent support that interface. Support is browser-dependent.
- **Page JavaScript:** `window.hedyDecks.tools.list()` lists tool names, descriptions, and schemas. `await window.hedyDecks.tools.call(name, input)` returns the parsed result. The input is an object or its JSON text.
- **Ordinary browser:** open `/studio`, select a tool in **Agent command desk**, paste its JSON arguments, and run it. Read the visible result. The source editor, preview, import, render, and export controls also work with ordinary clicking and typing.
- **Chat only:** a person can copy the agent's source or arguments into Studio and copy the result back.

Use the page's actual catalogue as the calling authority. WebMCP client APIs can vary; the fallback interface does not require WebMCP. A tool available in one browser does not give it access to another device's local storage.

Results use `{ok:true,...}` on successful execution or `{ok:false,error:{code,message,diagnostics?}}` on failure. The WebMCP result exposes the same object in `structuredContent` and JSON in `content[0].text`; failures also set `isError:true`. A completed validation can have `ok:true` and `valid:false`: the check ran successfully but found errors.

## Catalogue

| Tool | Input | Result and behavior |
| --- | --- | --- |
| `hedy2_instructions` | `{}` | Essentials plus spec, schema, example, and Studio URLs. |
| `hedy2_list` | `{}` | `projects`: local source IDs, titles, revisions, slide counts, and update times, newest first. |
| `hedy2_create` | `{title?}`, `{example:true,title?}`, or `{document}` | Saves a new source project; returns `id`, `revision`, complete `document`, and `studioUrl`. |
| `hedy2_read` | `{id,slideId?}` | Complete source and source hash, or selected slide plus theme, stage, shared data/components, and asset metadata. No binary asset output. |
| `hedy2_edit` | `{id,expectedRevision,operations,requestId?}` | Atomically applies 1–1,000 stable-ID operations; returns current document and new revision. |
| `hedy2_replace` | `{id,expectedRevision,document,requestId?}` | Replaces the complete source, preserving its document ID; returns new revision and document. |
| `hedy2_validate` | `{id}` | `valid`, `diagnostics`, source hash, and the checked revision. Includes browser layout checks. |
| `hedy2_render` | `{id}` | Validates and saves a frozen presentation bundle; returns `deckId`, `presentUrl`, `sourceHash`, rendered `revision`, `frameCount`, and `stale`. |
| `hedy2_export` | `{id,download?,base64?}` | Editable ZIP: `filename`, `mime`, `bytes`, local `downloadUrl`; optional base64 file bytes. |
| `hedy2_handoff` | `{id,expectedRevision,idempotencyKey?}` | Uploads a saved editable snapshot (including assets and notes), up to 25 MiB; returns `openUrl`, `downloadUrl`, `expiresAt`, and source identity only after completion. Default 24-hour expiry. |
| `hedy2_convert` | `{files:[{filename,base64,mime?}]}` | Converts PowerPoint/PDF/images locally into a new V2 project with flat slide artwork, editable notes and titles. Use export or handoff on the returned ID. [Details](/docs/import-files.md). |
| `hedy2_import` | `{source,asCopy?}` or `{base64,asCopy?}` | Imports JSON source text or ZIP bytes; returns source `id`, revision, document, and `studioUrl`. |
| `hedy2_undo` | `{id,expectedRevision,requestId?}` | Restores the latest retained local snapshot as a new revision. |
| `hedy2_asset` | `{id,expectedRevision,assetId,base64,mime,alt?,requestId?}` | Adds/replaces asset bytes, verifies their signature, computes SHA-256 metadata, and returns `id`, new revision, and asset metadata. |

### Create and inspect

```js
const created = await window.hedyDecks.tools.call("hedy2_create", {
  example: true
});
if (!created.ok) throw new Error(created.error.message);
const read = await window.hedyDecks.tools.call("hedy2_read", {
  id: created.id
});
```

A source document may begin at revision 0. Saving a new local project normalizes it to at least revision 1. Use the actual returned revision for every mutation. A new document supplied to `hedy2_create` must have a unique source ID. Use `hedy2_import` with `asCopy:true` for an independent copy of an existing document.

`hedy2_read` with `slideId` reduces output without losing shared context. It returns `slide`, not `document`, alongside deck title, theme, stage, data, components, and asset metadata.

### Exact edits

```js
const result = await window.hedyDecks.tools.call("hedy2_edit", {
  id: read.id,
  expectedRevision: read.revision,
  requestId: "rename-deck-001",
  operations: [
    { op: "setDeck", fields: { title: "Our next chapter" } }
  ]
});
```

Editing operations are `setDeck`, `putSlide`, `removeSlide`, `moveSlide`, `putNode`, `removeNode`, `setData`, and `setComponent`. Their complete shapes and insertion semantics are in the [V2 specification](/docs/hedydeck-v2.md#revisions-and-editing).

`putSlide` and `putNode` replace complete objects. Read the source first and preserve the fields you intend to retain. `setDeck` replaces supplied fields; supplying a theme requires a complete theme. Theme defaults do not fill a partial replacement.

`expectedRevision` prevents a stale agent from overwriting a newer edit. On `REVISION_CONFLICT`, read the document again and reconcile. Failed batches commit nothing. `requestId` contains 1–128 letters, digits, periods, underscores, colons, or hyphens. Retrying the identical input with the same ID returns its original result within the last 64 retained keyed mutations. Changed input with the same ID fails as `REQUEST_REUSED`. That replay may describe an older revision if later changes already happened; read again before continuing a new edit.

Undo retains up to 30 earlier local edit snapshots. It increments the current revision rather than moving the revision number backward. There is no exposed redo or arbitrary history checkout operation. Local history is not included in export packages.

### Assets

Use standard base64 without whitespace or a `data:` prefix. Supported MIME values are `image/png`, `image/jpeg`, `image/webp`, and `font/woff2`; each asset is 1 byte to 32 MiB, with a 128 MiB source-and-assets budget.

The asset tool creates package metadata and computes its hash. Read the new revision before adding an image node referencing `assetId`. For a custom font, its asset ID is the registered font family. Set a node's `style.fontFamily` or the theme's family to that ID.

A monolithic JSON document cannot supply binary asset bytes by itself. For a new project with images, create an asset-free source, attach assets, then add their nodes; or import the complete ZIP. `hedy2_replace` reuses existing matching asset bytes. Attach new or changed bytes first, and preserve the returned metadata in the replacement source.

### Validate, render, and export

```js
const checked = await window.hedyDecks.tools.call("hedy2_validate", { id: read.id });
if (checked.ok && checked.valid) {
  const built = await window.hedyDecks.tools.call("hedy2_render", { id: read.id });
  // Inspect built.ok, built.stale, and built.presentUrl before proceeding.
}
await window.hedyDecks.tools.call("hedy2_export", {
  id: read.id,
  download: true
});
```

Validation and render results do not themselves establish visual quality. Inspect Studio's previews, especially line wrapping, labels, image crops, and reveal steps. A render reports the source revision it used. If `stale:true`, newer edits occurred during rendering; render the current revision before presenting that work.

`hedy2_render` creates a separate playback bundle in the existing presentation library and returns a link. It does not automatically navigate or modify a currently running show. Playback `deckId` differs from editable source `id`.

Export packages contain source and assets, not approved-preview claims or local revision history. Export is not a visual validation gate: it can save a structurally valid draft whose layout still needs correction. `download:true` initiates a browser download. The `downloadUrl` is a temporary object URL for this page, not a remotely shareable URL; use the downloaded file for transfer. `base64:true` is useful only when an agent can write a file and accepts a potentially large result.

Import never overwrites a different local source with the same ID. Importing an identical source returns the existing local project. `asCopy:true` assigns a new ID, resets its revision to 1, and adds “(copy)” to its title.

### Optional temporary link

Use `hedy2_handoff` only when you intend to send the saved editable package to temporary server storage. Read the current revision, supply it as `expectedRevision`, and return the successful `openUrl`, `downloadUrl`, and `expiresAt` to the recipient. Anyone with the complete link can access the uploaded snapshot, including its speaker notes. The source remains locally editable; later changes do not update an existing link.

The temporary transfer limit is 25 MiB, separate from the 128 MiB local package limit. A link expires after 24 hours and is not a durable backup. An optional `idempotencyKey` contains 1–128 letters, digits, periods, underscores, colons, or hyphens. The last 64 handoff retry records are retained in this browser. Retry only the same source revision with the same key. On a revision conflict, read again and choose which revision to upload.

The tool shares one implementation across WebMCP, page JavaScript, and the ordinary Agent command desk. See [temporary handoff](/docs/temporary-handoff.md) for access, expiry, revocation, and the public file-upload HTTP protocol available to agents outside the browser.

## Boundaries

The `hedy2_*` catalogue is exposed through the browser, not the Hedy administration connector. The optional temporary handoff has a public file-transfer HTTP API; it does not remotely edit a Studio project. No separate V2 MCP server is provided. TURN servers and presentation room codes do not expose Studio editing permissions.

V2 rendering produces static images for the existing presenter/remote/receivers. Notes are included in their current bundle format, so do not treat them as secret. Export the editable file for durable backup; local browser storage can be cleared.

Earlier unprefixed tools (`deck_instructions`, `create_deck`, `validate_deck`, `import_deck`) remain associated with V1 HTML. See [V1 tool documentation](/docs/agent-tools-v1.md) only when deliberately using that earlier workflow. `/api/validate` is the legacy HTML endpoint, not a V2 source or ZIP validator.
