@kvasar/google-stitch 0.1.22 → 0.1.24

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "openclaw-google-stitch",
3
3
  "name": "Google Stitch MCP",
4
- "version": "0.1.22",
4
+ "version": "0.1.24",
5
5
  "description": "Integrates Google Stitch MCP services into OpenClaw",
6
6
  "skills": ["skills"],
7
7
  "configSchema": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kvasar/google-stitch",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "OpenClaw plugin for Google Stitch UI generation, screen design, variants, and design systems",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -45,16 +45,7 @@ export class StitchMCPClient {
45
45
  this.connected = true;
46
46
  }
47
47
  }
48
- async createProject(name: string) {
49
- await this.connect();
50
-
51
- return this.client.callTool({
52
- name: "create_project",
53
- arguments: {
54
- name: name,
55
- },
56
- });
57
- }
48
+
58
49
 
59
50
  async generateScreen(params: {
60
51
  projectId: string;
@@ -1,60 +1,24 @@
1
- type SelectedScreenInstance = {
2
- id: string;
3
- sourceScreen: string;
4
- };
1
+ import { Type, Static } from "@sinclair/typebox";
5
2
 
6
- type ApplyDesignSystemParams = {
7
- projectId: string;
8
- selectedScreenInstances: SelectedScreenInstance[];
9
- assetId: string;
10
- };
3
+ const SelectedScreenInstanceSchema = Type.Object({
4
+ id: Type.String({ description: "Required. Screen instance ID (not source screen ID)." }),
5
+ sourceScreen: Type.String({ description: "Required. Resource name format: projects/{project}/screens/{screen}" })
6
+ });
11
7
 
12
- export const applyDesignSystemTool = (client: any) => ({
13
- name: "apply_design_system",
14
- description:
15
- "Applies a design system asset to one or more screens, updating colors, fonts, and shapes",
8
+ const ApplyDesignSystemSchema = Type.Object({
9
+ projectId: Type.String({ description: "Required. Project ID without prefix." }),
10
+ selectedScreenInstances: Type.Array(SelectedScreenInstanceSchema, {
11
+ description: "Required. Screen instances to update from get_project."
12
+ }),
13
+ assetId: Type.String({ description: "Required. Design system asset ID without assets/ prefix." })
14
+ });
16
15
 
17
- parameters: {
18
- type: "object",
19
- properties: {
20
- projectId: {
21
- type: "string",
22
- description: "Required. Project ID without prefix."
23
- },
24
- selectedScreenInstances: {
25
- type: "array",
26
- description:
27
- "Required. Screen instances to update from get_project.",
28
- items: {
29
- type: "object",
30
- properties: {
31
- id: {
32
- type: "string",
33
- description:
34
- "Required. Screen instance ID (not source screen ID)."
35
- },
36
- sourceScreen: {
37
- type: "string",
38
- description:
39
- "Required. Resource name format: projects/{project}/screens/{screen}"
40
- }
41
- },
42
- required: ["id", "sourceScreen"]
43
- }
44
- },
45
- assetId: {
46
- type: "string",
47
- description:
48
- "Required. Design system asset ID without assets/ prefix."
49
- }
50
- },
51
- required: [
52
- "projectId",
53
- "selectedScreenInstances",
54
- "assetId"
55
- ]
56
- },
16
+ type ApplyDesignSystemParams = Static<typeof ApplyDesignSystemSchema>;
57
17
 
18
+ export const applyDesignSystemTool = (client: any) => ({
19
+ name: "apply_design_system",
20
+ description: "Applies a design system asset to one or more screens, updating colors, fonts, and shapes",
21
+ parameters: ApplyDesignSystemSchema,
58
22
  async execute(_: string, params: ApplyDesignSystemParams) {
59
23
  return await client.request("apply_design_system", params);
60
24
  }
@@ -1,141 +1,89 @@
1
- type ColorMode =
2
- | "COLOR_MODE_UNSPECIFIED"
3
- | "LIGHT"
4
- | "DARK";
1
+ import { Type, Static } from "@sinclair/typebox";
5
2
 
6
- type FontType =
7
- | "FONT_UNSPECIFIED"
8
- | "INTER"
9
- | "DM_SANS"
10
- | "GEIST";
3
+ const ColorMode = Type.Union([
4
+ Type.Literal("COLOR_MODE_UNSPECIFIED"),
5
+ Type.Literal("LIGHT"),
6
+ Type.Literal("DARK")
7
+ ]);
11
8
 
12
- type Roundness =
13
- | "ROUNDNESS_UNSPECIFIED"
14
- | "ROUND_FOUR"
15
- | "ROUND_EIGHT"
16
- | "ROUND_TWELVE"
17
- | "ROUND_FULL";
9
+ const FontType = Type.Union([
10
+ Type.Literal("FONT_UNSPECIFIED"),
11
+ Type.Literal("INTER"),
12
+ Type.Literal("DM_SANS"),
13
+ Type.Literal("GEIST")
14
+ ]);
18
15
 
19
- type ColorVariant =
20
- | "COLOR_VARIANT_UNSPECIFIED"
21
- | "MONOCHROME"
22
- | "NEUTRAL"
23
- | "TONAL_SPOT"
24
- | "VIBRANT"
25
- | "EXPRESSIVE"
26
- | "FIDELITY"
27
- | "CONTENT"
28
- | "RAINBOW"
29
- | "FRUIT_SALAD";
16
+ const Roundness = Type.Union([
17
+ Type.Literal("ROUNDNESS_UNSPECIFIED"),
18
+ Type.Literal("ROUND_FOUR"),
19
+ Type.Literal("ROUND_EIGHT"),
20
+ Type.Literal("ROUND_TWELVE"),
21
+ Type.Literal("ROUND_FULL")
22
+ ]);
30
23
 
31
- type DesignTheme = {
32
- colorMode: ColorMode;
33
- headlineFont: FontType;
34
- bodyFont: FontType;
35
- labelFont?: FontType;
36
- roundness: Roundness;
37
- customColor: string;
38
- colorVariant?: ColorVariant;
39
- overridePrimaryColor?: string;
40
- overrideSecondaryColor?: string;
41
- overrideTertiaryColor?: string;
42
- overrideNeutralColor?: string;
43
- designMd?: string;
44
- };
24
+ const ColorVariant = Type.Union([
25
+ Type.Literal("COLOR_VARIANT_UNSPECIFIED"),
26
+ Type.Literal("MONOCHROME"),
27
+ Type.Literal("NEUTRAL"),
28
+ Type.Literal("TONAL_SPOT"),
29
+ Type.Literal("VIBRANT"),
30
+ Type.Literal("EXPRESSIVE"),
31
+ Type.Literal("FIDELITY"),
32
+ Type.Literal("CONTENT"),
33
+ Type.Literal("RAINBOW"),
34
+ Type.Literal("FRUIT_SALAD")
35
+ ]);
45
36
 
46
- type DesignSystem = {
47
- displayName: string;
48
- theme: DesignTheme;
49
- };
37
+ const DesignThemeSchema = Type.Object({
38
+ colorMode: Type.Union([Type.Literal("LIGHT"), Type.Literal("DARK")], {
39
+ description: "Color mode"
40
+ }),
41
+ headlineFont: Type.Union([Type.Literal("INTER"), Type.Literal("DM_SANS"), Type.Literal("GEIST")], {
42
+ description: "Headline font"
43
+ }),
44
+ bodyFont: Type.Union([Type.Literal("INTER"), Type.Literal("DM_SANS"), Type.Literal("GEIST")], {
45
+ description: "Body font"
46
+ }),
47
+ labelFont: Type.Optional(Type.Union([Type.Literal("INTER"), Type.Literal("DM_SANS"), Type.Literal("GEIST")], {
48
+ description: "Label font"
49
+ })),
50
+ roundness: Type.Union([
51
+ Type.Literal("ROUND_FOUR"),
52
+ Type.Literal("ROUND_EIGHT"),
53
+ Type.Literal("ROUND_TWELVE"),
54
+ Type.Literal("ROUND_FULL")
55
+ ], {
56
+ description: "Roundness level"
57
+ }),
58
+ customColor: Type.String({ description: "Hex seed color" }),
59
+ colorVariant: Type.Optional(Type.Union([
60
+ Type.Literal("MONOCHROME"),
61
+ Type.Literal("NEUTRAL"),
62
+ Type.Literal("TONAL_SPOT"),
63
+ Type.Literal("VIBRANT"),
64
+ Type.Literal("EXPRESSIVE")
65
+ ], {
66
+ description: "Color variant"
67
+ })),
68
+ designMd: Type.Optional(Type.String({ description: "Optional markdown design instructions" }))
69
+ });
50
70
 
51
- type CreateDesignSystemParams = {
52
- designSystem: DesignSystem;
53
- projectId?: string;
54
- };
71
+ const DesignSystemSchema = Type.Object({
72
+ displayName: Type.String({ description: "Required. Display name." }),
73
+ theme: DesignThemeSchema
74
+ });
55
75
 
56
- export const createDesignSystemTool = (client: any) => ({
57
- name: "create_design_system",
58
- description:
59
- "Creates a new design system with colors, typography, roundness, and theme tokens for a Stitch project",
76
+ const CreateDesignSystemSchema = Type.Object({
77
+ projectId: Type.Optional(Type.String({ description: "Optional. Project ID. If omitted, creates a global design asset." })),
78
+ designSystem: DesignSystemSchema
79
+ });
60
80
 
61
- parameters: {
62
- type: "object",
63
- properties: {
64
- projectId: {
65
- type: "string",
66
- description:
67
- "Optional. Project ID. If omitted, creates a global design asset."
68
- },
69
- designSystem: {
70
- type: "object",
71
- description: "Required. Design system definition.",
72
- properties: {
73
- displayName: {
74
- type: "string",
75
- description: "Required. Display name."
76
- },
77
- theme: {
78
- type: "object",
79
- properties: {
80
- colorMode: {
81
- type: "string",
82
- enum: ["LIGHT", "DARK"]
83
- },
84
- headlineFont: {
85
- type: "string",
86
- enum: ["INTER", "DM_SANS", "GEIST"]
87
- },
88
- bodyFont: {
89
- type: "string",
90
- enum: ["INTER", "DM_SANS", "GEIST"]
91
- },
92
- labelFont: {
93
- type: "string",
94
- enum: ["INTER", "DM_SANS", "GEIST"]
95
- },
96
- roundness: {
97
- type: "string",
98
- enum: [
99
- "ROUND_FOUR",
100
- "ROUND_EIGHT",
101
- "ROUND_TWELVE",
102
- "ROUND_FULL"
103
- ]
104
- },
105
- customColor: {
106
- type: "string",
107
- description: "Hex seed color"
108
- },
109
- colorVariant: {
110
- type: "string",
111
- enum: [
112
- "MONOCHROME",
113
- "NEUTRAL",
114
- "TONAL_SPOT",
115
- "VIBRANT",
116
- "EXPRESSIVE"
117
- ]
118
- },
119
- designMd: {
120
- type: "string",
121
- description: "Optional markdown design instructions"
122
- }
123
- },
124
- required: [
125
- "colorMode",
126
- "headlineFont",
127
- "bodyFont",
128
- "roundness",
129
- "customColor"
130
- ]
131
- }
132
- },
133
- required: ["displayName", "theme"]
134
- }
135
- },
136
- required: ["designSystem"]
137
- },
81
+ type CreateDesignSystemParams = Static<typeof CreateDesignSystemSchema>;
138
82
 
83
+ export const createDesignSystemTool = (client: any) => ({
84
+ name: "create_design_system",
85
+ description: "Creates a new design system with colors, typography, roundness, and theme tokens for a Stitch project",
86
+ parameters: CreateDesignSystemSchema,
139
87
  async execute(_: string, params: CreateDesignSystemParams) {
140
88
  return await client.request("create_design_system", params);
141
89
  }
@@ -20,7 +20,7 @@ export function createProjectTool(client: StitchMCPClient) {
20
20
  ),
21
21
  }),
22
22
  async execute(_id: string, params: CreateProjectParams) {
23
- const result = await client.createProject(params.title);
23
+ const result = await client.request("create_project",params);
24
24
  return {
25
25
  content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
26
26
  };
@@ -1,7 +1,49 @@
1
- export const editScreensTool = (client:any) => ({
1
+ import { Type, Static } from "@sinclair/typebox";
2
+
3
+ const EditScreensSchema = Type.Object({
4
+ projectId: Type.String({
5
+ description: "Required. Project ID without prefix.",
6
+ }),
7
+
8
+ selectedScreenIds: Type.Array(Type.String(), {
9
+ description:
10
+ "Required. Screen IDs to edit, without `screens/` prefix.",
11
+ minItems: 1,
12
+ }),
13
+
14
+ prompt: Type.String({
15
+ description: "Required. Edit instruction.",
16
+ }),
17
+
18
+ deviceType: Type.Optional(
19
+ Type.Union([
20
+ Type.Literal("DEVICE_TYPE_UNSPECIFIED"),
21
+ Type.Literal("MOBILE"),
22
+ Type.Literal("DESKTOP"),
23
+ Type.Literal("TABLET"),
24
+ Type.Literal("AGNOSTIC"),
25
+ ])
26
+ ),
27
+
28
+ modelId: Type.Optional(
29
+ Type.Union([
30
+ Type.Literal("MODEL_ID_UNSPECIFIED"),
31
+ Type.Literal("GEMINI_3_PRO"),
32
+ Type.Literal("GEMINI_3_FLASH"),
33
+ Type.Literal("GEMINI_3_1_PRO"),
34
+ ])
35
+ ),
36
+ });
37
+
38
+ type EditScreensParams = Static<typeof EditScreensSchema>;
39
+
40
+ export const editScreensTool = (client: any) => ({
2
41
  name: "edit_screens",
3
- description: "edit screens",
4
- async execute(_: string, params: any) {
42
+ description:
43
+ "Edits existing screens using a text prompt. This process may take a few minutes.",
44
+ parameters: EditScreensSchema,
45
+
46
+ async execute(_: string, params: EditScreensParams) {
5
47
  return await client.request?.("edit_screens", params);
6
48
  },
7
- });
49
+ });
@@ -6,7 +6,7 @@ import {
6
6
  import fs from "node:fs";
7
7
  import path from "node:path";
8
8
  import os from "node:os";
9
- import { Type } from "@sinclair/typebox";
9
+ import { Type, Static } from "@sinclair/typebox";
10
10
 
11
11
 
12
12
  type StitchFile = {
@@ -22,68 +22,75 @@ type SessionOutputComponent = {
22
22
 
23
23
  };
24
24
 
25
+ type ScreenType = "SCREEN_TYPE_UNSPECIFIED" | "COMPONENT" | "LAYOUT" | "PAGE" | "FLOW";
26
+ type ScreenStatus = "SCREEN_STATUS_UNSPECIFIED" | "DRAFT" | "PUBLISHED" | "ARCHIVED";
27
+ type DisplayMode = "DISPLAY_MODE_UNSPECIFIED" | "LIGHT" | "DARK";
28
+
29
+ type DesignTheme = {
30
+ colorMode?: string;
31
+ headlineFont?: string;
32
+ bodyFont?: string;
33
+ labelFont?: string;
34
+ roundness?: string;
35
+ customColor?: string;
36
+ colorVariant?: string;
37
+ };
38
+
39
+ type ScreenMetadata = {
40
+ agent?: string;
41
+ status?: ScreenStatus;
42
+ displayMode?: DisplayMode;
43
+ };
44
+
25
45
  type StitchResponse = {
26
46
  screen?: {
27
47
  name?: string;
48
+ id?: string;
28
49
  title?: string;
29
50
  prompt?: string;
30
51
  screenshot?: StitchFile;
31
52
  htmlCode?: StitchFile;
53
+ figmaExport?: StitchFile;
54
+ theme?: DesignTheme;
32
55
  deviceType?: DeviceType;
56
+ screenType?: ScreenType;
57
+ screenMetadata?: ScreenMetadata;
33
58
  width?: string;
34
59
  height?: string;
60
+ groupId?: string;
61
+ groupName?: string;
62
+ generatedBy?: string;
63
+ isCreatedByClient?: boolean;
35
64
  };
36
65
  output_components?: SessionOutputComponent[];
37
66
  };
38
67
 
68
+ const GenerateScreenSchema = Type.Object({
69
+ projectId: Type.String({ description: "Required. Project ID without prefix." }),
70
+ prompt: Type.String({ description: "Natural language prompt describing the UI screen" }),
71
+ deviceType: Type.Optional(Type.Union([
72
+ Type.Literal("DEVICE_TYPE_UNSPECIFIED"),
73
+ Type.Literal("MOBILE"),
74
+ Type.Literal("DESKTOP"),
75
+ Type.Literal("TABLET"),
76
+ Type.Literal("AGNOSTIC")
77
+ ])),
78
+ modelId: Type.Optional(Type.Union([
79
+ Type.Literal("MODEL_ID_UNSPECIFIED"),
80
+ Type.Literal("GEMINI_3_PRO"),
81
+ Type.Literal("GEMINI_3_FLASH"),
82
+ Type.Literal("GEMINI_3_1_PRO")
83
+ ]))
84
+ });
85
+
86
+ type GenerateScreenParams = Static<typeof GenerateScreenSchema>;
87
+
39
88
  export function generateScreenFromTextTool(client: StitchMCPClient) {
40
89
  return {
41
90
  name: "generate_screen_from_text",
42
91
  description: "Generate a UI screen from a natural language prompt",
43
-
44
- parameters: {
45
- type: "object",
46
- properties: {
47
- projectId: {
48
- type: "string",
49
- description: "Required. Project ID without prefix."
50
- },
51
- prompt: {
52
- type: "string",
53
- description: "Describe the UI screen to generate"
54
- },
55
- deviceType: {
56
- type: "string",
57
- enum: [
58
- "DEVICE_TYPE_UNSPECIFIED",
59
- "MOBILE",
60
- "DESKTOP",
61
- "TABLET",
62
- "AGNOSTIC"
63
- ]
64
- },
65
- modelId: {
66
- type: "string",
67
- enum: [
68
- "MODEL_ID_UNSPECIFIED",
69
- "GEMINI_3_PRO",
70
- "GEMINI_3_FLASH",
71
- "GEMINI_3_1_PRO"
72
- ]
73
- }
74
- },
75
- required: ["projectId", "prompt"]
76
- },
77
-
78
- async execute(
79
- _id: string,
80
- params: {
81
- projectId: string;
82
- prompt: string;
83
- deviceType?: DeviceType;
84
- modelId?: ModelId;
85
- }
86
- ) {
92
+ parameters: GenerateScreenSchema,
93
+ async execute(_id: string, params: GenerateScreenParams) {
87
94
  const result = (await client.generateScreen(params)) as StitchResponse;
88
95
 
89
96
  const screen = result.screen;
@@ -100,6 +107,45 @@ export function generateScreenFromTextTool(client: StitchMCPClient) {
100
107
 
101
108
  const content: Array<{ type: string; [key: string]: any }> = [];
102
109
 
110
+ // Add screen metadata summary first
111
+ if (screen) {
112
+ const screenInfo = `
113
+ ## Screen Generated Successfully
114
+
115
+ **Title:** ${screen.title || "Untitled"}
116
+ **Resource Name:** ${screen.name || "N/A"}
117
+ **ID:** ${screen.id || "N/A"}
118
+ **Device Type:** ${screen.deviceType || "N/A"}
119
+ **Screen Type:** ${screen.screenType || "N/A"}
120
+ **Dimensions:** ${screen.width || "N/A"} x ${screen.height || "N/A"}
121
+ **Generated By:** ${screen.generatedBy || "N/A"}
122
+ **Prompt:** ${screen.prompt || "N/A"}
123
+
124
+ **Metadata:**
125
+ - Agent: ${screen.screenMetadata?.agent || "N/A"}
126
+ - Status: ${screen.screenMetadata?.status || "N/A"}
127
+ - Display Mode: ${screen.screenMetadata?.displayMode || "N/A"}
128
+
129
+ **Group Info:**
130
+ - Group ID: ${screen.groupId || "N/A"}
131
+ - Group Name: ${screen.groupName || "N/A"}
132
+
133
+ **Theme:**
134
+ - Color Mode: ${screen.theme?.colorMode || "N/A"}
135
+ - Headline Font: ${screen.theme?.headlineFont || "N/A"}
136
+ - Body Font: ${screen.theme?.bodyFont || "N/A"}
137
+ - Roundness: ${screen.theme?.roundness || "N/A"}
138
+ - Color Variant: ${screen.theme?.colorVariant || "N/A"}
139
+
140
+ **Client Created:** ${screen.isCreatedByClient ? "Yes" : "No"}
141
+ `;
142
+
143
+ content.push({
144
+ type: "text",
145
+ text: screenInfo.trim()
146
+ });
147
+ }
148
+
103
149
  if (modelText) {
104
150
  content.push({
105
151
  type: "text",
@@ -178,6 +224,7 @@ export function generateScreenFromTextTool(client: StitchMCPClient) {
178
224
  <h3>${escapeHtml(
179
225
  screen?.title || "Generated screen"
180
226
  )}</h3>
227
+ <p>No HTML preview available</p>
181
228
  </div>`;
182
229
  }
183
230
 
@@ -186,6 +233,19 @@ export function generateScreenFromTextTool(client: StitchMCPClient) {
186
233
  html
187
234
  });
188
235
 
236
+ // Add Figma export info if available
237
+ if (screen?.figmaExport) {
238
+ const figmaInfo = `
239
+ **Figma Export Available:** ${screen.figmaExport.downloadUrl ? "Yes" : "No"}
240
+ ${screen.figmaExport.name ? `**File Name:** ${screen.figmaExport.name}` : ""}
241
+ `;
242
+
243
+ content.push({
244
+ type: "text",
245
+ text: figmaInfo.trim()
246
+ });
247
+ }
248
+
189
249
  if (suggestionText) {
190
250
  content.push({
191
251
  type: "text",
@@ -1,7 +1,84 @@
1
- export const generateVariantsTool = (client:any) => ({
1
+ import { Type, Static } from "@sinclair/typebox";
2
+
3
+ const VariantOptionsSchema = Type.Object({
4
+ variantCount: Type.Optional(
5
+ Type.Integer({
6
+ minimum: 1,
7
+ maximum: 5,
8
+ description: "Number of variants (1–5). Default: 3.",
9
+ })
10
+ ),
11
+
12
+ creativeRange: Type.Optional(
13
+ Type.Union([
14
+ Type.Literal("CREATIVE_RANGE_UNSPECIFIED"),
15
+ Type.Literal("REFINE"),
16
+ Type.Literal("EXPLORE"),
17
+ Type.Literal("REIMAGINE"),
18
+ ])
19
+ ),
20
+
21
+ aspects: Type.Optional(
22
+ Type.Array(
23
+ Type.Union([
24
+ Type.Literal("VARIANT_ASPECT_UNSPECIFIED"),
25
+ Type.Literal("LAYOUT"),
26
+ Type.Literal("COLOR_SCHEME"),
27
+ Type.Literal("IMAGES"),
28
+ Type.Literal("TEXT_FONT"),
29
+ Type.Literal("TEXT_CONTENT"),
30
+ ])
31
+ )
32
+ ),
33
+ });
34
+
35
+ const GenerateVariantsSchema = Type.Object({
36
+ projectId: Type.String({
37
+ description: "Required. Project ID without prefix.",
38
+ }),
39
+
40
+ selectedScreenIds: Type.Array(Type.String(), {
41
+ description: "Required. Screen IDs to generate variants for.",
42
+ minItems: 1,
43
+ }),
44
+
45
+ prompt: Type.String({
46
+ description: "Required. Text guiding variant generation.",
47
+ }),
48
+
49
+ variantOptions: VariantOptionsSchema,
50
+
51
+ deviceType: Type.Optional(
52
+ Type.Union([
53
+ Type.Literal("DEVICE_TYPE_UNSPECIFIED"),
54
+ Type.Literal("MOBILE"),
55
+ Type.Literal("DESKTOP"),
56
+ Type.Literal("TABLET"),
57
+ Type.Literal("AGNOSTIC"),
58
+ ])
59
+ ),
60
+
61
+ modelId: Type.Optional(
62
+ Type.Union([
63
+ Type.Literal("MODEL_ID_UNSPECIFIED"),
64
+ // deprecated but still supported by API
65
+ Type.Literal("GEMINI_3_PRO"),
66
+ Type.Literal("GEMINI_3_FLASH"),
67
+ Type.Literal("GEMINI_3_1_PRO"),
68
+ ])
69
+ ),
70
+ });
71
+
72
+ type GenerateVariantsParams = Static<typeof GenerateVariantsSchema>;
73
+
74
+ export const generateVariantsTool = (client: any) => ({
2
75
  name: "generate_variants",
3
- description: "generate variants",
4
- async execute(_: string, params: any) {
76
+ description:
77
+ "Generates design variants of existing screens based on selected screens and variant options.",
78
+
79
+ parameters: GenerateVariantsSchema,
80
+
81
+ async execute(_: string, params: GenerateVariantsParams) {
5
82
  return await client.request?.("generate_variants", params);
6
83
  },
7
- });
84
+ });
@@ -1,7 +1,16 @@
1
- export const getProjectTool = (client:any) => ({
1
+ import { Type, Static } from "@sinclair/typebox";
2
+
3
+ const GetProjectSchema = Type.Object({
4
+ // This tool appears to accept any parameters as per the API
5
+ });
6
+
7
+ type GetProjectParams = Static<typeof GetProjectSchema>;
8
+
9
+ export const getProjectTool = (client: any) => ({
2
10
  name: "get_project",
3
11
  description: "get project",
4
- async execute(_: string, params: any) {
12
+ parameters: GetProjectSchema,
13
+ async execute(_: string, params: GetProjectParams) {
5
14
  return await client.request?.("get_project", params);
6
15
  },
7
16
  });
@@ -2,6 +2,7 @@ import { StitchMCPClient } from "../services/stitch-mcp-client.js";
2
2
  import fs from "node:fs";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
+ import { Type, Static } from "@sinclair/typebox";
5
6
 
6
7
  type StitchFile = {
7
8
  name?: string;
@@ -27,11 +28,13 @@ type Screen = {
27
28
  isCreatedByClient?: boolean;
28
29
  };
29
30
 
30
- type GetScreenParams = {
31
- name: string;
32
- projectId: string;
33
- screenId: string;
34
- };
31
+ const GetScreenSchema = Type.Object({
32
+ name: Type.String({ description: "Required. Resource name. Format: projects/{project}/screens/{screen}" }),
33
+ projectId: Type.String({ description: "Required (deprecated). Project ID without prefix." }),
34
+ screenId: Type.String({ description: "Required (deprecated). Screen ID without prefix." })
35
+ });
36
+
37
+ type GetScreenParams = Static<typeof GetScreenSchema>;
35
38
 
36
39
  type ContentItem = {
37
40
  type: string;
@@ -40,35 +43,9 @@ type ContentItem = {
40
43
 
41
44
  export const getScreenTool = (client: StitchMCPClient) => ({
42
45
  name: "get_screen",
43
- description:
44
- "Retrieves and visually renders a specific screen within a Stitch project.",
45
-
46
- parameters: {
47
- type: "object",
48
- properties: {
49
- name: {
50
- type: "string",
51
- description:
52
- "Required. Resource name. Format: projects/{project}/screens/{screen}"
53
- },
54
- projectId: {
55
- type: "string",
56
- description:
57
- "Required (deprecated). Project ID without prefix."
58
- },
59
- screenId: {
60
- type: "string",
61
- description:
62
- "Required (deprecated). Screen ID without prefix."
63
- }
64
- },
65
- required: ["name", "projectId", "screenId"]
66
- },
67
-
68
- async execute(
69
- _: string,
70
- params: GetScreenParams
71
- ) {
46
+ description: "Retrieves and visually renders a specific screen within a Stitch project.",
47
+ parameters: GetScreenSchema,
48
+ async execute(_: string, params: GetScreenParams) {
72
49
  const { name, projectId, screenId } = params;
73
50
 
74
51
  if (!name || !projectId || !screenId) {
@@ -1,7 +1,55 @@
1
- export const updateDesignSystemTool = (client:any) => ({
1
+ import { Type, Static } from "@sinclair/typebox";
2
+
3
+ /**
4
+ * Reusable nested theme schema
5
+ */
6
+ const DesignThemeSchema = Type.Object({
7
+ name: Type.Optional(Type.String()),
8
+ primaryColor: Type.Optional(Type.String()),
9
+ secondaryColor: Type.Optional(Type.String()),
10
+ typography: Type.Optional(Type.String()),
11
+ spacing: Type.Optional(Type.String()),
12
+ });
13
+
14
+ /**
15
+ * Main design system schema
16
+ */
17
+ const DesignSystemSchema = Type.Object({
18
+ name: Type.Optional(Type.String()),
19
+ description: Type.Optional(Type.String()),
20
+ themes: Type.Optional(Type.Array(DesignThemeSchema)),
21
+ components: Type.Optional(Type.Array(Type.String())),
22
+ tokens: Type.Optional(Type.Record(Type.String(), Type.Any())),
23
+ });
24
+
25
+ /**
26
+ * Update schema
27
+ */
28
+ const UpdateDesignSystemSchema = Type.Object({
29
+ name: Type.String({
30
+ pattern: "^assets\\/[^\\/]+$",
31
+ description:
32
+ "Required. Resource name. Format: `assets/{asset}`.",
33
+ }),
34
+
35
+ projectId: Type.String({
36
+ description: "Required. Project ID without prefix.",
37
+ }),
38
+
39
+ designSystem: DesignSystemSchema,
40
+ });
41
+
42
+ type UpdateDesignSystemParams = Static<typeof UpdateDesignSystemSchema>;
43
+
44
+ export const updateDesignSystemTool = (client: any) => ({
2
45
  name: "update_design_system",
3
- description: "update design system",
4
- async execute(_: string, params: any) {
46
+
47
+ description:
48
+ "Updates an existing design system. Identifies the asset by its name field.",
49
+
50
+ parameters: UpdateDesignSystemSchema,
51
+
52
+ async execute(_: string, params: UpdateDesignSystemParams) {
5
53
  return await client.request?.("update_design_system", params);
6
54
  },
7
- });
55
+ });