@appscreenshotstudio/mcp 0.3.0 → 0.4.0

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
@@ -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.
@@ -136,27 +154,15 @@ Show all supported device specs. No API call needed.
136
154
 
137
155
  **Free.**
138
156
 
139
- ## Prompts
140
-
141
- MCP prompts are pre-defined workflows your agent can follow.
142
-
143
- ### `create-app-screenshots`
157
+ ## Claude Code Skill
144
158
 
145
- Full guided workflow: research the codebase, generate screenshots with rich context, iterate, and export. Best results when used from within the app's project directory.
146
-
147
- | Argument | Default | Description |
148
- |---|---|---|
149
- | `platform` | ios | "ios", "android", or "both" |
150
- | `extra_instructions` | none | Additional instructions like "use dark theme" |
159
+ The MCP server auto-installs a Claude Code skill on first startup. The skill teaches Claude a structured research-first workflow for better screenshot results. You can also install it manually:
151
160
 
152
- ### `improve-screenshots`
153
-
154
- Research the codebase and improve an existing screenshot project. Compares current designs to the actual app and makes targeted fixes.
161
+ ```bash
162
+ npx @appscreenshotstudio/mcp install-skill
163
+ ```
155
164
 
156
- | Argument | Required | Description |
157
- |---|---|---|
158
- | `project_id` | Yes | Project ID to improve |
159
- | `focus` | No | What to focus on: "headlines", "colors", "story flow", etc. |
165
+ Once installed, use `/appscreenshotstudio` in Claude Code or just ask "generate App Store screenshots for my app".
160
166
 
161
167
  ## Supported Devices
162
168
 
@@ -183,7 +189,7 @@ The AI generates professional screenshots using:
183
189
  1. **Research** — Agent calls `prepare-screenshot-brief`, then searches your codebase for app name, features, colors, screens, and audience
184
190
  2. **Generate** — Agent calls `generate-screenshots` with `codebase_context` for app-specific designs
185
191
  3. **Iterate** — Agent calls `edit-screenshots` to refine (codebase context carries over automatically)
186
- 4. **Upload** — Open the project URL, upload your actual app screenshots into the device mockups
192
+ 4. **Upload** — Agent calls `upload-screenshots` with local file paths to fill device mockups
187
193
  5. **Export** — Agent calls `render-screenshots` or click "Download All" in the web app
188
194
 
189
195
  ## 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';
