Tools

Canvas scope

What agents can read and write on the canvas, how screens get breakpoints, and when they ask first.

This page describes what an AI client can read and write on a Shippp canvas through MCP: which layers it sees, where it can create screens, frames and loose elements, how a screen gets its breakpoint, and when the client should ask you before it writes.

Note

The edit commands form a closed registry (shippp_get_command_schema returns the exact formats). Anything outside it is refused with a named reason, never guessed.

What the client can read

ToolScopeSource
shippp_list_unitsScreens (responsive artboards), master components, and the rest of the canvas: loose elements on design pages and frames created as non-responsive panels, each with its page and size.The saved snapshot. A change set applied moments ago appears after it persists.
shippp_get_context_packResolved values of specific layers by id: inside a screen, a loose canvas element (screen: null), a panel frame, or a component. Up to 40 nodes per call with subtree reads; above that the result says it was truncated.The live document.
shippp_get_active_selectionYour current canvas selection and the file it belongs to.The live editor.
shippp_read_design_system / shippp_get_tokensTokens, text styles and component contracts.The live document.
shippp_get_previewA PNG of a screen or a region of it.The live document, rendered on the server.

Not readable today: component pools as a group, and a compact whole-tree listing (id, name, type, parent) beyond the 40-node context pack. find targets match layer names only.

What the client can write

Edits go through shippp_apply_change_set: one atomic set of up to 50 commands that validate and commit together. Creating commands accept a localId ($name) that later commands in the same set can reference.

GroupCommandsNotes
Content and structurenode.insert, node.move, node.duplicate, node.remove, style.set, text.set, image.setWrites into a container or frame; instance internals are owned by the component.
Screens and pagessection.create, section.duplicate, screen.create, page.createScreens, their breakpoint views and design pages.
Componentscomponent.create, component.createFromSelection, component.place, instance.swap, swapProp.set, variant.addValueBuild a component once, place instances.
Design systemtoken.create / update / rename, textStyle.create / update / rename, breakpoint.add, font.addTokens, text styles, breakpoints and fonts.
Annotationcomment.add / reply / resolve / reopen, guide.add / move / removeComments and ruler guides.

Where new things land

  • Inside a screen or container: node.insert with the container's parentId (get it from a context pack). Under a flow container the element joins the flow; under a free-form container it lands at the given x/y.
  • Loose on the canvas: node.insert with parentId: null and optional pageId places a free element on a design page at x/y, outside any screen. It is listed under canvas, not screens.
  • A new screen: section.create with a device preset (desktop, laptop, tablet, mobile or custom). The screen joins the breakpoint ladder; add views with screen.create.
  • A sized frame: section.create with width and height. With responsive: false it is a panel or component canvas that never joins the breakpoint ladder: no breakpoint label, no screen rows.

What is refused

ReasonMeaning
needs-clarificationsection.create was called without a preset and without width + height. The client must ask you which shape you want instead of inventing a screen.
not-a-containernode.insert targeted a leaf layer (text, image, shape). Pick a container or a frame.
not-responsivescreen.create targeted a frame created with responsive: false. Panels have no breakpoint views.
capability-deniedThe target is inside a placed component instance. Edit the component definition instead; the error names the address.
breakpoint-takenscreen.create asked for a breakpoint that already has a view in that section.
Whole-screen removalnode.remove does not delete a top-level screen or a whole component; those are Shippp-side operations.

How a screen gets its breakpoint

A responsive screen's breakpoint comes from its width alone: the highest breakpoint whose threshold the width reaches, on the file's own ladder. The stored device preset does not decide. A 280 px wide screen therefore reads as the smallest band, and the context pack reports that band. A frame created with responsive: false reports no breakpoint at all.

Patterns for agents

  • Edit an existing screen: read a context pack for the screen, take the container's id as parentId, then insert.
  • Repeating UI: build the first copy, turn it into a component with component.createFromSelection, and place the rest with component.place. Never paste duplicated trees.
  • Ask before you create a screen: when the request is not a whole screen (a sidebar panel, a card, a widget), ask which you want: a new screen (which preset), a sized frame on the canvas (responsive or not), or an insert into an existing screen's section (which container). The server refuses an unshaped section.create with needs-clarification.

Known limits

  • Context packs with subtree reads stop at 40 nodes and say so; there is no compact tree mode yet.
  • padding in the same style.set patch as display: flex is refused as padding-not-supported; set the layout first, then the padding.
  • An empty container cannot be set to hug its content; add children first.
  • A new container starts with a white background; pass backgroundColor: transparent in the same set when you want it see-through.
  • Text that relies on symbol glyphs may render as empty boxes if the chosen font lacks them.
  • The client sees the design document, not Shippp's own interface. It cannot read how the editor's panels look.