MCP recipes
Four tasks, end to end. Each one gives the exact call sequence, what to check after each step, and the durable handle you finish holding.
They are ordered deliberately. The first is the habit every other recipe depends on.
What every recipe assumes
A connected client. See Install. The inspect recipe uses only read-only tools; the other three write to a canvas, and one of them can incur provider cost.
Handles, not names. Every step passes a handle the service returned. Nothing here reconstructs a canvas: or node: identifier from context.
Read before write. Any recipe that changes an existing canvas starts with canvas_get and keeps the revision it returned.
Explicit approval before paid work. Exactly one recipe — Run a canvas workflow — can charge a provider, and it stops for approval at the point where that becomes possible.
The shape they all share
The Canvas Agent Guide states this sequence, and every recipe below is an instance of it:
Identify one exact canvas handle
Never choose between candidates on your own. canvas_list gives you handles; the user decides which.
Read the current state
canvas_get before reasoning about or changing anything. Keep the revision.
Read the relevant guide topic
guide_search then guide_get for anything unfamiliar. Both are free and need no scope.
Plan the smallest change that satisfies the request
Preserve unrelated nodes, connections, positions, and metadata.
Validate the proposal
canvas_validate with the proposed operations before anything large, spatial, or destructive.
Apply atomically
One canvas_apply_batch with the current baseRevision and one stable idempotency key.
Verify and report
Read the validation block that comes back with the write. Report the exact changed handles and any unresolved warning. Finish with open_canvas.
What to do when a step fails
| Failure | What it means | Do |
|---|---|---|
409 on a write or a dry-run | The canvas changed after you read it | Re-read, rebase your change around the newer graph, preserve the concurrent edit, retry |
403 insufficient_scope | The token lacks a scope the tool needs | Reconnect. The challenge names the scope. Do not work around it |
| A paid call times out | Normal — it exceeded waitSeconds | Poll the returned run: or job: handle. Never re-call the paid tool |
| A paid call fails terminally | The provider rejected or failed the work | Report it and stop. Ask for fresh intent before any new attempt |
| An operation is rejected | The batch is atomic, so nothing was applied | Fix the named operation. Do not resend the batch minus the failure unless that is genuinely the intent |