WebMCP
Let AI agents make your store screenshots
Storedeck registers 22 tools with document.modelContext — the WebMCP API — covering everything the editor can do. An agent can run the whole job, from simulator captures to localized, A/B-ready exports, while you watch the canvas.
How agents connect
- WebMCP-capable browsers and agent runtimes discover the tools automatically on any Storedeck page; calling one opens the editor if needed.
- Browser automation without WebMCP (Playwright, CDP, agent-browser eval): call the same tools through
await window.storedeck.callTool("get_app_state", {})and list them withwindow.storedeck.listTools(). - Inputs are validated against the published JSON schemas and errors explain what to fix, so agents can self-correct.
The model agents work with
Project (one app, its languages) → variants (A/B test arms with status and hypothesis) → platform decks (store + device + exact size) → screens (images and copy per language, background, device, text, elements, popouts). Every id is returned by get_app_state; most tools also accept screenIndex and default to the current selection, and design tools take a scope of screen, platform or variant.
A complete run
get_app_state→ pick or create a project withmanage_project.manage_screensupload with data URLs;get_imagesmodeoriginalto read the app.set_copywith every screen × language in one call.set_background,set_device,set_text_stylewithscope: "platform".get_images(rendered) +get_screenlayout warnings → fix → repeat.manage_platformadd withcloneFromDeckIdfor Android, iPad, Mac or TV;manage_variantcreate for A/B tests.exportand save the PNGs.
Add this to your repo's AGENTS.md
Coding agents (Claude Code, Codex, Cursor…) read AGENTS.md. With this section they can refresh your store screenshots on request — capture, design, review with you, export.
## Store screenshots (Storedeck)
Use **Storedeck** (https://storedeck.byanr.com — free, open source, runs in
the browser) to create App Store, Google Play, desktop and TV store
screenshots. Prefer it over hand-editing images or writing canvas scripts.
It exposes WebMCP tools (also callable as `window.storedeck.callTool(name, input)`).
**Workflow — do this without asking the user to click:**
1. Capture fresh screenshots (e.g. `xcrun simctl io booted screenshot shot-01.png`,
`adb exec-out screencap -p > shot-01.png`). For other languages, capture again
with the app in that language and name files `shot-01_de.png`, `shot-01_te.png`.
2. Open https://storedeck.byanr.com and call `get_app_state`. Open this app's
project if it exists (`manage_project` action=open) or create it with the
platforms you ship on (`platformIds`, see `get_platform_catalog`).
3. Upload captures with `manage_screens` action=upload (`filename` +
`data:image/png;base64,...`, max 10 per call). Localized files land on the
matching screen automatically.
4. Look at the originals (`get_images` mode=original), then write one headline
(2–5 words, benefit-first) and subheadline (4–10 words) per screen with a
single `set_copy` call — include every project language.
5. Style with `set_background`, `set_device` (preset, 2D `chrome` or 3D) and
`set_text_style`, using `scope: "platform"` or `"variant"` to keep the set
consistent. Reuse a finished platform for others with `manage_platform`
action=add + `cloneFromDeckId`.
6. Review: `get_images` (rendered) and `get_screen` layout warnings (text
overlapping the device, headlines wrapping too much). Fix and re-check.
7. Show the user the rendered previews and ask for feedback. For A/B tests,
create a variant with `manage_variant` action=create (it copies the current
one) and change only what is being tested.
8. `export` with `delivery: "return"` and save each `dataUrl` to
`store-assets/<platform>/<language>/<NN-name>.png`, then report the paths.
Notes: sizes and counts come from the catalog — never upscale previews for
final assets. Everything stays in the user's browser storage.
Tool reference
Read
get_app_state
Get app stateread-onlySTART HERE. Returns the open project (languages, variants → platform decks → screens with ids, image languages and headline/subheadline copy), all saved projects, the current selection and view, undo history and next-step hints. Image bytes are not included (use get_images). Call again after structural changes.
Parameters (2)
| variantId | string | Only include this variant |
| includeCopy | boolean | Include headline/subheadline text per screen (default true) |
get_screen
Get screen designread-onlyFull design of one screen (default: selected): background, device, text style, copy per language, elements, popouts, image info, output size, plus computed layout (device and text rectangles in output px) and warnings such as text overlapping the device or running off-canvas.
Parameters (4)
| screenId | string | Screen id. Defaults to the selected screen. |
| screenIndex | integer | 0-based screen position within deckId (or the selected platform); alternative to screenId. |
| deckId | string | Platform deck id used with screenIndex or scope. Defaults to the selected platform. |
| language | string | Language used for layout warnings (default: current) |
get_platform_catalog
Get store platform catalogread-onlyStore screenshot specs: every platform id with its output sizes, orientation, screenshot count limits and requirements. Stores: app-store, google-play, microsoft-store, steam, amazon-appstore, tv-stores, web.
Parameters (1)
| store | "app-store" | "google-play" | "microsoft-store" | "steam" | "amazon-appstore" | "tv-stores" | "web" | Filter by store |
get_strings
Get localization stringsread-onlyThe localization table: every headline, subheadline and text-element string per language, with missing translations listed. Filter by variant/platform. Use before translating, then write with set_copy.
Parameters (4)
| variantId | string | |
| deckId | string | |
| languages | string[] | Only these languages |
| onlyMissing | boolean | Only rows with missing translations |
get_images
Get images for visionread-onlyImages for visual QA. mode "rendered" (default) returns the styled composition exactly as exported, downscaled to maxDimension (default 900 px, JPEG). mode "original" returns uploaded source screenshots (use to read the app UI before writing copy). Waits for fonts, images and 3D models. Target with screenId/screenIds/screenIndex or scope.
Parameters (10)
| screenId | string | Screen id. Defaults to the selected screen. |
| screenIds | string[] | Several screen ids at once. |
| screenIndex | integer | 0-based screen position within deckId (or the selected platform); alternative to screenId. |
| deckId | string | Platform deck id used with screenIndex or scope. Defaults to the selected platform. |
| scope | "screen" | "platform" | "variant" | screen (default): one screen. platform: every screen in the platform deck. variant: every screen of every platform in the selected variant. |
| language | string | Language to render (default: current) |
| mode | "rendered" | "original" | |
| maxDimension | integer | Longest side in px (200-1600, default 900). Never upscales. |
| format | "jpeg" | "png" | Default jpeg (smaller for agent context) |
| maxImages | integer | Cap for multi-screen requests (default 6) |
Navigate
select
Select variant, platform, screen or languageMoves the editor focus so the user sees what you work on: variantId (A/B variant), deckId (platform), screenId or screenIndex, and language (preview language). Switching variant keeps the same platform and screen position when possible.
Parameters (5)
| variantId | string | |
| deckId | string | |
| screenId | string | |
| screenIndex | integer | |
| language | string | Project language code, e.g. "de" |
set_view
Change editor viewControls the editor UI: view (design = single screen canvas, board = all screens × languages grid, strings = localization table, compare = A/B variants side by side), inspectorTab, selected element/popout, which variants to compare, and the store safe-area overlay.
Parameters (6)
| view | "design" | "board" | "strings" | "compare" | |
| inspectorTab | "background" | "device" | "text" | "elements" | "popouts" | |
| selectedElementId | string | Element id or "" to clear |
| selectedPopoutId | string | Popout id or "" to clear |
| compareVariantIds | string[] | Variants shown in compare view (2-4) |
| showSafeArea | boolean |
Structure
manage_project
Manage projectsProjects are the top-level container (one per app). Actions: create {name, appName?, platformIds?, languages?} — new project with an "Original" variant; open {projectId}; rename {name, appName?}; duplicate {projectId?, name?}; delete {projectId, confirm:true} (permanent); export_file {projectId?} downloads a .storedeck.json backup for the user; import_file {bundle} imports a backup (object or JSON string).
Parameters (8)
| action* | "create" | "open" | "rename" | "duplicate" | "delete" | "export_file" | "import_file" | |
| name | string | Project name (1-100 chars) |
| appName | string | App name used in guides/exports |
| projectId | string | |
| platformIds | "app-store-iphone" | "app-store-ipad" | "app-store-mac" | "app-store-apple-tv" | "app-store-vision-pro" | "app-store-watch" | "google-play-phone" | "google-play-tablet-7" | "google-play-tablet-10" | "google-play-chromebook" | "google-play-tv" | "google-play-wear" | "google-play-xr" | "google-play-automotive" | "google-play-artwork" | "ms-store-desktop" | "ms-store-xbox" | "steam-screenshots" | "steam-capsules" | "amazon-fire-tv" | "amazon-fire-tablet" | "smart-tv" | "web-social"[] | create: initial platforms (default app-store-iphone) |
| languages | string[] | create: initial languages (default ["en"]) |
| confirm | boolean | delete: must be true |
| bundle | any | import_file: project bundle object or JSON string |
manage_variant
Manage A/B variantsVariants are alternative screenshot sets for A/B tests (App Store Product Page Optimization, Google Play store listing experiments). Actions: create {name?, cloneFromVariantId?, blank?, platformIds?} — clones the selected variant by default so you only change what the test is about; update {variantId, name?, status?, hypothesis?} (status draft|control|testing|winner|archived — one control/winner at a time); delete {variantId}; move {variantId, toIndex}.
Parameters (9)
| action* | "create" | "update" | "delete" | "move" | |
| variantId | string | |
| name | string | |
| cloneFromVariantId | string | |
| blank | boolean | create: start with empty platforms instead of cloning |
| platformIds | "app-store-iphone" | "app-store-ipad" | "app-store-mac" | "app-store-apple-tv" | "app-store-vision-pro" | "app-store-watch" | "google-play-phone" | "google-play-tablet-7" | "google-play-tablet-10" | "google-play-chromebook" | "google-play-tv" | "google-play-wear" | "google-play-xr" | "google-play-automotive" | "google-play-artwork" | "ms-store-desktop" | "ms-store-xbox" | "steam-screenshots" | "steam-capsules" | "amazon-fire-tv" | "amazon-fire-tablet" | "smart-tv" | "web-social"[] | create+blank: platforms to add |
| status | "draft" | "control" | "testing" | "winner" | "archived" | |
| hypothesis | string | What this variant tests, e.g. "Benefit-first headlines lift installs" |
| toIndex | integer |
manage_platform
Manage store platformsEach variant holds one deck per store platform (iPhone, iPad, Android phone, Mac, Apple TV, Android TV, Windows, Steam, Fire TV, …; ids via get_platform_catalog). Actions: add {platformId, sizeId?, variantId?, cloneFromDeckId?, allVariants?} — cloneFromDeckId copies screens, images and copy and rescales the design to the new size (the fastest way to go from iPhone to Android/iPad); remove {deckId}; set_size {deckId?, sizeId? | width+height, orientation?} — design values rescale automatically.
Parameters (10)
| action* | "add" | "remove" | "set_size" | |
| platformId | "app-store-iphone" | "app-store-ipad" | "app-store-mac" | "app-store-apple-tv" | "app-store-vision-pro" | "app-store-watch" | "google-play-phone" | "google-play-tablet-7" | "google-play-tablet-10" | "google-play-chromebook" | "google-play-tv" | "google-play-wear" | "google-play-xr" | "google-play-automotive" | "google-play-artwork" | "ms-store-desktop" | "ms-store-xbox" | "steam-screenshots" | "steam-capsules" | "amazon-fire-tv" | "amazon-fire-tablet" | "smart-tv" | "web-social" | |
| sizeId | string | Size id from the catalog, or "custom" with width/height |
| variantId | string | |
| deckId | string | |
| cloneFromDeckId | string | |
| allVariants | boolean | add: add to every variant |
| width | integer | set_size: custom width |
| height | integer | set_size: custom height |
| orientation | "portrait" | "landscape" |
manage_screens
Manage screensScreens are the individual store images of a platform deck. Actions: upload {screenshots:[{filename, dataUrl, language?}], deckId?, screenId?} — PNG/JPEG data URLs, max 10 per call; language suffixes in filenames (home_de.png, home-pt-br.png) are detected, and files whose base name matches an existing screen become its localized image; new screens copy the selected screen's style. add_blank {deckId?, name?}; delete {screenId}; duplicate {screenId}; move {screenId, toIndex} (store order); rename {screenId, name}; remove_image {screenId, language}.
Parameters (8)
| action* | "upload" | "add_blank" | "delete" | "duplicate" | "move" | "rename" | "remove_image" | |
| screenshots | { filename, dataUrl, language }[] | upload: images |
| deckId | string | |
| screenId | string | |
| screenIndex | integer | |
| name | string | |
| toIndex | integer | |
| language | string |
Copy & localization
manage_languages
Manage languagesProject languages (lower-case BCP-47 like "de", "pt-br", "zh-tw", "te"). Actions: add {languages:[...]}, remove {language} (copy is kept and returns if re-added), set_default {language} (fallback for missing copy/images), switch {language} (preview language — same as select).
Parameters (3)
| action* | "add" | "remove" | "set_default" | "switch" | |
| language | string | |
| languages | string[] |
set_copy
Write headlines & translationsWrites store copy (the words, not styling) in bulk. Each entry targets a screen (screenId, or screenIndex + optional deckId), a field (headline, subheadline, or "element:<elementId>" for text badges), a language and text. Languages are added to the project automatically. Copywriting: headline 2–5 words, benefit-first; subheadline 4–10 words that expand it; every screen tells a different part of the story and screen 1 carries the core value proposition. Use \n for manual line breaks. Prefer one call with all entries.
Parameters (1)
| entries* | { screenId, screenIndex, deckId, field, language, text }[] |
copy_strings
Copy strings between platformsCopies headline/subheadline copy from one platform deck to another by screen position (e.g. reuse iPhone copy for Android). Optional languages filter.
Parameters (3)
| fromDeckId* | string | |
| toDeckId* | string | |
| languages | string[] |
Design
set_background
Set backgroundBackground of the targeted screens: type gradient|solid|image; gradient {kind linear|radial, angle (CSS degrees, 0 = up), stops [{color, position 0-100}]}; gradientPreset (Indigo Rush, Midnight Abyss, Obsidian Plum, Carbon Slate, Steel Blue, Neon Horizon, Electric Surge, Synthwave Dusk, Northern Lights, Deep Forest, Emerald Canopy, Ocean Pulse, Desert Dusk, Ember Glow, Mocha Silk, Golden Hour, Pacific Sunset, Volcanic Dawn, Deep Ocean, Reef Lagoon, Gold Noir, Velvet Noir, Morning Mist, Sage Whisper, Royal Navy, Paper White); solid; imageDataUrl (sets type image); imageFit cover|contain|stretch; imageBlur; overlayColor/overlayOpacity (tint for contrast); noise/noiseIntensity.
Parameters (16)
| screenId | string | Screen id. Defaults to the selected screen. |
| screenIds | string[] | Several screen ids at once. |
| screenIndex | integer | 0-based screen position within deckId (or the selected platform); alternative to screenId. |
| deckId | string | Platform deck id used with screenIndex or scope. Defaults to the selected platform. |
| scope | "screen" | "platform" | "variant" | screen (default): one screen. platform: every screen in the platform deck. variant: every screen of every platform in the selected variant. |
| type | "gradient" | "solid" | "image" | |
| gradient | { kind, angle, stops } | |
| gradientPreset | "Indigo Rush" | "Midnight Abyss" | "Obsidian Plum" | "Carbon Slate" | "Steel Blue" | "Neon Horizon" | "Electric Surge" | "Synthwave Dusk" | "Northern Lights" | "Deep Forest" | "Emerald Canopy" | "Ocean Pulse" | "Desert Dusk" | "Ember Glow" | "Mocha Silk" | "Golden Hour" | "Pacific Sunset" | "Volcanic Dawn" | "Deep Ocean" | "Reef Lagoon" | "Gold Noir" | "Velvet Noir" | "Morning Mist" | "Sage Whisper" | "Royal Navy" | "Paper White" | |
| solid | string | Hex color #rrggbb |
| imageDataUrl | string | data:image/... background image |
| imageFit | "cover" | "contain" | "stretch" | |
| imageBlur | number | px |
| overlayColor | string | Hex color #rrggbb |
| overlayOpacity | number | 0-100 |
| noise | boolean | |
| noiseIntensity | number | 0-100 |
set_device
Set device frame & placementHow the screenshot is presented. preset (centered: Centered; bleed-bottom: Bleed bottom; bleed-top: Bleed top; float-center: Float center; tilt-left: Tilt left; tilt-right: Tilt right; perspective: Perspective; float-bottom: Float bottom; side-right: Text left, device right; side-left: Device left, text right) — explicit fields override it. scale (% of canvas width), x/y (50 = centered; <0 or >100 bleeds off-canvas), rotation, perspective, cornerRadius; chrome {style: none|phone|tablet|laptop|monitor|browser|window|tv|watch, color} draws a 2D device frame (phone for mobile, laptop/window/browser for desktop, tv for TV); use3D with model3D iphone|samsung, modelColor and rotation3D {x,y,z}; shadow {...}; border {...} (outline stroke).
Parameters (19)
| screenId | string | Screen id. Defaults to the selected screen. |
| screenIds | string[] | Several screen ids at once. |
| screenIndex | integer | 0-based screen position within deckId (or the selected platform); alternative to screenId. |
| deckId | string | Platform deck id used with screenIndex or scope. Defaults to the selected platform. |
| scope | "screen" | "platform" | "variant" | screen (default): one screen. platform: every screen in the platform deck. variant: every screen of every platform in the selected variant. |
| preset | "centered" | "bleed-bottom" | "bleed-top" | "float-center" | "tilt-left" | "tilt-right" | "perspective" | "float-bottom" | "side-right" | "side-left" | |
| scale | number | % of canvas width |
| x | number | |
| y | number | |
| rotation | number | Degrees |
| perspective | number | Shear -50..50 |
| cornerRadius | number | |
| chrome | { style, color } | |
| use3D | boolean | |
| model3D | "iphone" | "samsung" | |
| modelColor | string | iphone: natural|blue|white|black|desert|deep-purple|gold|red; samsung: gray|black|silverblue|whitesilver|pinkgold|jadegreen|jetblack |
| rotation3D | { x, y, z } | |
| shadow | { enabled, color, blur, opacity, x, y } | |
| border | { enabled, color, width, opacity } |
set_text_style
Style headline & subheadlineTypography and layout of the headline/subheadline (content is set with set_copy). headline/subheadline {enabled, font, size (output px), weight, color, opacity, italic, underline, strikethrough, uppercase, letterSpacing}; position top|bottom; align left|center|right (mirrored automatically for RTL languages); offsetY (% from edge); x (block center %) and maxWidth (% of width) for side-by-side layouts; lineHeight (%); gap (% of headline size). With language set, headline/subheadline size, offsetY and lineHeight are stored as an override for that language only (for long German or short CJK copy); resetLanguageOverride removes it.
Parameters (16)
| screenId | string | Screen id. Defaults to the selected screen. |
| screenIds | string[] | Several screen ids at once. |
| screenIndex | integer | 0-based screen position within deckId (or the selected platform); alternative to screenId. |
| deckId | string | Platform deck id used with screenIndex or scope. Defaults to the selected platform. |
| scope | "screen" | "platform" | "variant" | screen (default): one screen. platform: every screen in the platform deck. variant: every screen of every platform in the selected variant. |
| language | string | Store size/offset/lineHeight as a per-language override |
| resetLanguageOverride | boolean | |
| headline | { enabled, font, size, weight, color, opacity, italic, underline, strikethrough, uppercase, letterSpacing } | |
| subheadline | { enabled, font, size, weight, color, opacity, italic, underline, strikethrough, uppercase, letterSpacing } | |
| position | "top" | "bottom" | |
| align | "left" | "center" | "right" | |
| offsetY | number | % from top/bottom edge |
| x | number | Text block center in % of width |
| maxWidth | number | % of canvas width |
| lineHeight | number | % |
| gap | number | % of headline size |
manage_elements
Manage overlay elementsFloating overlays on a screen (badges, awards, emoji, icons, logos — not the headline). Actions: add {kind: text|emoji|icon|image, text+language (text), emoji, icon (Lucide name), imageDataUrl (image), properties?}; update {elementId, properties?, text?, language?}; delete {elementId}; reorder {elementId, toIndex} (later = on top). Layers: behind-device, above-device, above-text.
Parameters (13)
| action* | "add" | "update" | "delete" | "reorder" | |
| screenId | string | Screen id. Defaults to the selected screen. |
| screenIndex | integer | 0-based screen position within deckId (or the selected platform); alternative to screenId. |
| deckId | string | Platform deck id used with screenIndex or scope. Defaults to the selected platform. |
| elementId | string | |
| kind | "text" | "emoji" | "icon" | "image" | |
| text | string | |
| language | string | |
| emoji | string | |
| icon | string | |
| imageDataUrl | string | |
| properties | { name, x, y, width, rotation, opacity, layer, font, fontSize, fontWeight, color, italic, frame, frameColor, frameScale, emoji, icon, strokeWidth, shadow } | Element properties; only those matching the element kind apply. |
| toIndex | integer |
manage_popouts
Manage magnified popoutsPopouts crop a region of the screen's source screenshot and show it enlarged (callouts for key UI). Actions: add {properties?}, update {popoutId, properties}, delete {popoutId}. Crop values are % of the source image; placement is % of the canvas.
Parameters (6)
| action* | "add" | "update" | "delete" | |
| screenId | string | Screen id. Defaults to the selected screen. |
| screenIndex | integer | 0-based screen position within deckId (or the selected platform); alternative to screenId. |
| deckId | string | Platform deck id used with screenIndex or scope. Defaults to the selected platform. |
| popoutId | string | |
| properties | { cropX, cropY, cropWidth, cropHeight, x, y, width, rotation, opacity, cornerRadius, shadow, border } |
transfer_style
Copy design to other screensCopies design from a source screen to targets — across screens, platforms or variants. Copy (words) and screenshots stay with each target; pixel values rescale when sizes differ. parts selects background/device/text/elements (all by default). Targets: targetScreenIds, or targetScope platform (source deck) | variant (every deck in source variant) | project (everything).
Parameters (6)
| sourceScreenId | string | |
| sourceScreenIndex | integer | |
| deckId | string | Deck for sourceScreenIndex |
| targetScreenIds | string[] | |
| targetScope | "platform" | "variant" | "project" | |
| parts | { background, device, text, elements } |
Output
export
Export store imagesread-onlyRenders full-resolution store images. delivery "return" (default) returns data URLs to save as files (max 24 per call — narrow with screenIds/deckIds/languages). delivery "download" builds a ZIP in the browser for the user (variant/platform-WxH/lang/NN-name.png). Defaults: selected platform deck, current language, PNG. JPEG is flattened (stores reject alpha).
Parameters (8)
| variantIds | string[] | |
| deckIds | string[] | |
| screenIds | string[] | |
| languages | string[] | |
| allLanguages | boolean | Every project language |
| allPlatforms | boolean | Every deck of the selected variant(s) |
| format | "png" | "jpeg" | |
| delivery | "return" | "download" |
history
Undo / redoUndo or redo document changes (yours and the user's). steps defaults to 1.
Parameters (2)
| action* | "undo" | "redo" | |
| steps | integer |
Want the machine-readable version? The same schemas are served at /llms.txt, and the automation guide walks through a full example.
Try it with your agent
Open the editor in a WebMCP-capable browser and ask your agent to “make App Store screenshots for my app”.