Deterministic App Store screenshot composition as an MCP server.
This package gives your agent a stable rendering backend with persisted state so screenshot sets stay consistent across runs.
- An MCP server (stdio) distributed via npm
- A deterministic screenshot renderer (no AI image generation)
- A simple persisted state layer for consistency
screenshots.validate_state- Validates an existing
screenshot-config.jsonfile at explicitstatePath
- Validates an existing
screenshots.render_generic- Renders one screenshot with fallback resolution from state and writes output under
screenshots-asc
- Renders one screenshot with fallback resolution from state and writes output under
screenshots.render_batch- Renders many screenshots from a config file and writes outputs under
screenshots-asc
- Renders many screenshots from a config file and writes outputs under
screenshots.how_to_use_tools(resource)- Agent-facing workflow and quality guidance
screenshots.discover_benefits_and_brand_color(prompt)- Agent-facing discovery prompt scaffold
- It does not run LLM discovery itself.
- Discovery is done by the client agent.
- The server stores and applies decisions consistently.
Use without global install:
npx -y screenshot-asoOr install globally:
npm install -g screenshot-asoThen run:
screenshot-asoExample stdio config:
{
"mcpServers": {
"screenshot-aso": {
"command": "npx",
"args": ["-y", "screenshot-aso"]
}
}
}Required state path:
- You must provide
statePathon related MCP calls. statePathmust be a path ending withscreenshot-config.json.- The server does not auto-discover project roots or default state locations.
State includes:
brandColor(#RRGGBB)benefits(headline-readytextLines)defaults(backgroundColor, fixedsize: "6.9",frameColor)breakouts(array of per-screenshot breakout entries identified byscreenshotKey; latest matching entry wins)
Important behavior:
render_*tools do not modifyscreenshot-config.json.- agents/users edit
screenshot-config.jsondirectly, then runscreenshots.validate_state. - Render outputs are written under:
<dirname(statePath)>/screenshots-asc
- Choose a project-specific
statePathending withscreenshot-config.json. - Read/edit that
screenshot-config.jsondirectly. - Run
screenshots.validate_statewith the samestatePath. - If
brandColororbenefitsare missing, infer and add them inscreenshot-config.json. - Render via
screenshots.render_genericorscreenshots.render_batchwith samestatePath. - For breakout tuning, iterate
render_genericand persist accepted breakout values by editingscreenshot-config.json.
Input requirements:
statePathis requiredinputPathimage should be1320x2868, or very close in aspect ratio (near0.460251) to prevent content cutoff from cover-cropping- Provide exactly one text source:
textLines, orbenefitId(resolved from state)
Resolution order:
- background color:
input.backgroundColorstate.defaults.backgroundColorstate.brandColor
- size:
- fixed to
6.9(ifinput.sizeis provided, it must be6.9)
- fixed to
- frame color:
input.frameColorstate.defaults.frameColor
- breakout:
input.breakoutstate.breakouts[screenshotKey]- none
Breakout coordinate modes:
rectPx: crop in raw input screenshot pixels (x,y,width,height), with origin at the input image top-left before cover-croppingrectNorm: normalized crop (0..1) over the visible phone-screen area in the frame, with origin at the phone-screen top-left (x=0,y=0) and bottom-right at (x=1,y=1)- when input aspect ratio differs, renderer maps coordinates through cover-cropping and clamps final source pixels to image bounds
Output behavior:
render_genericwrites to<dirname(statePath)>/screenshots-asc- output file name is
<inputBase>-generic.png
screenshots.render_batch accepts a configPath pointing to JSON:
{
"shots": [
{
"input": "raw/shot-1.png",
"textLines": [{ "text": "TRACK CARD PRICES" }],
"bg": "#07163F",
"frameColor": "natural",
"breakout": {
"rectNorm": { "x": 0.05, "y": 0.18, "width": 0.9, "height": 0.2 },
"edgeOverflow": 0.08
}
}
]
}render_batch also requires statePath; generated outputs are written to <dirname(statePath)>/screenshots-asc.
Output files are named as <NN>-<inputBase>.png (for example 01-home.png).
Each shots[].input image should be 1320x2868, or very close in aspect ratio.
For local development and contribution workflow, see CONTRIBUTING.md.