Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .agents/skills/stitch-sdk-usage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,18 @@ Both methods use cached data from the generation response when available, fallin
For agents and orchestration scripts that forward JSON payloads to MCP tools:

```typescript
import { StitchToolClient } from '@google/stitch-sdk';
import { stitch } from '@google/stitch-sdk';

const client = new StitchToolClient(); // reads STITCH_API_KEY from env
const tools = await client.listTools();
const result = await client.callTool("generate_screen_from_text", {
// Find available tools
const { tools } = await stitch.listTools();
for (const tool of tools) {
console.log(`${tool.name}: ${tool.description}`);
}
// Call a tool with a JSON payload
const result = await stitch.callTool("generate_screen_from_text", {
projectId: "123", prompt: "A login page"
});
await client.close();
await stitch.close();
```

## Error Handling
Expand Down
11 changes: 8 additions & 3 deletions packages/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,18 @@ for (const tool of tools) {
console.log(tool.name, tool.description);
}

// Call a tool directly
const result = await client.callTool("create_project", {
// Call a tool directly — returns are now strongly typed!
import { CreateProjectResponse } from "@google/stitch-sdk";
const result = await client.callTool<CreateProjectResponse>("create_project", {
title: "Agent Project",
});
console.log(result.project?.projectId);

await client.close();
```

The client auto-connects on the first `callTool` or `listTools` call. No explicit `connect()` needed.
All tool responses and input parameters are strictly typed and exported from the SDK.

## API Reference

Expand Down Expand Up @@ -165,8 +168,10 @@ A generated UI screen. Provides access to HTML and screenshots.
Low-level authenticated pipe to the Stitch MCP server. Use this when you need direct tool access (e.g., in an AI agent).

```ts
import { StitchToolClient, GetScreenResponse } from "@google/stitch-sdk";

const client = new StitchToolClient({ apiKey: "..." });
const result = await client.callTool<any>("tool_name", { arg: "value" });
const result = await client.callTool<GetScreenResponse>("get_screen", { projectId: "...", screenId: "..." });
await client.close();
```

Expand Down
5 changes: 5 additions & 0 deletions packages/sdk/generated/domain-map.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
"method": "designSystem",
"returns": "DesignSystem",
"description": "Create a DesignSystem handle from an existing ID without an API call."
},
{
"method": "screen",
"returns": "Screen",
"description": "Create a Screen handle from an existing ID without an API call."
}
],
"sideEffects": [
Expand Down
16 changes: 9 additions & 7 deletions packages/sdk/generated/src/designsystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
DO NOT EDIT — changes will be overwritten.

Source: tools-manifest.json (sha256:2f1a623ec115...)
domain-map.json (sha256:baa17d36f4c1...)
Generated: 2026-04-28T16:31:23.449Z
domain-map.json (sha256:ffa082d8fbe7...)
Generated: 2026-04-28T20:49:35.251Z
*/
import { type StitchToolClient } from "../../src/client.js";
import { StitchError } from "../../src/spec/errors.js";
import { DesignTheme, File, ProjectMetadata, ScreenInstance, Typography, UserFeedback, ProjectInput, ScreenInput, Asset, BoundingBox, ComponentRegion, Design, DesignSuggestion, DesignSystemInput, ProgressUpdate, ProgressUpdates, PrototypeLink, PrototypeLinks, PrototypeState, PrototypeV2Spec, ScreenMetadata, SessionOutputComponent, VariantOptions, SelectedScreenInstance } from "./types.generated.js";
import { UpdateDesignSystemResponse, ApplyDesignSystemResponse } from "./responses.generated.js";
import { Screen } from "./screen.js";

/** Represents a visual theme or branding applied to projects and screens. */
Expand Down Expand Up @@ -36,9 +38,9 @@ export class DesignSystem {
* Updates a design system for a project. Use this tool when the user wants to change the overall visual theme, style, or branding of the application.
* Tool: update_design_system
*/
async update(designSystem: any): Promise<DesignSystem> {
async update(designSystem: DesignSystemInput): Promise<DesignSystem> {
try {
const raw = await this.client.callTool<any>("update_design_system", { name: `assets/${this.assetId}`, projectId: this.projectId, designSystem });
const raw = await this.client.callTool<UpdateDesignSystemResponse>("update_design_system", { name: `assets/${this.assetId}`, projectId: this.projectId, designSystem });
return new DesignSystem(this.client, { ...raw, projectId: this.projectId });
} catch (error) {
throw StitchError.fromUnknown(error);
Expand All @@ -49,10 +51,10 @@ export class DesignSystem {
* Applies a design system to a list of screens. Use this tool when the user wants to update one or more screens to match the style of a design system.
* Tool: apply_design_system
*/
async apply(selectedScreenInstances: any[]): Promise<Screen[]> {
async apply(selectedScreenInstances: SelectedScreenInstance[]): Promise<Screen[]> {
try {
const raw = await this.client.callTool<any>("apply_design_system", { assetId: this.assetId, projectId: this.projectId, selectedScreenInstances });
return ((raw.outputComponents || []).flatMap((a: any) => a?.design?.screens || []) || []).map((item: any) => new Screen(this.client, { ...item, projectId: this.projectId }));
const raw = await this.client.callTool<ApplyDesignSystemResponse>("apply_design_system", { assetId: this.assetId, projectId: this.projectId, selectedScreenInstances });
return ((raw.outputComponents || []).flatMap((a: any) => a?.design?.screens || []) || []).map((item) => new Screen(this.client, { ...item, projectId: this.projectId }));
} catch (error) {
throw StitchError.fromUnknown(error);
}
Expand Down
6 changes: 4 additions & 2 deletions packages/sdk/generated/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
DO NOT EDIT — changes will be overwritten.

Source: tools-manifest.json (sha256:2f1a623ec115...)
domain-map.json (sha256:baa17d36f4c1...)
Generated: 2026-04-28T16:31:23.449Z
domain-map.json (sha256:ffa082d8fbe7...)
Generated: 2026-04-28T20:49:35.251Z
*/
export { Stitch } from "./stitch.js";
export { Project } from "./project.js";
export { Screen } from "./screen.js";
export { DesignSystem } from "./designsystem.js";
export { toolDefinitions, type ToolDefinition, type ToolInputSchema, type ToolPropertySchema } from "./tool-definitions.js";
export type * from "./types.generated.js";
export type * from "./responses.generated.js";
27 changes: 17 additions & 10 deletions packages/sdk/generated/src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
DO NOT EDIT — changes will be overwritten.

Source: tools-manifest.json (sha256:2f1a623ec115...)
domain-map.json (sha256:baa17d36f4c1...)
Generated: 2026-04-28T16:31:23.449Z
domain-map.json (sha256:ffa082d8fbe7...)
Generated: 2026-04-28T20:49:35.251Z
*/
import { type StitchToolClient } from "../../src/client.js";
import { StitchError } from "../../src/spec/errors.js";
import { DesignTheme, File, ProjectMetadata, ScreenInstance, Typography, UserFeedback, ProjectInput, ScreenInput, Asset, BoundingBox, ComponentRegion, Design, DesignSuggestion, DesignSystemInput, ProgressUpdate, ProgressUpdates, PrototypeLink, PrototypeLinks, PrototypeState, PrototypeV2Spec, ScreenMetadata, SessionOutputComponent, VariantOptions, SelectedScreenInstance } from "./types.generated.js";
import { GenerateScreenFromTextResponse, ListScreensResponse, GetScreenResponse, CreateDesignSystemResponse, ListDesignSystemsResponse } from "./responses.generated.js";
import { Screen } from "./screen.js";
import { DesignSystem } from "./designsystem.js";

Expand Down Expand Up @@ -37,7 +39,7 @@ export class Project {
*/
async generate(prompt: string, deviceType?: "DEVICE_TYPE_UNSPECIFIED" | "MOBILE" | "DESKTOP" | "TABLET" | "AGNOSTIC", modelId?: "MODEL_ID_UNSPECIFIED" | "GEMINI_3_PRO" | "GEMINI_3_FLASH" | "GEMINI_3_1_PRO"): Promise<Screen> {
try {
const raw = await this.client.callTool<any>("generate_screen_from_text", { projectId: this.projectId, prompt, deviceType, modelId });
const raw = await this.client.callTool<GenerateScreenFromTextResponse>("generate_screen_from_text", { projectId: this.projectId, prompt, deviceType, modelId });
const _projected = (raw?.outputComponents ?? []).find((c: any) => c?.design?.screens != null)?.design?.screens?.[0];
if (!_projected) throw new StitchError({ code: "UNKNOWN_ERROR", message: "Incomplete API response from generate_screen_from_text: expected object at projection path", recoverable: false });
return new Screen(this.client, { ..._projected, projectId: this.projectId })
Expand All @@ -52,8 +54,8 @@ export class Project {
*/
async screens(): Promise<Screen[]> {
try {
const raw = await this.client.callTool<any>("list_screens", { projectId: this.projectId });
return (raw?.screens || []).map((item: any) => new Screen(this.client, { ...item, projectId: this.projectId }));
const raw = await this.client.callTool<ListScreensResponse>("list_screens", { projectId: this.projectId });
return (raw?.screens || []).map((item) => new Screen(this.client, { ...item, projectId: this.projectId }));
} catch (error) {
throw StitchError.fromUnknown(error);
}
Expand All @@ -65,7 +67,7 @@ export class Project {
*/
async getScreen(screenId: string): Promise<Screen> {
try {
const raw = await this.client.callTool<any>("get_screen", { projectId: this.projectId, screenId, name: `projects/${this.projectId}/screens/${screenId}` });
const raw = await this.client.callTool<GetScreenResponse>("get_screen", { projectId: this.projectId, screenId, name: `projects/${this.projectId}/screens/${screenId}` });
return new Screen(this.client, { ...raw, projectId: this.projectId });
} catch (error) {
throw StitchError.fromUnknown(error);
Expand All @@ -76,9 +78,9 @@ export class Project {
* Creates a new design system for a project. Use this tool when the user wants to set or update the overall visual theme, style, or branding of the application.
* Tool: create_design_system
*/
async createDesignSystem(designSystem: any): Promise<DesignSystem> {
async createDesignSystem(designSystem: DesignSystemInput): Promise<DesignSystem> {
try {
const raw = await this.client.callTool<any>("create_design_system", { projectId: this.projectId, designSystem });
const raw = await this.client.callTool<CreateDesignSystemResponse>("create_design_system", { projectId: this.projectId, designSystem });
return new DesignSystem(this.client, { ...raw, projectId: this.projectId });
} catch (error) {
throw StitchError.fromUnknown(error);
Expand All @@ -91,8 +93,8 @@ export class Project {
*/
async listDesignSystems(): Promise<DesignSystem[]> {
try {
const raw = await this.client.callTool<any>("list_design_systems", { projectId: this.projectId });
return (raw?.designSystems || []).map((item: any) => new DesignSystem(this.client, { ...item, projectId: this.projectId }));
const raw = await this.client.callTool<ListDesignSystemsResponse>("list_design_systems", { projectId: this.projectId });
return (raw?.designSystems || []).map((item) => new DesignSystem(this.client, { ...item, projectId: this.projectId }));
} catch (error) {
throw StitchError.fromUnknown(error);
}
Expand All @@ -102,4 +104,9 @@ export class Project {
designSystem(id: string): DesignSystem {
return new DesignSystem(this.client, { name: id, projectId: this.projectId });
}

/** Create a Screen handle from an existing ID without an API call. */
screen(id: string): Screen {
return new Screen(this.client, { id: id, projectId: this.projectId });
}
}
115 changes: 115 additions & 0 deletions packages/sdk/generated/src/responses.generated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { DesignTheme, File, ProjectMetadata, ScreenInstance, Typography, UserFeedback, ProjectInput, ScreenInput, Asset, BoundingBox, ComponentRegion, Design, DesignSuggestion, DesignSystemInput, ProgressUpdate, ProgressUpdates, PrototypeLink, PrototypeLinks, PrototypeState, PrototypeV2Spec, ScreenMetadata, SessionOutputComponent, VariantOptions, SelectedScreenInstance } from "./types.generated.js";
/**
* AUTO-GENERATED by scripts/generate-sdk.ts
DO NOT EDIT — changes will be overwritten.

Source: tools-manifest.json (sha256:2f1a623ec115...)
domain-map.json (sha256:ffa082d8fbe7...)
Generated: 2026-04-28T20:49:35.251Z
*/

/** Response message for create_project. */
export interface CreateProjectResponse {
backgroundTheme?: string;
createTime?: string;
designTheme?: DesignTheme;
deviceType?: "DEVICE_TYPE_UNSPECIFIED" | "MOBILE" | "DESKTOP" | "TABLET" | "AGNOSTIC";
metadata?: ProjectMetadata;
name?: string;
origin?: "ORIGIN_UNSPECIFIED" | "STITCH" | "IMPORTED_FROM_GALILEO";
projectType?: "PROJECT_TYPE_UNSPECIFIED" | "TEXT_TO_UI" | "TEXT_TO_UI_PRO" | "TEXT_TO_UI_PRO_IMAGE_SPACE" | "IMAGE_TO_UI" | "IMAGE_TO_UI_PRO" | "PROJECT_DESIGN";
readTime?: string;
screenInstances?: ScreenInstance[];
thumbnailScreenshot?: File;
title?: string;
updateTime?: string;
visibility?: "VISIBILITY_UNSPECIFIED" | "PUBLIC" | "PRIVATE";
}

/** Response message for get_project. */
export interface GetProjectResponse {
backgroundTheme?: string;
createTime?: string;
designTheme?: DesignTheme;
deviceType?: "DEVICE_TYPE_UNSPECIFIED" | "MOBILE" | "DESKTOP" | "TABLET" | "AGNOSTIC";
metadata?: ProjectMetadata;
name?: string;
origin?: "ORIGIN_UNSPECIFIED" | "STITCH" | "IMPORTED_FROM_GALILEO";
projectType?: "PROJECT_TYPE_UNSPECIFIED" | "TEXT_TO_UI" | "TEXT_TO_UI_PRO" | "TEXT_TO_UI_PRO_IMAGE_SPACE" | "IMAGE_TO_UI" | "IMAGE_TO_UI_PRO" | "PROJECT_DESIGN";
readTime?: string;
screenInstances?: ScreenInstance[];
thumbnailScreenshot?: File;
title?: string;
updateTime?: string;
visibility?: "VISIBILITY_UNSPECIFIED" | "PUBLIC" | "PRIVATE";
}

/** Response message for list_projects. */
export interface ListProjectsResponse {
projects?: ProjectInput[];
}

/** Response message for list_screens. */
export interface ListScreensResponse {
screens?: ScreenInput[];
}

/** Response message for get_screen. */
export interface GetScreenResponse {
deviceType?: "DEVICE_TYPE_UNSPECIFIED" | "MOBILE" | "DESKTOP" | "TABLET" | "AGNOSTIC";
height?: string;
htmlCode?: File;
name?: string;
screenshot?: File;
title?: string;
width?: string;
}

/** Response message for generate_screen_from_text. */
export interface GenerateScreenFromTextResponse {
outputComponents?: SessionOutputComponent[];
projectId?: string;
sessionId?: string;
}

/** Response message for edit_screens. */
export interface EditScreensResponse {
outputComponents?: SessionOutputComponent[];
projectId?: string;
sessionId?: string;
}

/** Response message for generate_variants. */
export interface GenerateVariantsResponse {
outputComponents?: SessionOutputComponent[];
projectId?: string;
sessionId?: string;
}

/** Response message for create_design_system. */
export interface CreateDesignSystemResponse {
copiedFrom?: string;
designSystem?: DesignSystemInput;
name?: string;
version?: string;
}

/** Response message for update_design_system. */
export interface UpdateDesignSystemResponse {
copiedFrom?: string;
designSystem?: DesignSystemInput;
name?: string;
version?: string;
}

/** Response message for list_design_systems. */
export interface ListDesignSystemsResponse {
designSystems?: Asset[];
}

/** Response message for apply_design_system. */
export interface ApplyDesignSystemResponse {
outputComponents?: SessionOutputComponent[];
projectId?: string;
sessionId?: string;
}
Loading
Loading