@@ -124,7 +124,7 @@ function buildDesignMessage(input) {
124
124
  // ─── MCP Server ─────────────────────────────────────────────────────────────────
125
125
  const server = new McpServer({
126
126
  name: 'appscreenshotstudio',
127
- version: '0.1.0',
127
+ version: '0.4.0',
128
128
  });
129
129
  // Tool 1: generate-screenshots
130
130
  server.registerTool('generate-screenshots', {
@@ -244,9 +244,9 @@ Costs 5 credits per generation.`,
244
244
  `Credits remaining: ${creditsRemaining}`,
245
245
  '',
246
246
  'Next steps:',
247
- '1. Open the project URL in a browser',
248
- '2. Upload app screenshots into the device mockups',
249
- '3. Click "Download All" to export final PNGs',
247
+ '1. Use upload-screenshots to add your app screenshots into the device frames',
248
+ '2. Use render-screenshots to export final PNGs',
249
+ '3. Or open the project URL in a browser to preview and adjust',
250
250
  '',
251
251
  chatData.suggestions?.length
252
252
  ? `Suggestions: ${chatData.suggestions.join(', ')}`
@@ -355,7 +355,7 @@ Example edit messages:
355
355
  // Tool 3: render-screenshots
356
356
  server.registerTool('render-screenshots', {
357
357
  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 the web app first.',
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 upload-screenshots first.',
359
359
  inputSchema: z.object({
360
360
  project_id: z.string().describe('Project ID to render'),
361
361
  }),
@@ -730,6 +730,94 @@ This tool helps you gather the right information so generate-screenshots produce
730
730
  }],
731
731
  };
732
732
  });
733
+ // Tool 8: upload-screenshots
734
+ server.registerTool('upload-screenshots', {
735
+ title: 'Upload App Screenshots',
736
+ 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.
737
+
738
+ Reads files from your local filesystem, converts them to base64, and sets them on the device mockup elements in the specified cards.
739
+
740
+ Free — no credit cost. The screenshots are placed into the device frames that were created by generate-screenshots.
741
+
742
+ Workflow:
743
+ 1. generate-screenshots → creates project with empty device frames
744
+ 2. upload-screenshots → fills the device frames with your actual app UI
745
+ 3. render-screenshots → exports final PNGs at App Store dimensions
746
+
747
+ Tips:
748
+ - Take screenshots from the iOS Simulator (Cmd+S) or Android emulator
749
+ - Use PNG format for best quality
750
+ - Screenshots are automatically fitted into the device frame
751
+ - You can upload different screenshots to different cards`,
752
+ inputSchema: z.object({
753
+ project_id: z.string().describe('Project ID from a previous generate-screenshots call'),
754
+ screenshots: z.array(z.object({
755
+ file_path: z.string().describe('Absolute path to a screenshot file on the local filesystem (PNG, JPG, or WEBP)'),
756
+ card_index: z.number().int().min(0).describe('Which card to place this screenshot on (0-based)'),
757
+ })).min(1).max(10)
758
+ .describe('Array of screenshots to upload, each mapped to a specific card index'),
759
+ }),
760
+ }, async ({ project_id, screenshots }) => {
761
+ // Read local files and convert to base64
762
+ const screenshotData = [];
763
+ const errors = [];
764
+ for (const { file_path, card_index } of screenshots) {
765
+ try {
766
+ if (!existsSync(file_path)) {
767
+ errors.push(`File not found: ${file_path}`);
768
+ continue;
769
+ }
770
+ const buffer = readFileSync(file_path);
771
+ const ext = file_path.toLowerCase().split('.').pop();
772
+ const mimeType = ext === 'jpg' || ext === 'jpeg' ? 'image/jpeg'
773
+ : ext === 'webp' ? 'image/webp'
774
+ : 'image/png';
775
+ const base64 = `data:${mimeType};base64,${buffer.toString('base64')}`;
776
+ screenshotData.push({ card_index, image_base64: base64 });
777
+ }
778
+ catch (err) {
779
+ errors.push(`Failed to read ${file_path}: ${err instanceof Error ? err.message : String(err)}`);
780
+ }
781
+ }
782
+ if (screenshotData.length === 0) {
783
+ return {
784
+ content: [{
785
+ type: 'text',
786
+ text: `No screenshots could be read.\n\nErrors:\n${errors.join('\n')}`,
787
+ }],
788
+ };
789
+ }
790
+ // Upload to API
791
+ const res = await apiCall('POST', `/api/v1/projects/${project_id}/upload-screenshots`, {
792
+ screenshots: screenshotData,
793
+ });
794
+ if (!res.ok) {
795
+ return {
796
+ content: [{
797
+ type: 'text',
798
+ text: `Upload failed: ${JSON.stringify(res.data)}${errors.length ? `\n\nFile read errors:\n${errors.join('\n')}` : ''}`,
799
+ }],
800
+ };
801
+ }
802
+ const data = res.data.data;
803
+ const lines = [
804
+ `Uploaded ${data.uploaded} screenshot${data.uploaded !== 1 ? 's' : ''} into device mockups.`,
805
+ '',
806
+ ];
807
+ for (const r of data.results) {
808
+ lines.push(` Card ${r.card_index + 1}: ${r.success ? 'OK' : r.error}`);
809
+ }
810
+ if (errors.length) {
811
+ lines.push('', 'File read warnings:', ...errors.map(e => ` ${e}`));
812
+ }
813
+ 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');
814
+ return {
815
+ content: [{
816
+ type: 'text',
817
+ text: lines.join('\n'),
818
+ }],
819
+ };
820
+ });
733
821
  // ─── Start server ───────────────────────────────────────────────────────────────
734
822
  function autoInstallSkill() {
735
823
  try {
@@ -737,11 +825,10 @@ function autoInstallSkill() {
737
825
  const src = join(__dir, '..', 'skills', 'appscreenshotstudio', 'SKILL.md');
738
826
  const destDir = join(homedir(), '.claude', 'skills', 'appscreenshotstudio');
739
827
  const dest = join(destDir, 'SKILL.md');
740
- if (!existsSync(src) || existsSync(dest))
828
+ if (!existsSync(src))
741
829
  return;
742
830
  mkdirSync(destDir, { recursive: true });
743
831
  copyFileSync(src, dest);
744
- console.error('Installed Claude Code skill to ~/.claude/skills/appscreenshotstudio/');
745
832
  }
746
833
  catch {
747
834
  // Silent fail — skill install is optional
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appscreenshotstudio/mcp",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "MCP server for generating App Store screenshots via AppScreenshotStudio",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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: Review and Iterate
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 5: Export
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 |