# ScreenMake > ScreenMake designs App Store and Google Play screenshots in the browser. Start from your app's own screens, frame them on iPhone, iPad and Android devices, restyle the whole set in one sentence, translate it into 39 languages, export at every store size and publish straight to App Store Connect. Free to design; a paid plan to export without a watermark and to publish. # MCP server reference ## Connect ScreenMake runs a remote MCP server (Model Context Protocol, Streamable HTTP transport). Any MCP client that supports remote HTTP servers can use it. - **Server URL:** `https://screenmake.com/api/mcp` - **Authentication:** `Authorization: Bearer `. Keys start with `sdmcp_`. - **Getting a key:** in the ScreenMake Studio, open Settings from the account menu, then "API keys & MCP", and create a key. It is shown once. Each key works on one project; a project can have up to 10 active keys. Deleting a key cuts off access immediately. - **Plan:** MCP access needs a paid plan. AI tools called through MCP use credits the same way as in the Studio. Client configuration (the usual shape for remote HTTP servers): ```json { "mcpServers": { "screenmake": { "type": "http", "url": "https://screenmake.com/api/mcp", "headers": { "Authorization": "Bearer sdmcp_your_key_here" } } } } ``` ### HTTP errors | Status | Meaning | |---|---| | 401 | Missing, invalid or deleted key. | | 402 | `MCP_REQUIRES_PLAN`: the key's owner has no active paid plan. | | 403 | The request's host isn't allowed, or the account is restricted. | | 503 | Sign-in is temporarily unavailable; retry later. | Tool results are JSON with `ok: true` on success, or `ok: false` with a `code` and an `error` message. Codes each tool can return are listed in its description. ### Limits - `shots_upload`: up to 10 images per call, 8 MiB each, 24 MiB in total. Images travel as base64 or data URLs. - Request bodies are capped at 40 MiB. ## How the server works This MCP server reads and edits one project from its saved database state. A project-scoped bearer token limits every operation to that project and owner. The server does not need a Studio tab to be open or focused, and it does not simulate clicks or open dialogs. Successful design mutations are atomically saved against the revision that was read. An authenticated Studio tab for the same project receives a small change signal, fetches the authoritative saved project, and refreshes the canvas. If no tab is open, the saved result appears when Studio is next opened. The canvas is the visual result surface. MCP calls do not open the inspector, switch rail sections, manipulate search/filter controls, invoke file pickers, or show app notifications. A saved project change is not proof that a browser has painted it; verify with a read tool, then inspect the open canvas if one is available. ### Recommended workflow 1. Call **editor_get_context** first when the project, device, active screen, or target is unclear. Use **header_get_state**, **screens_list**, **screens_get_details**, **canvas_get_layout**, **uploads_list**, **shots_list**, or **inspector_get_state** for more specific information. 2. Use stable screen, layer, upload, Shot, and catalog IDs returned by read tools. Layer IDs include their kind, for example `text:abc` or `image:def`. 3. Call the setter or action for the requested change. Omitting optional screenId targets the saved active screen. 4. A successful project mutation returns `persisted: true` and a new `revision`. An authenticated open Studio client refreshes from that saved revision. A `REVISION_CONFLICT` means another writer changed the project after the tool read it; reread context and retry only if the requested change is still appropriate. 5. Verify the saved result with a getter such as **screens_get_details** or **inspector_get_state**. Canvas preview images are not currently available from the independent server renderer. Example: `screens_list({})` returns ordered screen IDs. Call `screens_duplicate({"screenId":""})` once, then use its `duplicateScreenId` to inspect the full copy. The response includes a revision; a retransmission with the same MCP request ID returns the first result rather than duplicating again. Example: `uploads_list({"query":"logo"})` returns project upload IDs. Pass one to `canvas_add_image({"uploadId":""})` to add it to the active screen. A data URL can also be passed to canvas_add_image; the server validates and saves the image to this project before committing the layer. Example: `canvas_get_layout({"screenId":""})` provides screen-local design-pixel geometry and stable layer IDs. Then `canvas_align_layers({"screenId":"","layerIds":["text:title","image:hero"],"horizontal":"center"})` commits the alignment. Selection, camera, and viewport state are local to a Studio session and are not read or manipulated by this server. ### Saved project state and live Studio updates The database is the source of truth. Project reads and edits are scoped by both the token's project ID and owner ID. Every write uses a compare-and-swap revision, and every changed MCP command has an idempotency receipt so retrying the same JSON-RPC request does not apply the operation twice. Concurrent local editor and MCP writes cannot silently overwrite each other: one writer receives a revision conflict and the application preserves the other writer's newer state. Successful results describe persistence, not browser paint completion. While an authenticated Studio tab is open for the same project, it subscribes to a project-specific signal and fetches the saved state through the user's authenticated project route. The signal never includes the project document. No tab is required for an MCP command to run or save. Selection, camera, viewport, the browser's color theme, and editor undo history are session-local and are not part of saved project design state. ### Screens and layers Use **screens_list** for compact summaries and ordering, **screens_get_details** for complete saved screen/layer data, and **screens_select** to set the saved active screen. **screens_add**, **screens_duplicate**, **screens_delete**, and **screens_reorder** change the selected device's screen deck. Duplication copies the complete screen design and assigns fresh IDs to the new screen and each editable layer. The last screen cannot be deleted. Reordering requires every current screen ID exactly once. Use **canvas_get_layout** before placing or aligning when IDs or geometry are not already known. Coordinates and dimensions are in design pixels local to the screen; returned visible bounds account for rotation. **canvas_set_layer_transform**, **canvas_align_layers**, **canvas_distribute_layers**, **canvas_duplicate_layer**, **canvas_delete_layer**, **canvas_set_layer_visibility**, **canvas_reorder_layer**, and **canvas_update_text** operate directly on saved layer data. These actions persist and refresh open Studio clients. They do not change session-local layer selection or camera position. **Every device deck is addressable.** A screenId from any deck (iPhone, iPad, …) works in every screen and layer tool, and the edit lands in that deck without switching the saved device, so the user's open Studio doesn't move. Pass `device` to **screens_list**, **editor_get_context**, **screens_add**, **canvas_get_layout** or **canvas_capture_preview** to read or add in another deck. Device and mockup layers in **canvas_get_layout** carry `screenRect`, the app screen inside the frame, to place overlays against. **Many edits at once:** **canvas_apply_batch** runs up to 200 commands (`{ command, args }`, e.g. `canvas.set_layer_transform`) as one saved revision, all or nothing, across decks. Use it for re-layouts instead of hundreds of single calls. **Languages:** styles are shared by every language. With an explicit non-source `locale`, **inspector_set_text_style** sets that language's own fontSize, fontFamily and boxWidth, and **inspector_set_text_range_style** styles ranges of that language's own text. **localization_status** lists text that is tight or overflowing per language, measured with the real fonts. Text box heights always follow the wrapped source text. **canvas_focus** cannot select layers or control camera/zoom without an open Studio session. Use **screens_select** when the goal is to change the project's active screen. Layer/camera focus requests return a session-state error instead of pretending they happened. ### Header Use **header_get_state** to read the saved app name, connected/isolated canvas mode, platform, device, last device per platform, orientation, locale, and available choices. It also reports that undo, redo, export, and rendered preview are unavailable through saved project state. - **header_set_app_name**, **header_set_canvas_mode**, **header_set_platform**, **header_set_device**, **header_set_orientation**, and **header_set_locale** update saved project settings. Switch platform before selecting a device from another platform. Landscape is supported only for the larger Android tablets. Locale must already be configured in the project; add or remove languages (and pick the source language) with **header_set_locales**, and see what is still untranslated with **localization_status**. Translate the whole deck with **localization_translate** (AI, cheap; mode "shorten" for tight lines), or write strings yourself with **localization_set_strings**; keep brand names with **localization_set_glossary**. App screenshots per language: **localization_translate_screenshots** (AI redraw, image-edit price each) or **localization_set_screenshot** with a shot or upload. **app_store_status** and **app_store_link_app** cover App Store Connect. **app_store_publish** publishes every deck (iPhone, iPad) in every App Store language each project language fills (en also fills en-GB, en-AU, en-CA when nothing else claims them); run it with dryRun first, and publish for real only when the user asks. It renders in an open Studio tab of the project, or in ScreenMake's cloud renderer when none is open, and succeeds only once Apple has processed every screenshot. **app_store_verify** reads the listing back, no browser needed. - **header_reset** can reset the current device deck or every deck. It requires an explicit approval handshake and exact scope-bound token before replacing saved data. - **header_undo** and **header_redo** return `PERSISTENT_HISTORY_REQUIRED`: durable cross-session history is not implemented, so the tools do not revert or replay a project snapshot. - **header_set_theme** returns `EDITOR_PREFERENCE_NOT_PROJECT_STATE`: theme is a browser preference, not project design data. - **header_export_bundle** returns `SERVER_RENDERER_REQUIRED`: an export that depends on an open browser is intentionally unavailable to the headless MCP endpoint. Canvas snapping and alignment guides remain part of the editor. These MCP tools do not alter snapping preferences or show the removed header menu. ### Bottom canvas toolbar **canvas_add_text**, **canvas_add_image**, **canvas_add_shape**, and **canvas_add_icon** add saved layers to a requested screen or the saved active screen. They do not open toolbar menus, the inspector, dialogs, or file pickers. Image input is validated and stored in the project before its layer is committed. Use **canvas_list_icon_families** and **canvas_search_icons** to discover exact icon, emoji, and 3D icon names before calling canvas_add_icon. The Move, Select, Hand, Draw, and Copy region tools are session interactions and are not exposed as saved project actions. **canvas_capture_preview** returns the rendered screen (or a crop around one layer) as an image, produced by the Studio export engine (in a signed-in Studio tab of the project, or in ScreenMake's cloud renderer when no tab is open), so it matches exported PNGs. Use it after each meaningful visual change to verify fonts, alignment and composition. It renders any deck and any language (`device`, `locale`) off-screen without changing what the Studio shows; with no tab open the first preview takes longer while the cloud renderer starts; it returns `PREVIEW_STUDIO_UNAVAILABLE` when neither answers and retries once when the renderer drops (`PREVIEW_STUDIO_LOST`). ### Elements and AI images Use **elements_list_categories** and **elements_search_assets** to find catalog assets. Search does not change visible rail filters. Pass the returned `assetRef` to **elements_add_asset**; paths should not be constructed by hand. **elements_generate_asset** and **stock_generate_asset** create a custom isolated image from a prompt, optional reference, and aspect/rendering settings; the result is stored as a project upload and inserted as a new image layer. **image_generate** creates an image from a prompt. **image_edit** edits one source image from a project image layer, Uploads ID, or validated image data URL, with an optional PNG mask. By default edit adds a new layer; `replaceSource: true` replaces the specified source layer while preserving its geometry and style. These tools wait for server generation, store the final image privately in the project, and commit the layer without showing a generator dialog or temporary UI. For AI images, `background: "transparent"` requests transparency and PNG is the default output. A failed project commit after image storage may leave an unreferenced private file for later cleanup. **mockups_generate** creates a transparent PNG using a saved Shot as protected screen artwork and optional reference data URLs. It stores and inserts the final image only after generation completes; no generator UI is shown. ### Mockups, Stock, Shots, and Uploads - **mockups_list** reads current catalog variants and orientation support; **mockups_add** inserts the selected variant into the saved screen. - **stock_search** exposes the same filters as the Stock panel, including downloadable file format and the transparent color filter, without changing rail search/filter controls. Search results distinguish thumbnail previewURL from the best available source downloadURL. - For a reusable file, call **stock_import_asset** with the result's Pixabay ID and category. For a transparent PNG, search with File format set to PNG and Color set to Transparent, then import with PNG format and required transparency enabled. The import downloads the full-size available file into ScreenMake, checks its encoded format and alpha pixels, and returns an absolute download URL plus a reusable asset reference for **elements_add_asset**. **stock_add_to_canvas** performs the same download and validation, then adds the image layer in one call. Preserve and display the returned Pixabay attribution. - **shots_list**, **shots_upload**, **shots_reorder**, and **shots_delete** manage reusable project screenshots. **shots_inject** assigns a saved Shot to a built-in device slot or user-added mockup layer. Shot bytes are stored privately and only stable IDs and metadata are kept in project state. - **uploads_list** finds reusable project images and **uploads_remove** removes an image from the library; existing canvas layers keep their source. Uploads accept supported image formats and are private to the authenticated owner and project. ### Inspector The inspector is addressed by stable project IDs; no MCP call selects a layer or manipulates the visible inspector. Read **inspector_get_state** before applying an unfamiliar setting. Without `layerId`, it returns the screen background and caption state. With `layerId`, it returns saved properties relevant to the layer kind and the valid inspector controls/presets. Use **inspector_set_screen_background** for theme, color, gradient, image, abstract, mesh/aurora, or supported shader backgrounds. Use **inspector_set_layer_appearance** for shared corner radii, stroke, shadow, glow, and color adjustments. Type-specific setters are **inspector_set_text_style**, **inspector_set_text_range_style**, **inspector_set_image_style**, **inspector_set_icon_style**, **inspector_set_shape_style**, **inspector_set_clip_style**, and **inspector_set_mockup_style**. **inspector_search_fonts** returns font choices without opening the picker. **inspector_remove_image_background** runs the configured background-removal service for an image layer, validates the transparent PNG result, stores it in project Uploads, and replaces that layer's source while preserving its geometry and style. Missing configuration, invalid results, or service errors return an error without changing the saved project. ### Permissions and error handling Every tool is bound to the owner and project encoded by its MCP bearer token. Never use a token for another project or attempt to infer another user's project ID. Catalog cover changes and permanent catalog deletion require the separate admin scope and the documented confirmation flow. The user must approve permanent deletion in conversation before retrying with `approved: true`; the application shows no confirmation dialog. Common errors include `INVALID_SCREEN`, `INVALID_LAYER`, `INVALID_UPLOAD`, `INVALID_SHOT`, `INVALID_ASSET_REF`, `INVALID_MOCKUP`, `INVALID_LOCALE`, `DEVICE_PLATFORM_MISMATCH`, `ORIENTATION_UNAVAILABLE`, `REVISION_CONFLICT`, `PROJECT_READ_FAILED`, `PROJECT_COMMIT_FAILED`, `SERVER_RENDERER_REQUIRED`, and `PERSISTENT_HISTORY_REQUIRED`. Empty library searches are successful and return an empty list with a null next cursor. Validation and service errors do not commit project changes. Image generation or upload may leave an unreferenced private file if the subsequent project commit fails; the response still reports the commit error and never reports the image as added. ## Resources - `seedance://left-rail/guide`: Editor MCP guide. Guide to header controls, bottom canvas insertion tools, and Screens, Elements, Mockups, Stock, Shots, and private Uploads tools, including workflows, IDs, constraints, and confirmation behavior. - `seedance://editor/guide`: Editor MCP guide. Guide to header controls, bottom canvas insertion tools, and Screens, Elements, Mockups, Stock, Shots, and private Uploads tools, including workflows, IDs, constraints, and confirmation behavior. - `seedance://editor/context`: Saved project context. Read device, orientation, saved active screen, screen summaries, saved Shots, and Uploads count from the project database; no Studio tab is required. - `seedance://editor/header`: Saved project header state. Read project-backed app name, canvas mode, platform/device, orientation, locale, and available choices. Session-local theme/history and browser export are not available from saved state. - `seedance://editor/canvas`: Saved canvas layout. Read screen-local design geometry, stable layer IDs, visibility, and order. Session-local layer selection, viewport, and camera are not persisted. - `seedance://editor/inspector`: Saved inspector state. Read screen background or explicitly targeted layer properties and applicable settings from saved project state. No current selection is required. - `seedance://editor/screens`: Saved screens. Read ordered screen summaries for the saved current device. - `seedance://left-rail/categories`: Left-rail library categories. Read category IDs and counts for Elements, Mockups, and Pixabay Stock. This does not change the visible rail or its filters. ## Tools (82) ### Project context #### `editor_get_context`: Get editor context _read-only, idempotent_ Read the project app name, device, orientation, locale, saved active screen, ordered screen summaries, Shots and Uploads count. Pass device (e.g. ipad) to read another device's deck without switching. Use this first when the target is unclear. Layer selection, camera and browser state are session-local and are not returned. No Studio tab is required. Errors: INVALID_DEVICE, PROJECT_READ_FAILED. Parameters: - `device` ("iphone" | "iphone-duo" | "iphone-duo-open" | "ipad" | "mac" | "apple-watch-ultra" | "apple-watch-series" | "apple-tv" | "android" | "android-7" | "android-10" | "chromebook" | "wear-os" | "android-tv" | "feature-graphic" | "windows" | "browser"): Device deck to read or edit (e.g. ipad) without switching the saved device. Omit for the saved device; a screenId from another deck is found automatically. ### Project settings (app name, platform, device, orientation, languages, export) #### `header_get_state`: Get header state _read-only, idempotent_ Read saved app name, Connected/Isolated mode, platform/device, last device per platform, orientation, locale and valid choices. Also reports undo, redo, preview and export unavailable because they need durable history or a separate renderer. Browser theme, selection and camera are session-local. No Studio tab is required. Errors: PROJECT_READ_FAILED. Parameters: none. #### `header_set_app_name`: Set the app name _idempotent_ Set the design/export App name stored in project state; this is separate from the project title. Accepts 1–120 characters. Saves the new value and refreshes authenticated open Studio clients. Errors: INVALID_APP_NAME, REVISION_CONFLICT. Parameters: - `appName` (string, required; max length 120) #### `header_undo`: Undo the latest editor action Not available: persistent cross-session project history has not been implemented. Returns PERSISTENT_HISTORY_REQUIRED and leaves project state unchanged. Use explicit project setters for changes. Parameters: none. #### `header_redo`: Redo the latest undone action Not available: persistent cross-session project history has not been implemented. Returns PERSISTENT_HISTORY_REQUIRED and leaves project state unchanged. Parameters: none. #### `header_set_canvas_mode`: Set connected or isolated canvas mode _idempotent_ Set saved Connected/Isolated canvas interaction mode. Connected allows transferable layer drag across screens; Isolated keeps a dragged layer on its source screen. This does not change project contents or simulate a drag. Open Studio clients refresh from the project signal. Errors: REVISION_CONFLICT, PROJECT_COMMIT_FAILED. Parameters: - `enabled` (boolean, required) #### `header_set_platform`: Switch store destination _idempotent_ Select Apple App Store, Google Play, Microsoft Store, or Chrome Web Store and restore the last saved device for that destination. Open Studio clients refresh from the project signal. Use header_get_state to verify. Errors: INVALID_PLATFORM, REVISION_CONFLICT. Parameters: - `platform` ("ios" | "android" | "windows" | "web", required) #### `header_set_device`: Select a device deck _idempotent_ Set the saved device deck. Apple: iphone, iphone-duo (outer display), iphone-duo-open (inner display), ipad, mac, apple-watch-ultra, apple-watch-series, apple-tv. Google: android, android-7, android-10, chromebook, wear-os, android-tv, feature-graphic. Microsoft: windows. Chrome Web Store: browser. Switch destination first when needed. Errors: DEVICE_PLATFORM_MISMATCH, REVISION_CONFLICT. Parameters: - `device` ("iphone" | "iphone-duo" | "iphone-duo-open" | "ipad" | "mac" | "apple-watch-ultra" | "apple-watch-series" | "apple-tv" | "android" | "android-7" | "android-10" | "chromebook" | "wear-os" | "android-tv" | "feature-graphic" | "windows" | "browser", required) #### `header_set_orientation`: Set device orientation _idempotent_ Set portrait or landscape in saved project state. Landscape is supported on iPad and Android 7-inch and 10-inch tablets. Open Studio clients refresh size-dependent canvas state. Errors: ORIENTATION_UNAVAILABLE, REVISION_CONFLICT. Parameters: - `orientation` ("portrait" | "landscape", required) #### `header_set_locale`: Set active locale _idempotent_ Set the active saved locale to one already configured in the project; this does not add/remove locales. Open Studio clients refresh localized copy from the saved state. Errors: INVALID_LOCALE with valid choices, REVISION_CONFLICT. Parameters: - `locale` (string, required; min length 1, max length 32) #### `header_set_locales`: Add or remove languages Add and/or remove project languages and choose the source language (the one the deck is designed in, translations come from it). Use App Store locale codes: en-US, en-GB, de-DE, fr-FR, es-ES, es-MX, it, ja, ko, zh-Hans, zh-Hant, pt-BR, ru, ar-SA, he, tr, nl-NL… Removing a language deletes its translations and screenshots on every device. To translate, switch with header_set_locale and write text with canvas_update_text (it writes the active locale). Errors: INVALID_LOCALE, SOURCE_LOCALE, REVISION_CONFLICT. Parameters: - `add` (string[]; max 40 items) - `remove` (string[]; max 40 items) - `sourceLocale` (string; min length 2, max length 16) #### `header_set_theme`: Set editor theme _idempotent_ Unavailable to the headless project API: light/dark appearance is a browser-local preference, not saved project design state. Returns EDITOR_PREFERENCE_NOT_PROJECT_STATE and makes no change. Parameters: - `theme` ("light" | "dark", required) #### `header_reset`: Reset a device deck or every device _destructive_ Reset the current device deck or every device deck to defaults. First call returns an exact warning and short-lived project-bound confirmation token. After the user explicitly approves that exact scope, retry with the same scope and token within five minutes. Approval is bound to the saved project revision; if the project changes first, request approval again. The token is single-use across server instances and consumed atomically with the reset. No app dialog appears; persistent undo is unavailable. Errors: CONFIRMATION_REQUIRED, CONFIRMATION_UNAVAILABLE, INVALID_CONFIRMATION, CONFIRMATION_SCOPE_MISMATCH, CONFIRMATION_STALE, CONFIRMATION_ALREADY_USED, REVISION_CONFLICT. Parameters: - `scope` ("current-device" | "all-devices", required) - `approved` (boolean) - `confirmationToken` (string; format uuid) #### `header_export_bundle`: Export the device bundle Unavailable without a separate server-side renderer and export packager. Returns SERVER_RENDERER_REQUIRED and does not open a browser or trigger a download. The project is unchanged. Parameters: none. ### Screens #### `screens_list`: List screens _read-only, idempotent_ List stable screen IDs, labels, headlines, layouts and order for the saved device deck, or another deck with device (e.g. ipad). Read-only; does not alter active screen. No Studio tab is required. Errors: INVALID_DEVICE, PROJECT_READ_FAILED. Parameters: - `device` ("iphone" | "iphone-duo" | "iphone-duo-open" | "ipad" | "mac" | "apple-watch-ultra" | "apple-watch-series" | "apple-tv" | "android" | "android-7" | "android-10" | "chromebook" | "wear-os" | "android-tv" | "feature-graphic" | "windows" | "browser"): Device deck to read or edit (e.g. ipad) without switching the saved device. Omit for the saved device; a screenId from another deck is found automatically. #### `screens_get_details`: Get screen and layer details _read-only, idempotent_ Read a screen's saved localized copy, layout, background, built-in visibility, screenshots and editable layers with stable IDs/transforms. Omit screenId for the saved active screen. Embedded image bytes are summarized. Read-only; does not change active screen. Errors: INVALID_SCREEN, PROJECT_READ_FAILED. Parameters: - `screenId` (string; min length 1) - `device` ("iphone" | "iphone-duo" | "iphone-duo-open" | "ipad" | "mac" | "apple-watch-ultra" | "apple-watch-series" | "apple-tv" | "android" | "android-7" | "android-10" | "chromebook" | "wear-os" | "android-tv" | "feature-graphic" | "windows" | "browser"): Device deck to read or edit (e.g. ipad) without switching the saved device. Omit for the saved device; a screenId from another deck is found automatically. #### `screens_select`: Focus a screen in the canvas _idempotent_ Set screenId as the saved active screen for the current device deck. This does not select a layer, change camera, switch rails or open UI. Open Studio clients refresh from saved state. Errors: INVALID_SCREEN, REVISION_CONFLICT. Parameters: - `screenId` (string, required; min length 1) #### `screens_add`: Add a screen Add and set active a screen in the current saved device deck. Layout defaults to device-bottom, or feature-graphic on that device. Supported layouts: hero, device-bottom, device-top, two-devices, no-device, split-landscape and feature-graphic. No rail/dialog is opened. Errors: INVALID_LAYOUT, REVISION_CONFLICT. Parameters: - `layout` ("hero" | "device-bottom" | "device-top" | "two-devices" | "no-device" | "split-landscape" | "feature-graphic") - `device` ("iphone" | "iphone-duo" | "iphone-duo-open" | "ipad" | "mac" | "apple-watch-ultra" | "apple-watch-series" | "apple-tv" | "android" | "android-7" | "android-10" | "chromebook" | "wear-os" | "android-tv" | "feature-graphic" | "windows" | "browser"): Device deck to read or edit (e.g. ipad) without switching the saved device. Omit for the saved device; a screenId from another deck is found automatically. #### `screens_duplicate`: Duplicate a screen Duplicate the full specified screen design, including text, background, screenshot assignments and editable layers. Assigns fresh screen/layer IDs, inserts after the source and saves the copy as active. Retries with the same MCP request ID replay the first result. Errors: INVALID_SCREEN, REVISION_CONFLICT. Parameters: - `screenId` (string, required; min length 1) #### `screens_delete`: Delete a screen _destructive_ Delete a screen from the current device deck and choose the nearest remaining screen as active when the deleted screen was active. The final screen cannot be deleted. Saves one project revision; persistent undo is unavailable. Errors: LAST_SCREEN, INVALID_SCREEN, REVISION_CONFLICT. Parameters: - `screenId` (string, required; min length 1) #### `screens_reorder`: Reorder screens Set the complete order for the current device deck. Provide each current screen ID exactly once; use screens_list first. Does not change the saved active screen. Errors: INVALID_SCREEN_ORDER with current IDs, REVISION_CONFLICT. Parameters: - `screenIds` (string[], required; min 1 items, max 200 items) ### Canvas layers (text, images, shapes, icons, layout) #### `canvas_list_icon_families`: List canvas icon and emoji catalogs _read-only, idempotent_ Read icon families, standard emoji categories and Fluent 3D emoji categories available for canvas insertion. No picker or Studio tab is required. Use family IDs with canvas_search_icons(kind=icons), or category IDs with kind=emoji or kind=3d. Errors: PROJECT_READ_FAILED. Parameters: none. #### `canvas_search_icons`: Search canvas icons and emojis _read-only, idempotent_ Search available icon families, native emoji or Fluent 3D emoji. kind is icons (default), emoji, 3d or all. query matches names, keywords, labels and emoji characters. familyId filters icon searches; category filters emoji/3D searches. offset defaults to 0 and limit to 48 (maximum 100). Pass returned iconName to canvas_add_icon. Search changes no UI. Errors: INVALID_ICON_FAMILY, INVALID_ICON_FILTER, PROJECT_READ_FAILED. Parameters: - `kind` ("icons" | "emoji" | "3d" | "all"; default "icons") - `query` (string; max length 120) - `familyId` (string; max length 40) - `category` (string; max length 60) - `offset` (integer; min 0, max 9007199254740991) - `limit` (integer; min 1, max 100) #### `canvas_get_layout`: Inspect canvas layout and layers _read-only, idempotent_ Read the saved screen's design size and every layer's stable ID, kind, name, visibility, transform, z-order and rotation-aware bounds. Text layers include their full text and inlineStyles with exact character ranges and styling (including highlights). Text layers also include content: the glyph box measured from the real font (x, width, centerX, baselineY, capCenterY), which is what to align and center against. Device and mockup layers include screenRect, the app screen inside the frame, to place overlays against. screenId may be from any device deck. Coordinates are screen-local design pixels. Workspace position, viewport, camera and selection are session-local and are not returned. Read-only and compact (no image bytes). Use before geometry or alignment operations. Errors: INVALID_SCREEN, PROJECT_READ_FAILED. Parameters: - `screenId` (string; min length 1) - `device` ("iphone" | "iphone-duo" | "iphone-duo-open" | "ipad" | "mac" | "apple-watch-ultra" | "apple-watch-series" | "apple-tv" | "android" | "android-7" | "android-10" | "chromebook" | "wear-os" | "android-tv" | "feature-graphic" | "windows" | "browser"): Device deck to read or edit (e.g. ipad) without switching the saved device. Omit for the saved device; a screenId from another deck is found automatically. #### `canvas_measure_text`: Measure text with real font metrics _read-only, idempotent_ Measure how text renders, using the actual font file (no browser): advance width with kerning and letter-spacing, wrapped lines, line height, and the baseline / cap-height center offsets from the top of the text box. Pass layerId to measure an existing text layer (returns its measured content box in screen pixels, alignment aware), or pass text plus style to measure before creating a layer. Use it to size boxes exactly and to center text, or a text + icon group, inside shapes. Read-only. Errors: INVALID_LAYER, FONT_METRICS_UNAVAILABLE. Parameters: - `screenId` (string; min length 1) - `layerId` (string; min length 1) - `text` (string; min length 1, max length 4000) - `fontFamily` (string; min length 1, max length 120) - `fontWeight` (integer; min 100, max 900) - `fontSize` (number; min 6, max 1000) - `letterSpacing` (number; min -100, max 100) - `lineHeight` (number; min 0.5, max 3) - `uppercase` (boolean) - `maxWidth` (number; max 100000): Wrap width in design px; omit for single-line measurement. - `locale` (string; min length 2, max length 16): Language of the text; picks the script fallback face (e.g. Noto Sans JP for ja) and CJK line breaking, as the Studio draws it. #### `canvas_capture_preview`: Capture a canvas preview image _read-only, idempotent_ Render a saved screen (scope=screen) or a crop around one stable layer (scope=layer) and return it as an image you can look at. Rendering uses the Studio's own export engine, so the preview matches exported PNGs exactly (fonts, effects, mockups, shaders). Any device deck and any project language can be previewed (screenId from any deck, or device; locale) without changing what the open Studio shows. Renders in a signed-in ScreenMake Studio tab of the project when one is open (it may stay in the background), otherwise in ScreenMake's cloud renderer (the first such preview takes longer while it starts); a render that dies with its renderer is retried once. scale 0.2–1 (default 0.5) of the design size; padding adds design pixels around a layer crop. Use it after every meaningful visual change to verify alignment, typography and composition. Read-only. Errors: INVALID_SCREEN, INVALID_LAYER, INVALID_LOCALE, PREVIEW_STUDIO_UNAVAILABLE, PREVIEW_STUDIO_LOST, PREVIEW_TIMEOUT, PREVIEW_RENDER_FAILED. Parameters: - `scope` ("screen" | "layer"; default "screen") - `screenId` (string; min length 1) - `device` ("iphone" | "iphone-duo" | "iphone-duo-open" | "ipad" | "mac" | "apple-watch-ultra" | "apple-watch-series" | "apple-tv" | "android" | "android-7" | "android-10" | "chromebook" | "wear-os" | "android-tv" | "feature-graphic" | "windows" | "browser"): Device deck to read or edit (e.g. ipad) without switching the saved device. Omit for the saved device; a screenId from another deck is found automatically. - `locale` (string; min length 2, max length 16): Project language to render; defaults to the saved language. - `layerId` (string; min length 1) - `scale` (number; min 0.2, max 1, default 0.5) - `padding` (number; min 0, max 500, default 24) #### `canvas_focus`: Focus a screen or select canvas layers _idempotent_ Persist the requested screen as active when layerIds is omitted and zoom is omitted or none. Layer selection and camera/zoom belong to an open Studio session, so requests for those changes return SESSION_SELECTION_UNAVAILABLE or SESSION_CAMERA_UNAVAILABLE. Use screens_select to set the saved active screen. Errors include INVALID_SCREEN, INVALID_LAYER, and the session-state codes above. Parameters: - `screenId` (string; min length 1) - `layerIds` (string[]; max 100 items) - `zoom` ("none" | "screen" | "selection") #### `canvas_set_layer_transform`: Position, resize, or rotate a layer Text layers are fixed-width boxes: width is the wrap/alignment box (glyphs are not scaled) and height is always derived from the wrapped text measured with the real font (the response says heightDerived: true and returns the height used), so change size with inspector_set_text_style fontSize, never with height. Mockup layers keep their frame's aspect ratio: the height follows the width (or the width a lone height); the response reports aspectKept. Set x/y/width/height/rotation for a stable layer on the specified or saved active screen. Coordinates are screen-local design pixels; width/height must be positive and no greater than 100000; rotation is degrees. Unspecified values stay unchanged; off-screen placement is allowed. The update commits atomically to saved project state; open Studio clients refresh from the project signal. Inspect canvas_get_layout when geometry is unclear. Errors: INVALID_SCREEN, INVALID_LAYER, INVALID_TRANSFORM, EMPTY_TRANSFORM, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `x` (number; min -1000000, max 1000000) - `y` (number; min -1000000, max 1000000) - `width` (number; max 100000) - `height` (number; max 100000) - `rotation` (number; min -36000, max 36000) #### `canvas_apply_batch`: Apply many edits as one Run up to 200 editor commands in order as one edit: one saved revision, all or nothing (if any operation fails, nothing is saved and the result names the failing index and error). Use it to re-lay out whole decks instead of hundreds of single calls. Each operation is { command, args }: command is the internal name (canvas.set_layer_transform, canvas.align_layers, canvas.update_text, canvas.add_text, canvas.add_shape, canvas.reorder_layer, inspector.set_text_style, inspector.set_text_range_style, inspector.set_clip_style, screens.add, …; the schema lists every allowed command) and args are that tool's arguments (screenId, layerId, …). screenId may be from any device deck; args.device targets a deck explicitly. Later operations see earlier ones' results. A revision conflict reruns the batch once on the newer state. Errors: COMMAND_NOT_ALLOWED, BATCH_FAILED, REVISION_CONFLICT, PROJECT_COMMIT_FAILED. Parameters: - `operations` (object[], required; min 1 items, max 200 items) - `command` ("canvas.get_layout" | "canvas.search_icons" | "inspector.search_fonts" | "uploads.list" | "mockups.list" | "shots.list" | "canvas.set_layer_transform" | "canvas.align_layers" | "canvas.distribute_layers" | "canvas.duplicate_layer" | "canvas.delete_layer" | "canvas.set_layer_visibility" | "canvas.reorder_layer" | "canvas.update_text" | "canvas.add_text" | "canvas.add_shape" | "canvas.add_icon" | "canvas.add_image" | "canvas.add_clip" | "elements.add" | "mockups.add" | "shots.inject" | "screens.add" | "screens.select" | "screens.duplicate" | "inspector.set_background" | "inspector.set_layer_appearance" | "inspector.set_text_style" | "inspector.set_text_range_style" | "inspector.set_image_style" | "inspector.set_icon_style" | "inspector.set_shape_style" | "inspector.set_clip_style" | "inspector.set_mockup_style", required) - `args` (object) #### `canvas_align_layers`: Align canvas layers Align layers to screen edges/center or a reference layer, using rotation-aware visible bounds. Choose horizontal left/center/right, vertical top/center/bottom, or both. Without referenceLayerId the screen is the target. With it, the reference layer must not also be in layerIds. Sizes and rotations stay unchanged. Positions commit atomically; authenticated open Studio clients refresh from the signal. Errors: INVALID_SCREEN, INVALID_LAYER, ALIGNMENT_REQUIRED, INVALID_ALIGNMENT_TARGET, INVALID_ALIGNMENT, REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerIds` (string[], required; min 1 items, max 100 items) - `horizontal` ("left" | "center" | "right") - `vertical` ("top" | "center" | "bottom") - `referenceLayerId` (string; min length 1) #### `canvas_distribute_layers`: Distribute canvas layers evenly Distribute at least three stable layers horizontally or vertically with equal visible edge gaps. Rotation-aware outer bounds stay fixed; middle layers move. Impossible nonnegative gaps return INVALID_DISTRIBUTION without changing state. All positions commit atomically to saved project data. Errors: INVALID_SCREEN, INVALID_LAYER, DUPLICATE_LAYER_ID, INVALID_DISTRIBUTION, REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerIds` (string[], required; min 3 items, max 100 items) - `axis` ("horizontal" | "vertical", required) #### `canvas_duplicate_layer`: Duplicate a canvas layer Copy an editable text, image, icon, shape, clip or catalog mockup layer on the same screen. The copy gets a new stable ID, moves 24 design pixels right/down and is raised above existing layers. Session-local selection is unchanged. Built-in caption/device layers cannot be copied. Errors: INVALID_SCREEN, INVALID_LAYER, BUILT_IN_LAYER, REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) #### `canvas_delete_layer`: Delete a canvas layer _destructive_ Remove an editable layer from its screen. Built-in device layers are hidden because they belong to the screen layout. This saves a project revision; it does not delete Uploads/Shots or modify session-local selection. Errors: INVALID_SCREEN, INVALID_LAYER, REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) #### `canvas_set_layer_visibility`: Show or hide a canvas layer Set visibility for a built-in device layer or editable layer on the specified or active screen. The saved layer remains in the project and keeps its geometry; session-local selection is unchanged. Errors: INVALID_SCREEN, INVALID_LAYER, REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `visible` (boolean, required) #### `canvas_reorder_layer`: Change layer stacking order Set a layer to front/back, one step forward/backward, or above/below a reference on the same screen. IDs come from canvas_get_layout or screens_get_details. Saves z-order atomically and preserves geometry. above/below require a distinct referenceLayerId. Errors: INVALID_SCREEN, INVALID_LAYER, REFERENCE_LAYER_REQUIRED, INVALID_REORDER_TARGET, REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `placement` ("front" | "back" | "forward" | "backward" | "above" | "below", required) - `referenceLayerId` (string; min length 1) #### `canvas_update_text`: Edit text on a canvas layer Replace text in a stable text layer. The saved current-locale string changes and translations for other locales remain intact. Empty/whitespace-only text is rejected. The update is committed; open Studio clients refresh from the project signal. Errors: INVALID_SCREEN, INVALID_TEXT, INVALID_TEXT_LAYER, REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `text` (string, required; min length 1, max length 4000) - `locale` (string; min length 2, max length 16): Language to write; defaults to the saved language. Only source-language text resizes the shared box; translations fit themselves to it. #### `canvas_add_text`: Add text to the canvas Add a text layer to screenId or the saved active screen. text is required (1–4000 characters); fontSize defaults to the toolbar value and accepts 6–1000 design units; fontWeight is 100–900; fontFamily is a CSS family; color is a CSS color; align is left/center/right within the box. Text layers are fixed-width boxes: boxWidth (design px, default a generous estimate) is the wrap edge and alignment area, never a glyph scale, and the height is derived from the wrapped lines measured with the real font. To center text on the canvas, use boxWidth equal to the canvas width, align=center and x=0; for left-aligned labels set x to the text start and a boxWidth wider than the text. The target becomes the saved active screen; no layer selection UI or dialog opens. Errors: INVALID_SCREEN, INVALID_TEXT, INVALID_TEXT_COLOR, REVISION_CONFLICT. Parameters: - `text` (string, required; min length 1, max length 4000) - `screenId` (string; min length 1) - `boxWidth` (number; max 100000) - `fontSize` (number; min 6, max 1000) - `fontWeight` (integer; min 100, max 900) - `fontFamily` (string; max length 120) - `color` (string; max length 80) - `align` ("left" | "center" | "right") #### `canvas_add_image`: Add an image to the canvas Add a project image using exactly one uploadId from uploads_list or a base64 dataUrl. Supports PNG/JPEG/WebP/GIF/AVIF/BMP/ICO up to 25 MB. A data URL is validated, saved privately and registered in Uploads before the centered image layer is committed. No file picker is opened. Response includes uploadId, dimensions and layerId, never image bytes or private storage locations. Errors: INVALID_SCREEN, INVALID_UPLOAD, INVALID_IMAGE_SOURCE, INVALID_IMAGE_DATA, IMAGE_TOO_LARGE, IMAGE_STORAGE_UNAVAILABLE, IMAGE_UPLOAD_FAILED, REVISION_CONFLICT. Parameters: - `uploadId` (string; format uuid) - `dataUrl` (string; min length 1, max length 35000000) - `screenId` (string; min length 1) #### `canvas_add_shape`: Add a shape to the canvas Add rectangle, rounded, ellipse, triangle, line, star, polygon or arrow to screenId or the saved active screen. Defaults match the toolbar's initial size and accent style. The screen becomes the saved active screen; no toolbar popup or selection UI is opened. Freeform drawing and pop-out creation are not included. Errors: INVALID_SCREEN, INVALID_SHAPE, REVISION_CONFLICT. Parameters: - `kind` ("rectangle" | "rounded" | "ellipse" | "triangle" | "line" | "star" | "polygon" | "arrow", required) - `screenId` (string; min length 1) #### `canvas_add_icon`: Add an icon, emoji, or 3D emoji to the canvas Add an icon, native emoji or 3D emoji using the exact iconName returned by canvas_search_icons, for example lucide:Sparkles, emoji:🚀 or fluent3d:rocket. Optional screenId defaults to the saved active screen. No picker opens and no session-local layer selection is changed. Errors: INVALID_SCREEN, INVALID_ICON, REVISION_CONFLICT. Parameters: - `iconName` (string, required; min length 1, max length 120) - `screenId` (string; min length 1) ### Layer and background styles #### `inspector_get_state`: Inspect screen and layer styling state _read-only, idempotent_ Read saved screen/background settings or explicitly target one stable layerId from screens_get_details. Returns saved revision and 1-based displayed screenNumber. Without layerId, returns background, localized caption, screenshots, visibility and available layer IDs. With layerId, returns kind, geometry, saved type-specific properties, applicable controls and textFields with exact UTF-16 offsets and inline range substrings. Object properties and inline text formatting are separate targets. No selection or inspector UI is needed; selected text range is session-local and is not returned. Errors: INVALID_SCREEN, INVALID_LAYER, PROJECT_READ_FAILED. Parameters: - `screenId` (string; min length 1) - `layerId` (string; min length 1) #### `inspector_search_fonts`: Search available text fonts _read-only, idempotent_ Search the font catalog without opening a picker or changing editor UI. query matches family/category; offset defaults 0 and limit defaults 30 (max 100). Returns family names and supported weights for inspector_set_text_style or inspector_set_text_range_style. Empty results return an empty array and null nextOffset. Errors: FONT_CATALOG_UNAVAILABLE. Parameters: - `query` (string; max length 120) - `offset` (integer; min 0, max 9007199254740991, default 0) - `limit` (integer; min 1, max 100, default 30) #### `inspector_set_screen_background`: Set a screen background Set a screen background in saved project state without opening the inspector, preset picker, upload picker, rail, toast, or modal. Omit screenId for the saved active screen. Supports theme, solid color, linear/radial gradients with 2–8 stops, project image sources from Uploads or Shots, abstract palettes, mesh/aurora data, and shader presets/controls. For image backgrounds, provide sourceKind and sourceId from uploads_list or shots_list. For shaders, use presetId from inspector_get_state; controls may include only the visible controls for that preset (library presets: color1/2/3, intensity, density, grainAmount; Paper presets: colors, scale, frame, and listed variant controls). The change is committed as one project revision; authenticated open Studio clients refresh from the project signal. The inspector keeps its pre-tool view until the user next interacts with the editor. Errors: INVALID_SCREEN, INVALID_UPLOAD, INVALID_SHOT, INVALID_BACKGROUND, INVALID_SHADER_PRESET, SHADER_PRESET_REQUIRED, INVALID_SHADER_CONTROL, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, or REVISION_CONFLICT. Parameters: - `type` ("theme" | "solid" | "gradient" | "image" | "abstract" | "shader" | "mesh" | "aurora", required): Background kind; supply the fields that kind uses. - `screenId` (string; min length 1) - `color` (string; min length 1, max length 80): solid: fill color. - `gradientType` ("linear" | "radial"): gradient: linear or radial. - `angle` (number; min -360, max 360): gradient: angle in degrees. - `stops` (object[]; min 2 items, max 8 items): gradient: 2–8 color stops, position 0–1. - `color` (string, required; min length 1, max length 80) - `position` (number, required; min 0, max 1) - `sourceKind` ("upload" | "shot"): image: source library. - `sourceId` (string; min length 1, max length 200): image: upload or shot ID. - `objectFit` ("cover" | "contain" | "fill"): image: fit mode. - `overlayColor` (string; min length 1, max length 80): image: optional overlay color. - `overlayOpacity` (number; min 0, max 1): image: overlay opacity. - `preset` ("blobs" | "mesh" | "noise" | "geometric" | "aurora"): abstract: palette style. - `colors` (string[]; max 8 items): abstract: palette colors. - `presetId` (string; min length 1, max length 100): shader: preset ID from inspector_get_state. - `controls` (object): shader: visible control values for the preset. - `baseColor` (string; min length 1, max length 80): mesh/aurora: base color. - `blobs` (object[]; max 32 items): mesh: soft color blobs, x/y/size in percent. - `color` (string, required; min length 1, max length 80) - `x` (number, required; min 0, max 100) - `y` (number, required; min 0, max 100) - `size` (number, required; min 10, max 100) - `blur` (number, required; min 0, max 200) - `opacity` (number, required; min 0, max 1) - `bands` (object[]; max 32 items): aurora: light bands. - `color` (string, required; min length 1, max length 80) - `angle` (number, required; min 0, max 360) - `width` (number, required; min 10, max 100) - `offset` (number, required; min -50, max 150) - `opacity` (number, required; min 0, max 1) - `blur` (number, required; min 0, max 200) #### `inspector_set_layer_appearance`: Set shared layer effects and color adjustments Set Photoshop-style stroke/shadow/glow effects, per-corner radii, and color adjustments on one or more stable layer IDs. These shared inspector controls apply to built-in device layers and every editable text, image, icon, shape, clip, and mockup layer. Provide layerId or layerIds and at least one property. effectPreset accepts none or a preset ID from inspector_get_state; use effects to provide exact values instead. null clears effects, adjustments, or radii. Color adjustments accept partial slider values and unspecified values keep their current setting. One atomic project revision saves the edit; authenticated open Studio clients refresh from the project signal. It does not change session-local selection or operate the inspector. The inspector keeps its pre-tool view until the user next interacts with the editor. Errors: INVALID_SCREEN, INVALID_LAYER, INVALID_EFFECT_PRESET, EMPTY_APPEARANCE_PATCH, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, or REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string; min length 1) - `layerIds` (string[]; min 1 items, max 100 items) - `patch` (object, required) - `effects` (object | null) - `effectPreset` ("none" | "floatingCard" | "uiPanel" | "photoInset" | "silhouettePop" | "softLift" | "studioFloat" | "instantFilm" | "galleryMount" | "editorial" | "brutalist" | "neonCyan" | "ultraviolet" | "aurora" | "roseHalo" | "emberGlow" | "glassEdge" | "inkOutline" | "porcelain" | "cleanEdge" | "deepShadow") - `colorAdjustments` (object | null) - `cornerRadii` (object | null) #### `inspector_set_text_style`: Style text layers Set text content and typography/fill/effect/fade controls for a text: layer. Omit field. Text content is written to the given locale (current project locale by default) while other locales remain unchanged. Styles are shared by every language, except with an explicit non-source locale: then fontSize, fontFamily (e.g. a CJK face) and boxWidth apply to that language only, and any shared-only setting returns LOCALE_STYLE_SHARED instead of changing every language. Box heights follow the source text; translations fit themselves to the shared box. fontSize is 12–400; other controls match the inspector. Fill supports solid or gradient; effect presets are none, soft-shadow, glossy, outline, neon, and embossed. This does not enter text editing, change selection, open inspector UI, or show a dialog. The project update is committed, and authenticated open Studio clients refresh from the project signal. The inspector keeps its pre-tool view until the user next interacts with the editor. Errors: INVALID_SCREEN, INVALID_LAYER_TYPE, INVALID_LAYER, INVALID_LOCALE, LOCALE_STYLE_SHARED, NO_TRANSLATION, TEXT_FIELD_REQUIRED, UNSUPPORTED_TEXT_SETTING, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, or REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `field` ("headline" | "label") - `locale` (string; min length 1, max length 32) - `text` (string; max length 4000) - `style` (object) - `fontSize` (number; min 0.2, max 1000) - `fontWeight` (integer; min 100, max 900) - `color` (string; min length 1, max length 80) - `fill` (object | object | null) - `fade` (object | null) - `effect` (object | null) - `align` ("left" | "center" | "right") - `lineHeight` (number; min 0.5, max 3) - `letterSpacing` (number; min -100, max 100) - `fontFamily` (string; min length 1, max length 120) - `textShadow` (string | null) - `backgroundColor` (string | null) - `padding` (number; min 0, max 100) - `opacity` (number; min 0, max 1) - `uppercase` (boolean) - `boxWidth` (number; max 100000): Fixed text box width in design px. Sets the wrap edge and alignment area; glyphs are never scaled. #### `inspector_set_text_range_style`: Style a range of text characters Apply or clear inline styling on an exact character range in a text: layer. field is the raw text element ID (without text:). start is inclusive and end is exclusive; offsets are zero-based JavaScript UTF-16 character indexes, matching the editor selection model. Inspect the exact text first; out-of-bounds ranges are rejected. locale (default: the saved language) picks whose text the offsets index: a translation with its own text gets its own ranges, leaving other languages alone; the source language and translations still showing the source text use the shared ranges. Style supports color/fill, highlight color/radius/padding, fade, text effect, font weight/style/size/family, letter spacing, shadow, uppercase, and underline. A style patch preserves unspecified formatting, including when selecting a subrange within existing styling. Set a property to null to unset only that property. clear=true removes the entire existing style for that exact selection range. This writes inline style data only and does not simulate selecting text or affect inspector focus. The inspector keeps its pre-tool view until the user next interacts with the editor. Errors: INVALID_SCREEN, INVALID_LAYER_TYPE, TEXT_FIELD_REQUIRED, TEXT_FIELD_MISMATCH, INVALID_TEXT_RANGE, NO_TEXT_STYLE, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, or REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `field` (string, required; min length 1, max length 120) - `start` (integer, required; min 0, max 100000) - `end` (integer, required; min 1, max 100000) - `locale` (string; min length 2, max length 16) - `style` (object) - `color` (string | null) - `fill` (object | object | null) - `fade` (object | null) - `effect` (object | null) - `fontWeight` (integer | null) - `fontStyle` ("normal" | "italic" | null) - `textDecoration` ("none" | "underline" | null) - `backgroundColor` (string | null) - `backgroundRadius` (number | null) - `backgroundPadding` (number | null) - `fontSize` (number | null) - `fontFamily` (string | null) - `letterSpacing` (number | null) - `textShadow` (string | null) - `uppercase` (boolean | null) - `clear` (boolean) #### `inspector_set_image_style`: Style or replace an image layer Set image treatment presets and the image inspector's source, flip, tint, fade, fit, opacity, radius, border, shadow, or cutout controls for one image: layer. Use treatment from inspector_get_state to apply Floating card, UI panel, Photo inset, or Subject cutout; then optionally override individual settings. Replace source with exactly one sourceKind/sourceId from Uploads or Shots; this resets its crop and fit to match the inspector's Replace image action. Use null to clear tint, fade, or shadow. No picker, inspector interaction, dialog, toast, or selection change occurs; the resulting image is committed to saved project state and authenticated open Studio clients refresh from the project signal. The inspector keeps its pre-tool view until the user next interacts with the editor. Errors: INVALID_SCREEN, INVALID_LAYER_TYPE, INVALID_LAYER, INVALID_IMAGE_SOURCE, INVALID_IMAGE_TREATMENT, INVALID_UPLOAD, INVALID_SHOT, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, or REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `treatment` ("card" | "panel" | "photo" | "cutout") - `sourceKind` ("upload" | "shot") - `sourceId` (string; min length 1, max length 200) - `style` (object) - `flipX` (boolean) - `flipY` (boolean) - `tintColor` (string | null) - `fade` (object | null) - `opacity` (number; min 0, max 1) - `borderRadius` (number; min 0, max 100000) - `borderWidth` (number; min 0, max 100000) - `borderColor` (string; min length 1, max length 80) - `objectFit` ("cover" | "contain" | "fill" | "none") - `shadow` (string | null) - `cutout` (boolean) #### `inspector_remove_image_background`: Remove an image layer background Remove the background of an image: layer in saved project state. The source must be readable from this project and at most 8 MB. The validated transparent PNG is stored in Uploads and replaces the layer source while preserving its geometry/style. No modal, picker or toast is opened. Errors: INVALID_SCREEN, INVALID_LAYER_TYPE, IMAGE_SOURCE_UNAVAILABLE, BACKGROUND_REMOVAL_UNAVAILABLE, BACKGROUND_REMOVAL_FAILED, INVALID_BACKGROUND_REMOVAL_RESULT, REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) #### `inspector_set_icon_style`: Style an icon layer Set flip, fade, color, stroke width, and opacity for one icon: layer, matching the icon inspector. Color and stroke width are validated against that icon's capabilities (emoji/3D assets may not support them). The icon's catalog name is not changed here; use existing canvas insertion tools for a different icon. The edit is saved as a project revision without inspector selection/control changes or popups; authenticated open Studio clients refresh from the project signal. The inspector keeps its pre-tool view until the user next interacts with the editor. Errors: INVALID_SCREEN, INVALID_LAYER_TYPE, UNSUPPORTED_ICON_SETTING, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, or REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `style` (object, required) - `flipX` (boolean) - `flipY` (boolean) - `color` (string; min length 1, max length 80) - `fade` (object | null) - `strokeWidth` (number; min 0.5, max 5) - `opacity` (number; min 0, max 1) #### `inspector_set_shape_style`: Style a shape layer Change an existing shape: layer's shape kind, opacity, fill/stroke, stroke width, radius, polygon/star side count, CSS shadow, and fade using the shape inspector's settings. Kinds match the inspector: rectangle, rounded, ellipse, triangle, line, star, polygon, and arrow. Switching to line/arrow initializes a visible stroke as the inspector does. Shared corner radii/effects and color adjustments use inspector_set_layer_appearance. The update is committed to saved project state without driving inspector UI; authenticated open Studio clients refresh from the project signal. The inspector keeps its pre-tool view until the user next interacts with the editor. Errors: INVALID_SCREEN, INVALID_LAYER_TYPE, UNSUPPORTED_SHAPE_KIND, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, or REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `style` (object, required) - `kind` ("rectangle" | "rounded" | "ellipse" | "triangle" | "line" | "star" | "polygon" | "arrow") - `fill` (string; min length 1, max length 80) - `fade` (object | null) - `stroke` (string; min length 1, max length 80) - `strokeWidth` (number; min 0, max 50) - `opacity` (number; min 0, max 1) - `borderRadius` (number; min 0, max 100000) - `sides` (integer; min 3, max 12) - `shadow` (string | null) #### `inspector_set_clip_style`: Style a selection clip layer Set the clip's source (sourceShotId, sourceUploadId, or followDevice to crop the screen of the device under it, following that device's screenshot), source crop, subject-cutout mode, border, corner radius, opacity, transparency fade, drop-shadow preset/custom values, and outer-glow preset/custom values for one clip: layer. Crop is normalized 0–1 within the source screenshot and must remain inside it; cutout=true applies the inspector's border/radius reset. Presets are none/soft/elevated/dramatic/neon for shadow and none/subtle/vibrant/intense for glow. Shared appearance effects are controlled with inspector_set_layer_appearance. No text-selection, inspector, or canvas selection changes occur; the layer edit is saved and authenticated open Studio clients refresh from the project signal. The inspector keeps its pre-tool view until the user next interacts with the editor. Errors: INVALID_SCREEN, INVALID_LAYER_TYPE, INVALID_CROP, INVALID_CLIP_SOURCE, INVALID_SHOT, INVALID_UPLOAD, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, or REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `style` (object, required) - `srcX` (number; min 0, max 1) - `srcY` (number; min 0, max 1) - `srcW` (number; min 0.05, max 1) - `srcH` (number; min 0.05, max 1) - `borderColor` (string; min length 1, max length 80) - `borderWidth` (number; min 0, max 50) - `borderRadius` (number; min 0, max 500) - `cutout` (boolean) - `shadowPreset` ("none" | "soft" | "elevated" | "dramatic" | "neon") - `shadowColor` (string; min length 1, max length 80) - `shadowBlur` (number; min 0, max 120) - `shadowOffsetY` (number; min -60, max 60) - `shadowOffsetX` (number; min -60, max 60) - `shadowSpread` (number; min -30, max 30) - `glowPreset` ("none" | "subtle" | "vibrant" | "intense") - `glowColor` (string; min length 1, max length 80) - `glowBlur` (number; min 0, max 120) - `glowSpread` (number; min -20, max 40) - `opacity` (number; min 0, max 1) - `fade` (object | null) - `sourceShotId` (string; min length 1, max length 200): Crop this Shot instead; crop fractions stay. - `sourceUploadId` (string; min length 1, max length 200): Crop this Upload instead; crop fractions stay. - `followDevice` (true): Crop the screen of the device under the clip (or the slide's screen) and follow it when it changes, e.g. after the iPad screens are placed. #### `inspector_set_mockup_style`: Style a mockup layer and choose its screenshot Set the catalog mockup variant, screenshot source, opacity, and fade for one mockup: layer. mockupId choices come from mockups_list and changing variants preserves center, rotation, stacking, and screenshot selection while fitting the new frame into its current bounds. screenshot=primary or secondary uses that screen's matching source. screenshot=custom requires exactly one shotId or uploadId from shots_list/uploads_list. The saved project change does not open the mockup catalog, source picker, inspector, or rail; authenticated open Studio clients refresh from the project signal. The inspector keeps its pre-tool view until the user next interacts with the editor. Errors: INVALID_SCREEN, INVALID_LAYER_TYPE, INVALID_MOCKUP, INVALID_MOCKUP_SOURCE, MOCKUP_ORIENTATION_UNAVAILABLE, INVALID_SHOT, INVALID_UPLOAD, PROJECT_READ_FAILED, PROJECT_COMMIT_FAILED, or REVISION_CONFLICT. Parameters: - `screenId` (string; min length 1) - `layerId` (string, required; min length 1) - `style` (object, required) - `mockupId` (string; min length 1, max length 180) - `screenshot` ("primary" | "secondary" | "custom") - `shotId` (string; min length 1) - `uploadId` (string; min length 1) - `opacity` (number; min 0, max 1) - `fade` (object | null) ### Your app's own screenshots (Shots) #### `shots_list`: List saved Shots _read-only, idempotent_ List saved app screenshots with stable Shot ID, name, dimensions, and source path. Read-only; use a returned ID for mockups_generate or shots_inject. An empty library returns an empty shots array. Parameters: none. #### `shots_upload`: Upload Shots to the project library Add one or more reusable screenshots to the project library without opening a file picker. Each image requires name, mimeType (image/png or image/jpeg), and base64 bytes without a data-URL prefix. Maximum 8 MB per image, up to 10 images and 24 MB total per call. Images are stored using the app upload route; if storage is temporarily unavailable, the editor keeps the data URL as its existing UI fallback. Invalid format, per-file size, or batch size returns INVALID_IMAGE_TYPE, IMAGE_TOO_LARGE, or BATCH_TOO_LARGE. This does not place them on the canvas until shots_inject or mockups_generate is called. Parameters: - `images` (object[], required; min 1 items, max 10 items) - `name` (string, required; min length 1, max length 200) - `mimeType` ("image/png" | "image/jpeg", required) - `base64` (string, required; min length 1, max length 11200000) #### `shots_reorder`: Reorder saved Shots Set the complete order of screenshot-library items. Provide every current Shot ID exactly once in the desired order. Use shots_list first. This changes library order only, not any canvas content. Invalid or incomplete lists return INVALID_SHOT_ORDER with the current IDs. Parameters: - `shotIds` (string[], required; max 500 items) #### `shots_delete`: Remove a Shot from the project library _destructive_ Remove a saved screenshot from the project library by ID. Existing canvas layers that already reference its image are not changed. This is a normal persisted project edit and does not show a confirmation dialog or toast. A stale ID returns INVALID_SHOT. Parameters: - `shotId` (string, required; min length 1) #### `shots_inject`: Inject a Shot into a mockup Replace the screenshot shown in a specific built-in or user-added mockup slot. Provide shotId from shots_list, optional screenId (active screen by default), and mockupId: 'device' for the primary built-in device, 'deviceSecondary' for its secondary slot, or the raw mockup layer ID from screens_get_details. The target screen becomes the saved active screen; no rail navigation, selection dialog, or toast occurs. Returns INVALID_SHOT, INVALID_SCREEN, or INVALID_MOCKUP_SLOT when a target is missing or does not provide the requested slot. Parameters: - `shotId` (string, required; min length 1) - `screenId` (string; min length 1) - `mockupId` (string, required; min length 1) ### Uploads #### `uploads_list`: List project Uploads _read-only, idempotent_ List private images in this project. Optional query filters name/MIME type; offset defaults to 0 and limit to 50 (max 100). Returns IDs, names, MIME types, dimensions, byte sizes and timestamps. Empty libraries return assets=[] and total=0. Errors: PROJECT_READ_FAILED. Parameters: - `query` (string; max length 120) - `offset` (integer; min 0, max 9007199254740991) - `limit` (integer; min 1, max 100) #### `uploads_remove`: Remove an image from Uploads _destructive_ Remove an uploadId from this project's reusable Uploads list. Existing canvas layers referencing the image remain unchanged. Use uploads_list for valid IDs. This is a saved project edit, not an undoable browser action. Errors: INVALID_UPLOAD, REVISION_CONFLICT. Parameters: - `uploadId` (string, required; format uuid) ### Device mockups #### `mockups_list`: Browse mockups _read-only, idempotent_ Browse the same dynamic Mockups catalog shown in the rail without opening or changing the panel. Returns category and group summaries plus paginated variants. Filter with query, category ID, groupId, or collectionId; query matches device name, variant name, and category. offset defaults to 0 and limit defaults to 48 (maximum 100). Use a returned variant ID with mockups_add; a variant without geometry for the current orientation cannot be inserted. Search with no matches returns an empty items array and null nextOffset. Parameters: - `query` (string; max length 200) - `category` (string; max length 80) - `groupId` (string; max length 180) - `collectionId` (string; max length 100) - `offset` (integer; min 0, max 9007199254740991) - `limit` (integer; min 1, max 100) #### `mockups_add`: Add a mockup to the canvas Insert a catalog mockup variant as an editable mockup layer on screenId or the saved active screen. Use the exact variant ID from mockups_list. The variant must have frame geometry for current orientation. Saves the project; open Studio clients refresh from the signal. Errors: INVALID_MOCKUP, MOCKUP_ORIENTATION_UNAVAILABLE, INVALID_SCREEN, REVISION_CONFLICT. Parameters: - `mockupId` (string, required; min length 1, max length 180) - `screenId` (string; min length 1) #### `mockups_generate`: Generate a mockup from a Shot Create a transparent PNG device mockup using screenshotId from shots_list as protected screen artwork, then store and add it to screenId or the saved active screen. prompt is required (up to 1200 chars); deviceReference is one PNG/JPEG/WebP data URL; references allows up to 14 supporting data URLs. Screenshot up to 15 MB, references up to 6 MB each and 24 MB total. Generation completes server-side before the layer is committed; there is no temporary UI. Errors: INVALID_SHOT, SHOT_UNAVAILABLE, INVALID_REFERENCE_IMAGE, GENERATION_UNAVAILABLE, INVALID_MODEL_RESULT, IMAGE_STORAGE_UNAVAILABLE, REVISION_CONFLICT. Parameters: - `prompt` (string, required; min length 1, max length 1200) - `screenshotId` (string, required; min length 1) - `deviceReference` (string; max length 8500000) - `references` (string[]; max 14 items) - `screenId` (string; min length 1) ### Elements library #### `elements_list_categories`: List element categories _read-only, idempotent_ List prepared Elements library categories and asset counts. This is read-only. Use a category ID as the category filter in elements_search_assets. Returns LIBRARY_UNAVAILABLE when the catalog service is not configured or reachable. Parameters: none. #### `elements_search_assets`: Search element assets _read-only, idempotent_ Search the prepared Elements library without changing the visible rail tab, query field, filters, selection, or canvas. Returns asset references that can be passed to the corresponding add tool. Use the cursor from the previous response to continue; an empty result is a successful empty list. Catalog or semantic-index failures return an actionable LIBRARY_UNAVAILABLE or LIBRARY_SEARCH_UNAVAILABLE error. Inputs: query is optional (up to 120 characters) and uses the editor's semantic asset search; category is an Elements category ID; cursor is the numeric nextCursor from the previous response (default 0); limit is 1–72 (default 48). Semantic query results are ranked and capped at the first 200 matches before pagination. Results return stable assetRef and assetKey values, names, category, dimensions, file size, and preview URL. Parameters: - `query` (string; max length 120) - `category` (string; max length 180) - `cursor` (integer; min 0, max 9007199254740991) - `limit` (integer; min 1, max 72) #### `elements_add_asset`: Add an element asset to the canvas Add a prepared Elements catalog asset as a centered image layer. Pass the exact assetRef from elements_search_assets; do not construct asset paths. Optional screenId defaults to the saved active screen. The target becomes saved active; open Studio clients refresh after commit. Errors: INVALID_ASSET_REF, INVALID_SCREEN, REVISION_CONFLICT. Parameters: - `assetRef` (string, required; min length 1, max length 1200) - `name` (string; max length 180, default "Element") - `screenId` (string; min length 1) #### `elements_generate_asset`: Generate and add an element Generate an isolated asset on a transparent background from a prompt and add it to the requested or saved active screen. Prompt 1–1200 chars; aspectRatio defaults 1:1 (other ratios use the nearest of square, portrait, landscape, tall and wide); renderingSpeed defaults BALANCED (TURBO/BALANCED/QUALITY); negativePrompt up to 500 chars lists things to leave out; referenceImage (image data or an approved HTTPS image) guides the subject, style and colors directly; referenceDescription up to 4000 chars adds notes about it. Generation completes server-side before project state changes; no placeholder or generator UI is shown. Errors: INVALID_PROMPT, INVALID_REFERENCE_IMAGE, GENERATION_UNAVAILABLE, RATE_LIMITED, IMAGE_REQUEST_FAILED, INVALID_MODEL_RESULT, IMAGE_STORAGE_UNAVAILABLE, REVISION_CONFLICT. Parameters: - `prompt` (string, required; min length 1, max length 1200) - `aspectRatio` ("1:3" | "3:1" | "1:2" | "2:1" | "9:16" | "16:9" | "10:16" | "16:10" | "2:3" | "3:2" | "3:4" | "4:3" | "4:5" | "5:4" | "1:1") - `renderingSpeed` ("TURBO" | "BALANCED" | "QUALITY") - `negativePrompt` (string; max length 500) - `referenceImage` (string; max length 12000000) - `referenceDescription` (string; max length 4000) - `screenId` (string; min length 1) ### Stock photos and illustrations #### `stock_generate_asset`: Generate and add a custom stock asset Generate an isolated image from a prompt and add it to screenId or the saved active screen. Prompt 1–1200 chars; aspectRatio defaults 1:1; renderingSpeed defaults BALANCED; negativePrompt up to 500 chars. referenceImage accepts image data or approved HTTPS image hosts; referenceDescription up to 4000 chars. Runs server-side and commits only the completed output; no generator UI or placeholder is shown. Errors include INVALID_PROMPT, INVALID_REFERENCE_IMAGE, GENERATION_UNAVAILABLE, IMAGE_REQUEST_FAILED, IMAGE_STORAGE_UNAVAILABLE and REVISION_CONFLICT. Parameters: - `prompt` (string, required; min length 1, max length 1200) - `aspectRatio` ("1:3" | "3:1" | "1:2" | "2:1" | "9:16" | "16:9" | "10:16" | "16:10" | "2:3" | "3:2" | "3:4" | "4:3" | "4:5" | "5:4" | "1:1") - `renderingSpeed` ("TURBO" | "BALANCED" | "QUALITY") - `negativePrompt` (string; max length 500) - `referenceImage` (string; max length 12000000) - `referenceDescription` (string; max length 4000) - `screenId` (string; min length 1) #### `stock_search`: Search Pixabay stock _read-only, idempotent_ Search Pixabay without changing visible Stock rail filters or query state. Filters mirror the Stock panel: query (up to 100 characters), category, imageType, orientation, format (all/png/jpeg/webp/gif/avif), colors (including transparent), language, minWidth/minHeight, editorsChoice, safeSearch, order, and page. PNG format is matched against downloadable image variants, not thumbnail extensions; format searches scan Pixabay's first 500 results and return up to 48 matches per page. Results include previewURL for thumbnails and downloadURL plus source-size variants for the actual file. For genuine transparent PNGs, search with colors:["transparent"] and format:"png", then call stock_import_asset with requireTransparency:true. The import downloads and validates the real PNG alpha channel, stores the file in ScreenMake, and returns a direct downloadURL and assetRef. Use stock_add_to_canvas to import and place a result in one call. Parameters: - `query` (string; max length 100) - `category` ("backgrounds" | "nature" | "people" | "animals" | "buildings" | "computer" | "food" | "travel" | "business" | "fashion" | "science" | "education" | "feelings" | "health" | "places" | "religion" | "industry" | "sports" | "transportation" | "music") - `imageType` ("all" | "photo" | "illustration" | "vector"; default "all") - `orientation` ("all" | "horizontal" | "vertical"; default "all") - `format` ("all" | "png" | "jpeg" | "webp" | "gif" | "avif"; default "all") - `colors` ("any" | "grayscale" | "transparent" | "red" | "orange" | "yellow" | "green" | "turquoise" | "blue" | "lilac" | "pink" | "white" | "gray" | "black" | "brown"[]; max 14 items) - `language` ("cs" | "da" | "de" | "en" | "es" | "fr" | "id" | "it" | "hu" | "nl" | "no" | "pl" | "pt" | "ro" | "sk" | "fi" | "sv" | "tr" | "vi" | "th" | "bg" | "ru" | "el" | "ja" | "ko" | "zh"; default "en") - `minWidth` (integer; min 0, max 50000) - `minHeight` (integer; min 0, max 50000) - `editorsChoice` (boolean; default false) - `safeSearch` (boolean; default true) - `order` ("popular" | "latest"; default "popular") - `page` (integer; min 1, max 11, default 1) #### `stock_import_asset`: Download and import a Pixabay asset _idempotent_ Download the best available Pixabay image variant (original when available, otherwise fullHD/large/webformat) into ScreenMake's reusable Stock asset library without changing the canvas. Use pixabayId and category from stock_search. Set format:"png" and requireTransparency:true to accept only a real PNG with transparent pixels; the server checks downloaded bytes and alpha pixels instead of trusting previewURL or tags. Returns the stable assetRef for elements_add_asset plus an absolute downloadURL that serves the stored image bytes, source variant, MIME type, format, dimensions, byte size, alpha status, and Pixabay attribution. Errors include STOCK_IMPORT_FAILED, IMAGE_FORMAT_UNAVAILABLE, TRANSPARENCY_UNAVAILABLE, and IMAGE_TOO_LARGE. Parameters: - `pixabayId` (integer, required; max 9007199254740991) - `category` ("other" | "backgrounds" | "nature" | "people" | "animals" | "buildings" | "computer" | "food" | "travel" | "business" | "fashion" | "science" | "education" | "feelings" | "health" | "places" | "religion" | "industry" | "sports" | "transportation" | "music"; default "other") - `format` ("all" | "png" | "jpeg" | "webp" | "gif" | "avif"; default "all") - `requireTransparency` (boolean; default false) #### `stock_add_to_canvas`: Import and add a stock image Download a Pixabay search result's best available source variant, validate its actual file format, import it into ScreenMake, and add it as an image layer to the target or saved active screen. Pass the numeric ID and category returned by stock_search (category may be 'other'). Optional format and requireTransparency enforce PNG or another file type and, for transparent PNGs, real alpha pixels. The result includes the layer ID and a direct downloadURL for the stored file. Open Studio clients refresh after commit. Errors: STOCK_IMPORT_FAILED, IMAGE_FORMAT_UNAVAILABLE, TRANSPARENCY_UNAVAILABLE, IMAGE_TOO_LARGE, INVALID_SCREEN, REVISION_CONFLICT. Parameters: - `pixabayId` (integer, required; max 9007199254740991) - `category` ("other" | "backgrounds" | "nature" | "people" | "animals" | "buildings" | "computer" | "food" | "travel" | "business" | "fashion" | "science" | "education" | "feelings" | "health" | "places" | "religion" | "industry" | "sports" | "transportation" | "music"; default "other") - `format` ("all" | "png" | "jpeg" | "webp" | "gif" | "avif"; default "all") - `requireTransparency` (boolean; default false) - `name` (string; max length 180) - `screenId` (string; min length 1) ### AI images #### `image_generate`: Generate an image with AI Generate a final image from a 1–4000 character prompt, save it to project Uploads and add a centered image layer on screenId or the saved active screen. imageSize defaults landscape_4_3; background defaults auto (transparent is supported); quality defaults high; outputFormat defaults PNG; variant defaults flare. Generation runs on the server and only the completed result is committed; no progress layer/dialog appears. Errors include INVALID_IMAGE_SETTINGS, GENERATION_UNAVAILABLE, RATE_LIMITED, IMAGE_TIMEOUT, INVALID_MODEL_RESULT, IMAGE_STORAGE_UNAVAILABLE and REVISION_CONFLICT. Parameters: - `prompt` (string, required; min length 1, max length 4000) - `variant` ("flare" | "sunburst") - `imageSize` ("auto" | "square" | "square_hd" | "portrait_4_3" | "portrait_16_9" | "landscape_4_3" | "landscape_16_9") - `background` ("auto" | "transparent" | "opaque") - `quality` ("auto" | "low" | "medium" | "high" | "xhigh" | "max") - `outputFormat` ("png" | "jpeg" | "webp") - `screenId` (string; min length 1) #### `image_edit`: Edit an image with AI Edit exactly one source: imageLayerId (optionally sourceScreenId), uploadId, shotId (one of the app screenshots in Shots, e.g. to turn the real app UI into a 3D, tilted, in-hand or stylized visual), or base64 imageDataUrl. Optional maskUploadId or PNG maskDataUrl must match source dimensions. Default adds a new centered image layer; replaceSource=true replaces the source layer while preserving geometry and style and requires the same target screen. screenId otherwise defaults to source screen or saved active screen. Inputs up to 16 MB each and 24 MB combined; background transparent and PNG output are supported. Generation runs server-side, without progress UI; only the final saved result is committed. Errors include INVALID_IMAGE_SOURCE, INVALID_MASK, MASK_DIMENSIONS_MISMATCH, INVALID_REPLACEMENT_TARGET, IMAGE_TIMEOUT, IMAGE_STORAGE_UNAVAILABLE and REVISION_CONFLICT. Parameters: - `prompt` (string, required; min length 1, max length 4000) - `imageLayerId` (string; min length 1, max length 200) - `sourceScreenId` (string; min length 1) - `uploadId` (string; format uuid) - `shotId` (string; min length 1, max length 200) - `imageDataUrl` (string; min length 1, max length 23000000) - `maskUploadId` (string; format uuid) - `maskDataUrl` (string; min length 1, max length 23000000) - `replaceSource` (boolean) - `variant` ("flare" | "sunburst") - `imageSize` ("auto" | "square" | "square_hd" | "portrait_4_3" | "portrait_16_9" | "landscape_4_3" | "landscape_16_9") - `background` ("auto" | "transparent" | "opaque") - `quality` ("auto" | "low" | "medium" | "high" | "xhigh" | "max") - `outputFormat` ("png" | "jpeg" | "webp") - `screenId` (string; min length 1) ### Translation #### `localization_status`: Translation status _read-only_ For each project language on the device deck: how many text layers it has its own translation for, which still show the source text, and which don't fit, measured with the real fonts as the Studio lays them out: tight (shrunk below 80% to fit) and overflow (too big even at the smallest size), each with screen, layerId, text and fitPercent. device reads another deck; locales limits the report. Parameters: - `device` ("iphone" | "iphone-duo" | "iphone-duo-open" | "ipad" | "mac" | "apple-watch-ultra" | "apple-watch-series" | "apple-tv" | "android" | "android-7" | "android-10" | "chromebook" | "wear-os" | "android-tv" | "feature-graphic" | "windows" | "browser"): Device deck to read or edit (e.g. ipad) without switching the saved device. Omit for the saved device; a screenId from another deck is found automatically. - `locales` (string[]; max 40 items) #### `localization_translate`: Translate the deck's text with AI Translate the current device's text layers from the source language into project languages with AI, as native App Store marketing copy: line breaks and highlighted words kept, the app name and glossary never translated, each line sized to fit (boxes refit automatically). Defaults: every non-source language, only strings still missing. scope "all" retranslates everything; layerIds limits it to some text: layers. mode "shorten" rewrites existing translations shorter (use for layers localization_status reports as tight). The result lists fitProblems: translations still tight or overflowing after the refit. Charged by tokens used (cheap). Errors: INVALID_LOCALE, NO_TARGET_LANGUAGES, INSUFFICIENT_CREDITS, REVISION_CONFLICT. Parameters: - `locales` (string[]; max 40 items) - `scope` ("missing" | "all") - `layerIds` (string[]; max 200 items) - `mode` ("translate" | "shorten") #### `localization_set_strings`: Write translations Set the text of text layers in one project language (your own translations, or fixes), without switching the active language. layerId is text: from canvas_get_layout or localization_status. An empty text goes back to showing the source text. Boxes refit to the new text automatically. Parameters: - `locale` (string, required; min length 2, max length 16) - `strings` (object[], required; min 1 items, max 200 items) - `layerId` (string, required; min length 1, max length 80) - `text` (string, required; max length 2000) #### `localization_set_glossary`: Set never-translate terms _idempotent_ Replace the list of words AI translation must keep exactly as written (brand, product and feature names). The app name is always kept and needn't be listed. Parameters: - `terms` (string[], required; max 100 items) #### `localization_set_screenshot`: Set a language's app screenshot Give one app screenshot shown inside a device on a screen its own version in a project language (the source language keeps the original). Pick the image with shotId (shots_list) or uploadId (uploads_list); clear: true goes back to the source screenshot. On screens with several devices, mockupLayerId (mockup:) picks which one. Parameters: - `locale` (string, required; min length 2, max length 16) - `screenId` (string, required; min length 1, max length 80) - `mockupLayerId` (string; min length 1, max length 80) - `shotId` (string; min length 1, max length 80) - `uploadId` (string; min length 1, max length 80) - `clear` (boolean) #### `localization_translate_screenshots`: Translate app screenshots with AI Redraw the app screenshots inside the current device's mockups in a project language with ScreenMake AI: only the interface text is translated, everything else stays identical, at the original size. Covers screenshots that have no version in that language yet (retranslate: true redoes them), optionally only on screenIds. Up to 4 per call (about a minute each); the result says how many remain. Costs the image-edit price per screenshot. Errors: INVALID_LOCALE, INSUFFICIENT_CREDITS, REVISION_CONFLICT. Parameters: - `locale` (string, required; min length 2, max length 16) - `screenIds` (string[]; max 30 items) - `retranslate` (boolean) ### App Store Connect #### `app_store_status`: App Store Connect status _read-only_ Whether the user's App Store Connect account is connected, their apps, the app this project publishes to, its versions open for changes per platform with their languages, and which App Store language each project language publishes to. Use app_store_publish (try dryRun first) to publish and app_store_verify to read the live listing back. Parameters: none. #### `app_store_link_app`: Link this project to an App Store app Choose which App Store Connect app this project publishes screenshots to (appId from app_store_status), and optionally map project languages to App Store languages, e.g. {"en": "en-US", "pt": "pt-PT"}. Unmapped languages use the obvious match. A single App Store language also fills that language's other storefronts no project language claims (en → en-US, en-GB, en-AU, en-CA); give a list, e.g. {"en": ["en-US"]}, to publish to exactly those. Parameters: - `appId` (string, required; min length 1, max length 40) - `localeMap` (object) #### `app_store_verify`: Check the App Store listing _read-only_ Read-only, no browser needed. Reads the linked app's iOS version (the one open for changes, else the newest) back from App Store Connect: every App Store language's screenshot sets with counts, processing states and file names. Also checks, per device deck, that each App Store language this project publishes to has one processed (COMPLETE) screenshot per screen. device: iphone, ipad or all (default: every deck with screens). Parameters: - `device` ("iphone" | "ipad" | "all") #### `app_store_publish`: Publish screenshots to the App Store _destructive, idempotent_ Replaces the linked app's screenshots (iOS version open for changes) with this project's decks, in every App Store language each project language fills. dryRun: true changes nothing and returns where every deck and language would go, plus anything blocking it; run it first and show the user. A real publish replaces live listing screenshots, so only run it when the user asked to publish. It renders in the user's open Studio tab, or in ScreenMake's cloud renderer when none is open (same engine as Export), waits for Apple to process every screenshot, retries a failed one once, and succeeds only when the listing read back has them all. Takes several minutes. device: iphone, ipad or all (default: every deck with screens). Nothing is submitted for review. Parameters: - `device` ("iphone" | "ipad" | "all") - `dryRun` (boolean) # Help center ## Make your first screenshots Source: https://screenmake.com/help/your-first-screenshots _What happens between creating an account and seeing your first designed set._ When you create an account, a short setup gets ScreenMake ready for your app. It takes about a minute, and while you finish it ScreenMake designs a first draft in the background. 1. Tell us about your app. Search for it on the App Store, or type its name if it isn’t published yet. 2. Add a few screenshots of the app itself. These are the screens that go inside the device frames. 3. Answer the short questions about your goal and the look you want. 4. Open the Studio. Your first draft is waiting, and everything in it can be edited. ### The draft is a starting point The first draft shows what’s possible with your own screens. Every headline, colour, frame and background in it can be changed, by hand or by asking AI Mode. > You can skip the setup and start from a blank project. Nothing is lost: you can add your screenshots later from Shots. ## Make a Quick Draft Source: https://screenmake.com/help/quick-draft _A designed set of screenshots from your app’s screens, without starting from an empty canvas._ Quick Draft reads your app’s screens, writes a headline for each, draws artwork that fits your app and lays out a full set. Every draft comes out different, and everything in it can be edited afterwards. 1. Open Screens in the left rail and choose Quick Draft. 2. Pick three to eight screens of your app, from Shots or from your computer. 3. Give your app’s name and a line about what it does. If it’s on the App Store, you can use its page too. 4. Choose a mood, a colour palette or your brand colour, and how many screens you want. Add your real App Store rating if you’d like it shown. Or leave it all to “Surprise me”. 5. Check the words. You can edit any label or headline while the artwork is being drawn. 6. Look at your draft. “Another direction” changes everything; “New colours” and “New layout” change one thing at a time. Then open it. ### Good to know - A draft opens as a new project. The project you were working on isn’t changed. - You can close the window while it works. Its progress shows at the bottom of the canvas. - Changing the direction, colours, layout or words is instant and can be repeated as often as you like. - Artwork never covers your app’s screen: it is kept to the sides or behind the device. - Plain screenshots of your app give the best result. > Creating a draft uses AI credits. Trying other directions and editing the words doesn’t. If a draft can’t be finished, nothing is charged. ## Find your way around the Studio Source: https://screenmake.com/help/the-studio _The panels on the left, the canvas in the middle, and the controls at the top._ ### The left rail - Screens: the screens in your set. Add, duplicate, reorder and delete them here. - Shots: the screenshots of your own app. Add them once and drop them into any device frame. - Mockups: device frames such as iPhone and iPad. - Elements: illustrations, badges, arrows and other design pieces. - Stock: photographs and images you can search. - Uploads: your own images, such as a logo. - Languages: translate your text and screenshots. - AI Mode: describe what you want and let ScreenMake design it. ### The canvas All your screens sit side by side on the canvas. Click anything to select it, drag to move it, and use the handles to resize or rotate. You can drag an element from one screen onto another. ### The inspector When something is selected, the panel on the right shows what you can change about it: text style, colours, background, corner radius, shadows and so on. ### The top bar Choose the device, platform and language you’re working on, open History to step back, and use Export and Publish when you’re ready to ship. ## Add your app’s screenshots Source: https://screenmake.com/help/add-app-screenshots _Put captures of your own app into ScreenMake and place them in device frames._ 1. Open Shots in the left rail. 2. Choose “Add app screenshots” and pick the captures from your computer, or drag them in. 3. Select a device frame on the canvas and choose the shot to put inside it. ### Good to know - You add each capture once. The same shot can be used in as many frames and screens as you like. - Use full-resolution captures from a simulator or a real device, so they stay sharp at App Store size. - Each language can have its own captures. See “Translate your screenshots”. ## Device frames and mockups Source: https://screenmake.com/help/device-frames _Add an iPhone, iPad or other device frame and put your app inside it._ 1. Open Mockups in the left rail. 2. Pick a frame to add it to the selected screen. 3. With the frame selected, choose which of your Shots appears inside it. 4. Move, resize and tilt the frame on the canvas, or adjust it in the inspector. ### Keeping a set consistent A set of screenshots reads best when the frames share a size and position from one screen to the next. Duplicate a finished screen and swap the shot and headline, rather than building each screen from scratch. ## Make the iPad version Source: https://screenmake.com/help/ipad-version _Turn a finished iPhone set into an iPad set without redesigning it._ ### Your options If your app runs on iPad, the App Store asks for iPad screenshots too. “Make the iPad version” in the top bar carries your iPhone design over to iPad sizes. - Your app screens on iPad: ScreenMake redraws each of your iPhone captures at iPad size, keeping the same interface. Choose “Exactly as it runs on iPad” or “Fill the iPad screen”. - Design only: the layout is carried over with empty iPad frames, ready for your own iPad captures. ### Before you publish Redrawn screens are an aid. Your listing has to show your app as it really looks on iPad, so compare them with the real thing and replace any that differ. > Redrawing screens uses AI credits. “Design only” doesn’t. The work runs in the background, and its progress shows at the bottom of the canvas. ## Design with AI Mode Source: https://screenmake.com/help/ai-mode _Describe the change you want and ScreenMake makes it on the canvas._ 1. Open AI Mode in the left rail. 2. Say what you want in plain words, for example “make the headlines shorter and bolder” or “give screen 3 a darker background”. 3. Attach an image if you have a reference, or dictate instead of typing. 4. Watch the changes land on the canvas. Keep going in the same chat to refine them. ### Changing your mind - Every message keeps a saved version of your project from just before it. You can restore any of them from the chat. - “Edit message” takes you back to that point and puts your message in the box, so you can reword it and send it again. - History in the top bar steps back through your own edits too. ### Getting better results - Be specific about which screen and which element you mean. - Ask for one kind of change at a time. - Tell it what to keep as well as what to change. > AI Mode uses AI credits. A request that fails doesn’t cost anything. ## How AI credits work Source: https://screenmake.com/help/credits _What uses credits, when they arrive, and what happens to the ones you don’t use._ ### What uses credits Only the AI tools use credits: AI Mode, Quick Draft, creating and editing images with AI, AI mockups, redrawing screens for iPad, AI translation of screenshots, and dictation. Designing by hand, exporting and publishing don’t use any. ### When you get them - Every new account starts with a few credits to try the AI tools. - Pro includes 160 credits every month, and Studio includes 600. - Unused plan credits carry over for one more month, up to two months’ worth. - Need more? Credit packs of 50, 150 or 400 never expire, and are used after your plan credits. ### If something fails Credits are taken only when a tool finishes successfully. If it fails, they come back on their own. If you think credits were taken wrongly, contact us and we’ll check. ## Translate your screenshots Source: https://screenmake.com/help/translate _Add languages, translate the text, and give each market its own captures._ 1. Open Languages in the left rail and choose “Add languages”. 2. Pick the markets you want. With “Translate right away” on, the text is localized as each language is added. 3. Switch language from the top bar to see and adjust each version. ### Text - Translations are written to fit your design, so a longer language doesn’t break the layout. - “Never translate” keeps brand and feature names exactly as you wrote them, in every language. - “Edit all strings” shows every text in every language in one table. - Working with a translator? Export the strings as a CSV or strings file, and bring the translations back in. ### App screenshots Each language can show your app in that language. Add localized captures for a language, pick them from Shots, or have ScreenMake translate the text inside your existing captures. > Translating with AI uses credits. Typing a translation yourself doesn’t. ## Export your screenshots Source: https://screenmake.com/help/export _Download store-ready images for every screen, device and language._ 1. Choose Export in the top bar. To export one screen, use the Export button on that screen. 2. Pick the screens: all of them, just this one, or a selection. 3. Pick the devices and the languages to include. 4. Choose PNG or JPEG, and the store size or every size. 5. Export. Several images arrive together as a zip. ### Sizes Images are exported at the sizes the App Store and Google Play ask for, so you can upload them as they are. > Exports from a free account carry a ScreenMake watermark. A paid plan removes it. ## Publish to the App Store Source: https://screenmake.com/help/publish _Connect App Store Connect once, then send your screenshots to your listing._ ### Connect App Store Connect ScreenMake uses an App Store Connect API key from your own Apple developer account. The Studio walks you through it step by step. 1. In App Store Connect, open Users and Access, then the Integrations tab. If it’s your first time there, Apple asks you to request access. 2. Create a key with the App Manager role. That role can update listings and nothing else: no finances and no team. 3. Copy the Issuer ID and the Key ID, and download the key file. Apple lets you download it only once. 4. Give the three to ScreenMake when it asks. ### Publish 1. Choose Publish in the top bar and pick your app. 2. Check what will be sent. Publishing replaces the screenshots on your App Store listing with this set, in every language. 3. Confirm. You can close the dialog; progress shows at the bottom of the canvas. > The screenshots are added to the version of your app that’s open for editing in App Store Connect. Apple still reviews them with your next submission. ### Your key The key is stored encrypted and is used only for what you ask. You can disconnect it at any time in Settings, and revoke it in App Store Connect. ## Connect your own AI assistant Source: https://screenmake.com/help/connect-your-assistant _Let an AI assistant that supports MCP work on your ScreenMake project._ If you use an AI assistant that supports the Model Context Protocol (MCP), it can read and edit a ScreenMake project for you: add screens, change text, translate, and more. 1. Open Settings from the account menu at the bottom left, then “API keys & MCP”. 2. Create a key and give it a name. Copy it straight away: it’s shown only once. 3. In your assistant, add ScreenMake as an MCP server using the server URL shown in Settings, with the key as its bearer token. ### Good to know - A key works on one project only. - AI tools run through your assistant use credits in the same way as in the Studio. - Delete a key in Settings to cut off access immediately. > Connecting an assistant needs a paid plan. ## Plans, billing and cancelling Source: https://screenmake.com/help/plans-and-billing _What’s free, what a plan adds, and how to change or cancel it._ ### Free and paid Designing is free. A paid plan lets you ship: export without the watermark, publish to the App Store, and connect your own AI assistant. - Pro: $19 a month or $204 a year, with 160 AI credits every month. - Studio: $69 a month or $708 a year, with 600 AI credits every month. ### Manage your plan Open Settings from the account menu at the bottom left, then Billing. From there you can change plan, update your card, see your payments and download invoices. ### Cancelling Cancel at any time from Settings → Billing. Your plan stays active until the end of the period you’ve paid for, and your projects stay in your account afterwards. ### Refunds A first plan payment can be refunded within 14 days if you’ve barely used it. The full rule is in our refund policy at /refunds. > Payments are handled by Stripe, so its name may appear on your statement. ## Your account and sign-in Source: https://screenmake.com/help/your-account _Passwords, signing in with Google, and deleting your account._ ### Forgotten password On the sign-in page choose “Forgot password?” and enter your email. We send a link to set a new one. If it doesn’t arrive within a few minutes, check your spam folder. ### Signing in with Google If you created your account with Google, use the Google button to sign in. There’s no separate ScreenMake password for that account. ### Deleting your account Write to support@screenmake.com from the address on your account and ask us to delete it. We remove your account, projects and uploads within 30 days. Cancel any paid plan first so you aren’t charged again. ### Your data What we collect and how we use it is set out in our privacy policy at /privacy. ## Something isn’t working Source: https://screenmake.com/help/something-isnt-working _Quick things to try, and what to tell us so we can fix it fast._ ### Try these first - Reload the page. Your work is saved as you go, so nothing is lost. - If an AI tool stopped, check your credit balance and try again. A failed request doesn’t use credits. - If an upload is refused, check that the file is an image and try a smaller one. - If publishing fails, check that your App Store Connect key is still active and has the App Manager role. - Use an up-to-date desktop browser. The Studio is built for a computer screen rather than a phone. ### Still stuck? Tell us Send us a request from the help center. It helps a lot if you include: - what you were trying to do, and what happened instead; - the exact wording of any error message; - which project and screen it happened on; - roughly when it happened.