shotforge-mcp
Generates upload-ready App Store screenshot images and App Preview videos, including per-page/per-language outputs, iPhone/iPad size formats, and App Store Connect-compatible folder layouts.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
shotforge
App Store screenshots from your real app screens — decided and written by your own Claude. Give shotforge your screenshots; Claude looks at them and proposes the design (main colour, text/accent colour, number of pages, 2D or 3D template) and writes the headline copy in every language you want. You can fix any of those yourself, and whatever you fix is kept exactly. The output is one separate, upload-ready image per page per language (1320×2868 for iPhone 6.9″) — never one combined image.
Türkçe okumak için: README.tr.md

Features
Claude does the thinking, locally rendered. Colours, page count, template and copy are decided by Claude from the screenshots; rendering is pure Python (Pillow + numpy). No design service, no account, no telemetry.
Three ways to bring your own Claude: the
claudeCLI (Claude Code login), an Anthropic API key, or MCP (Claude Desktop, Claude Code, Cursor, …) where your chat Claude is the designer.You stay in control. Pass any of: main background colour, text colour, accent colour, page count, your own headlines (full or partial), 2D/3D, or a template. Everything you give is kept verbatim; Claude (or the built-in rules) fills the rest.
7 templates, 2D and 3D. 2D = phone flat or rotated only in the plane; 3D = phone tilted in perspective with visible thickness. Automatic selection follows documented rules (
shotforge rules) and never picks a template whose theme clashes with your colour.Asks before it starts. The slash command, MCP tools and terminal share one question list; anything left blank gets a default, with colours taken from your screenshots.
App Store and Google Play from one run: phone and tablet sizes, App Store Header and Search Results images, and the Play feature graphic.
Multi-language in one run (
--langs en,tr,de): one folder per language plus a zip, optional per-language screenshots, App Preview video converter.Brand file:
shotforge.tomlkeeps colours, font, logo and tone, so every run and every app looks the same.Maestro capture:
shotforge captureruns your flows per language on a booted device and writes the screenshots shotforge reads.Store tests:
--variants 2writes complete sets that differ by copy, design or both, ready for Custom Product Pages and Play experiments.fastlane folders:
--layout fastlanewrites the treesdeliverandsupplyupload. shotforge itself uploads nothing.ASO copy:
--keywordstells the AI which search terms to work into the headlines.Readable by construction: unreadable text colours are corrected per slide (contrast ≥ 3:1 for headlines) and reported.
Related MCP server: MagicScreenshots
Install
Requires Python 3.10+.
# CLI
pipx install "git+https://github.com/ibrahimatmaca/shotforge"
# CLI + MCP server
pipx install "shotforge[mcp] @ git+https://github.com/ibrahimatmaca/shotforge"
# or run without installing (needs uv)
uvx --from "shotforge[mcp] @ git+https://github.com/ibrahimatmaca/shotforge" shotforge-mcp
shotforge doctor # checks Python deps, ffmpeg (optional), claude CLI / API keysQuick start
shotforgeRun it on its own in a terminal. It asks where your screenshots are, then everything else, including who writes the headlines (AI, you, or a file). Press Enter to accept a default.
In Claude Code, install the slash command once with shotforge install-claude --global, then type /store-shots. The questions appear in the conversation.
AI-written headlines need claude auth login or ANTHROPIC_API_KEY. Without either, shotforge tells you at the start and you write the headlines yourself.
With flags
# 1) Let Claude decide everything (uses your logged-in `claude` CLI, or ANTHROPIC_API_KEY)
shotforge create ./screens --app "Habita" --about "Habit tracker with weekly stats" --langs en,tr --no-ask -o out
# Not using Claude? Add: --ai openai (needs OPENAI_API_KEY and `pip install openai`)
# 2) Fix the choices you care about; Claude fills the rest
shotforge create ./screens --app "Habita" --dimension 3d --bg-color "#0B1026" --accent "#F472B6" --count 6 -o out
# 3) Write your own copy (partial is fine) — see "Your own text" below
shotforge create ./screens --app "Habita" --texts my-texts.txt -o out
# 4) Answer questions in the terminal (Enter = let Claude decide)
shotforge create ./screens --app "Habita" --askResult, as separate files per language:
out/
en/
app-store/
iphone-6.9/01_en.png …
header-search/5244x2950.png, 3840x2560.png, 1920x1280.png
previews/iphone-6.9.mp4 # only if you pass --preview
google-play/
phone/01_en.png …
feature-graphic/1024x500.png
tr/ …
manifest.json # every file, its size, the decisions and warnings
habita.zip # en/, tr/, manifest.json
shotforge.copy.json, _review/ # not in the zipWithout -o, output goes to ./shotforge-out/<app>/. Add --sheet for a single side-by-side _review/overview_<lang>.jpg
(a review aid, not a deliverable) and --brief for a copy-paste prompt to recreate the set in Claude Design.
What it asks, and the defaults
Question | Flag | If left blank |
Screenshots |
| required, asked again until given |
Store |
| both |
Header and Search Results images (App Store) |
| all three |
Languages |
| en, tr |
2D, 3D or a template |
| chosen by the rules |
Device sizes |
| iphone-6.9, android-phone |
Pages |
| 6–7 |
Headlines and tone |
| written by Claude |
Background, text, accent colour |
| from the screenshots; template default if they are neutral |
App icon for the wide images |
| none |
App Preview recording, shared or per language |
| skipped |
Output |
|
|
--no-ask skips the questions and uses these defaults. Passing --device draws that one device with the old out/<lang>/ layout, no store folders or zip.
Separate screenshots per language or platform: put them in <folder>/tr/, <folder>/android/, <folder>/android/tr/, <folder>/ipad/ or <folder>/android-tablet/, with the same file names. shotforge warns when it has to fall back, for example to an English UI on a Turkish page.
Store notes:
Google Play takes up to 8 images per device type and at least 4 for tablets; extra pages are dropped with a warning.
Google's guidance recommends against device imagery, taglines over 20% of the image, and words like "Best" or "Free". It is a recommendation, not a requirement for phones and tablets, but it can affect where the listing is featured, so shotforge warns on every Play run.
Per third-party guides, 5244x2950 works for both the App Store header and search results (PNG only), while 3:2 sizes work for search results only. Check the crop in App Store Connect's preview; shotforge keeps text near the centre.
App Preview needs ffmpeg and is App Store only; Google Play takes a YouTube link.
Who decides what
Decision | You fix it with | If you don't |
Main background colour |
| Claude picks one from the app's look (local colour analysis as a hint) |
Text colour |
| automatic, readable on every slide |
Accent colour |
| Claude / derived from the background |
Number of pages |
| Claude picks 6 or 7 |
Copy |
| Claude writes it, looking at each screenshot |
2D / 3D |
| rules / Claude decide |
Template |
| rules / Claude decide |
If you fix everything, Claude is not called at all. If you fix a background colour, Claude's template choice is overridden when its
theme clashes with that colour (the reason is printed). Results are written to shotforge.copy.json; edit it and run
shotforge render to redraw without calling Claude again.
Your own text
# slide 1
shot: 01_home.png (optional)
en: Build habits that *stick* | Your whole day on one calm screen
tr: Kalıcı *alışkanlıklar* edin | Tüm günün tek sakin ekranda
# slide 2
tr: Gününü *planla* (missing 'en' -> Claude writes it)*word* = accent colour · | … = subtitle · \n = line break. JSON works too. Example: examples/texts.example.txt.
Templates: 2D vs 3D
Template | Theme | Suits | |
2D |
| colorful | education, lifestyle, productivity, health |
2D |
| dark | fitness, health, finance, utilities |
2D |
| dark | health, fitness, productivity, utilities |
2D |
| dark | social, entertainment, productivity |
3D |
| colorful | entertainment, lifestyle, travel, shopping, social, photo |
3D |
| light | lifestyle, shopping, travel, photo, education, social |
3D |
| dark | games, entertainment, photo, fitness, social |
Automatic choice (--template auto, see shotforge rules; try shotforge analyze ./screens --category health):
3D score = +2 for games/photo/travel/shopping/entertainment/lifestyle, −2 for finance/productivity/utilities/health (−1 fitness/education),
+1 for ≤ 3 distinct screenshots, −2 for dense small-text UIs, +1 for a premium/playful/creative tone → 3D when ≥ 1, else 2D.
Inside the family: +3 theme match (dark colour → dark template, very light → light, vivid mid-tone → colorful), +3 category match.
--template disables the auto choice; --dimension restricts it.
Per-slide layouts, colours and decorations come from shotforge/templates/*.json (palette, bg_mode, layouts, defaults with
$bg/$accent/$text placeholders). Copy one, edit it, and pass --template my.json.
Use it from your own Claude via MCP
shotforge-mcp is a stdio MCP server. In MCP mode your chat Claude is the designer: it looks at the screenshots, asks you
what you want to fix, writes the copy, and calls the tools; shotforge renders and returns an overview image so Claude can check
its own work. No API key is needed.
Run shotforge mcp to see the setup steps, the tools and whether the server can start.
# Claude Code
claude mcp add shotforge -- shotforge-mcp
# (without installing: claude mcp add shotforge -- uvx --from "shotforge[mcp] @ git+https://github.com/ibrahimatmaca/shotforge" shotforge-mcp)Claude Desktop / Cursor / any MCP client (claude_desktop_config.json or the client's MCP settings):
{
"mcpServers": {
"shotforge": {
"command": "uvx",
"args": ["--from", "shotforge[mcp] @ git+https://github.com/ibrahimatmaca/shotforge", "shotforge-mcp"]
}
}
}(If you installed with pipx, use "command": "shotforge-mcp" and no args.)
Tool | Purpose |
| local colour/theme/density analysis + rule-based 2D/3D recommendation + rules and template catalogue |
| templates with dimension, theme and suited categories |
| takes Claude's/your decisions ( |
| redraw from |
| screen recording → App Store app-preview spec (ffmpeg) |
A prompt named store_screenshots walks Claude through the whole flow. Then just say:
"Make App Store screenshots from ~/Desktop/habita-screens for my app Habita, English and Turkish, 3D."
Output goes to ~/shotforge-out by default.
Claude Code slash command
shotforge install-claude --global # writes ~/.claude/commands/store-shots.mdType /store-shots in Claude Code, in the terminal or the desktop app. It asks for your screenshots, app name and the questions above in the conversation, runs
shotforge create, opens the overview images and fixes problems it finds. You can also give them up front: /store-shots ./screens "Habita" "habit tracker".
Brand file
Put shotforge.toml in your project (see examples/shotforge.toml). create, plan and render find it in the current folder
or a parent, up to the repository root; --brand FILE picks another one and --no-brand ignores it. Flags win over the file, and the file wins over the AI.
[brand]
tone = "calm, direct, benefit-first"
template = "bubble"
langs = ["en", "tr"]
font = "assets/Brand-Bold.otf" # relative to this file, must stay inside its folder
logo = "assets/logo.png" # small, in the free band beside the headline; header icon unless --icon is given
[brand.colors]
background = "#6D28D9"
text = "#FFFFFF"
accent = "#FDE047"render keeps the design in the copy file and takes only font and logo from the brand file. To restyle hand-edited colours, use the render flags.
Keywords
shotforge create ./screens --app Habita --keywords "habit tracker,daily routine"The AI works the terms in where they read naturally and within the length limits, and shotforge lists any not found word for word (a localized term can be the reason). Offline mode writes placeholder copy and can't use them. Apple doesn't document screenshot text as a search ranking factor, so keep filling the App Store keyword field; treat this as matching your headlines to what people searched for. Google Play's guidelines advise against words like "Best", "#1" and "Free" in images, and shotforge warns about them.
Store test variants
shotforge create ./screens --app Habita --variants 3 --variant-by both -o out
# out/variant-a/, out/variant-b/, out/variant-c/ — each with its own copy file, manifest, zip and images--variant-by copy keeps the design of variant A and gives each variant another messaging angle. design keeps A's text and colours, uses another template, and tries the other of 2D/3D for B unless
you set --dimension; no further AI call is made. both (default) changes both. --template sets variant A only. Different copy needs an AI backend: offline runs warn that the headlines are the same.
Design questions are not asked with --variants, so pass choices as flags. Upload each folder as its own Custom Product Page or Play experiment.
Maestro capture
shotforge doesn't know your app's screens. Your Maestro flow decides which pages are captured: every takeScreenshot is one page, and the flow taps its way there. shotforge runs that flow per language and collects the PNGs. It doesn't boot a device, install the app or change the device language.
1. Install Maestro and your app. Install Maestro, then install a build of your app on a simulator or emulator. shotforge doctor shows whether Maestro and a booted device are found.
2. Choose the pages. Pick the 6–8 screens that sell the app, in the order you want to show them. Google Play takes at most 8 images per device type, and the App Store at most 10.
3. Find what to tap. Use Maestro Studio (right-click an element on the device) or maestro hierarchy in a terminal. Prefer id over visible text, because text changes with the language. An id may need adding to your app, such as accessibilityIdentifier on iOS.
4. Write one flow in its own folder, so your normal test runs don't pick it up:
# .maestro/shots/store.yaml
appId: com.example.habita
---
- launchApp:
clearState: true
permissions:
all: allow
- runFlow: login.yaml # if the screens need an account; use a test account
- extendedWaitUntil:
visible:
id: "home_list"
timeout: 15000
- takeScreenshot: 01_home
- tapOn:
id: "tab_stats"
- waitForAnimationToEnd
- takeScreenshot: 02_stats
- tapOn:
id: "tab_goals"
- waitForAnimationToEnd
- takeScreenshot: 03_goalsNumber the names: the number sets the page order. Use the same names in every language, because shotforge matches screens by file name.
Keep the pages in one file. Maestro runs the flows in a folder in no fixed order and ignores subfolders.
clearStatesigns the app out, so the flow has to log in again, or removeclearState.Use test data with realistic content. The screens are published as they are.
For iPhone and iPad, or for iOS and Android, write separate flows if the navigation differs, and capture with
--platform ios,ipad,androidorandroid-tablet.
5. Capture in each language. Maestro sets the language on the device, not in the flow, so use one of these:
A. One device per language (works without changing your app). Start each device, install the app on it if it's new, and capture that language. Keep one device running at a time, or pass --device <id>:
maestro start-device --platform ios --device-locale en_US
shotforge capture --flows .maestro/shots/store.yaml --langs en --platform ios -o shots
maestro start-device --platform ios --device-locale tr_TR
shotforge capture --flows .maestro/shots/store.yaml --langs tr --platform ios -o shotsB. Your app reads the language at launch (one device, one command). shotforge passes each language to the flow as ${LANG}. Send it as a launch argument, and have a debug build of your app read it (UserDefaults on iOS, intent extras on Android) and switch language:
- launchApp:
arguments:
appLanguage: ${LANG}shotforge capture --flows .maestro/shots/store.yaml --langs en,tr --platform ios -o shots6. Check the screenshots. Open shots/ios/tr/ and confirm the UI really is in Turkish: a language that didn't switch still produces images, with no error. shotforge warns about missing names (within one run), about shapes that would be cropped, and about older PNGs in the folder, which it leaves in place and which would become slides.
7. Create the images:
shotforge create shots --app Habita --langs en,trWith option B you can do steps 5 and 7 in one command: shotforge create shots --maestro .maestro/shots/store.yaml --capture-platform ios --app Habita --langs en,tr.
fastlane
shotforge create ./screens --app Habita --layout fastlane -o store
fastlane deliver --screenshots_path store/fastlane/screenshots --skip_binary_upload --skip_metadata --overwrite_screenshots
fastlane supply --metadata_path store/fastlane/metadata/android --skip_upload_apk --skip_upload_aab --skip_upload_metadata --skip_upload_changelogsstore/fastlane/screenshots/en-US/APP_IPHONE_67_iphone-6.9_01_en.png # deliver finds the device from the image size
store/fastlane/metadata/android/en-US/images/phoneScreenshots/01_en.png # also sevenInchScreenshots, tenInchScreenshots
store/fastlane/metadata/android/en-US/images/featureGraphic.png
store/app-store-extra/en/header-search/5244x2950.png # deliver doesn't upload these
store/en/app-store/previews/iphone-6.9.mp4 # App Previews, if any: upload these yourselfLanguage codes become store locales (en → en-US, tr → tr on Apple and tr-TR on Play). Check a new device size against your fastlane version; both tools change with the stores.
App Store Connect
shotforge create ./screens --app Habita --store appstore --header-sizes no --layout asc -o media
# media/en-US/APP_IPHONE_67/01_en.png, media/tr/APP_IPHONE_67/… — works with folder-based uploaders such as
# asc apps media upload com.example.MyApp --folder media/ --replace (keremerkan/asc-cli)
shotforge preview recording.mov -o preview.mp4 # 886x1920, 30 fps, H.264/AAC, ≤ 30 s (needs ffmpeg)--layout asc folder names: iphone-6.9 → APP_IPHONE_67, iphone-6.5 → APP_IPHONE_65, ipad-13 → APP_IPAD_PRO_3GEN_129;
en → en-US. Check them against your uploader's docs — Apple changes these identifiers over time. shotforge sizes prints the sizes.
App previews are plain screen recordings (no frame added).
Backends, privacy and cost
| What runs |
|
|
|
|
| Anthropic API with your key ( |
| OpenAI Responses API with |
| no AI: local rules decide design, placeholder copy |
Screenshots leave your machine only toward the AI you configured (your Claude Code account, your Anthropic or OpenAI API key, or your MCP host) —
shotforge itself has no server and no telemetry. The OpenAI backend sends store: false, so responses are not kept for later retrieval; your
OpenAI account's data terms still apply. Usage counts against your plan or API billing. The model's answer is validated
(page count, file names, template name, hex colours, empty titles) and retried once; remaining problems are repaired by the rules.
Status and known limitations
Beta (v0.5). CI runs the test-suite on Linux with Python 3.10–3.14 on every push and PR, and weekly on macOS with Python 3.13.
The
claude -ppath is covered by tests against a fakeclaudeexecutable that mimics Claude Code's JSON envelope; please report anything that differs with your real installation. The MCP server was exercised with the official MCP client onmcp1.30 and 2.3.Linux/macOS are tested; Windows is untested.
Device frames are generic modern-phone drawings, not Apple's official bezels. ~5–6 s per image.
Headlines: ≤ 3 lines, subtitles ≤ 2 lines; long text shrinks automatically, and text that still overflows is reported. The bundled Inter font has no Japanese, Korean or Arabic glyphs: shotforge warns, and
--fontselects another font (Arabic also needs Pillow with raqm). Screenshot analysis is a simple heuristic (a hint, not a verdict).Tablet output crops a phone screenshot to the tablet ratio; supply real tablet screens. Android output reuses iOS screens unless you supply
android/.Arabic and Hebrew are not laid out right to left. The App Store header-only 3840x1646 size is not generated.
Development
git clone https://github.com/ibrahimatmaca/shotforge && cd shotforge
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest -qSee CONTRIBUTING.md.
Credits and disclaimer
Bundled font: Inter (SIL Open Font License 1.1, see
shotforge/fonts/LICENSE-Inter.txt).Template art direction was inspired by publicly viewable template galleries such as AppScreens'. shotforge is an independent project and is not affiliated with or endorsed by AppScreens, Apple or Anthropic. All templates are original code; no third-party assets are included. "App Store" and "iPhone" are trademarks of Apple Inc.; "Claude" is a trademark of Anthropic.
License
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Generate exact-size App Store and Google Play screenshots, feature graphics, and listing copy.
AI-designed App Store screenshot sets from your app's screens, uploaded to App Store Connect.
Generate and edit images and create short videos inside Claude. Prepaid credits, no subscription.
Create and edit app store screenshot projects with AI, then export in the web editor.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to create editable app store screenshot projects, manage authorized assets, review and correct designs with browser tools, and provide editor links for website export.MIT

MagicScreenshotsofficial
AlicenseNot gradedqualityCmaintenanceEnables AI agents to search a daily-updated library of real App Store screenshots, preview videos and listing history from thousands of top apps by category, chart, look or app name. It also generates and localizes the user's own App Store screenshots at App Store resolution, restyled after any app in the library.MIT- AlicenseAqualityAmaintenanceConnects Claude to Apple's App Store Connect API, letting you manage apps, builds, TestFlight beta groups and testers, customer reviews and replies, sales and finance reports, and team users through natural language. Write actions such as invites, beta review submissions, and review responses require confirmation before anything is sent.22447 npm1MIT
- AlicenseNot gradedqualityCmaintenanceEnables agents to design App Store and Google Play screenshot sets from templates or simulator captures, translate captions into 41 languages with automatic text fitting, render the pixels, and publish straight to App Store Connect or Google Play.1MIT