@appscreenshotstudio/mcp 0.4.4 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -200,7 +200,7 @@ The AI generates professional screenshots using:
200
200
  - **Frame color**: recolor the device frame — `natural` (default), `black`, `white`, `gold`. Requires Growth plan or higher.
201
201
  - **Panoramics**: slice one wide image across cards (chat tags the cards, then `generate-panoramic-background` creates and slices the image) or stretch a foreground element across adjacent cards (`apply_element_span`). Gallery gutters are accounted for.
202
202
  - **9 device perspectives**: flat, left-15, left-30, right-15, right-30, isometric, top-down, landscape-left, landscape-right
203
- - **14 layouts**: `text-top-device-bottom`, `text-top-device-tilted`, `device-hero`, `social-proof`, `review-clip`, `screen-hero`, `lifestyle-hero`, `photo-device-hero`, `feature-grid`, `before-after`, `stats-hero`, `metric-badge`, `annotated-feature`, `step-flow`. The AI varies `deviceScale`, `deviceSide`, `textPosition`, and `textAlign` per card so a set never looks like duplicates.
203
+ - **13 layouts**: `text-top-device-bottom`, `text-top-device-tilted`, `device-hero`, `social-proof`, `review-clip`, `screen-hero`, `lifestyle-hero`, `feature-grid`, `before-after`, `stats-hero`, `metric-badge`, `annotated-feature`, `step-flow`. The AI varies `deviceScale`, `deviceSide`, `textPosition`, and `textAlign` per card so a set never looks like duplicates.
204
204
 
205
205
  ## Workflow
206
206
 
@@ -219,6 +219,7 @@ The AI generates professional screenshots using:
219
219
 
220
220
  ## Links
221
221
 
