The execute tool
Agents change a document by sending short JavaScript snippets to the execute tool. Each call is a transaction: if anything fails, every change in that call is reverted.
How it works
execute is an MCP tool. It takes the absolute filePath of the .ptl document and an input string with the snippet. Potlot runs the snippet in a JavaScript runtime with the Potlot API in scope, against a working copy of the document.
If the snippet finishes, the changes are kept and the editor shows them. If any statement throws, a check after the run fails, or the run takes longer than 30 seconds, every change from that call is rolled back and the canvas stays as it was.
Your first snippet
document is the root of the document. In a document with pages, layers inserted into it land on the page the agent works on.
card = Insert(document, {type: "frame", name: "Card", layout: "vertical", gap: 12, padding: 24, fill: "#18181B"})
Insert(card, {type: "text", name: "Greeting", content: "Hello, canvas", fontSize: 20, fill: "#F4F4F5"})
TakeScreenshot([card])- Always give new layers a readable
name. The result maps each name to the new id. - Never set
id. Potlot generates ids and ignores yours. - Do not write comments in snippets.
Keeping ids between calls
Each snippet runs in its own scope. Plain global assignments persist: write card = Insert(...) without const or let, and a later call can use card. Values are carried over as JSON, so ids, numbers, strings, arrays and plain objects survive; functions do not.
The API
| Kind | Functions |
|---|---|
| Change layers | Insert, Copy, Update, Replace, Move, Delete |
| Read | Get, GetPages, GetVariables, GetTextStyles |
| Tokens | SetVariables, DeleteVariables, SetTextStyles, DeleteTextStyles, RenameTextStyle |
| Helpers | FindEmptySpace, Print, TakeScreenshot, SearchIcons, ShowPage |
| Images and art | Generate, CancelGenerate, ImportImage, InsertSVG, ReplaceSVG, BakeTransforms, Import |
| Files | Export |
Paths are layer ids. Inside a component instance, use instanceId/childId: Update on such a path becomes an override, and Delete disables that child in the instance. Update with null removes a property. Update cannot change id or type.
What a call returns
success: whether the snippet ran and its changes were kept.names: each new layer's name mapped to its id.logs: whatPrintwrote. Strings print raw, other values as JSON.warnings: problems Potlot noticed, such as an unknown icon, a top-level layer placed over another one, or text below WCAG contrast.- Screenshots from
TakeScreenshot, attached as images. errorandeditIdwhen the call failed.
Fixing a failed call
When a call fails, do not resend the whole snippet. Call execute again with the editId and a list of edits: find and replace pairs that patch the failed snippet. Each find is copied exactly from the failed snippet and must match once, unless you add all: true. Only the latest failed snippet can be retried. In this example the failed snippet had misspelled card.
{
"filePath": "/Users/me/Designs/landing.ptl",
"editId": "edit-3",
"edits": [{"find": "Insert(crad,", "replace": "Insert(card,"}]
}Keep calls small
Send one section per call: a header, a form, a list of cards. The canvas plays each statement as it arrives, so people watch the design come together, and a mistake reverts only that section. End a call that finishes a section with a screenshot and check it before moving on. See Screenshots.
Something unclear, missing or broken? Write to feedback@anaknegeri.dev.