Skip to content
Open
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
7 changes: 7 additions & 0 deletions packages/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,13 @@ This is not an officially supported Google product. This project is not
eligible for the [Google Open Source Software Vulnerability Rewards
Program](https://bughunters.google.com/open-source-security).

## Examples

- [Basic Design Generation](./examples/basic-design)
- [Design System Extraction](./examples/design-system-extraction)
- [Stitch MCP Server](./examples/mcp-server)
- [CI Visual Testing](./examples/ci-visual-testing/README.md) - Integrating Stitch SDK for visual regression testing.

## License

Apache 2.0 — see [LICENSE](LICENSE) for details.
12 changes: 12 additions & 0 deletions packages/sdk/examples/ci-visual-testing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# CI Visual Testing with Stitch

This directory contains an example of how to integrate the Stitch SDK into a CI pipeline for visual testing and regression analysis. The process is broken into two parts:

1. **Deterministic Runner** (`scripts/ci-runner.ts`): Re-runs the Stitch generation with the baseline prompt, captures the new screenshot URL, and outputs a JSON diff report.
2. **Agent Skill** (`SKILL.md`): Teaches an agent how to evaluate the visual diff report, download the before/after screenshots, and make a pass/fail judgment.

## Running the Example

```bash
bun run scripts/ci-runner.ts
```
13 changes: 13 additions & 0 deletions packages/sdk/examples/ci-visual-testing/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Stitch CI Visual Testing Skill

**Description:** Teaches an agent how to evaluate visual diffs from Stitch screenshot URLs during CI.

## Context
When the deterministic CI runner (`scripts/ci-runner.ts`) finishes, it outputs a JSON report containing the baseline screenshot URL and the new candidate screenshot URL.

## Agent Instructions
1. **Read the CI Report**: Parse the JSON output from `scripts/ci-runner.ts`.
2. **Fetch Screenshots**: Download the images from the provided CDN URLs.
3. **Analyze Visual Differences**: Compare the layout, typography, and color schemes.
4. **Evaluate Constraints**: Check if the candidate design still meets the original prompt constraints.
5. **Output Verdict**: Produce a Pass/Fail verdict with specific reasoning based on the visual comparison.
33 changes: 33 additions & 0 deletions packages/sdk/examples/ci-visual-testing/scripts/ci-runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { stitch } from "@google/stitch-sdk";

// Simulate reading a baseline definition from source control
const baseline = {
projectId: "9651283129364717298", // Sample project
prompt: "A login screen with email and password fields, minimalist design",
baselineImageUrl: "https://lh3.googleusercontent.com/a/sample-baseline",
};

if (!process.env.STITCH_API_KEY) {
console.error("STITCH_API_KEY is required");
process.exit(1);
}

console.log("Starting CI Visual Test Runner...");
const project = stitch.project(baseline.projectId);

console.log("Generating candidate design...");
const candidateScreen = await project.generate(baseline.prompt);

console.log("Fetching candidate screenshot URL...");
const candidateImageUrl = await candidateScreen.getImage();

const report = {
baseline: baseline.baselineImageUrl,
candidate: candidateImageUrl,
candidateScreenId: candidateScreen.id,
prompt: baseline.prompt,
};

console.log("\n--- CI REPORT ---");
console.log(JSON.stringify(report, null, 2));
console.log("-----------------");
35 changes: 35 additions & 0 deletions packages/sdk/examples/mcp-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Stitch Design MCP Server Example

This example demonstrates how to build a Model Context Protocol (MCP) server that exposes the Stitch SDK to agent frameworks. It wraps the core Stitch functionality into high-level, compound tools that are optimized for AI agents.

## Why wrap Stitch in another MCP Server?

Stitch itself is an MCP server, but its native tools are low-level (e.g., `create_project`, `generate_screen_from_text`). When building an AI agent that generates and implements UI designs, wrapping the Stitch SDK in a custom MCP server allows you to:

1. **Create Compound Actions**: Combine generation, asset extraction, and theme parsing into a single tool call (e.g., `generate_and_extract`), saving the agent multiple round-trips.
2. **Add Domain-Specific Logic**: Translate Stitch's generic HTML output into your framework's specific structure (e.g., scaffolding a Next.js or Astro project automatically).
3. **Control Tool Exposure**: Expose only the specific workflows your agent needs, rather than the entire raw Stitch API.

## Example Tools

This server exposes compound tools:

- `generate_and_extract`: Generates a screen from a prompt and returns the extracted theme + HTML body + screenshot URL in one call.
- `compare_themes`: Generates variants of a screen and diffs their configs.
- `scaffold_project`: Generates multiple screens based on a requirement and returns them as a page manifest.

## Running the Server

To start the MCP server over standard input/output (stdio), which is the standard way MCP clients communicate with servers:

```bash
export STITCH_API_KEY="your-api-key"
bun run src/index.ts
```

## Using with an MCP Client

You can use this server with any MCP-compatible client, such as the Vercel AI SDK or an agent framework.

1. Configure your client to spawn this script as a child process.
2. The server communicates via standard input/output using the MCP protocol.
94 changes: 94 additions & 0 deletions packages/sdk/examples/mcp-server/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Skill: Building a Stitch MCP Server

This skill teaches an agent how to wrap the Stitch SDK into a custom Model Context Protocol (MCP) server.

## Context

While Stitch provides its own MCP tools, agents often benefit from compound tools that combine multiple Stitch operations or add domain-specific logic. By creating a custom MCP server, you can provide an agent with high-level workflows tailored to specific tasks, such as generating a UI and immediately extracting its Tailwind config in a single step.

## Implementation Pattern

1. **Initialize the MCP Server**: Use the `@modelcontextprotocol/sdk/server` package.
2. **Define Compound Tools**: Create tools that encapsulate multiple Stitch SDK calls.
3. **Use the Stitch SDK**: Use `@google/stitch-sdk` to interact with Stitch within your tool handlers.
4. **Connect Transport**: Start the server using the `StdioServerTransport`.

## Example: `generate_and_extract` Tool

This compound tool generates a screen and extracts the relevant parts (HTML body, Tailwind config, image URL) in a single step.

```typescript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { stitch } from "@google/stitch-sdk";

// 1. Initialize Server
const server = new Server(
{ name: "stitch-custom-mcp", version: "1.0.0" },
{ capabilities: { tools: {} } }
);

// 2. Define Tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "generate_and_extract",
description: "Generates a UI screen and extracts its theme and HTML body.",
inputSchema: {
type: "object",
properties: {
prompt: { type: "string", description: "The UI to generate" },
title: { type: "string", description: "Project title" }
},
required: ["prompt", "title"]
}
}
]
};
});

// 3. Handle Tool Calls using Stitch SDK
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "generate_and_extract") {
const { prompt, title } = request.params.arguments as any;

// Use the Stitch SDK
const project = await stitch.createProject(title);
const screen = await project.generate(prompt);

const htmlUrl = await screen.getHtml();
const imageUrl = await screen.getImage();

// Fetch and extract data (simplified for example)
const resp = await fetch(htmlUrl);
const html = await resp.text();
const configMatch = html.match(/<script id="tailwind-config">([\s\S]*?)<\/script>/);

return {
content: [{
type: "text",
text: JSON.stringify({
imageUrl,
tailwindConfig: configMatch ? configMatch[1].trim() : null,
htmlLength: html.length
}, null, 2)
}]
};
}
throw new Error("Tool not found");
});

// 4. Connect Transport
async function run() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Stitch Custom MCP Server running on stdio");
}

run().catch(console.error);
```
Loading