@applaunchflow/mcp 0.1.2 → 0.1.3

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
@@ -1,11 +1,26 @@
1
- # applaunchflow MCP
1
+ # AppLaunchFlow MCP
2
2
 
3
- Local stdio MCP server for applaunchflow.
3
+ MCP server for AppLaunchFlow — create App Store & Google Play screenshots with AI.
4
+
5
+ ## Setup
6
+
7
+ Add to your MCP client config (e.g. Claude Desktop):
8
+
9
+ ```json
10
+ {
11
+ "mcpServers": {
12
+ "applaunchflow": {
13
+ "command": "npx",
14
+ "args": ["-y", "@applaunchflow/mcp@latest"]
15
+ }
16
+ }
17
+ }
18
+ ```
4
19
 
5
20
  ## Auth
6
21
 
7
22
  ```bash
8
- pnpm --dir applaunchflow-mcp dev auth login --base-url http://localhost:3000
23
+ npx -y @applaunchflow/mcp@latest auth login
9
24
  ```
10
25
 
11
26
  Credentials are stored in `~/.applaunchflow/credentials.json`.
@@ -16,11 +31,9 @@ Environment overrides:
16
31
  - `applaunchflow_MCP_TOKEN`
17
32
  - `applaunchflow_MCP_COOKIE_NAME`
18
33
 
19
- ## Run
34
+ ## Development
20
35
 
21
36
  ```bash
22
- pnpm --dir applaunchflow-mcp build
23
- node applaunchflow-mcp/build/index.js
37
+ pnpm install
38
+ pnpm dev
24
39
  ```
25
-
26
- The server uses stdio transport and exposes tools/resources for project, screenshot, layout, template, variant, graphics, and ASO workflows.
@@ -34,7 +34,6 @@ export class AppLaunchFlowClient {
34
34
  buildHeaders(extraHeaders) {
35
35
  const headers = new Headers(extraHeaders);
36
36
  headers.set("Cookie", `${this.credentials.cookieName}=${this.credentials.token}`);
37
- headers.set("Authorization", `Bearer ${this.credentials.token}`);
38
37
  return headers;
39
38
  }
40
39
  async requestJson(path, options = {}) {
package/build/index.js CHANGED
@@ -39,8 +39,8 @@ Preferred workflows:
39
39
  - When adding or editing elements, ensure text and screenshots do not overlap. Verify that positions place elements in distinct, non-conflicting areas of the canvas.
40
40
  - After composition-sensitive edits, inspect the returned translation or re-fetch the layout before reporting success. If elements overlap or are poorly positioned, fix them before telling the user the edit is done.
41
41
  - ALWAYS use browse_templates when a template choice is needed. Never offer templates via text bullet points or AskUserQuestion. The gallery opens in the browser and returns the user's selection automatically.
42
- - Use actual visual previews from the template tools/resources. Do not rely on adjective-heavy descriptions alone.
43
- - Keep the full template catalog available when the user is browsing templates. Only narrow to a small shortlist if the user explicitly asks for recommendations or fewer options.
42
+ - When you need visual context about a screenshot (e.g. to extract colors, understand the app UI, or make context-specific edits), use view_screenshot to look at the actual image.
43
+ - After generating a new variant, always include the editor URL in the reply so the user can open it directly.
44
44
 
45
45
  Translation and localization:
46
46
  - When the user asks to translate, localize, or create a version in another language, ALWAYS use translate_layouts. Do NOT manually edit text nodes via transform_layout for translation.
@@ -43,7 +43,27 @@ export function registerScreenshotTools(server, client) {
43
43
  },
44
44
  }, async (args) => {
45
45
  try {
46
- return ok(await client.generateLayouts(args), "Generated layouts");
46
+ const result = await client.generateLayouts(args);
47
+ const generationId = args.generationId || args.projectId || "";
48
+ const variantId = result.variantId || "";
49
+ const editorUrl = `${client.credentials.baseUrl}/editor?projectId=${generationId}&variantId=${variantId}&device=phone`;
50
+ return {
51
+ content: [
52
+ {
53
+ type: "text",
54
+ text: [
55
+ "Generated layouts successfully.",
56
+ `Editor URL: ${editorUrl}`,
57
+ "IMPORTANT: Paste this exact editor URL in the reply so the user can open it.",
58
+ ].join("\n"),
59
+ },
60
+ ],
61
+ structuredContent: {
62
+ success: true,
63
+ data: { ...result, editorUrl },
64
+ message: "Generated layouts",
65
+ },
66
+ };
47
67
  }
48
68
  catch (error) {
49
69
  return fail(error);
@@ -291,40 +291,4 @@ export function registerTemplateTools(server, client, selectionCoordinator) {
291
291
  return fail(error);
292
292
  }
293
293
  });
294
- server.registerTool("list_templates", {
295
- title: "List Templates",
296
- description: "List all AppLaunchFlow screenshot templates with visual preview resources. Prefer visual comparison over text-only descriptions.",
297
- inputSchema: {
298
- deviceType: z
299
- .enum(TEMPLATE_PREVIEW_DEVICE_TYPES)
300
- .optional()
301
- .describe("Which preview device to attach for each template."),
302
- },
303
- }, async ({ deviceType = "phone" }) => {
304
- try {
305
- const payload = decorateTemplatePayload(await client.listTemplates(), client.credentials.baseUrl);
306
- const galleryUrl = buildTemplateGalleryUrl(client.credentials.baseUrl, {
307
- deviceType,
308
- });
309
- return buildListTemplatesResult(payload, deviceType, galleryUrl);
310
- }
311
- catch (error) {
312
- return fail(error);
313
- }
314
- });
315
- server.registerTool("get_template_details", {
316
- title: "Get Template Details",
317
- description: "Get details and visual preview resources for a single screenshot template.",
318
- inputSchema: {
319
- templateId: z.string(),
320
- },
321
- }, async ({ templateId }) => {
322
- try {
323
- const payload = decorateTemplatePayload(await client.getTemplate(templateId), client.credentials.baseUrl);
324
- return buildTemplateDetailsResult(payload);
325
- }
326
- catch (error) {
327
- return fail(error);
328
- }
329
- });
330
294
  }
@@ -53,20 +53,6 @@ export function registerVariantTools(server, client) {
53
53
  return fail(error);
54
54
  }
55
55
  });
56
- server.registerTool("switch_variant", {
57
- title: "Switch Variant",
58
- description: "Set a variant as active",
59
- inputSchema: {
60
- variantId: z.string().uuid(),
61
- },
62
- }, async ({ variantId }) => {
63
- try {
64
- return ok(await client.switchVariant(variantId), "Switched variant");
65
- }
66
- catch (error) {
67
- return fail(error);
68
- }
69
- });
70
56
  server.registerTool("duplicate_variant", {
71
57
  title: "Duplicate Variant",
72
58
  description: "Duplicate an existing variant",
@@ -81,18 +67,4 @@ export function registerVariantTools(server, client) {
81
67
  return fail(error);
82
68
  }
83
69
  });
84
- server.registerTool("delete_variant", {
85
- title: "Delete Variant",
86
- description: "Delete a content variant",
87
- inputSchema: {
88
- variantId: z.string().uuid(),
89
- },
90
- }, async ({ variantId }) => {
91
- try {
92
- return ok(await client.deleteVariant(variantId), "Deleted variant");
93
- }
94
- catch (error) {
95
- return fail(error);
96
- }
97
- });
98
70
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applaunchflow/mcp",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "MCP server for AppLaunchFlow — create App Store & Google Play screenshots with AI.",
5
5
  "license": "MIT",
6
6
  "repository": {