222
+ - [Screenshot API + MCP overview](https://appscreenshotstudio.com/api)
222
223
  - [Full docs](https://appscreenshotstudio.com/docs/mcp)
223
224
  - [REST API reference](https://appscreenshotstudio.com/docs/api)
224
225
  - [Pricing](https://appscreenshotstudio.com/pricing)
package/dist/index.js CHANGED
@@ -38,6 +38,33 @@ const DEVICES = [
38
38
  { id: 'apple-watch-ultra', name: 'Apple Watch Ultra 2', width: 410, height: 502, category: 'apple-watch', required: true },
39
39
  ];
40
40
  const VALID_DEVICE_IDS = DEVICES.map(d => d.id);
41
+ // Aliases callers commonly pass instead of the canonical id: display-name
42
+ // derivations ("iPhone 16 Pro Max" -> iphone-16-pro-max) and legacy slugs.
43
+ // Mirrors MARKETING_TO_SPEC in lib/device-specs.ts — keep the two in sync.
44
+ const DEVICE_ALIASES = {
45
+ 'iphone-16-pro': 'iphone-6.9',
46
+ 'iphone-16-pro-max': 'iphone-6.9',
47
+ 'iphone-17-pro': 'iphone-6.3',
48
+ 'samsung-galaxy-s25-ultra': 'android-phone',
49
+ 'ipad-pro-13': 'ipad-13',
50
+ 'ipad-12.9': 'ipad-13',
51
+ 'ipad-pro-12.9': 'ipad-13',
52
+ 'android-tablet': 'android-tablet-10',
53
+ 'apple-watch': 'apple-watch-ultra',
54
+ };
55
+ /**
56
+ * Resolve a caller-supplied device id to a canonical one, or return the list of
57
+ * valid devices for a helpful error. Runs at the tool boundary so an unknown
58
+ * device fails fast (before a project is created and generation credits are
59
+ * spent) instead of surfacing late as a render-time "Unknown device".
60
+ */
61
+ function resolveDeviceId(input) {
62
+ const normalized = DEVICE_ALIASES[input] ?? input;
63
+ if (VALID_DEVICE_IDS.includes(normalized))
64
+ return { id: normalized };
65
+ const options = DEVICES.map(d => `${d.id} (${d.name})`).join(', ');
66
+ return { error: `Unknown device "${input}". Valid devices: ${options}.` };
67
+ }
41
68
  // ─── API helper ─────────────────────────────────────────────────────────────────
42
69
  async function apiCall(method, path, body) {
43
70
  if (!API_KEY) {
@@ -127,7 +154,7 @@ function buildDesignMessage(input) {
127
154
  // ─── MCP Server ─────────────────────────────────────────────────────────────────
128
155
  const server = new McpServer({
129
156
  name: 'appscreenshotstudio',
130
- version: '0.4.4',
157
+ version: '0.5.2',
131
158
  });
132
159
  // Tool 1: generate-screenshots
133
160
  server.registerTool('generate-screenshots', {
@@ -138,7 +165,7 @@ IMPORTANT: Before calling this tool, research the user's codebase to populate th
138
165
 
139
166
  The AI picks a narrative arc that fits the app's sell angle (trust-first for finance/health, visual-first for creative/lifestyle, problem-first for pain-relief apps, numbers-led for SaaS/analytics, community-first for social, feature-forward for multi-mode apps) and assigns a job to each card: HOOK → EDUCATE → PROVE → CONVERT.
140
167
 
141
- 14 layout types available per card:
168
+ 13 layout types available per card:
142
169
  - text-top-device-bottom: headline top, flat device bottom (feature/educate)
143
170
  - text-top-device-tilted: headline left, tilted device right (or mirrored)
144
171
  - device-hero: headline + large centered device, product-forward
@@ -146,7 +173,6 @@ The AI picks a narrative arc that fits the app's sell angle (trust-first for fin
146
173
  - review-clip: rating-statement headline + stars + quote + bottom-clipped device
147
174
  - screen-hero: top-clipped device + centered headline + optional trust stat
148
175
  - lifestyle-hero: full-bleed photo background + text overlay (no device)
149
- - photo-device-hero: full-bleed photo background + headline overlay + flat device
150
176
  - feature-grid: headline + 2×2 or 2×3 icon+label grid, no device
151
177
  - before-after: dark before-half + bright after-half (transformation apps)
152
178
  - stats-hero: giant centered stat(s), no device, numbers-led
@@ -210,10 +236,16 @@ Costs 5 credits per generation.`,
210
236
  .describe('Context gathered from researching the app codebase. Dramatically improves screenshot quality — the more detail here, the better the output.'),
211
237
  }),
212
238
  }, async (input) => {
239
+ // Resolve/validate the device up front so an unknown id fails fast here
240
+ // instead of after a project (and its 5 generation credits) is spent.
241
+ const resolved = resolveDeviceId(input.device_id);
242
+ if ('error' in resolved) {
243
+ return { content: [{ type: 'text', text: resolved.error }] };
244
+ }
213
245
  // Step 1: Create project (with codebase context if provided)
214
246
  const projectName = `${input.app_name} Screenshots`;
215
247
  const createBody = {
216
- device_id: input.device_id,
248
+ device_id: resolved.id,
217
249
  name: projectName,
218
250
  };
219
251
  if (input.codebase_context) {
@@ -274,13 +306,13 @@ What you can change:
274
306
  - Text: headlines, subtitles, badge text, font size, font family (Inter, Poppins, Montserrat, DM Sans, Space Grotesk, etc.)
275
307
  - Text styling: per-word color, bold, italic, underline, highlight pills (colored background behind words), gradient text, text stroke outlines
276
308
  - Colors: brand palette, gradient backgrounds, accent colors, text colors
277
- - Layouts (14 types): text-top-device-bottom, text-top-device-tilted, device-hero, social-proof, review-clip, screen-hero, lifestyle-hero, photo-device-hero, feature-grid, before-after, stats-hero, metric-badge, annotated-feature, step-flow. The AI picks a narrative arc (HOOK → EDUCATE → PROVE → CONVERT) across the set.
309
+ - Layouts (13 types): text-top-device-bottom, text-top-device-tilted, device-hero, social-proof, review-clip, screen-hero, lifestyle-hero, feature-grid, before-after, stats-hero, metric-badge, annotated-feature, step-flow. The AI picks a narrative arc (HOOK → EDUCATE → PROVE → CONVERT) across the set.
278
310
  - Layout params: deviceScale (small/medium/large), deviceSide (left/right), textPosition (above/below), textAlign (left/center)
279
311
  - Device mockups: perspective variants (flat, left-15, right-15, left-30, right-30, isometric, top-down, landscape-left, landscape-right), 2D rotation, resize, reposition
280
312
  - Frame color: recolor the device frame — "natural" (default), "black", "white", "gold". Examples: "make the iPhone gold", "black titanium finish", "white iPhone". Requires Growth plan or higher.
281
313
  - Switch devices: "make this for Apple Watch" / "duplicate for Android tablet" clones the project at the target device's canvas size
282
314
  - Add/remove cards: add a social proof card, remove card 3, add a marketing title card
283
- - Compound fields (auto-positioned): statRow, laurelStat, pressBanner, starRating, quote, featureGrid, beforeAfterSplit
315
+ - Compound fields (auto-positioned): statRow, laurelStat, pressBanner, starRating, quote, featureGrid, beforeAfterSplit, stepList
284
316
  - Panoramic backgrounds: one wide AI or Pexels image sliced across multiple cards ("pano the background across cards 1-3"). The edit only tags the cards; call generate-panoramic-background afterwards to create and slice the wide image.
285
317
  - Panoramic element spans: stretch a foreground image, device-mockup, or shape across adjacent cards ("pano the device across cards 1-2")
286
318
  - Floating elements: add/edit badges, star ratings
@@ -377,7 +409,7 @@ Example edit messages:
377
409
  // Tool 3: render-screenshots
378
410
  server.registerTool('render-screenshots', {
379
411
  title: 'Render Screenshots to PNG',
380
- description: 'Export a screenshot project to high-resolution PNG files at exact App Store dimensions. Returns download URLs for each card. Free no credit cost. Note: device mockups will show empty frames unless app screenshots have been uploaded via upload-screenshots first.',
412
+ description: 'Export a screenshot project to high-resolution PNG files at exact App Store dimensions. Returns download URLs for each card. Free (no credit cost). Rendering blocks until the PNGs are ready: expect roughly 20-40s for iPhone sets and 60-120s for iPad (the larger canvas renders slower), so allow up to ~2 minutes before treating it as failed. Note: device mockups will show empty frames unless app screenshots have been uploaded via upload-screenshots first.',
381
413
  inputSchema: z.object({
382
414
  project_id: z.string().describe('Project ID to render'),
383
415
  }),
@@ -389,16 +421,34 @@ server.registerTool('render-screenshots', {
389
421
  };
390
422
  }
391
423
  const data = res.data.data;
392
- return {
393
- content: [{
394
- type: 'text',
395
- text: [
396
- `Rendered ${data.images?.length || 0} screenshots:`,
397
- '',
398
- ...(data.images || []).map((img, i) => `Card ${i + 1}: ${img.url} (${img.width}×${img.height})`),
399
- ].join('\n'),
400
- }],
401
- };
424
+ const images = data.images || [];
425
+ // Text block: full-resolution download URLs (for export / saving to disk).
426
+ const content = [
427
+ {
428
+ type: 'text',
429
+ text: [
430
+ `Rendered ${images.length} screenshot${images.length === 1 ? '' : 's'}:`,
431
+ '',
432
+ ...images.map((img, i) => `Card ${i + 1}: ${img.url} (${img.width}×${img.height})`),
433
+ '',
434
+ 'Previews are shown below. To compare all cards side by side at full size,',
435
+ 'refine by hand, or export, open the project URL in the builder.',
436
+ ].join('\n'),
437
+ },
438
+ ];
439
+ // Image blocks: downscaled inline previews so image-capable agents
440
+ // (Claude Code, Cursor) display the screenshots in-chat. The API returns
441
+ // each preview as a `data:<mime>;base64,<data>` URL; MCP image content
442
+ // needs the raw base64 + mimeType, so split it out.
443
+ for (const img of images) {
444
+ if (!img.preview)
445
+ continue;
446
+ const match = /^data:(image\/[a-zA-Z+]+);base64,(.+)$/.exec(img.preview);
447
+ if (!match)
448
+ continue;
449
+ content.push({ type: 'image', mimeType: match[1], data: match[2] });
450
+ }
451
+ return { content };
402
452
  });
403
453
  // Tool 4: list-devices
404
454
  server.registerTool('list-devices', {
@@ -760,7 +810,7 @@ This tool helps you gather the right information so generate-screenshots produce
760
810
  if (platform === 'android' || platform === 'both') {
761
811
  deviceTips.push('**Android (required for Play Store):**');
762
812
  deviceTips.push('- Android Phone (android-phone): 1080×2340 — REQUIRED');
763
- deviceTips.push('- Android Tablet 7" (android-tablet-10): 1200×1920 — optional');
813
+ deviceTips.push('- Android Tablet 7" (android-tablet-10): 1200×1920 — REQUIRED');
764
814
  deviceTips.push('');
765
815
  }
766
816
  // Schema reminder
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@appscreenshotstudio/mcp",
3
- "version": "0.4.4",
3
+ "version": "0.5.2",
4
4
  "description": "MCP server for generating App Store screenshots via AppScreenshotStudio",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "homepage": "https://appscreenshotstudio.com/docs/mcp",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "https://github.com/appscreenshotstudio/mcp-server"
10
+ "url": "https://github.com/TWWorks-org/mcp-server"
11
11
  },
12
12
  "keywords": [
13
13
  "mcp",
@@ -2,7 +2,7 @@
2
2
  name: appscreenshotstudio
3
3
  version: 1.0.0
4
4
  description: Generate App Store screenshots by researching the codebase and calling AppScreenshotStudio MCP tools. Use when the user mentions "screenshots", "App Store", "Play Store", "store listing", or wants to create marketing screenshots for their app.
5
- allowed_tools:
5
+ allowed-tools:
6
6
  - Read
7
7
  - Glob
8
8
  - Grep
@@ -76,16 +76,22 @@ If the user has actual app screenshots (from Simulator, emulator, or screen capt
76
76
  - Fills the empty device mockups with real app UI
77
77
  - Free — no credit cost
78
78
 
79
- ### Step 5: Review and Iterate
79
+ ### Step 5: Show and Iterate (the core loop)
80
80
 
81
- Share the project URL and offer refinements using `edit-screenshots`:
82
- - "Want to change any headlines or colors?"
83
- - "Should I add a social proof card with ratings?"
84
- - "Want to try a different layout style?"
81
+ This is conversational refinement, so iterate right here in the chat. Don't send the user away to look at links.
82
+
83
+ 1. **Show.** Call `render-screenshots` (free) after generating. It returns inline image previews, so the screenshots display directly in the conversation. Show them.
84
+ 2. **Refine.** Let the user react in plain language and apply changes with `edit-screenshots`:
85
+ - "Want any headlines or colors changed?"
86
+ - "Should I add a social proof card with ratings?"
87
+ - "Different layout style?"
88
+ 3. **Re-show.** Call `render-screenshots` again to display the updated set inline. Repeat the show → refine → re-show loop until the user is happy.
89
+
90
+ Hand off to the builder only when it genuinely helps: share the project URL and frame it as the place to **compare all cards side by side at full size, nudge things by hand, or export**. It is the compare-and-export step, not the required destination. Coarse, language-expressible edits ("warmer background", "swap the headline") are faster to do right here in chat.
85
91
 
86
92
  ### Step 6: Export
87
93
 
88
- Call `render-screenshots` to export PNGs at exact App Store dimensions. This is free.
94
+ `render-screenshots` is also the export: it returns download URLs for the final PNGs at exact App Store dimensions, and it is free. Give the user those URLs. The builder project URL is the alternative when they want to compare the full set visually or hand-tweak before downloading.
89
95
 
90
96
  ## Headline Rules
91
97