@appscreen/mcp
Enables generating App Store screenshots from layout JSON and image files, with tools to submit render jobs and poll render status for completed exports.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@appscreen/mcpRender App Store screenshots from ~/app/layout.json and ~/app/home.png"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@appscreen/mcp
MCP server for AppScreen — generate App Store / Play Store screenshots from any MCP-capable agent (Claude Desktop, Claude Code, Cursor, Codex, etc.).
Install
# Latest, no install — recommended for end users
npx -y @appscreen/mcpRelated MCP server: storeshots-mcp
Configure (Claude Desktop)
~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"appscreen": {
"command": "npx",
"args": ["-y", "@appscreen/mcp"],
"env": {
"APPSCREEN_API_KEY": "mcm_live_…"
}
}
}
}Omit APPSCREEN_API_KEY for anonymous use (5 lifetime renders, then sign-up required).
Configure (other clients)
Claude Code:
claude mcp add appscreen -- npx -y @appscreen/mcpCursor:
.cursor/mcp.json— same JSON shape as above.Codex:
codex mcp add appscreen -- npx -y @appscreen/mcp, or add to~/.codex/config.toml:[mcp_servers.appscreen] command = "npx" args = ["-y", "@appscreen/mcp"] env = { APPSCREEN_API_KEY = "mcm_live_…" }
Tools
render_screenshots— Accepts screens (layout JSON) and image files. Returns ajobId(keyed/async) or a download link (anon/inline). Free anon use capped at 5 lifetime.get_render_status— Polls ajobId. Returns status + signed download URL when done.
Pass images by path, not base64
The server runs locally, so give it a file path — it reads the bytes off disk. Do not base64-encode real screenshots into the call: an LLM emitting an 18k–90k-char base64 string drops a character partway down and the PNG renders black below it.
"files": [
{ "name": "1.png", "path": "~/app/screenshots/home.png" }, // ✅ preferred
{ "name": "2.png", "path": "/abs/path/settings.png" }
]
// base64 is accepted only for tiny synthetic test images:
// { "name": "x.png", "base64": "iVBORw0KG..." }Bundle download URLs are signed and expire after ~1h. Re-poll to refresh.
Quota
Signed-in usage is metered in credits: 1 credit = 1 exported image (screens × sizes × languages). A failed export is refunded; auto-translate is free. An MCP key spends the credits of the workspace it was created in.
Plan | Credits / month | Notes |
Free | 50 | Any one size per export, English, 10 screens per export. 3 renders / hour. |
Starter — $4 / mo | 400 | All 5 sizes, any 3 languages per export, auto-translate. 3 renders / hour. |
Pro — $8 / mo | 2,500 | All 15 languages, 200 screens per export. Full-rate MCP. |
Team — $29 / mo | 8,000 pooled | 3 seats included. Full-rate MCP. |
One-time credit packs work on every plan, including Free: 100 for $5, 400 for $15, 1,500 for $39, valid 12 months. Anonymous use (no key) is not metered in credits — it is capped at 5 renders, lifetime.
Every tool response includes _meta.quota = {used, cap, tier, resetAt}, plus balance (credits left) and, on a render submit, cost when the API reports them. For a signed-in caller used and cap count credits (cap − used = balance) and tier is the plan id; for an anonymous caller they count the 5 lifetime renders and tier is anon-mcp. When less than half is left the text content carries a short notice ("N credits left …"); below 20%, or at zero, the response also includes _meta.upgradeUrl.
An export the workspace can't cover fails with HTTP 402 insufficient_credits — the error text gives the cost and the balance. Full details: https://appscreen.co/pricing.
Environment
Var | Purpose |
| Optional. MCP key ( |
| Override API URL. Defaults to |
| Override client identifier (auto-detected from MCP initialize). |
License
MIT
Available Tools
2 toolsget_render_statusPoll a render jobA
Returns status (queued|running|done|failed), progress, and downloadUrl when ready. Only needed when render_screenshots returned a jobId with status=queued (the keyed/async path). Anonymous and small renders often complete inline — if render_screenshots already returned a downloadUrl, you do NOT need to poll.
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden, and it does disclose the status enumeration, that progress and downloadUrl vary by lifecycle stage, and that results may already be complete inline. It stops short of stating polling cadence, job expiry, or failure detail, which would matter for an async poller.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the return shape and then the gating condition. Every clause earns its place, including the explicit 'you do NOT need to poll' guard.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by enumerating the return fields. Combined with the clear preconditions, an agent has everything needed to decide whether and how to call this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
One parameter with 0% schema description coverage, but the description supplies the semantics the schema lacks: the jobId originates from render_screenshots on the keyed/async path. The schema itself carries the UUID pattern. Slightly thin on what a malformed or expired jobId yields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (poll/returns status) and resource (render job), and enumerates the exact return values (queued|running|done|failed, progress, downloadUrl). It is immediately distinguishable from render_screenshots, the only sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the triggering condition: use only when render_screenshots returned a jobId with status=queued, and explicitly states when NOT to use it (if a downloadUrl was already returned). Both the positive and negative cases are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_screenshotsRender App Store / Play Store screenshotsA
Queue a screenshot render; returns jobId, poll get_render_status until done, then fetch the bundle from the resource_link.
BEFORE CALLING THIS: read the appscreen://options resource and present the user the FULL menu of background effects, frames, and presets — each has a preview URL they can open. Let the user pick; never choose a background or frame silently. blur+tint, mesh, and every frame are all valid choices they should see.
IMAGES — put a local file path right on the element; the server reads the bytes off disk and wires up the binding for you. Never base64 real screenshots (a large base64 corrupts token-by-token → renders black):
• screenshot: screens[i].screenshot.path = "/shot.png" (or pathsByLang: { en, es } for per-locale shots)
• background image: screens[i].bg = { kind:"image", box, path:"/bg.png" }
• logo/decoration: screens[i].objects[] = { kind:"image", id:"logo", box, mime:"image/png", path:"~/logo.png" }
Geometry is automatic: omit screenshot.box and the server centers the device at the correct aspect ratio. screensMeta is auto-derived when you upload exactly one file per screen. Text overlays use the tiptap doc format and support rich, PARTIAL styling — per-run color, fontSize, fontWeight, fontFamily (~37 fonts), plus bold/italic/underline and per-paragraph align. See appscreen://schema/text + appscreen://catalog/fonts. Free anonymous tier: 5 lifetime renders.
| Name | Required | Description | Default |
|---|---|---|---|
| files | No | Low-level uploads + manual screensMeta binding. PREFER inline paths instead: put screenshot.path / screenshot.pathsByLang on each screen, bg.path on an image background, and path on image objects — the server assembles the upload + binding for you. Use this top-level files[] only if you're hand-managing screensMeta. | |
| langs | Yes | Locales (catalog.langs). | |
| sizes | Yes | Target canvas sizes (catalog.sizes[].id). | |
| layout | No | One of catalog.layouts (default = `default`). | |
| rounded | No | ||
| screens | Yes | ||
| screensMeta | No | ||
| cornerRadius | No | ||
| idempotencyKey | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses the async job pattern, the free-tier quota (5 lifetime renders), the failure mode of base64 (renders black), and that geometry and screensMeta are auto-derived. It stops short of describing error handling or the bundle's contents, so not quite a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the operational sequence, then bullets the image-handling rules with concrete paths. The 'why' behind each rule (corruption, auto-binding) earns its space. Slightly dense and overlapping with schema descriptions, but no padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description correctly explains the return flow (jobId → poll → resource_link bundle). For a 9-param nested tool with no annotations, it covers the critical path but omits guidance on the required sizes/langs catalogs and the files[] fallback.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 44%, so the description must compensate — and it does for the hard nested params: screens[i].screenshot.path, pathsByLang, bg kind:'image' with path, objects[] images, omitting screenshot.box for auto-centering, and the tiptap text format. It leaves sizes, langs, layout, files[], and idempotencyKey unexplained, so it doesn't fully close the gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Queue a screenshot render') scoped to App Store / Play Store screenshots, and immediately names the sibling it works with ('poll get_render_status'). An agent can distinguish this from get_render_status without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit sequencing: call this, then poll get_render_status, then fetch from the resource_link. It also gives a hard precondition ('BEFORE CALLING THIS: read the appscreen://options resource') and a behavioral rule ('never choose a background or frame silently'). This is exactly when/when-not/alternatives coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.30.0- First observed
get_render_status - First observed
render_screenshots
TDQS
Scored across 2 tools
The tools have perfectly distinct responsibilities: one initiates the asynchronous rendering job, and the other checks the status of that job. There is no functional overlap between the two endpoints.
Both tool names follow a highly consistent and predictable `verb_noun` pattern (`render_screenshots` and `get_render_status`). This clear convention aids immediate agent understanding.
For managing a multi-step asynchronous process like rendering, two tools are ideally scoped. They capture the essential start and check functions without introducing unnecessary complexity.
The tools successfully cover the core lifecycle of requesting and monitoring a render job. The only minor gap is the lack of an explicit 'cancel' or 'update' operation for an existing job.
Maintenance
Related MCP Connectors
Create App Store screenshots, icons, ASO copy, localization, and revisions via hosted MCP.
Generate on-brand images from your AI agent: design, edit, and render templates over MCP.
Turn your app's screens into editable App Store and Google Play screenshot sets, from your agent.
Clean PNG/JPEG screenshots via REST or MCP, with goal-driven multi-step navigation.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server for ScreenshotFreeAPI – capture website screenshots, render HTML/PDF, and fetch app store listing screenshots from any MCP-compatible AI client.710 npmMIT
- AlicenseAqualityBmaintenanceAn MCP server that turns raw app screenshots into polished, pixel-perfect store listing visuals with device frames, benefit-driven headlines, brand colors, and exact store dimensions for iOS and Android.6249 npm27MIT
- AlicenseNot gradedqualityCmaintenancestdio bridge to the hosted ScreenMocks MCP server: design and export localized App Store / Play Store screenshots — device frames, 3D mockups, text, per-locale overrides across 48 locales, and a measured layout report the agent can verify its design against.MIT
- AlicenseNot gradedqualityCmaintenanceEnables coding agents to capture App Store and Google Play screenshots of real app UIs and produce editable, store-ready image sets.MIT