Skip to main content
Glama

Showoff.dev – AI Mockup Generator

Edit a scene

edit_scene

Changes a still or film project with a batch of ops: add, move or remove devices, put screenshots on screens, texts, background, camera, motion, highlights, store sets, rename. The batch is atomic: later ops see earlier ones, and either all apply or none. Use it for every change to an existing image or film project; use update_launch_video for a launch video and create_project to start a new one. Before saving, the result is reviewed: if an op introduces an error nothing is saved and you get the findings with ready-to-send fixes (dry_run only reviews). Someone with the project open sees the change live, and every save becomes a version (list_versions). After geometry changes the camera is re-framed and texts re-laid out unless keep_camera is true. Returns the review and a preview sketch. The full op catalog is in the description of ops.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
opsNoOps (all in one atomic batch; later ops see earlier ones; objects created in this batch can be referenced as "$<ref>"): - {op:"add_device", device, variant?, name?, ref?, x?, z?, float?, turn?, lean?, roll?, lid?, browser?, dock?, appearance?, image?, layout?} — without x/z it is placed next to the group, then use apply_composition. In a store set give image and layout instead: image 2 = image 2, image 2.5 = across the seam of images 2 and 3. layout ("phones-fanned-close"|"phone-corner-close"|"two-phones-crossed-portrait"|"three-phones-fanned"|"three-phones-staggered"|"phone-stack"|"two-phones-leaning"|"two-phones-offset"|"three-phones-floating"|"phone-cropped-front"|"two-ipads-fanned"|"macbook-front"|"macbook-from-above"|"hero"|"tilt"|"tilt-left"|"top"|"full"|"duo"|"panorama"|"panorama-close") places and sizes the device the way a store image needs it (see the guide, "App Store sets"): one device per image in our own layouts, and once in the set a highlight: one of our templates, best on a seam (image 1.5) so it lies across both images; a template takes several devices (add one per place with the same image and layout, the first stands in front). Without it a device gets a layout for one device. The review rejects a second highlight, a second device in an image and anything cut at a seam. turn, lean and roll then change the pose of our own layouts. layout "none", or any of x, y, z, scale, places the device by hand - {op:"update_device", id, image?, layout?, x?, z?, float?, turn?, lean?, roll?, lid?, variant?, device? (swap model), status_bar? (false when the screenshot already shows its own status/menu bar), browser? ("safari"|"chrome"|"arc"|"none" — MacBook/Studio Display only: puts a plain web page capture into a browser window below the menu bar), dock? (true: the macOS Dock below it), appearance? ("light"|"dark" for window, Dock and desktop), fit? ("auto"|"cover"|"contain" — how the screenshot sits on the screen)} - {op:"remove", id} - {op:"apply_composition", composition, text_space?, azimuth?, elevation?} — re-arranges ALL devices (see list_compositions) - {op:"apply_reference", reference, with_background?} — places the devices, camera and format like a measured reference shot. Fewer devices than the reference are fine: they take the places nearest the center and the camera re-frames (5 phones from a 7-phone grid). Kinds must match (phone on a phone place). - {op:"set_screen", device_id, media_id | media_ids[], fit?: "auto"|"cover"|"contain"} - {op:"add_text", text, role?: "headline"|"subline"|"caption", region?: "top"|"bottom"|"left"|"right"|"auto", color?: "#hex"|"auto", weight?, font?: "sans"|"mono"|"serif", ref?, image?, translations?} — in a store set: image (1…n) is required and every image takes one title only (role headline, two to six words, set in two lines; no subline or caption), translations: {"de": "…", "fr": "…"} for the other languages of the set - {op:"update_text", id, text?, language?, translations?, image?, role?, region?, color?, weight?, font?} — with language, text is that language's version (store sets) - {op:"place_text", id?, region?, image?} — re-layout text - {op:"set_background", palette: id, accent?: "#hex"} | {preset} | {solid: "#hex"} | {gradient: {angle, stops: ["#hex", …]}} | {transparent: true} - {op:"match_image", width, height, world?: "floating"|"lying"|"standing", devices: [{id?, corners: [[x,y],[x,y],[x,y],[x,y]], edge?: "display"|"glas"|"gehaeuse"}]} — rebuild the exact layout of a picture the user gave you: for every device the four pixel corners of its SCREEN in that picture (top-left, top-right, bottom-right, bottom-left as seen from the device, top = camera / Dynamic Island side; corners outside the frame are fine). The server solves camera, perspective, lens and every pose from them — do not guess angles yourself. One entry per device, in the order of the scene's devices (or with id). Returns fit_error_px; above ~2 % of the width the corners were misread. - {op:"frame_camera", azimuth?, elevation?, fov?, margin?} — re-frames; omitted values keep the current camera (also a reference camera). azimuth −180…180, elevation −20…89, margin 1 = edge to edge, 1.15 default, below 1 crops boldly - {op:"set_format", format} — preset name or {width, height} (ends a store set) - {op:"set_store_set", store?: "iphone"|"ipad"|"mac"|"play", images?: 1–10, languages?: ["en","de",…], camera?: "reset"} — turns the image project into a row of store screenshots side by side (iphone 1320×2868 each, ipad 2064×2752, mac 2880×1800, play 1080×1920). The stage becomes as wide as all images; export_image cuts it into one PNG per image and language, in one ZIP. The first language is the one the texts are written in. Changing images keeps everything in its image. Sets its own frontal camera and has no floor: devices are placed by layout, not by float. - {op:"remove_store_set", format?} — back to one image - {op:"set_shadow", opacity?, blur?} - {op:"set_depth_of_field", strength?, focus?} — depth of field like a real lens (stills and films): one plane stays sharp, devices in front of or behind it get softer with their distance to it. strength 0–1 (0 = off, 0.2–0.5 subtle, 1 strong); focus: "auto" (the frontmost device in frame, the default) or a device id. Text always stays sharp. - {op:"set_motion", id, entrance?, loop?, amount?, exit?} (film only; quick way: entrance: einfliegen|einfedern|auftauchen|hereindrehen|hereinrollen; loop: schweben|treiben|kreisen|wiegen|kippen|schaukeln|hand|pulsieren|drehen — or an array of them, loops add up (["schweben", "schaukeln"] floats and rocks); amount only with a single loop; exit: true/false or its own kind hinausfliegen|hinausfedern|verschwinden|hinausdrehen|hinausrollen; entrances and exits always run on Extended ease keyframes — soft start, long landing) - {op:"set_effects", id, effects: [{type, from?, to?, amount?, side?, once?, cycle?, from_angle?, to_angle?}, …]} (film only; full control, replaces all motion of that object; type: any entrance, exit or loop above, or "lid" for a laptop lid (from_angle/to_angle 0–130°, several lid effects in a row = open, then close); from/to in seconds — stagger devices by giving each its own times; side: "left"|"right" for rollen; once: true for a single turn of drehen; cycle: seconds per loop) - {op:"set_camera_move", shots: [{from, to, travel?, orbit?, raise?, distance?, zoom?, name?} | {from, to, travel?, focus: {device, x?, y?, w?, h?}, zoom?}, …], outro?, style?} (film only; the camera glides from the project view to each shot in turn and back during `outro` seconds. orbit/raise: degrees around/above the target relative to the project camera (set that first with frame_camera); distance: share of the current distance (0.8 = 20 % closer); zoom: lens factor (1 = as is); focus: frame a rectangle on a device screen (fractions 0–1, top-left origin). travel: seconds to glide there (default 2, slow drifts 3–5 s); shots must not overlap; leave room after the last shot for the outro in a loop. shots: [] removes the camera move) - {op:"set_duration", seconds, loop?} (film only; 6–10 s keeps motion calm — entrances and exits take a share of it) - {op:"set_highlight", device, kind: "lift"|"loupe"|"redact", rect: {x, y, w, h}, snap?, radius?, lens?: {x, y, size, zoom?}, screen?, id?} — point at one spot of a screen. rect: the spot in fractions of the screen (0–1, top-left origin, like camera focus); a rough rect around the element is enough. snap (default true): the server looks at the screenshot and moves each side of the rect onto the edge of the element you mean (a card, a widget, a row, a button — at most 6 % of the screen width, inward first) and measures its corner radius, so a lifted card is exactly that element and takes no background with it. The result names what the rect became (`rect`, `radius`, `snapped`); a side without a clear edge stays where you put it, and screen recordings are not snapped. snap: false keeps your rect as given. radius: corner radius as a share of the screen width (0 = sharp corners), only to overrule the measured one. lift: the spot floats off the display as its own card with a soft shadow while the rest of the screen dims (one row, one card, one button). loupe: a round glass lens floats over the screen and shows the spot enlarged, sharp in the middle and bent at the rim like real glass; lens: its center (fractions), its diameter (share of the screen width, 0.3–0.7) and zoom (1.2–4). By default it sits right over the spot, sized so the spot fills its clear middle at about 2×. redact: the spot is pixelated beyond reading, in every render — for names, emails, numbers; it only snaps outward, never uncovering what you marked. screen: index of the device's screen it belongs to (films with several screens), omitted = always. id: change an existing highlight instead of adding one. At most 8 per device. - {op:"remove_highlight", device, id?} — without id removes all highlights of that device - {op:"auto_cut", device, screen?, follow?} (film only) — cuts the idle stretches out of a screen recording on that device (the first uncut one, or the one at position `screen`): the screen then plays the pieces of the same file back to back, and a film as long as the recording gets shorter. follow: true also lets the camera follow the action (closer where someone taps or types, wide while the whole screen changes); it replaces the camera move. - {op:"rename", name} Units: cm and degrees. The camera is re-framed and text re-laid-out automatically after geometry changes unless keep_camera is true (never in a store set: its camera stays where the images are).
folderNoOnly when the user asks to file it: move the project into this folder of their projects, e.g. "Store sets" or "Showoff/Trailer" (created when missing; "" = top level). Without ops it only files the project. Launch videos: update_launch_video.
dry_runNoReview and preview without saving.
previewNoAttach a preview sketch of the result (default true). false is faster when you only need the review.
project_idYesProject id (from create_project or list_projects).
keep_cameraNoDo not re-frame the camera automatically.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare only the safety profile (readOnly false, destructive false, openWorld false). The description goes well beyond: batch atomicity ('either all apply or none', later ops see earlier ones), the reject-and-return-findings behavior on error, live visibility to other viewers, version creation on every save, and automatic camera re-framing/text re-layout after geometry changes unless keep_camera is true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The prose is dense but mostly earns its place; the ops enumeration in the first sentence is somewhat redundant with the schema's full catalog. Front-loading atomicity and sibling routing is good, but the run-on sentences mix several concerns without separation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter, 60-op mutation tool with no output schema, the description covers atomicity, error handling, preview/version side effects, and prerequisite conventions. It even names what the call returns ('the review and a preview sketch'), which is needed since there is no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100% and the ops catalog is verbose in-schema, yet the description adds routing value: it points to `ops` for the full catalog and explains that keep_camera suppresses the automatic re-frame, and that folder without ops only files the project. It adds semantic framing rather than duplicating parameter definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (changes/edits) and resource (a still or film project) and enumerates the op families it covers (add/move/remove devices, screens, texts, background, camera, motion, highlights, store sets, rename). It explicitly distinguishes itself from siblings update_launch_video and create_project, so an agent can route without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing: 'Use it for every change to an existing image or film project; use update_launch_video for a launch video and create_project to start a new one.' It also states the dry_run-only review path, so the agent knows when to review vs commit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources