@appscreenshotstudio/mcp 0.3.1 → 0.4.1
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 +21 -2
- package/dist/index.js +99 -10
- package/package.json +1 -1
- package/skills/appscreenshotstudio/SKILL.md +10 -2
package/README.md
CHANGED
|
@@ -98,6 +98,24 @@ Make changes to an existing project with natural language. Optionally target spe
|
|
|
98
98
|
|
|
99
99
|
**Costs 5 credits.**
|
|
100
100
|
|
|
101
|
+
### `upload-screenshots`
|
|
102
|
+
|
|
103
|
+
Upload local app screenshots (from Simulator, emulator, or screen captures) into the device mockups of an existing project. Reads files from your local filesystem and places them into the device frames.
|
|
104
|
+
|
|
105
|
+
| Parameter | Type | Required | Description |
|
|
106
|
+
|---|---|---|---|
|
|
107
|
+
| `project_id` | string | Yes | From a previous `generate-screenshots` call |
|
|
108
|
+
| `screenshots` | array | Yes | Array of `{ file_path, card_index }` — maps local files to cards |
|
|
109
|
+
|
|
110
|
+
Each item in `screenshots`:
|
|
111
|
+
|
|
112
|
+
| Field | Type | Description |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| `file_path` | string | Absolute path to a local PNG, JPG, or WEBP file |
|
|
115
|
+
| `card_index` | number | Which card to place this screenshot on (0-based) |
|
|
116
|
+
|
|
117
|
+
**Free.**
|
|
118
|
+
|
|
101
119
|
### `render-screenshots`
|
|
102
120
|
|
|
103
121
|
Export to high-resolution PNGs. Returns download URLs.
|
|
@@ -153,7 +171,8 @@ Once installed, use `/appscreenshotstudio` in Claude Code or just ask "generate
|
|
|
153
171
|
| `iphone-6.9` | iPhone 16 Pro Max | 1260x2736 | App Store |
|
|
154
172
|
| `ipad-13` | iPad Pro 13" | 2064x2752 | App Store |
|
|
155
173
|
| `android-phone` | Android Phone | 1080x2340 | Play Store |
|
|
156
|
-
| `android-tablet-10` | Android Tablet
|
|
174
|
+
| `android-tablet-10` | Android Tablet 7" | 1200x1920 | Play Store |
|
|
175
|
+
| `apple-watch-ultra` | Apple Watch Ultra 2 | 410x502 | App Store |
|
|
157
176
|
|
|
158
177
|
## Design Features
|
|
159
178
|
|
|
@@ -171,7 +190,7 @@ The AI generates professional screenshots using:
|
|
|
171
190
|
1. **Research** — Agent calls `prepare-screenshot-brief`, then searches your codebase for app name, features, colors, screens, and audience
|
|
172
191
|
2. **Generate** — Agent calls `generate-screenshots` with `codebase_context` for app-specific designs
|
|
173
192
|
3. **Iterate** — Agent calls `edit-screenshots` to refine (codebase context carries over automatically)
|
|
174
|
-
4. **Upload** —
|
|
193
|
+
4. **Upload** — Agent calls `upload-screenshots` with local file paths to fill device mockups
|
|
175
194
|
5. **Export** — Agent calls `render-screenshots` or click "Download All" in the web app
|
|
176
195
|
|
|
177
196
|
## Security
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
import { existsSync, mkdirSync, copyFileSync } from 'node:fs';
|
|
5
|
+
import { existsSync, mkdirSync, copyFileSync, readFileSync } from 'node:fs';
|
|
6
6
|
import { join, dirname } from 'node:path';
|
|
7
7
|
import { homedir } from 'node:os';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
@@ -28,11 +28,13 @@ if (args[0] === 'install-skill') {
|
|
|
28
28
|
const API_BASE = process.env.APPSCREENSHOTSTUDIO_URL || 'https://appscreenshotstudio.com';
|
|
29
29
|
const API_KEY = process.env.APPSCREENSHOTSTUDIO_API_KEY;
|
|
30
30
|
// ─── Devices (mirrors lib/device-specs.ts) ─────────────────────────────────────
|
|
31
|
+
// ⚠️ Keep in sync: lib/device-specs.ts, mcp-server/README.md, docs/api page, docs/mcp page
|
|
31
32
|
const DEVICES = [
|
|
32
33
|
{ id: 'iphone-6.9', name: 'iPhone 16 Pro Max', width: 1260, height: 2736, category: 'iphone', required: true },
|
|
33
34
|
{ id: 'ipad-13', name: 'iPad Pro 13"', width: 2064, height: 2752, category: 'ipad', required: true },
|
|
34
35
|
{ id: 'android-phone', name: 'Android Phone', width: 1080, height: 2340, category: 'android-phone', required: true },
|
|
35
|
-
{ id: 'android-tablet-10', name: 'Android Tablet
|
|
36
|
+
{ id: 'android-tablet-10', name: 'Android Tablet 7"', width: 1200, height: 1920, category: 'android-tablet', required: true },
|
|
37
|
+
{ id: 'apple-watch-ultra', name: 'Apple Watch Ultra 2', width: 410, height: 502, category: 'apple-watch', required: true },
|
|
36
38
|
];
|
|
37
39
|
const VALID_DEVICE_IDS = DEVICES.map(d => d.id);
|
|
38
40
|
// ─── API helper ─────────────────────────────────────────────────────────────────
|
|
@@ -124,7 +126,7 @@ function buildDesignMessage(input) {
|
|
|
124
126
|
// ─── MCP Server ─────────────────────────────────────────────────────────────────
|
|
125
127
|
const server = new McpServer({
|
|
126
128
|
name: 'appscreenshotstudio',
|
|
127
|
-
version: '0.
|
|
129
|
+
version: '0.4.0',
|
|
128
130
|
});
|
|
129
131
|
// Tool 1: generate-screenshots
|
|
130
132
|
server.registerTool('generate-screenshots', {
|
|
@@ -244,9 +246,9 @@ Costs 5 credits per generation.`,
|
|
|
244
246
|
`Credits remaining: ${creditsRemaining}`,
|
|
245
247
|
'',
|
|
246
248
|
'Next steps:',
|
|
247
|
-
'1.
|
|
248
|
-
'2.
|
|
249
|
-
'3.
|
|
249
|
+
'1. Use upload-screenshots to add your app screenshots into the device frames',
|
|
250
|
+
'2. Use render-screenshots to export final PNGs',
|
|
251
|
+
'3. Or open the project URL in a browser to preview and adjust',
|
|
250
252
|
'',
|
|
251
253
|
chatData.suggestions?.length
|
|
252
254
|
? `Suggestions: ${chatData.suggestions.join(', ')}`
|
|
@@ -355,7 +357,7 @@ Example edit messages:
|
|
|
355
357
|
// Tool 3: render-screenshots
|
|
356
358
|
server.registerTool('render-screenshots', {
|
|
357
359
|
title: 'Render Screenshots to PNG',
|
|
358
|
-
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
|
|
360
|
+
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.',
|
|
359
361
|
inputSchema: z.object({
|
|
360
362
|
project_id: z.string().describe('Project ID to render'),
|
|
361
363
|
}),
|
|
@@ -690,7 +692,7 @@ This tool helps you gather the right information so generate-screenshots produce
|
|
|
690
692
|
if (platform === 'android' || platform === 'both') {
|
|
691
693
|
deviceTips.push('**Android (required for Play Store):**');
|
|
692
694
|
deviceTips.push('- Android Phone (android-phone): 1080×2340 — REQUIRED');
|
|
693
|
-
deviceTips.push('- Android Tablet
|
|
695
|
+
deviceTips.push('- Android Tablet 7" (android-tablet-10): 1200×1920 — optional');
|
|
694
696
|
deviceTips.push('');
|
|
695
697
|
}
|
|
696
698
|
// Schema reminder
|
|
@@ -730,6 +732,94 @@ This tool helps you gather the right information so generate-screenshots produce
|
|
|
730
732
|
}],
|
|
731
733
|
};
|
|
732
734
|
});
|
|
735
|
+
// Tool 8: upload-screenshots
|
|
736
|
+
server.registerTool('upload-screenshots', {
|
|
737
|
+
title: 'Upload App Screenshots',
|
|
738
|
+
description: `Upload local app screenshots (from Simulator, emulator, or screen captures) into the device mockups of an existing project. This lets you add real app UI into the device frames without leaving the terminal.
|
|
739
|
+
|
|
740
|
+
Reads files from your local filesystem, converts them to base64, and sets them on the device mockup elements in the specified cards.
|
|
741
|
+
|
|
742
|
+
Free — no credit cost. The screenshots are placed into the device frames that were created by generate-screenshots.
|
|
743
|
+
|
|
744
|
+
Workflow:
|
|
745
|
+
1. generate-screenshots → creates project with empty device frames
|
|
746
|
+
2. upload-screenshots → fills the device frames with your actual app UI
|
|
747
|
+
3. render-screenshots → exports final PNGs at App Store dimensions
|
|
748
|
+
|
|
749
|
+
Tips:
|
|
750
|
+
- Take screenshots from the iOS Simulator (Cmd+S) or Android emulator
|
|
751
|
+
- Use PNG format for best quality
|
|
752
|
+
- Screenshots are automatically fitted into the device frame
|
|
753
|
+
- You can upload different screenshots to different cards`,
|
|
754
|
+
inputSchema: z.object({
|
|
755
|
+
project_id: z.string().describe('Project ID from a previous generate-screenshots call'),
|
|
756
|
+
screenshots: z.array(z.object({
|
|
757
|
+
file_path: z.string().describe('Absolute path to a screenshot file on the local filesystem (PNG, JPG, or WEBP)'),
|
|
758
|
+
card_index: z.number().int().min(0).describe('Which card to place this screenshot on (0-based)'),
|
|
759
|
+
})).min(1).max(10)
|
|
760
|
+
.describe('Array of screenshots to upload, each mapped to a specific card index'),
|
|
761
|
+
}),
|
|
762
|
+
}, async ({ project_id, screenshots }) => {
|
|
763
|
+
// Read local files and convert to base64
|
|
764
|
+
const screenshotData = [];
|
|
765
|
+
const errors = [];
|
|
766
|
+
for (const { file_path, card_index } of screenshots) {
|
|
767
|
+
try {
|
|
768
|
+
if (!existsSync(file_path)) {
|
|
769
|
+
errors.push(`File not found: ${file_path}`);
|
|
770
|
+
continue;
|
|
771
|
+
}
|
|
772
|
+
const buffer = readFileSync(file_path);
|
|
773
|
+
const ext = file_path.toLowerCase().split('.').pop();
|
|
774
|
+
const mimeType = ext === 'jpg' || ext === 'jpeg' ? 'image/jpeg'
|
|
775
|
+
: ext === 'webp' ? 'image/webp'
|
|
776
|
+
: 'image/png';
|
|
777
|
+
const base64 = `data:${mimeType};base64,${buffer.toString('base64')}`;
|
|
778
|
+
screenshotData.push({ card_index, image_base64: base64 });
|
|
779
|
+
}
|
|
780
|
+
catch (err) {
|
|
781
|
+
errors.push(`Failed to read ${file_path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
if (screenshotData.length === 0) {
|
|
785
|
+
return {
|
|
786
|
+
content: [{
|
|
787
|
+
type: 'text',
|
|
788
|
+
text: `No screenshots could be read.\n\nErrors:\n${errors.join('\n')}`,
|
|
789
|
+
}],
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
// Upload to API
|
|
793
|
+
const res = await apiCall('POST', `/api/v1/projects/${project_id}/upload-screenshots`, {
|
|
794
|
+
screenshots: screenshotData,
|
|
795
|
+
});
|
|
796
|
+
if (!res.ok) {
|
|
797
|
+
return {
|
|
798
|
+
content: [{
|
|
799
|
+
type: 'text',
|
|
800
|
+
text: `Upload failed: ${JSON.stringify(res.data)}${errors.length ? `\n\nFile read errors:\n${errors.join('\n')}` : ''}`,
|
|
801
|
+
}],
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
const data = res.data.data;
|
|
805
|
+
const lines = [
|
|
806
|
+
`Uploaded ${data.uploaded} screenshot${data.uploaded !== 1 ? 's' : ''} into device mockups.`,
|
|
807
|
+
'',
|
|
808
|
+
];
|
|
809
|
+
for (const r of data.results) {
|
|
810
|
+
lines.push(` Card ${r.card_index + 1}: ${r.success ? 'OK' : r.error}`);
|
|
811
|
+
}
|
|
812
|
+
if (errors.length) {
|
|
813
|
+
lines.push('', 'File read warnings:', ...errors.map(e => ` ${e}`));
|
|
814
|
+
}
|
|
815
|
+
lines.push('', `Project URL: ${API_BASE}/builder/${project_id}`, '', 'Next steps:', '- Use render-screenshots to export final PNGs', '- Use edit-screenshots to adjust the design', '- Open the project URL to preview in the browser');
|
|
816
|
+
return {
|
|
817
|
+
content: [{
|
|
818
|
+
type: 'text',
|
|
819
|
+
text: lines.join('\n'),
|
|
820
|
+
}],
|
|
821
|
+
};
|
|
822
|
+
});
|
|
733
823
|
// ─── Start server ───────────────────────────────────────────────────────────────
|
|
734
824
|
function autoInstallSkill() {
|
|
735
825
|
try {
|
|
@@ -737,11 +827,10 @@ function autoInstallSkill() {
|
|
|
737
827
|
const src = join(__dir, '..', 'skills', 'appscreenshotstudio', 'SKILL.md');
|
|
738
828
|
const destDir = join(homedir(), '.claude', 'skills', 'appscreenshotstudio');
|
|
739
829
|
const dest = join(destDir, 'SKILL.md');
|
|
740
|
-
if (!existsSync(src)
|
|
830
|
+
if (!existsSync(src))
|
|
741
831
|
return;
|
|
742
832
|
mkdirSync(destDir, { recursive: true });
|
|
743
833
|
copyFileSync(src, dest);
|
|
744
|
-
console.error('Installed Claude Code skill to ~/.claude/skills/appscreenshotstudio/');
|
|
745
834
|
}
|
|
746
835
|
catch {
|
|
747
836
|
// Silent fail — skill install is optional
|
package/package.json
CHANGED
|
@@ -69,14 +69,21 @@ Call the `generate-screenshots` MCP tool with:
|
|
|
69
69
|
- `story_flow`: `"auto"` (default), `"hero-intro"`, `"problem-solution"`, `"benefit-first"`, etc.
|
|
70
70
|
- `codebase_context`: the full context object from Step 1
|
|
71
71
|
|
|
72
|
-
### Step 4:
|
|
72
|
+
### Step 4: Upload App Screenshots
|
|
73
|
+
|
|
74
|
+
If the user has actual app screenshots (from Simulator, emulator, or screen captures), upload them into the device frames using `upload-screenshots`:
|
|
75
|
+
- Takes local file paths and maps them to card indices
|
|
76
|
+
- Fills the empty device mockups with real app UI
|
|
77
|
+
- Free — no credit cost
|
|
78
|
+
|
|
79
|
+
### Step 5: Review and Iterate
|
|
73
80
|
|
|
74
81
|
Share the project URL and offer refinements using `edit-screenshots`:
|
|
75
82
|
- "Want to change any headlines or colors?"
|
|
76
83
|
- "Should I add a social proof card with ratings?"
|
|
77
84
|
- "Want to try a different layout style?"
|
|
78
85
|
|
|
79
|
-
### Step
|
|
86
|
+
### Step 6: Export
|
|
80
87
|
|
|
81
88
|
Call `render-screenshots` to export PNGs at exact App Store dimensions. This is free.
|
|
82
89
|
|
|
@@ -98,6 +105,7 @@ Headlines must pass the "one second test" — readable at thumbnail size.
|
|
|
98
105
|
| generate-screenshots | 5 credits |
|
|
99
106
|
| edit-screenshots | 5 credits |
|
|
100
107
|
| generate-background | 6 credits |
|
|
108
|
+
| upload-screenshots | free |
|
|
101
109
|
| render-screenshots | free |
|
|
102
110
|
| prepare-screenshot-brief | free |
|
|
103
111
|
| list-devices | free |
|