diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json
index c699a77..35c4102 100644
--- a/.claude-plugin/marketplace.json
+++ b/.claude-plugin/marketplace.json
@@ -10,7 +10,7 @@
"plugins": [
{
"name": "stitch-kit",
- "description": "Everything — all 35 skills in one install.",
+ "description": "Everything — all 36 skills in one install.",
"source": "./",
"strict": true,
"skills": [
@@ -27,13 +27,14 @@
"./skills/stitch-mcp-list-screens",
"./skills/stitch-mcp-get-screen",
"./skills/stitch-mcp-delete-project",
- "./skills/stitch-mcp-upload-screens-from-images",
"./skills/stitch-mcp-edit-screens",
"./skills/stitch-mcp-generate-variants",
"./skills/stitch-mcp-create-design-system",
"./skills/stitch-mcp-update-design-system",
"./skills/stitch-mcp-list-design-systems",
"./skills/stitch-mcp-apply-design-system",
+ "./skills/stitch-mcp-upload-design-md",
+ "./skills/stitch-mcp-create-design-system-from-design-md",
"./skills/stitch-nextjs-components",
"./skills/stitch-svelte-components",
"./skills/stitch-react-components",
diff --git a/.github/assets/banner.svg b/.github/assets/banner.svg
index 37e1484..a875e03 100644
--- a/.github/assets/banner.svg
+++ b/.github/assets/banner.svg
@@ -46,7 +46,7 @@
- 35 skills
+ 36 skills
|
5 layers
|
diff --git a/AGENTS.md b/AGENTS.md
index 47deab4..3328994 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -4,7 +4,7 @@ Guidance for Claude Code, Cursor, Copilot, Codex CLI, and other AI agents workin
## What this repo is
-A collection of Claude Code **skills** — 35 packaged instructions and scripts that extend AI agents with Stitch-specific capabilities: text-to-UI generation, design iteration (edit, variants, design systems), design token extraction, and multi-framework conversion. Think of it as a Stitch co-pilot that wraps all 14 MCP tools and knows the footguns so you don't have to learn them the hard way.
+A collection of Claude Code **skills** — 35 packaged instructions and scripts that extend AI agents with Stitch-specific capabilities: text-to-UI generation, design iteration (edit, variants, design systems), design token extraction, and multi-framework conversion. Think of it as a Stitch co-pilot that wraps 13 of the 15 Stitch MCP tools and knows the footguns so you don't have to learn them the hard way.
## Skill structure
@@ -88,7 +88,7 @@ For Stitch-based UI generation, load **`stitch-orchestrator`** or invoke the **`
| Layer | Count | Purpose |
|-------|-------|---------|
| **Brain** (`stitch-ui-*`, `stitch-ideate`) | 5 | Design intelligence — ideation agent, specs, prompts, variants, UED guide |
-| **Hands** (`stitch-mcp-*`) | 14 | MCP wrappers — one per Stitch API tool, handles ID format rules |
+| **Hands** (`stitch-mcp-*`) | 13 | MCP wrappers — one per Stitch API tool, handles ID format rules |
| **Conversion** | 7+ | Stitch HTML → framework components (Next.js, Svelte, React, HTML, RN, SwiftUI, shadcn) |
| **Quality** | 3 | Design tokens, accessibility audit, animations |
@@ -98,7 +98,7 @@ Skills marked `allowed-tools: ["stitch*:*"]` require the **Stitch MCP Server** c
Setup guide: https://stitch.withgoogle.com/docs/mcp/setup
-All 14 tools wrapped: `create_project`, `get_project`, `delete_project`, `list_projects`, `generate_screen_from_text`, `upload_screens_from_images`, `edit_screens`, `generate_variants`, `list_screens`, `get_screen`, `create_design_system`, `update_design_system`, `list_design_systems`, `apply_design_system`
+13 of the 15 Stitch MCP tools wrapped: `create_project`, `get_project`, `delete_project`, `list_projects`, `generate_screen_from_text`, `edit_screens`, `generate_variants`, `list_screens`, `get_screen`, `create_design_system`, `update_design_system`, `list_design_systems`, `apply_design_system`
Without MCP: the orchestrator falls back to prompt-only mode (generates ready-to-copy Stitch prompts instead of running the full workflow — still useful, just slower).
@@ -112,7 +112,6 @@ Without MCP: the orchestrator falls back to prompt-only mode (generates ready-to
| `stitch-ui-prompt-architect` | Design spec → structured Stitch prompt |
| `stitch-mcp-edit-screens` | Edit existing screens with text prompts (iteration) |
| `stitch-mcp-generate-variants` | Generate design alternatives with creativity controls |
-| `stitch-mcp-upload-screens-from-images` | Import screenshots for redesign workflows |
| `stitch-mcp-create-design-system` | Create reusable Stitch Design Systems |
| `stitch-mcp-apply-design-system` | Apply design systems to screens |
| `stitch-mcp-get-screen` | Retrieve screen HTML + screenshot by ID |
@@ -132,7 +131,7 @@ Without MCP: the orchestrator falls back to prompt-only mode (generates ready-to
See [`docs/`](docs/) for:
- `skills-index.md` — complete skills table with descriptions and layers
-- `mcp-schemas/` — JSON Schema for all 14 Stitch MCP tools
+- `mcp-schemas/` — JSON Schema for the 13 Stitch MCP tools this repo wraps
- `color-prompt-guide.md` — 8 ready-to-use color palette prompts for Stitch
- `tailwind-reference.md` — Tailwind utility class reference for conversions
- `mcp-naming-convention.md` — MCP tool name → skill name mapping
diff --git a/README.md b/README.md
index ce4ce78..1777b6d 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@ Then, inside Claude Code, add the skills:
/plugin install stitch-kit@stitch-kit
```
-Two steps, not one — the npx installer handles the agent and MCP wiring, the plugin adds the 35 skills. The agent works without them, but the skills are what make the output good.
+Two steps, not one — the npx installer handles the agent and MCP wiring, the plugin adds the 36 skills. The agent works without them, but the skills are what make the output good.
```bash
npx @booplex/stitch-kit update # update to latest
@@ -171,12 +171,12 @@ Pick your target:
## Architecture
-
+
-Five layers, 35 skills. Each layer exists because agents fail at something specific with Stitch, and the failures are different enough that one skill can't cover them.
+Five layers, 36 skills. Each layer exists because agents fail at something specific with Stitch, and the failures are different enough that one skill can't cover them.
-**The ID format thing deserves its own callout.** `generate_screen_from_text` wants `"3780309359108792857"`. `list_screens` wants `"projects/3780309359108792857"`. Pass the wrong one and you get a cryptic error. This is the #1 reason agents fail with raw Stitch MCP, and it's why there are 14 wrapper skills instead of letting agents call the API directly.
+**The ID format thing deserves its own callout.** `generate_screen_from_text` wants `"3780309359108792857"`. `list_screens` wants `"projects/3780309359108792857"`. Pass the wrong one and you get a cryptic error. This is the #1 reason agents fail with raw Stitch MCP, and it's why there's a dedicated wrapper skill per API tool instead of letting agents call the API directly.
Details → [docs/architecture.md](docs/architecture.md)
@@ -196,41 +196,52 @@ The examples folder is the secret weapon. Agents produce dramatically better out
## vs. the official Google Stitch Skills
-Google published [6 skills](https://github.com/google-labs-code/stitch-skills). They cover the basics — enhance a prompt, convert to React, make a video walkthrough. Useful starting point.
+Google's [official repo](https://github.com/google-labs-code/stitch-skills) ships 15 skills across three plugins — `stitch-design`, `stitch-build`, `stitch-utilities`. It's a real toolkit, not a stub, and it does one whole thing stitch-kit doesn't (see the gaps below).
-stitch-kit has 35. It covers the full pipeline: conversational ideation with web research, multi-screen batch generation, design system management, iteration loops, and conversion to 7 frameworks. Every official skill has a local equivalent that does more:
+Raw skill counts aren't a fair comparison: Google consolidated generate/edit/variants into one skill and the four design-system operations into another, where stitch-kit keeps them as separate wrappers. Different granularity, not more capability. Here's where both cover the same ground:
| Official | stitch-kit | What's different |
|----------|-----------|-----------------|
| `design-md` | `stitch-design-md` | Adds Section 6 — design system notes that feed back into Stitch prompts for consistent multi-screen output |
| `enhance-prompt` | `stitch-ui-prompt-architect` | Two modes: (A) vague → enhanced, same as official; (B) Design Spec → structured `[Context][Layout][Components]` prompt. Mode B produces significantly better results. |
| `stitch-loop` | `stitch-loop` | Visual verification step, explicit MCP naming, DESIGN.md integration |
-| `react-components` | `stitch-react-components` | MCP-native retrieval, optional DESIGN.md alignment |
+| `stitch::react-components` | `stitch-react-components` | Also accepts a local HTML file or URL, not just a Stitch screen |
+| `stitch::react-native` | `stitch-react-native-components` | Also accepts a local HTML file or URL; theirs adds a re-sync path for existing native components |
+| `stitch::generate-design` | `stitch-mcp-generate-screen-from-text` + `-edit-screens` + `-generate-variants` | Split into one skill per MCP tool, each enforcing the right ID format |
+| `stitch::manage-design-system` | `stitch-mcp-create/update/list/apply-design-system` | Same split-by-operation approach |
| `remotion` | `stitch-remotion` | Common patterns (slideshow, feature highlight, user flow), voiceover, dynamic text |
| `shadcn-ui` | `stitch-shadcn-ui` | Init styles support, custom registries, validation checklist |
-**What's entirely new (doesn't exist in the official repo):**
-- `stitch-ideate` — conversational design agent that researches trends, proposes directions, produces PRDs, and batch-generates all screens
-- `stitch-orchestrator` — end-to-end coordinator with smart ideation routing
-- `stitch-mcp-*` wrappers — all 14 Stitch API tools wrapped with ID format safety (this alone saves hours of debugging)
-- `stitch-mcp-edit-screens` — iterate on existing designs without regenerating from scratch
-- `stitch-mcp-generate-variants` — native variant generation with creativity controls
-- `stitch-mcp-upload-screens-from-images` — import screenshots for redesign workflows
-- `stitch-mcp-create/update/list/apply-design-system` — full Stitch Design System lifecycle
-- `stitch-ui-design-spec-generator` — structured spec before prompt (better output than pure prompt enhancement)
-- Mobile targets: `stitch-react-native-components` + `stitch-swiftui-components`
-- `stitch-design-system` — token extraction → CSS custom properties with dark mode
-- `stitch-a11y` — WCAG 2.1 AA audit + auto-fixes
-- `stitch-animate` — purposeful motion with `prefers-reduced-motion` handled
-- `stitch-skill-creator` — meta-skill for extending the plugin
+**What stitch-kit adds:**
+
+- `stitch-ideate` — conversational design agent that researches trends, proposes directions, produces PRDs, and batch-generates all screens. No equivalent.
+- `stitch-orchestrator` — end-to-end coordinator with smart ideation routing. No equivalent.
+- `stitch-ui-design-spec-generator` — structured spec before prompt, which beats pure prompt enhancement. No equivalent.
+- `stitch-swiftui-components` — SwiftUI isn't a target in the official repo at all.
+- `stitch-design-system` — token extraction → CSS custom properties with dark mode. Their `manage-design-system` handles Stitch-side design systems; this one emits CSS for your codebase.
+- `stitch-a11y` — a dedicated WCAG 2.1 AA audit-and-fix pass. They cover accessibility as guidance inside individual conversion skills, but there's no audit skill.
+- `stitch-animate` — implements motion in components. Their `taste-design` specifies motion philosophy in DESIGN.md; this writes the actual animation code with `prefers-reduced-motion` handled.
+- `stitch-skill-creator` — meta-skill for extending the plugin. No equivalent.
+- Every conversion skill takes a local HTML file or URL, so that half works with no Stitch account.
+
+**What Google has that stitch-kit doesn't** — worth knowing before you pick:
+
+- `stitch::upload-to-stitch` — uploads screenshots or mockups into a Stitch project. stitch-kit had a wrapper for this (`upload_screens_from_images`), but Google removed that tool from the live MCP API — there's no image-upload route left on the API side, so the wrapper skill is gone too. Recreate the design from a text prompt instead, or use one of the conversion skills' local-file routes if you already have markup.
+- `stitch::code-to-design` — pulls an *existing* web app into Stitch by chaining the two skills below. stitch-kit only goes design → code; this goes code → design.
+- `stitch::extract-static-html` — extracts self-contained static HTML, assets inlined, from a running app
+- `stitch::extract-design-md` — generates DESIGN.md from frontend **source code**. stitch-kit's version reads a Stitch project instead, so same output, different input.
+- `taste-design` — a stricter anti-generic DESIGN.md variant (calibrated color, asymmetric layout, deliberate motion)
+- `react-vite-dashboard` — Vite dashboard generator, Web3/DeFi flavored
+
+If your workflow starts from an app you've already built and you want it *in* Stitch, use the official repo — that's the direction stitch-kit doesn't cover.
---
## Full skill reference
-All 35 skills with descriptions, layers, and the ID format table → [docs/skills-index.md](docs/skills-index.md)
+All 36 skills with descriptions, layers, and the ID format table → [docs/skills-index.md](docs/skills-index.md)
-MCP API schemas (JSON Schema for all 14 Stitch tools) → [docs/mcp-schemas/](docs/mcp-schemas/)
+MCP API schemas (JSON Schema for the 15 Stitch tools, all wrapped) → [docs/mcp-schemas/](docs/mcp-schemas/)
---
diff --git a/agents/stitch-kit.md b/agents/stitch-kit.md
index edef388..3493d76 100644
--- a/agents/stitch-kit.md
+++ b/agents/stitch-kit.md
@@ -1,6 +1,6 @@
---
name: stitch-kit
-description: "Use this agent for anything Stitch-related: ideating designs through conversation, generating UI screens from text, editing/iterating designs, generating design variants, managing Stitch Design Systems, converting designs to production code, extracting design tokens, and running the full design-to-ship pipeline. Examples: (1) Generate a UI from a description or PRD using Stitch MCP; (2) Ideate a design — brainstorm, research trends, explore directions, produce a PRD; (3) Edit an existing screen with text prompts (change colors, layout, content); (4) Generate design variants with configurable creativity; (5) Upload screenshots and redesign them in Stitch; (6) Create and apply Stitch Design Systems for visual consistency; (7) Convert a Stitch screen to Next.js, Svelte, React, React Native, or SwiftUI components; (8) Extract design tokens and CSS variables from a generated screen; (9) Build a multi-page site iteratively with visual consistency across screens; (10) Audit components for WCAG 2.1 AA accessibility; (11) Parse a Stitch URL (stitch.withgoogle.com/projects/ID?node-id=SCREEN_ID) and go straight to conversion."
+description: "Use this agent for anything Stitch-related: ideating designs through conversation, generating UI screens from text, editing/iterating designs, generating design variants, managing Stitch Design Systems, converting designs to production code, extracting design tokens, and running the full design-to-ship pipeline. Examples: (1) Generate a UI from a description or PRD using Stitch MCP; (2) Ideate a design — brainstorm, research trends, explore directions, produce a PRD; (3) Edit an existing screen with text prompts (change colors, layout, content); (4) Generate design variants with configurable creativity; (5) Create and apply Stitch Design Systems for visual consistency; (6) Convert a Stitch screen to Next.js, Svelte, React, React Native, or SwiftUI components; (7) Extract design tokens and CSS variables from a generated screen; (8) Build a multi-page site iteratively with visual consistency across screens; (9) Audit components for WCAG 2.1 AA accessibility; (10) Parse a Stitch URL (stitch.withgoogle.com/projects/ID?node-id=SCREEN_ID) and go straight to conversion."
model: opus
---
@@ -13,7 +13,6 @@ You are a Stitch design-to-code specialist. You handle the full pipeline from UI
- Batch-generate multiple screens from a full PRD (up to 10 per call, auto-continuation for more)
- Edit existing screens with text prompts (edit_screens) — iterate without regenerating
- Generate design variants with configurable creativity and aspect controls (generate_variants)
-- Upload screenshots/mockups to redesign in Stitch (upload_screens_from_images)
- Create, update, list, and apply Stitch Design Systems for cross-screen consistency
- Convert Stitch HTML to Next.js 15 App Router, Svelte 5, Vite+React, HTML5, React Native/Expo, or SwiftUI
- Extract design tokens → CSS custom properties (light + dark mode)
@@ -46,7 +45,7 @@ Call `stitch-mcp-edit-screens` with specific edit instructions. Handle `output_c
Call `stitch-mcp-generate-variants` with `variantOptions` (creativeRange: REFINE/EXPLORE/REIMAGINE, aspects: LAYOUT/COLOR_SCHEME/IMAGES/TEXT_FONT/TEXT_CONTENT).
**If the user wants to upload a screenshot:**
-Encode the image to base64 with `scripts/encode-image.sh`, then call `stitch-mcp-upload-screens-from-images`. Offer edit or convert after.
+There's no upload route — the Stitch MCP API has no image-upload tool. Tell the user, and offer to recreate the design from a text prompt via `stitch-mcp-generate-screen-from-text`, or to hand-write the HTML and use a conversion skill's local-file route instead.
**If the user wants to convert an existing screen:**
Get the HTML via `get_screen`, download it with `fetch-stitch.sh` if needed, then run the appropriate framework skill.
@@ -67,7 +66,6 @@ Stitch uses inconsistent ID formats across tools. Use the `stitch-mcp-*` wrapper
| `list_screens` | `projects/ID` | — | Returns full paths |
| `get_screen` | Numeric | Numeric | — |
| `generate_screen_from_text` | Numeric | — | — |
-| `upload_screens_from_images` | Numeric | — | — |
| `edit_screens` | Numeric | Numeric array | — |
| `generate_variants` | Numeric | Numeric array | — |
| `create_design_system` | Numeric (optional) | — | Returns Asset `name` |
diff --git a/docs/mcp-schemas/README.md b/docs/mcp-schemas/README.md
index d1900ad..1cde600 100644
--- a/docs/mcp-schemas/README.md
+++ b/docs/mcp-schemas/README.md
@@ -1,6 +1,6 @@
# Stitch MCP API Schemas
-Formal JSON Schema definitions for all 14 Stitch MCP tools.
+Formal JSON Schema definitions for the 13 Stitch MCP tools this repo wraps.
Each file documents the full `arguments` (input) and `outputSchema` (output) for one tool.
@@ -22,7 +22,6 @@ Each file documents the full `arguments` (input) and `outputSchema` (output) for
| File | Tool | Purpose |
|------|------|---------|
| `generate_screen_from_text.json` | `generate_screen_from_text` | Generate a screen from a prompt. Input: **numeric project ID only**. |
-| `upload_screens_from_images.json` | `upload_screens_from_images` | Upload images as new screens. Input: **numeric project ID**, base64 images. |
| `edit_screens.json` | `edit_screens` | Edit existing screens with text prompts. Input: **numeric IDs only**. |
| `generate_variants.json` | `generate_variants` | Generate design variants. Input: **numeric IDs**, variant options. |
| `list_screens.json` | `list_screens` | List screens in a project. Input: `projects/{id}` format. |
@@ -41,19 +40,52 @@ Each file documents the full `arguments` (input) and `outputSchema` (output) for
## Key insights from the schemas
-### DesignTheme — 28 available fonts
+### DesignTheme is two different shapes — read this before "fixing" a schema
-All tools that return design data include a `DesignTheme` object. The `font` field accepts these enum values:
+The DesignTheme you **send** and the DesignTheme you **get back** are not the same object, and conflating them is the easiest way to break these files.
+
+| | Input DesignTheme | Output DesignTheme |
+|---|---|---|
+| Used by | `create_design_system`, `update_design_system` | `get_project`, `list_projects`, `create_project` responses |
+| Lives under | `arguments` | `outputSchema` |
+| `saturation` | **absent** | **present** (number, e.g. `3`) |
+| `font` (legacy singular) | **absent** | **present** (enum string) |
+| `namedColors`, `spacingScale` | absent | present |
+| `bodyFontFamily` / `headlineFontFamily` / `labelFontFamily` | absent | present — human-readable names like `"Inter"`, alongside the enum form |
+
+So `saturation` and `font` being missing from the live `create_design_system` tool definition does **not** mean they're dead. They're read-only response fields. Removing them from the output schemas makes the docs claim less than the API actually returns, which is its own kind of wrong.
+
+Verified 2026-07-20 against 85 real projects from `list_projects`: `font` appeared in 74, `saturation` in 57, `namedColors` in 15, the `*FontFamily` trio in 7.
+
+**Rule of thumb:** when refreshing these schemas from a live tool definition, that definition only describes the *input*. Confirm output fields against an actual API response, not the tool schema.
+
+### DesignTheme — 68 available fonts
+
+All tools that return design data include a `DesignTheme` object. The `bodyFont`, `headlineFont`, and `labelFont` fields (and the deprecated single `font` field) accept these enum values:
**Sans-serif (modern):**
`INTER`, `GEIST`, `DM_SANS`, `MANROPE`, `PLUS_JAKARTA_SANS`, `WORK_SANS`,
-`PUBLIC_SANS`, `SOURCE_SANS_THREE`, `NUNITO_SANS`, `SPACE_GROTESK`,
+`PUBLIC_SANS`, `SOURCE_SANS_3`, `NUNITO_SANS`, `SPACE_GROTESK`,
`BE_VIETNAM_PRO`, `LEXEND`, `EPILOGUE`, `HANKEN_GROTESK`, `SPLINE_SANS`,
-`RUBIK`, `ARIMO`, `SORA`, `METROPOLIS`, `MONTSERRAT`, `IBM_PLEX_SANS`
+`RUBIK`, `ARIMO`, `SORA`, `MONTSERRAT`, `IBM_PLEX_SANS`,
+`GOOGLE_SANS`, `GOOGLE_SANS_FLEX`, `GOOGLE_SANS_TEXT`, `NOTO_SANS`, `OPEN_SANS`,
+`KARLA`, `LIBRE_FRANKLIN`, `FIRA_SANS`, `CHIVO`, `QUESTRIAL`, `OUTFIT`,
+`BRICOLAGE_GROTESQUE`, `COMFORTAA`, `QUICKSAND`, `RALEWAY`, `ROBOTO_FLEX`, `SYNE`,
+`OSWALD`, `ANYBODY`, `ATKINSON_HYPERLEGIBLE_NEXT`
-**Serif:**
+**Serif (editorial):**
`NOTO_SERIF`, `NEWSREADER`, `DOMINE`, `LIBRE_CASLON_TEXT`, `EB_GARAMOND`,
-`LITERATA`, `SOURCE_SERIF_FOUR`
+`LITERATA`, `SOURCE_SERIF_4`, `IBM_PLEX_SERIF`, `MERRIWEATHER`, `PLAYFAIR_DISPLAY`,
+`BODONI_MODA`, `VOLLKORN`
+
+**Mono / code:**
+`JETBRAINS_MONO`, `GOOGLE_SANS_CODE`, `GOOGLE_SANS_MONO`, `SPACE_MONO`, `COURIER_PRIME`
+
+**Condensed / display / impact:**
+`BEBAS_NEUE`, `ANTON`, `ARCHIVO_NARROW`, `BARLOW_CONDENSED`, `CLIMATE_CRISIS`, `POIRET_ONE`, `METROPHOBIC`
+
+**Deprecated aliases (still valid, prefer the replacement):**
+`SOURCE_SERIF_FOUR` → use `SOURCE_SERIF_4` · `SOURCE_SANS_THREE` → use `SOURCE_SANS_3` · `METROPOLIS` → no direct successor
### DesignTheme — roundness values
@@ -65,9 +97,9 @@ All tools that return design data include a `DesignTheme` object. The `font` fie
| `ROUND_FULL` | `border-radius: 9999px` | Pill buttons |
| `ROUND_TWO` | — | **Deprecated / unused** |
-### DesignTheme — saturation
+### DesignTheme — other fields
-Integer 1–4. Higher = more vivid colors. Default (unset) is neutral.
+`labelFont` (captions/UI chrome typeface), `overridePrimaryColor` / `overrideSecondaryColor` / `overrideTertiaryColor` / `overrideNeutralColor` (exact hex overrides), `spacing` (map of spacing token name → CSS value), and `typography` (map of level name, e.g. `h1`/`body`, → a Typography token with `fontFamily`, `fontSize`, `fontWeight`, `letterSpacing`, `lineHeight`) round out the object. There is no `saturation` field on the live API.
### outputComponents pattern
@@ -117,7 +149,6 @@ Useful for: targeted HTML extraction, component-level conversion, design audits.
| `list_projects` | — | — | — |
| `delete_project` | `projects/NUMERIC` | — | — |
| `generate_screen_from_text` | **NUMERIC only** | — | — |
-| `upload_screens_from_images` | **NUMERIC only** | — | — |
| `edit_screens` | **NUMERIC only** | **NUMERIC array** | — |
| `generate_variants` | **NUMERIC only** | **NUMERIC array** | — |
| `list_screens` | `projects/NUMERIC` | — | — |
diff --git a/docs/mcp-schemas/create_design_system.json b/docs/mcp-schemas/create_design_system.json
index 8faf93d..31f2762 100644
--- a/docs/mcp-schemas/create_design_system.json
+++ b/docs/mcp-schemas/create_design_system.json
@@ -1,6 +1,6 @@
{
"name": "create_design_system",
- "description": "Creates a new Stitch Design System — a reusable theme configuration (colors, fonts, roundness, saturation) that can be applied to screens.\n",
+ "description": "Creates a new Stitch Design System — a reusable theme configuration (colors, fonts, roundness) that can be applied to screens.\n",
"arguments": {
"type": "object",
"properties": {
@@ -13,7 +13,9 @@
"type": "string"
}
},
- "required": ["designSystem"],
+ "required": [
+ "designSystem"
+ ],
"description": "Request message for CreateDesignSystem.",
"$defs": {
"DesignSystemInput": {
@@ -36,74 +38,284 @@
"type": "string"
}
},
- "required": ["displayName", "theme"],
+ "required": [
+ "displayName",
+ "theme"
+ ],
"type": "object"
},
"DesignTheme": {
"description": "Visual theme configuration.",
"properties": {
- "colorMode": { "enum": ["COLOR_MODE_UNSPECIFIED", "LIGHT", "DARK"], "type": "string" },
- "font": {
+ "colorMode": {
"enum": [
- "FONT_UNSPECIFIED", "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS", "SPACE_GROTESK",
- "SPLINE_SANS", "WORK_SANS", "DOMINE", "LIBRE_CASLON_TEXT", "EB_GARAMOND",
- "LITERATA", "SOURCE_SERIF_FOUR", "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE",
- "NUNITO_SANS", "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "COLOR_MODE_UNSPECIFIED",
+ "LIGHT",
+ "DARK"
],
"type": "string"
},
- "roundness": { "enum": ["ROUNDNESS_UNSPECIFIED", "ROUND_FOUR", "ROUND_EIGHT", "ROUND_TWELVE", "ROUND_FULL"], "type": "string" },
- "saturation": { "type": "integer", "minimum": 1, "maximum": 4 },
- "customColor": { "description": "Primary color (hex).", "type": "string" },
- "backgroundLight": { "description": "Light mode background (hex).", "type": "string" },
- "backgroundDark": { "description": "Dark mode background (hex).", "type": "string" },
- "preset": { "type": "string" },
- "description": { "type": "string" },
+ "roundness": {
+ "description": "Optional. ROUND_TWO is deprecated/unused.",
+ "enum": [
+ "ROUNDNESS_UNSPECIFIED",
+ "ROUND_TWO",
+ "ROUND_FOUR",
+ "ROUND_EIGHT",
+ "ROUND_TWELVE",
+ "ROUND_FULL"
+ ],
+ "type": "string"
+ },
+ "customColor": {
+ "description": "Primary color (hex).",
+ "type": "string"
+ },
+ "backgroundLight": {
+ "description": "Light mode background (hex).",
+ "type": "string"
+ },
+ "backgroundDark": {
+ "description": "Dark mode background (hex).",
+ "type": "string"
+ },
+ "preset": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
"colorVariant": {
"enum": [
- "COLOR_VARIANT_UNSPECIFIED", "MONOCHROME", "NEUTRAL", "TONAL_SPOT",
- "VIBRANT", "EXPRESSIVE", "FIDELITY", "CONTENT", "RAINBOW", "FRUIT_SALAD"
+ "COLOR_VARIANT_UNSPECIFIED",
+ "MONOCHROME",
+ "NEUTRAL",
+ "TONAL_SPOT",
+ "VIBRANT",
+ "EXPRESSIVE",
+ "FIDELITY",
+ "CONTENT",
+ "RAINBOW",
+ "FRUIT_SALAD"
],
"type": "string"
},
"headlineFont": {
"enum": [
"FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
"bodyFont": {
"enum": [
"FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
"labelFont": {
"enum": [
"FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
@@ -120,10 +332,59 @@
"type": "string",
"description": "Auto-generated markdown design system document"
},
- "overridePrimaryColor": { "type": "string", "description": "Hex override for primary color" },
- "overrideSecondaryColor": { "type": "string" },
- "overrideTertiaryColor": { "type": "string" },
- "overrideNeutralColor": { "type": "string" }
+ "overridePrimaryColor": {
+ "type": "string",
+ "description": "Hex override for primary color"
+ },
+ "overrideSecondaryColor": {
+ "type": "string"
+ },
+ "overrideTertiaryColor": {
+ "type": "string"
+ },
+ "overrideNeutralColor": {
+ "type": "string"
+ },
+ "spacing": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Optional. Map of spacing token name to CSS value (e.g. {\"sm\": \"8px\"})."
+ },
+ "typography": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/$defs/Typography"
+ },
+ "description": "Optional. Map of typography level name (e.g. \"h1\", \"body\") to Typography token overrides."
+ }
+ },
+ "type": "object"
+ },
+ "Typography": {
+ "description": "A single typography level's CSS overrides.",
+ "properties": {
+ "fontFamily": {
+ "type": "string",
+ "description": "Optional. CSS font-family value."
+ },
+ "fontSize": {
+ "type": "string",
+ "description": "Optional. CSS font-size value (e.g. \"1rem\")."
+ },
+ "fontWeight": {
+ "type": "string",
+ "description": "Optional. CSS font-weight value (e.g. \"600\")."
+ },
+ "letterSpacing": {
+ "type": "string",
+ "description": "Optional. CSS letter-spacing value."
+ },
+ "lineHeight": {
+ "type": "string",
+ "description": "Optional. CSS line-height value."
+ }
},
"type": "object"
}
@@ -132,9 +393,17 @@
"outputSchema": {
"type": "object",
"properties": {
- "name": { "description": "Asset identifier. Format: assets/{asset_id}", "type": "string" },
- "displayName": { "type": "string" },
- "designSystem": { "description": "The created design system object.", "type": "object" }
+ "name": {
+ "description": "Asset identifier. Format: assets/{asset_id}",
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "designSystem": {
+ "description": "The created design system object.",
+ "type": "object"
+ }
},
"description": "Asset response for CreateDesignSystem."
}
diff --git a/docs/mcp-schemas/create_design_system_from_design_md.json b/docs/mcp-schemas/create_design_system_from_design_md.json
new file mode 100644
index 0000000..2b1bf12
--- /dev/null
+++ b/docs/mcp-schemas/create_design_system_from_design_md.json
@@ -0,0 +1,57 @@
+{
+ "name": "create_design_system_from_design_md",
+ "description": "Creates a design system for a project, with user uploaded DESIGN.md file, and displays the design system in the UI.\n\n**Instructions for Tool Call:**\n* Should call `upload_design_md` tool first to upload DESIGN.md to a Stitch project.\n",
+ "arguments": {
+ "type": "object",
+ "properties": {
+ "projectId": {
+ "description": "Required. The project ID to update design system for, example: '4044680601076201931', without the `projects/` prefix.",
+ "type": "string"
+ },
+ "selectedScreenInstance": {
+ "$ref": "#/$defs/SelectedScreenInstance",
+ "description": "Required. The screen instance to create the design system from, which is created by UploadDesignMd RPC."
+ },
+ "deviceType": {
+ "description": "Optional. The device type of the screen.",
+ "type": "string",
+ "enum": [
+ "DEVICE_TYPE_UNSPECIFIED",
+ "MOBILE",
+ "DESKTOP",
+ "TABLET",
+ "AGNOSTIC"
+ ]
+ }
+ },
+ "required": ["projectId", "selectedScreenInstance"],
+ "description": "Request message for CreateDesignSystemFromDesignMd."
+ },
+ "$defs": {
+ "SelectedScreenInstance": {
+ "type": "object",
+ "description": "A screen instance to be edited by the agent, selected by the user.",
+ "properties": {
+ "id": {
+ "description": "Required. The id of the screen instance, NOT the source screen id. This is available in the screen instances in the Project info, fetched by `get_project`.",
+ "type": "string"
+ },
+ "sourceScreen": {
+ "description": "Required. The source screen of the screen instance. The resource name of the source screen. Format: projects/{project}/screens/{screen}",
+ "type": "string"
+ }
+ },
+ "required": ["id", "sourceScreen"]
+ }
+ },
+ "outputSchema": {
+ "type": "object",
+ "properties": {},
+ "description": "Returns the created design system, whose resource name is in assets/{asset_id} form."
+ },
+ "notes": [
+ "Second half of a two-call pair — upload_design_md must run first or there is no screen instance to reference.",
+ "Three ID formats in one call: projectId is bare numeric, selectedScreenInstance.id is the screen INSTANCE id (not the source screen id), and sourceScreen is the full projects/{p}/screens/{s} path.",
+ "The resulting asset id is passed bare to apply_design_system, but with the assets/ prefix to generate_screen_from_text."
+ ]
+}
diff --git a/docs/mcp-schemas/create_project.json b/docs/mcp-schemas/create_project.json
index 3840a27..1ca4768 100644
--- a/docs/mcp-schemas/create_project.json
+++ b/docs/mcp-schemas/create_project.json
@@ -167,7 +167,7 @@
"type": "string"
},
"font": {
- "description": "Optional. The font of the design.",
+ "description": "Optional. The font of the design. 68 fonts available. SOURCE_SERIF_FOUR, SOURCE_SANS_THREE, and METROPOLIS are deprecated aliases — prefer SOURCE_SERIF_4, SOURCE_SANS_3, and a modern sans alternative respectively.",
"enum": [
"FONT_UNSPECIFIED",
"BE_VIETNAM_PRO",
@@ -186,9 +186,12 @@
"LIBRE_CASLON_TEXT",
"EB_GARAMOND",
"LITERATA",
+ "SOURCE_SERIF_4",
"SOURCE_SERIF_FOUR",
"MONTSERRAT",
+ "METROPHOBIC",
"METROPOLIS",
+ "SOURCE_SANS_3",
"SOURCE_SANS_THREE",
"NUNITO_SANS",
"ARIMO",
@@ -197,7 +200,265 @@
"GEIST",
"DM_SANS",
"IBM_PLEX_SANS",
- "SORA"
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
+ ],
+ "type": "string"
+ },
+ "headlineFont": {
+ "description": "Optional. Typeface for headings and titles. Same enum as `font`.",
+ "enum": [
+ "FONT_UNSPECIFIED",
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
+ ],
+ "type": "string"
+ },
+ "bodyFont": {
+ "description": "Optional. Typeface for body text and paragraphs. Same enum as `font`.",
+ "enum": [
+ "FONT_UNSPECIFIED",
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
+ ],
+ "type": "string"
+ },
+ "labelFont": {
+ "description": "Optional. Typeface for labels, captions, and UI chrome. Same enum as `font`.",
+ "enum": [
+ "FONT_UNSPECIFIED",
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
@@ -217,10 +478,94 @@
],
"type": "string"
},
+ "overridePrimaryColor": {
+ "description": "Optional. Hex override for the primary color.",
+ "type": "string"
+ },
+ "overrideSecondaryColor": {
+ "description": "Optional. Hex override for the secondary color.",
+ "type": "string"
+ },
+ "overrideTertiaryColor": {
+ "description": "Optional. Hex override for the tertiary color.",
+ "type": "string"
+ },
+ "overrideNeutralColor": {
+ "description": "Optional. Hex override for the neutral color.",
+ "type": "string"
+ },
+ "spacing": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Optional. Map of spacing token name to CSS value (e.g. {\"sm\": \"8px\"})."
+ },
+ "typography": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/$defs/Typography"
+ },
+ "description": "Optional. Map of typography level name (e.g. \"h1\", \"body\") to Typography token overrides."
+ },
"saturation": {
- "description": "Optional. The saturation of the design between 1 and 4.",
- "format": "int32",
- "type": "integer"
+ "type": "number",
+ "description": "Read-only. Colour saturation level returned by the API (observed integer values, e.g. 3). Not settable via create/update_design_system — the input DesignTheme has no saturation field.",
+ "readOnly": true
+ },
+ "namedColors": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Read-only. Resolved semantic colour roles mapped to hex values (background, error, error_container, ...). Populated after the first screen is generated.",
+ "readOnly": true
+ },
+ "spacingScale": {
+ "type": "number",
+ "description": "Read-only. Numeric spacing scale returned by the API. Distinct from the settable `spacing` map.",
+ "readOnly": true
+ },
+ "bodyFontFamily": {
+ "type": "string",
+ "description": "Read-only. Human-readable resolved body font name, e.g. \"Inter\". The enum form is in bodyFont.",
+ "readOnly": true
+ },
+ "headlineFontFamily": {
+ "type": "string",
+ "description": "Read-only. Human-readable resolved headline font name, e.g. \"Libre Caslon Text\".",
+ "readOnly": true
+ },
+ "labelFontFamily": {
+ "type": "string",
+ "description": "Read-only. Human-readable resolved label font name, e.g. \"Public Sans\".",
+ "readOnly": true
+ }
+ },
+ "type": "object"
+ },
+ "Typography": {
+ "description": "A single typography level's CSS overrides.",
+ "properties": {
+ "fontFamily": {
+ "type": "string",
+ "description": "Optional. CSS font-family value."
+ },
+ "fontSize": {
+ "type": "string",
+ "description": "Optional. CSS font-size value (e.g. \"1rem\")."
+ },
+ "fontWeight": {
+ "type": "string",
+ "description": "Optional. CSS font-weight value (e.g. \"600\")."
+ },
+ "letterSpacing": {
+ "type": "string",
+ "description": "Optional. CSS letter-spacing value."
+ },
+ "lineHeight": {
+ "type": "string",
+ "description": "Optional. CSS line-height value."
}
},
"type": "object"
@@ -269,18 +614,39 @@
"description": "Optional. Human-readable name for the group (e.g., \"Warm Minimalism\").",
"type": "string"
},
- "height": { "format": "int32", "type": "integer" },
- "hidden": { "description": "User hid this screen from canvas.", "type": "boolean" },
- "id": { "type": "string" },
- "label": { "type": "string" },
+ "height": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "hidden": {
+ "description": "User hid this screen from canvas.",
+ "type": "boolean"
+ },
+ "id": {
+ "type": "string"
+ },
+ "label": {
+ "type": "string"
+ },
"sourceScreen": {
"description": "Format: projects/{project}/screens/{screen}",
"type": "string"
},
- "variantScreenInstance": { "$ref": "#/$defs/ScreenInstance" },
- "width": { "format": "int32", "type": "integer" },
- "x": { "format": "int32", "type": "integer" },
- "y": { "format": "int32", "type": "integer" }
+ "variantScreenInstance": {
+ "$ref": "#/$defs/ScreenInstance"
+ },
+ "width": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "x": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "y": {
+ "format": "int32",
+ "type": "integer"
+ }
},
"type": "object"
}
diff --git a/docs/mcp-schemas/generate_screen_from_text.json b/docs/mcp-schemas/generate_screen_from_text.json
index 83fb6fd..10e8e5e 100644
--- a/docs/mcp-schemas/generate_screen_from_text.json
+++ b/docs/mcp-schemas/generate_screen_from_text.json
@@ -203,16 +203,20 @@
"customColor": { "description": "Custom primary color (hex).", "type": "string" },
"description": { "description": "Brief aesthetic description.", "type": "string" },
"font": {
- "description": "28 fonts available. Use enum values in prompts for precise control.",
+ "description": "68 fonts available. SOURCE_SERIF_FOUR, SOURCE_SANS_THREE, and METROPOLIS are deprecated aliases — prefer SOURCE_SERIF_4, SOURCE_SANS_3, and a modern sans alternative respectively.",
"enum": [
- "FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "FONT_UNSPECIFIED", "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE", "NEWSREADER",
+ "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS", "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS",
+ "DOMINE", "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_4", "SOURCE_SERIF_FOUR",
+ "MONTSERRAT", "METROPHOBIC", "METROPOLIS", "SOURCE_SANS_3", "SOURCE_SANS_THREE", "NUNITO_SANS",
+ "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS", "IBM_PLEX_SANS",
+ "SORA", "ANYBODY", "ANTON", "ARCHIVO_NARROW", "ATKINSON_HYPERLEGIBLE_NEXT", "BARLOW_CONDENSED",
+ "BEBAS_NEUE", "BODONI_MODA", "BRICOLAGE_GROTESQUE", "CHIVO", "CLIMATE_CRISIS", "COMFORTAA",
+ "COURIER_PRIME", "FIRA_SANS", "GOOGLE_SANS", "GOOGLE_SANS_CODE", "GOOGLE_SANS_FLEX", "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT", "IBM_PLEX_SERIF", "JETBRAINS_MONO", "KARLA", "LIBRE_FRANKLIN", "MERRIWEATHER",
+ "NOTO_SANS", "OPEN_SANS", "OSWALD", "OUTFIT", "PLAYFAIR_DISPLAY", "POIRET_ONE",
+ "QUESTRIAL", "QUICKSAND", "RALEWAY", "ROBOTO_FLEX", "SPACE_MONO", "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
@@ -222,11 +226,6 @@
"enum": ["ROUNDNESS_UNSPECIFIED", "ROUND_TWO", "ROUND_FOUR", "ROUND_EIGHT", "ROUND_TWELVE", "ROUND_FULL"],
"type": "string"
},
- "saturation": {
- "description": "Color saturation 1–4. Higher = more vivid.",
- "format": "int32",
- "type": "integer"
- },
"colorVariant": {
"enum": [
"COLOR_VARIANT_UNSPECIFIED", "MONOCHROME", "NEUTRAL", "TONAL_SPOT",
@@ -236,40 +235,52 @@
},
"headlineFont": {
"enum": [
- "FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "FONT_UNSPECIFIED", "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE", "NEWSREADER",
+ "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS", "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS",
+ "DOMINE", "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_4", "SOURCE_SERIF_FOUR",
+ "MONTSERRAT", "METROPHOBIC", "METROPOLIS", "SOURCE_SANS_3", "SOURCE_SANS_THREE", "NUNITO_SANS",
+ "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS", "IBM_PLEX_SANS",
+ "SORA", "ANYBODY", "ANTON", "ARCHIVO_NARROW", "ATKINSON_HYPERLEGIBLE_NEXT", "BARLOW_CONDENSED",
+ "BEBAS_NEUE", "BODONI_MODA", "BRICOLAGE_GROTESQUE", "CHIVO", "CLIMATE_CRISIS", "COMFORTAA",
+ "COURIER_PRIME", "FIRA_SANS", "GOOGLE_SANS", "GOOGLE_SANS_CODE", "GOOGLE_SANS_FLEX", "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT", "IBM_PLEX_SERIF", "JETBRAINS_MONO", "KARLA", "LIBRE_FRANKLIN", "MERRIWEATHER",
+ "NOTO_SANS", "OPEN_SANS", "OSWALD", "OUTFIT", "PLAYFAIR_DISPLAY", "POIRET_ONE",
+ "QUESTRIAL", "QUICKSAND", "RALEWAY", "ROBOTO_FLEX", "SPACE_MONO", "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
"bodyFont": {
"enum": [
- "FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "FONT_UNSPECIFIED", "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE", "NEWSREADER",
+ "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS", "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS",
+ "DOMINE", "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_4", "SOURCE_SERIF_FOUR",
+ "MONTSERRAT", "METROPHOBIC", "METROPOLIS", "SOURCE_SANS_3", "SOURCE_SANS_THREE", "NUNITO_SANS",
+ "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS", "IBM_PLEX_SANS",
+ "SORA", "ANYBODY", "ANTON", "ARCHIVO_NARROW", "ATKINSON_HYPERLEGIBLE_NEXT", "BARLOW_CONDENSED",
+ "BEBAS_NEUE", "BODONI_MODA", "BRICOLAGE_GROTESQUE", "CHIVO", "CLIMATE_CRISIS", "COMFORTAA",
+ "COURIER_PRIME", "FIRA_SANS", "GOOGLE_SANS", "GOOGLE_SANS_CODE", "GOOGLE_SANS_FLEX", "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT", "IBM_PLEX_SERIF", "JETBRAINS_MONO", "KARLA", "LIBRE_FRANKLIN", "MERRIWEATHER",
+ "NOTO_SANS", "OPEN_SANS", "OSWALD", "OUTFIT", "PLAYFAIR_DISPLAY", "POIRET_ONE",
+ "QUESTRIAL", "QUICKSAND", "RALEWAY", "ROBOTO_FLEX", "SPACE_MONO", "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
"labelFont": {
"enum": [
- "FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "FONT_UNSPECIFIED", "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE", "NEWSREADER",
+ "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS", "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS",
+ "DOMINE", "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_4", "SOURCE_SERIF_FOUR",
+ "MONTSERRAT", "METROPHOBIC", "METROPOLIS", "SOURCE_SANS_3", "SOURCE_SANS_THREE", "NUNITO_SANS",
+ "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS", "IBM_PLEX_SANS",
+ "SORA", "ANYBODY", "ANTON", "ARCHIVO_NARROW", "ATKINSON_HYPERLEGIBLE_NEXT", "BARLOW_CONDENSED",
+ "BEBAS_NEUE", "BODONI_MODA", "BRICOLAGE_GROTESQUE", "CHIVO", "CLIMATE_CRISIS", "COMFORTAA",
+ "COURIER_PRIME", "FIRA_SANS", "GOOGLE_SANS", "GOOGLE_SANS_CODE", "GOOGLE_SANS_FLEX", "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT", "IBM_PLEX_SERIF", "JETBRAINS_MONO", "KARLA", "LIBRE_FRANKLIN", "MERRIWEATHER",
+ "NOTO_SANS", "OPEN_SANS", "OSWALD", "OUTFIT", "PLAYFAIR_DISPLAY", "POIRET_ONE",
+ "QUESTRIAL", "QUICKSAND", "RALEWAY", "ROBOTO_FLEX", "SPACE_MONO", "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
@@ -289,7 +300,28 @@
"overridePrimaryColor": { "type": "string", "description": "Hex override for primary color" },
"overrideSecondaryColor": { "type": "string" },
"overrideTertiaryColor": { "type": "string" },
- "overrideNeutralColor": { "type": "string" }
+ "overrideNeutralColor": { "type": "string" },
+ "spacing": {
+ "type": "object",
+ "additionalProperties": { "type": "string" },
+ "description": "Optional. Map of spacing token name to CSS value (e.g. {\"sm\": \"8px\"})."
+ },
+ "typography": {
+ "type": "object",
+ "additionalProperties": { "$ref": "#/$defs/Typography" },
+ "description": "Optional. Map of typography level name (e.g. \"h1\", \"body\") to Typography token overrides."
+ }
+ },
+ "type": "object"
+ },
+ "Typography": {
+ "description": "A single typography level's CSS overrides.",
+ "properties": {
+ "fontFamily": { "type": "string", "description": "Optional. CSS font-family value." },
+ "fontSize": { "type": "string", "description": "Optional. CSS font-size value (e.g. \"1rem\")." },
+ "fontWeight": { "type": "string", "description": "Optional. CSS font-weight value (e.g. \"600\")." },
+ "letterSpacing": { "type": "string", "description": "Optional. CSS letter-spacing value." },
+ "lineHeight": { "type": "string", "description": "Optional. CSS line-height value." }
},
"type": "object"
},
diff --git a/docs/mcp-schemas/get_project.json b/docs/mcp-schemas/get_project.json
index ac0773c..796753b 100644
--- a/docs/mcp-schemas/get_project.json
+++ b/docs/mcp-schemas/get_project.json
@@ -10,32 +10,52 @@
"x-google-identifier": true
}
},
- "required": ["name"],
+ "required": [
+ "name"
+ ],
"description": "Request message for GetProject."
},
"outputSchema": {
"type": "object",
"properties": {
- "backgroundTheme": { "type": "string" },
- "createTime": { "format": "date-time", "readOnly": true, "type": "string" },
+ "backgroundTheme": {
+ "type": "string"
+ },
+ "createTime": {
+ "format": "date-time",
+ "readOnly": true,
+ "type": "string"
+ },
"designTheme": {
"$ref": "#/$defs/DesignTheme",
"description": "Output only. The theme used to generate the first design in the project.",
"readOnly": true
},
"deviceType": {
- "enum": ["DEVICE_TYPE_UNSPECIFIED", "MOBILE", "DESKTOP", "TABLET", "AGNOSTIC"],
+ "enum": [
+ "DEVICE_TYPE_UNSPECIFIED",
+ "MOBILE",
+ "DESKTOP",
+ "TABLET",
+ "AGNOSTIC"
+ ],
"readOnly": true,
"type": "string"
},
- "metadata": { "$ref": "#/$defs/ProjectMetadata" },
+ "metadata": {
+ "$ref": "#/$defs/ProjectMetadata"
+ },
"name": {
"description": "Identifier. Format: projects/{project}",
"type": "string",
"x-google-identifier": true
},
"origin": {
- "enum": ["ORIGIN_UNSPECIFIED", "STITCH", "IMPORTED_FROM_GALILEO"],
+ "enum": [
+ "ORIGIN_UNSPECIFIED",
+ "STITCH",
+ "IMPORTED_FROM_GALILEO"
+ ],
"readOnly": true,
"type": "string"
},
@@ -51,17 +71,35 @@
],
"type": "string"
},
- "readTime": { "format": "date-time", "readOnly": true, "type": "string" },
+ "readTime": {
+ "format": "date-time",
+ "readOnly": true,
+ "type": "string"
+ },
"screenInstances": {
- "items": { "$ref": "#/$defs/ScreenInstance" },
+ "items": {
+ "$ref": "#/$defs/ScreenInstance"
+ },
"readOnly": true,
"type": "array"
},
- "thumbnailScreenshot": { "$ref": "#/$defs/File" },
- "title": { "type": "string" },
- "updateTime": { "format": "date-time", "readOnly": true, "type": "string" },
+ "thumbnailScreenshot": {
+ "$ref": "#/$defs/File"
+ },
+ "title": {
+ "type": "string"
+ },
+ "updateTime": {
+ "format": "date-time",
+ "readOnly": true,
+ "type": "string"
+ },
"visibility": {
- "enum": ["VISIBILITY_UNSPECIFIED", "PUBLIC", "PRIVATE"],
+ "enum": [
+ "VISIBILITY_UNSPECIFIED",
+ "PUBLIC",
+ "PRIVATE"
+ ],
"type": "string"
}
},
@@ -69,77 +107,347 @@
"DesignTheme": {
"description": "The theme of the design.",
"properties": {
- "backgroundDark": { "type": "string" },
- "backgroundLight": { "type": "string" },
+ "backgroundDark": {
+ "type": "string"
+ },
+ "backgroundLight": {
+ "type": "string"
+ },
"colorMode": {
- "enum": ["COLOR_MODE_UNSPECIFIED", "LIGHT", "DARK"],
+ "enum": [
+ "COLOR_MODE_UNSPECIFIED",
+ "LIGHT",
+ "DARK"
+ ],
+ "type": "string"
+ },
+ "customColor": {
+ "description": "Custom primary color (hex).",
+ "type": "string"
+ },
+ "description": {
"type": "string"
},
- "customColor": { "description": "Custom primary color (hex).", "type": "string" },
- "description": { "type": "string" },
"font": {
+ "description": "68 fonts available. SOURCE_SERIF_FOUR, SOURCE_SANS_THREE, and METROPOLIS are deprecated aliases — prefer SOURCE_SERIF_4, SOURCE_SANS_3, and a modern sans alternative respectively.",
"enum": [
"FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
- "preset": { "type": "string" },
+ "preset": {
+ "type": "string"
+ },
"roundness": {
"description": "ROUND_TWO is deprecated/unused.",
- "enum": ["ROUNDNESS_UNSPECIFIED", "ROUND_TWO", "ROUND_FOUR", "ROUND_EIGHT", "ROUND_TWELVE", "ROUND_FULL"],
+ "enum": [
+ "ROUNDNESS_UNSPECIFIED",
+ "ROUND_TWO",
+ "ROUND_FOUR",
+ "ROUND_EIGHT",
+ "ROUND_TWELVE",
+ "ROUND_FULL"
+ ],
"type": "string"
},
- "saturation": { "description": "1–4", "format": "int32", "type": "integer" },
"colorVariant": {
"enum": [
- "COLOR_VARIANT_UNSPECIFIED", "MONOCHROME", "NEUTRAL", "TONAL_SPOT",
- "VIBRANT", "EXPRESSIVE", "FIDELITY", "CONTENT", "RAINBOW", "FRUIT_SALAD"
+ "COLOR_VARIANT_UNSPECIFIED",
+ "MONOCHROME",
+ "NEUTRAL",
+ "TONAL_SPOT",
+ "VIBRANT",
+ "EXPRESSIVE",
+ "FIDELITY",
+ "CONTENT",
+ "RAINBOW",
+ "FRUIT_SALAD"
],
"type": "string"
},
"headlineFont": {
"enum": [
"FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
"bodyFont": {
"enum": [
"FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
"labelFont": {
"enum": [
"FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
@@ -156,45 +464,159 @@
"type": "string",
"description": "Auto-generated markdown design system document"
},
- "overridePrimaryColor": { "type": "string", "description": "Hex override for primary color" },
- "overrideSecondaryColor": { "type": "string" },
- "overrideTertiaryColor": { "type": "string" },
- "overrideNeutralColor": { "type": "string" }
+ "overridePrimaryColor": {
+ "type": "string",
+ "description": "Hex override for primary color"
+ },
+ "overrideSecondaryColor": {
+ "type": "string"
+ },
+ "overrideTertiaryColor": {
+ "type": "string"
+ },
+ "overrideNeutralColor": {
+ "type": "string"
+ },
+ "spacing": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Optional. Map of spacing token name to CSS value (e.g. {\"sm\": \"8px\"})."
+ },
+ "typography": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/$defs/Typography"
+ },
+ "description": "Optional. Map of typography level name (e.g. \"h1\", \"body\") to Typography token overrides."
+ },
+ "saturation": {
+ "type": "number",
+ "description": "Read-only. Colour saturation level returned by the API (observed integer values, e.g. 3). Not settable via create/update_design_system — the input DesignTheme has no saturation field.",
+ "readOnly": true
+ },
+ "bodyFontFamily": {
+ "type": "string",
+ "description": "Read-only. Human-readable resolved body font name, e.g. \"Inter\". The enum form is in bodyFont.",
+ "readOnly": true
+ },
+ "headlineFontFamily": {
+ "type": "string",
+ "description": "Read-only. Human-readable resolved headline font name, e.g. \"Libre Caslon Text\".",
+ "readOnly": true
+ },
+ "labelFontFamily": {
+ "type": "string",
+ "description": "Read-only. Human-readable resolved label font name, e.g. \"Public Sans\".",
+ "readOnly": true
+ }
+ },
+ "type": "object"
+ },
+ "Typography": {
+ "description": "A single typography level's CSS overrides.",
+ "properties": {
+ "fontFamily": {
+ "type": "string",
+ "description": "Optional. CSS font-family value."
+ },
+ "fontSize": {
+ "type": "string",
+ "description": "Optional. CSS font-size value (e.g. \"1rem\")."
+ },
+ "fontWeight": {
+ "type": "string",
+ "description": "Optional. CSS font-weight value (e.g. \"600\")."
+ },
+ "letterSpacing": {
+ "type": "string",
+ "description": "Optional. CSS letter-spacing value."
+ },
+ "lineHeight": {
+ "type": "string",
+ "description": "Optional. CSS line-height value."
+ }
},
"type": "object"
},
"File": {
"properties": {
- "downloadUrl": { "type": "string" },
- "name": { "type": "string" }
+ "downloadUrl": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
},
"type": "object"
},
"ProjectMetadata": {
"properties": {
- "isRemixed": { "type": "boolean" },
- "userRole": { "enum": ["ROLE_UNSPECIFIED", "OWNER", "READER"], "type": "string" }
+ "isRemixed": {
+ "type": "boolean"
+ },
+ "userRole": {
+ "enum": [
+ "ROLE_UNSPECIFIED",
+ "OWNER",
+ "READER"
+ ],
+ "type": "string"
+ }
},
"type": "object"
},
"ScreenInstance": {
"description": "An instance of a screen on the project canvas.",
"properties": {
- "groupId": { "type": "string" },
- "groupName": { "type": "string" },
- "height": { "format": "int32", "type": "integer" },
- "hidden": { "type": "boolean" },
- "id": { "type": "string" },
- "label": { "type": "string" },
- "sourceScreen": { "description": "Format: projects/{project}/screens/{screen}", "type": "string" },
+ "groupId": {
+ "type": "string"
+ },
+ "groupName": {
+ "type": "string"
+ },
+ "height": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "hidden": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "string"
+ },
+ "label": {
+ "type": "string"
+ },
+ "sourceScreen": {
+ "description": "Format: projects/{project}/screens/{screen}",
+ "type": "string"
+ },
"type": {
- "enum": ["SCREEN_INSTANCE_TYPE_UNSPECIFIED", "SCREEN_INSTANCE", "DESIGN_SYSTEM_INSTANCE", "GROUP_INSTANCE"],
+ "enum": [
+ "SCREEN_INSTANCE_TYPE_UNSPECIFIED",
+ "SCREEN_INSTANCE",
+ "DESIGN_SYSTEM_INSTANCE",
+ "GROUP_INSTANCE"
+ ],
"type": "string"
},
- "variantScreenInstance": { "$ref": "#/$defs/ScreenInstance" },
- "width": { "format": "int32", "type": "integer" },
- "x": { "format": "int32", "type": "integer" },
- "y": { "format": "int32", "type": "integer" }
+ "variantScreenInstance": {
+ "$ref": "#/$defs/ScreenInstance"
+ },
+ "width": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "x": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "y": {
+ "format": "int32",
+ "type": "integer"
+ }
},
"type": "object"
}
diff --git a/docs/mcp-schemas/list_projects.json b/docs/mcp-schemas/list_projects.json
index 1381115..7c08092 100644
--- a/docs/mcp-schemas/list_projects.json
+++ b/docs/mcp-schemas/list_projects.json
@@ -16,7 +16,9 @@
"properties": {
"projects": {
"description": "Projects sorted by update time (most recent first).",
- "items": { "$ref": "#/$defs/Project" },
+ "items": {
+ "$ref": "#/$defs/Project"
+ },
"type": "array"
}
},
@@ -24,84 +26,524 @@
"DesignTheme": {
"description": "The theme of the design.",
"properties": {
- "backgroundDark": { "type": "string" },
- "backgroundLight": { "type": "string" },
+ "backgroundDark": {
+ "type": "string"
+ },
+ "backgroundLight": {
+ "type": "string"
+ },
"colorMode": {
- "enum": ["COLOR_MODE_UNSPECIFIED", "LIGHT", "DARK"],
+ "enum": [
+ "COLOR_MODE_UNSPECIFIED",
+ "LIGHT",
+ "DARK"
+ ],
+ "type": "string"
+ },
+ "customColor": {
+ "type": "string"
+ },
+ "description": {
"type": "string"
},
- "customColor": { "type": "string" },
- "description": { "type": "string" },
"font": {
+ "description": "68 fonts available. SOURCE_SERIF_FOUR, SOURCE_SANS_THREE, and METROPOLIS are deprecated aliases — prefer SOURCE_SERIF_4, SOURCE_SANS_3, and a modern sans alternative respectively.",
+ "enum": [
+ "FONT_UNSPECIFIED",
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
+ ],
+ "type": "string"
+ },
+ "headlineFont": {
+ "description": "Optional. Typeface for headings and titles. Same enum as `font`.",
+ "enum": [
+ "FONT_UNSPECIFIED",
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
+ ],
+ "type": "string"
+ },
+ "bodyFont": {
+ "description": "Optional. Typeface for body text and paragraphs. Same enum as `font`.",
"enum": [
"FONT_UNSPECIFIED",
- "BE_VIETNAM_PRO", "EPILOGUE", "INTER", "LEXEND", "MANROPE",
- "NEWSREADER", "NOTO_SERIF", "PLUS_JAKARTA_SANS", "PUBLIC_SANS",
- "SPACE_GROTESK", "SPLINE_SANS", "WORK_SANS", "DOMINE",
- "LIBRE_CASLON_TEXT", "EB_GARAMOND", "LITERATA", "SOURCE_SERIF_FOUR",
- "MONTSERRAT", "METROPOLIS", "SOURCE_SANS_THREE", "NUNITO_SANS",
- "ARIMO", "HANKEN_GROTESK", "RUBIK", "GEIST", "DM_SANS",
- "IBM_PLEX_SANS", "SORA"
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
],
"type": "string"
},
- "preset": { "type": "string" },
+ "labelFont": {
+ "description": "Optional. Typeface for labels, captions, and UI chrome. Same enum as `font`.",
+ "enum": [
+ "FONT_UNSPECIFIED",
+ "BE_VIETNAM_PRO",
+ "EPILOGUE",
+ "INTER",
+ "LEXEND",
+ "MANROPE",
+ "NEWSREADER",
+ "NOTO_SERIF",
+ "PLUS_JAKARTA_SANS",
+ "PUBLIC_SANS",
+ "SPACE_GROTESK",
+ "SPLINE_SANS",
+ "WORK_SANS",
+ "DOMINE",
+ "LIBRE_CASLON_TEXT",
+ "EB_GARAMOND",
+ "LITERATA",
+ "SOURCE_SERIF_4",
+ "SOURCE_SERIF_FOUR",
+ "MONTSERRAT",
+ "METROPHOBIC",
+ "METROPOLIS",
+ "SOURCE_SANS_3",
+ "SOURCE_SANS_THREE",
+ "NUNITO_SANS",
+ "ARIMO",
+ "HANKEN_GROTESK",
+ "RUBIK",
+ "GEIST",
+ "DM_SANS",
+ "IBM_PLEX_SANS",
+ "SORA",
+ "ANYBODY",
+ "ANTON",
+ "ARCHIVO_NARROW",
+ "ATKINSON_HYPERLEGIBLE_NEXT",
+ "BARLOW_CONDENSED",
+ "BEBAS_NEUE",
+ "BODONI_MODA",
+ "BRICOLAGE_GROTESQUE",
+ "CHIVO",
+ "CLIMATE_CRISIS",
+ "COMFORTAA",
+ "COURIER_PRIME",
+ "FIRA_SANS",
+ "GOOGLE_SANS",
+ "GOOGLE_SANS_CODE",
+ "GOOGLE_SANS_FLEX",
+ "GOOGLE_SANS_MONO",
+ "GOOGLE_SANS_TEXT",
+ "IBM_PLEX_SERIF",
+ "JETBRAINS_MONO",
+ "KARLA",
+ "LIBRE_FRANKLIN",
+ "MERRIWEATHER",
+ "NOTO_SANS",
+ "OPEN_SANS",
+ "OSWALD",
+ "OUTFIT",
+ "PLAYFAIR_DISPLAY",
+ "POIRET_ONE",
+ "QUESTRIAL",
+ "QUICKSAND",
+ "RALEWAY",
+ "ROBOTO_FLEX",
+ "SPACE_MONO",
+ "SYNE",
+ "VOLLKORN"
+ ],
+ "type": "string"
+ },
+ "preset": {
+ "type": "string"
+ },
"roundness": {
"description": "ROUND_TWO is deprecated/unused.",
- "enum": ["ROUNDNESS_UNSPECIFIED", "ROUND_TWO", "ROUND_FOUR", "ROUND_EIGHT", "ROUND_TWELVE", "ROUND_FULL"],
+ "enum": [
+ "ROUNDNESS_UNSPECIFIED",
+ "ROUND_TWO",
+ "ROUND_FOUR",
+ "ROUND_EIGHT",
+ "ROUND_TWELVE",
+ "ROUND_FULL"
+ ],
"type": "string"
},
- "saturation": { "description": "1–4", "format": "int32", "type": "integer" }
+ "overridePrimaryColor": {
+ "type": "string",
+ "description": "Hex override for the primary color."
+ },
+ "overrideSecondaryColor": {
+ "type": "string",
+ "description": "Hex override for the secondary color."
+ },
+ "overrideTertiaryColor": {
+ "type": "string",
+ "description": "Hex override for the tertiary color."
+ },
+ "overrideNeutralColor": {
+ "type": "string",
+ "description": "Hex override for the neutral color."
+ },
+ "spacing": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Optional. Map of spacing token name to CSS value (e.g. {\"sm\": \"8px\"})."
+ },
+ "typography": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/$defs/Typography"
+ },
+ "description": "Optional. Map of typography level name (e.g. \"h1\", \"body\") to Typography token overrides."
+ },
+ "saturation": {
+ "type": "number",
+ "description": "Read-only. Colour saturation level returned by the API (observed integer values, e.g. 3). Not settable via create/update_design_system — the input DesignTheme has no saturation field.",
+ "readOnly": true
+ },
+ "namedColors": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Read-only. Resolved semantic colour roles mapped to hex values (background, error, error_container, ...). Populated after the first screen is generated.",
+ "readOnly": true
+ },
+ "spacingScale": {
+ "type": "number",
+ "description": "Read-only. Numeric spacing scale returned by the API. Distinct from the settable `spacing` map.",
+ "readOnly": true
+ },
+ "bodyFontFamily": {
+ "type": "string",
+ "description": "Read-only. Human-readable resolved body font name, e.g. \"Inter\". The enum form is in bodyFont.",
+ "readOnly": true
+ },
+ "headlineFontFamily": {
+ "type": "string",
+ "description": "Read-only. Human-readable resolved headline font name, e.g. \"Libre Caslon Text\".",
+ "readOnly": true
+ },
+ "labelFontFamily": {
+ "type": "string",
+ "description": "Read-only. Human-readable resolved label font name, e.g. \"Public Sans\".",
+ "readOnly": true
+ }
+ },
+ "type": "object"
+ },
+ "Typography": {
+ "description": "A single typography level's CSS overrides.",
+ "properties": {
+ "fontFamily": {
+ "type": "string",
+ "description": "Optional. CSS font-family value."
+ },
+ "fontSize": {
+ "type": "string",
+ "description": "Optional. CSS font-size value (e.g. \"1rem\")."
+ },
+ "fontWeight": {
+ "type": "string",
+ "description": "Optional. CSS font-weight value (e.g. \"600\")."
+ },
+ "letterSpacing": {
+ "type": "string",
+ "description": "Optional. CSS letter-spacing value."
+ },
+ "lineHeight": {
+ "type": "string",
+ "description": "Optional. CSS line-height value."
+ }
},
"type": "object"
},
"File": {
"properties": {
- "downloadUrl": { "type": "string" },
- "name": { "type": "string" }
+ "downloadUrl": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
},
"type": "object"
},
"Project": {
"description": "A project is a single app.",
"properties": {
- "backgroundTheme": { "type": "string" },
- "createTime": { "format": "date-time", "readOnly": true, "type": "string" },
- "designTheme": { "$ref": "#/$defs/DesignTheme", "readOnly": true },
+ "backgroundTheme": {
+ "type": "string"
+ },
+ "createTime": {
+ "format": "date-time",
+ "readOnly": true,
+ "type": "string"
+ },
+ "designTheme": {
+ "$ref": "#/$defs/DesignTheme",
+ "readOnly": true
+ },
"deviceType": {
- "enum": ["DEVICE_TYPE_UNSPECIFIED", "MOBILE", "DESKTOP", "TABLET", "AGNOSTIC"],
+ "enum": [
+ "DEVICE_TYPE_UNSPECIFIED",
+ "MOBILE",
+ "DESKTOP",
+ "TABLET",
+ "AGNOSTIC"
+ ],
"readOnly": true,
"type": "string"
},
- "metadata": { "$ref": "#/$defs/ProjectMetadata" },
+ "metadata": {
+ "$ref": "#/$defs/ProjectMetadata"
+ },
"name": {
"description": "Identifier. Format: projects/{project}",
"type": "string",
"x-google-identifier": true
},
"origin": {
- "enum": ["ORIGIN_UNSPECIFIED", "STITCH", "IMPORTED_FROM_GALILEO"],
+ "enum": [
+ "ORIGIN_UNSPECIFIED",
+ "STITCH",
+ "IMPORTED_FROM_GALILEO"
+ ],
"readOnly": true,
"type": "string"
},
"projectType": {
"enum": [
- "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"
+ "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"
],
"type": "string"
},
- "readTime": { "format": "date-time", "readOnly": true, "type": "string" },
+ "readTime": {
+ "format": "date-time",
+ "readOnly": true,
+ "type": "string"
+ },
"screenInstances": {
- "items": { "$ref": "#/$defs/ScreenInstance" },
+ "items": {
+ "$ref": "#/$defs/ScreenInstance"
+ },
"readOnly": true,
"type": "array"
},
- "thumbnailScreenshot": { "$ref": "#/$defs/File" },
- "title": { "type": "string" },
- "updateTime": { "format": "date-time", "readOnly": true, "type": "string" },
+ "thumbnailScreenshot": {
+ "$ref": "#/$defs/File"
+ },
+ "title": {
+ "type": "string"
+ },
+ "updateTime": {
+ "format": "date-time",
+ "readOnly": true,
+ "type": "string"
+ },
"visibility": {
- "enum": ["VISIBILITY_UNSPECIFIED", "PUBLIC", "PRIVATE"],
+ "enum": [
+ "VISIBILITY_UNSPECIFIED",
+ "PUBLIC",
+ "PRIVATE"
+ ],
"type": "string"
}
},
@@ -109,24 +551,60 @@
},
"ProjectMetadata": {
"properties": {
- "isRemixed": { "type": "boolean" },
- "userRole": { "enum": ["ROLE_UNSPECIFIED", "OWNER", "READER"], "type": "string" }
+ "isRemixed": {
+ "type": "boolean"
+ },
+ "userRole": {
+ "enum": [
+ "ROLE_UNSPECIFIED",
+ "OWNER",
+ "READER"
+ ],
+ "type": "string"
+ }
},
"type": "object"
},
"ScreenInstance": {
"properties": {
- "groupId": { "type": "string" },
- "groupName": { "type": "string" },
- "height": { "format": "int32", "type": "integer" },
- "hidden": { "type": "boolean" },
- "id": { "type": "string" },
- "label": { "type": "string" },
- "sourceScreen": { "description": "Format: projects/{project}/screens/{screen}", "type": "string" },
- "variantScreenInstance": { "$ref": "#/$defs/ScreenInstance" },
- "width": { "format": "int32", "type": "integer" },
- "x": { "format": "int32", "type": "integer" },
- "y": { "format": "int32", "type": "integer" }
+ "groupId": {
+ "type": "string"
+ },
+ "groupName": {
+ "type": "string"
+ },
+ "height": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "hidden": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "string"
+ },
+ "label": {
+ "type": "string"
+ },
+ "sourceScreen": {
+ "description": "Format: projects/{project}/screens/{screen}",
+ "type": "string"
+ },
+ "variantScreenInstance": {
+ "$ref": "#/$defs/ScreenInstance"
+ },
+ "width": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "x": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "y": {
+ "format": "int32",
+ "type": "integer"
+ }
},
"type": "object"
}
diff --git a/docs/mcp-schemas/upload_design_md.json b/docs/mcp-schemas/upload_design_md.json
new file mode 100644
index 0000000..ff9397c
--- /dev/null
+++ b/docs/mcp-schemas/upload_design_md.json
@@ -0,0 +1,29 @@
+{
+ "name": "upload_design_md",
+ "description": "Uploads DESIGN.md to a Stitch project. Use this tool when the user wants to create a design system from a DESIGN.md file.\n\n**Instructions for Tool Call:**\n* Call `create_design_system_from_design_md` tool immediately after this tool to create the design system from the uploaded DESIGN.md, and display the design system in the UI.\n",
+ "arguments": {
+ "type": "object",
+ "properties": {
+ "projectId": {
+ "description": "Required. The project ID to upload the DESIGN.md to, example: '4044680601076201931', without the `projects/` prefix.",
+ "type": "string"
+ },
+ "designMdBase64": {
+ "description": "Required. The base64-encoded DESIGN.md content. The decoded content must be valid UTF-8; uploads with invalid UTF-8 bytes will be rejected. Run `base64 -w 0 ` on Linux, or `base64 -i ` on macOS, to get an unwrapped base64 string.",
+ "type": "string"
+ }
+ },
+ "required": ["projectId", "designMdBase64"],
+ "description": "Request message for UploadDesignMd."
+ },
+ "outputSchema": {
+ "type": "object",
+ "properties": {},
+ "description": "Creates a screen instance holding the uploaded DESIGN.md. Read the instance id and its sourceScreen from get_project's screenInstances, then pass both to create_design_system_from_design_md."
+ },
+ "notes": [
+ "Half of a two-call pair. On its own this leaves an orphan screen instance and no design system.",
+ "projectId is numeric only here, but get_project (used to read back the screen instance) needs the projects/ prefix.",
+ "Google's own tool description says `base64 -w 0`, which is GNU-only and fails on macOS with 'invalid option -- w'."
+ ]
+}
diff --git a/docs/mcp-schemas/upload_screens_from_images.json b/docs/mcp-schemas/upload_screens_from_images.json
deleted file mode 100644
index b430cf9..0000000
--- a/docs/mcp-schemas/upload_screens_from_images.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
- "name": "upload_screens_from_images",
- "description": "Uploads one or more images into a Stitch project as new screens. Supports PNG, JPEG, WebP, and GIF formats.\n\n**Input Requirements:**\n1. **`projectId` (string - MANDATORY):** Numeric ID only — no `projects/` prefix.\n2. **`images` (array - MANDATORY):** Array of image objects with base64 content and MIME type.\n",
- "arguments": {
- "type": "object",
- "properties": {
- "projectId": {
- "description": "Required. Numeric project ID only — do NOT include 'projects/' prefix.",
- "type": "string"
- },
- "images": {
- "description": "Required. Array of images to upload.",
- "type": "array",
- "items": {
- "$ref": "#/$defs/ImageUpload"
- }
- }
- },
- "required": ["projectId", "images"],
- "description": "Request message for UploadScreensFromImages.",
- "$defs": {
- "ImageUpload": {
- "description": "An image to upload as a screen.",
- "properties": {
- "fileContentBase64": {
- "description": "Base64-encoded image data. No data: URI prefix.",
- "type": "string"
- },
- "mimeType": {
- "description": "MIME type of the image.",
- "enum": ["image/png", "image/jpeg", "image/webp", "image/gif"],
- "type": "string"
- }
- },
- "required": ["fileContentBase64", "mimeType"],
- "type": "object"
- }
- }
- },
- "outputSchema": {
- "type": "object",
- "properties": {
- "outputComponents": {
- "description": "Array of output components with session information.",
- "type": "array"
- },
- "projectId": { "type": "string" },
- "sessionId": { "type": "string" }
- },
- "description": "Response message for UploadScreensFromImages."
- }
-}
diff --git a/docs/skills-index.md b/docs/skills-index.md
index f550cb5..e782b38 100644
--- a/docs/skills-index.md
+++ b/docs/skills-index.md
@@ -1,6 +1,6 @@
# stitch-kit Skills Index
-Quick reference — all 35 skills organized by layer and stage.
+Quick reference — all 36 skills organized by layer and stage.
**Layers:**
- **Orchestrator** — entry point that coordinates other skills
@@ -27,7 +27,6 @@ Quick reference — all 35 skills organized by layer and stage.
| `stitch-mcp-get-project` | Get project metadata (uses `projects/ID` format) | Execution | Discovery |
| `stitch-mcp-delete-project` | Permanently delete a Stitch project (uses `projects/ID` format, requires confirmation) | Execution | Cleanup |
| `stitch-mcp-generate-screen-from-text` | Text → UI screen (core Stitch generation — numeric ID only) | Execution | Generate |
-| `stitch-mcp-upload-screens-from-images` | Import screenshots/mockups as new screens (numeric ID, base64 images) | Execution | Generate |
| `stitch-mcp-edit-screens` | Edit existing screens with text prompts — the iteration tool (numeric IDs) | Execution | Iterate |
| `stitch-mcp-generate-variants` | Generate design variants with creativity/aspect controls (numeric IDs) | Execution | Iterate |
| `stitch-mcp-list-screens` | List all screens in a project (uses `projects/ID` format) | Execution | Retrieve |
@@ -36,6 +35,8 @@ Quick reference — all 35 skills organized by layer and stage.
| `stitch-mcp-update-design-system` | Update an existing design system (requires asset `name`) | Execution | Design Systems |
| `stitch-mcp-list-design-systems` | List available design systems (optional project filter) | Execution | Design Systems |
| `stitch-mcp-apply-design-system` | Apply a design system to screens (numeric IDs + assetId) | Execution | Design Systems |
+| `stitch-mcp-upload-design-md` | Upload a DESIGN.md into a project (base64; pairs with the next row) | Execution | Design Systems |
+| `stitch-mcp-create-design-system-from-design-md` | Turn an uploaded DESIGN.md into a design system (screen-instance id + sourceScreen) | Execution | Design Systems |
| `stitch-nextjs-components` | Stitch HTML → Next.js 15 App Router components (TypeScript, dark mode, ARIA) | Conversion | Web |
| `stitch-svelte-components` | Stitch HTML → Svelte 5 / SvelteKit (runes, scoped CSS, transitions) | Conversion | Web |
| `stitch-html-components` | Stitch HTML → platform-agnostic HTML5 + CSS (PWA, WebView, Capacitor) | Conversion | Web |
@@ -81,7 +82,6 @@ This is the most common source of bugs when calling Stitch MCP tools directly:
| `get_project` | `projects/NUMERIC_ID` | — | — |
| `delete_project` | `projects/NUMERIC_ID` | — | — |
| `generate_screen_from_text` | **Numeric only** | — | — |
-| `upload_screens_from_images` | **Numeric only** | — | — |
| `edit_screens` | **Numeric only** | **Numeric array** | — |
| `generate_variants` | **Numeric only** | **Numeric array** | — |
| `list_screens` | `projects/NUMERIC_ID` | — | — |
@@ -93,7 +93,7 @@ This is the most common source of bugs when calling Stitch MCP tools directly:
**Rules of thumb:**
- **Read operations** (`get_project`, `list_screens`, `delete_project`) → `projects/ID` full path
-- **Generation/mutation** (`generate_screen_from_text`, `edit_screens`, `generate_variants`, `upload_screens_from_images`, `apply_design_system`) → numeric only
+- **Generation/mutation** (`generate_screen_from_text`, `edit_screens`, `generate_variants`, `apply_design_system`) → numeric only
- **Design system operations** → numeric `projectId` (optional), asset `name` for identity
See `mcp-naming-convention.md` for full details.
@@ -103,7 +103,7 @@ See `mcp-naming-convention.md` for full details.
## References
- `mcp-naming-convention.md` — ID format rules
-- `mcp-schemas/` — Formal JSON Schema definitions for all 14 Stitch MCP tools (fonts, roundness, componentRegions, outputComponents, variantOptions, designSystems)
+- `mcp-schemas/` — Formal JSON Schema definitions for the 13 Stitch MCP tools this repo wraps (fonts, roundness, componentRegions, outputComponents, variantOptions, designSystems)
- `color-prompt-guide.md` — 8 ready-to-use color palettes for Stitch prompts
- `tailwind-reference.md` — Tailwind utility class reference for conversions
- `prd-to-stitch-workflow.md` — PRD-driven design workflow
diff --git a/skills/stitch-design-system/SKILL.md b/skills/stitch-design-system/SKILL.md
index 9ce5cb7..0264ef8 100644
--- a/skills/stitch-design-system/SKILL.md
+++ b/skills/stitch-design-system/SKILL.md
@@ -72,8 +72,10 @@ Before parsing HTML, get the authoritative design data from the Stitch API. This
| `headlineFont` | `--font-sans` / heading | Map enum → font-family stack (see table below) |
| `bodyFont` | `--font-body` | Map enum → font-family stack |
| `labelFont` | `--font-label` | Map enum → font-family stack |
-| `roundness` | `--radius-md` baseline | ROUND_FOUR=4px, ROUND_EIGHT=8px, ROUND_TWELVE=12px, ROUND_FULL=9999px |
+| `roundness` | `--radius-md` baseline | ROUND_FOUR=4px, ROUND_EIGHT=8px, ROUND_TWELVE=12px, ROUND_FULL=9999px (ROUND_TWO also exists but is deprecated/unused) |
| `spacingScale` | spacing multiplier | 0=tight (base 2px), 1=compact (base 4px), 2=normal (base 4px), 3=spacious (base 8px) |
+| `spacing` | `--space-*` overrides | Optional map of spacing token name → CSS value (e.g. `{"sm": "8px"}`) — use in place of `spacingScale` when present |
+| `typography` | `--text-*` / `--font-*` overrides | Optional map of level name (`h1`, `body`, etc.) → Typography token (`fontFamily`, `fontSize`, `fontWeight`, `letterSpacing`, `lineHeight`) |
| `colorVariant` | informs palette approach | e.g., FIDELITY means stick to brand colors, VIBRANT means boost saturation |
**Font enum → CSS font-family mapping:**
@@ -94,20 +96,30 @@ Before parsing HTML, get the authoritative design data from the Stitch API. This
| `NUNITO_SANS` | `'Nunito Sans', system-ui, sans-serif` |
| `LEXEND` | `'Lexend', system-ui, sans-serif` |
| `PUBLIC_SANS` | `'Public Sans', system-ui, sans-serif` |
-| `SOURCE_SANS_THREE` | `'Source Sans 3', system-ui, sans-serif` |
+| `SOURCE_SANS_3` | `'Source Sans 3', system-ui, sans-serif` |
+| `SOURCE_SANS_THREE` | `'Source Sans 3', system-ui, sans-serif` — deprecated alias, prefer `SOURCE_SANS_3` |
| `MONTSERRAT` | `'Montserrat', system-ui, sans-serif` |
| `HANKEN_GROTESK` | `'Hanken Grotesk', system-ui, sans-serif` |
| `ARIMO` | `'Arimo', system-ui, sans-serif` |
| `BE_VIETNAM_PRO` | `'Be Vietnam Pro', system-ui, sans-serif` |
| `SPLINE_SANS` | `'Spline Sans', system-ui, sans-serif` |
-| `METROPOLIS` | `'Metropolis', system-ui, sans-serif` |
+| `METROPOLIS` | `'Metropolis', system-ui, sans-serif` — deprecated, no direct successor |
+| `JETBRAINS_MONO` | `'JetBrains Mono', ui-monospace, monospace` |
+| `GOOGLE_SANS_CODE` | `'Google Sans Code', ui-monospace, monospace` |
+| `SPACE_MONO` | `'Space Mono', ui-monospace, monospace` |
+| `BEBAS_NEUE` | `'Bebas Neue', system-ui, sans-serif` — condensed display |
+| `ANTON` | `'Anton', system-ui, sans-serif` — condensed display |
+| `ARCHIVO_NARROW` | `'Archivo Narrow', system-ui, sans-serif` — condensed |
| `EB_GARAMOND` | `'EB Garamond', Georgia, serif` |
| `LITERATA` | `'Literata', Georgia, serif` |
-| `SOURCE_SERIF_FOUR` | `'Source Serif 4', Georgia, serif` |
+| `SOURCE_SERIF_4` | `'Source Serif 4', Georgia, serif` |
+| `SOURCE_SERIF_FOUR` | `'Source Serif 4', Georgia, serif` — deprecated alias, prefer `SOURCE_SERIF_4` |
| `LIBRE_CASLON_TEXT` | `'Libre Caslon Text', Georgia, serif` |
| `NEWSREADER` | `'Newsreader', Georgia, serif` |
| `DOMINE` | `'Domine', Georgia, serif` |
| `NOTO_SERIF` | `'Noto Serif', Georgia, serif` |
+| `PLAYFAIR_DISPLAY` | `'Playfair Display', Georgia, serif` — editorial display |
+| `BODONI_MODA` | `'Bodoni Moda', Georgia, serif` — editorial display |
5. **Use these as the baseline.** Then use HTML analysis (Step 2) only for values the API doesn't provide: motion/transition durations, exact spacing pixel values, shadow definitions, additional colors beyond the namedColors set.
diff --git a/skills/stitch-html-components/SKILL.md b/skills/stitch-html-components/SKILL.md
index 43a2b42..21ae358 100644
--- a/skills/stitch-html-components/SKILL.md
+++ b/skills/stitch-html-components/SKILL.md
@@ -57,7 +57,7 @@ bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html"
Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch.
-**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above.
+**From a screenshot:** there's no upload route — the Stitch MCP API has no image-upload tool. Either recreate the design from a text prompt via `stitch-mcp-generate-screen-from-text`, or hand-write the HTML and use the local-file route above.
> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all.
diff --git a/skills/stitch-mcp-create-design-system-from-design-md/SKILL.md b/skills/stitch-mcp-create-design-system-from-design-md/SKILL.md
new file mode 100644
index 0000000..aa36254
--- /dev/null
+++ b/skills/stitch-mcp-create-design-system-from-design-md/SKILL.md
@@ -0,0 +1,90 @@
+---
+name: stitch-mcp-create-design-system-from-design-md
+description: Creates a Stitch Design System from a DESIGN.md that was already uploaded with stitch-mcp-upload-design-md. Second half of a two-step pair — the upload must happen first.
+allowed-tools:
+ - "stitch*:*"
+---
+
+# Stitch MCP — Create Design System from DESIGN.md
+
+Turns an uploaded DESIGN.md into a real Stitch Design System and displays it in the UI. This is step two of a pair — `stitch-mcp-upload-design-md` must have run first, because this tool consumes the screen instance that upload created.
+
+Calling it without a prior upload fails: there's no screen instance to point at.
+
+## Critical prerequisite
+
+**Only use this skill when the user explicitly mentions "Stitch"** in their request. Never trigger Stitch operations silently during regular conversation.
+
+## When to use
+
+- Immediately after `stitch-mcp-upload-design-md` returns — always, as a pair
+- Never on its own
+
+## Step 1: Confirm you have the screen instance
+
+You need two values from the upload step. If you didn't capture them, fetch them now with `get_project` (note: this one takes the `projects/` prefix):
+
+```json
+{
+ "name": "get_project",
+ "arguments": { "name": "projects/3780309359108792857" }
+}
+```
+
+Take the newest entry in `screenInstances` and read off both `id` and `sourceScreen`.
+
+## Step 2: Call the MCP tool
+
+```json
+{
+ "name": "create_design_system_from_design_md",
+ "arguments": {
+ "projectId": "3780309359108792857",
+ "selectedScreenInstance": {
+ "id": "a1b2c3d4e5f6",
+ "sourceScreen": "projects/3780309359108792857/screens/98b50e2ddc9943efb387052637738f61"
+ },
+ "deviceType": "DESKTOP"
+ }
+}
+```
+
+**Three different ID formats in one call.** This is the single easiest place to get it wrong:
+
+| Field | Format | Example |
+|-------|--------|---------|
+| `projectId` | numeric only, no prefix | `3780309359108792857` |
+| `selectedScreenInstance.id` | screen **instance** id — *not* the source screen id | `a1b2c3d4e5f6` |
+| `selectedScreenInstance.sourceScreen` | full resource path, both prefixes | `projects/.../screens/...` |
+
+`deviceType` is optional: `MOBILE`, `DESKTOP`, `TABLET`, or `AGNOSTIC`. Omit it and Stitch decides.
+
+## Step 3: Confirm and capture the asset id
+
+On success you get back a design system with an asset id in `assets/NUMERIC_ID` form. Store the numeric part — that's what applying and generating need.
+
+Announce it:
+> "Design system created from your DESIGN.md (asset `15996705518239280238`). Want me to apply it to existing screens, or use it for the next generation?"
+
+## Step 4: Put it to work
+
+- **Apply to existing screens** → `stitch-mcp-apply-design-system`
+- **Use for new screens** → pass `designSystem: "assets/15996705518239280238"` to `generate_screen_from_text`
+
+## ID format rules (critical — different tools need different formats)
+
+| Tool | ID format required |
+|------|-------------------|
+| `create_design_system_from_design_md` | Numeric projectId + the screen-instance pair above |
+| `upload_design_md` | Numeric only: `3780309359108792857` |
+| `apply_design_system` | Numeric `assetId`, no `assets/` prefix |
+| `generate_screen_from_text` | `designSystem` **does** take the `assets/` prefix |
+| `get_project` | Full path: `projects/3780309359108792857` |
+
+> Yes — `apply_design_system` wants the bare asset id while `generate_screen_from_text` wants it prefixed. Same identifier, two formats, depending on which tool you hand it to.
+
+## Integration
+
+- Preceded by `stitch-mcp-upload-design-md`, always
+- Followed by `stitch-mcp-apply-design-system` or a generation call
+- List what already exists with `stitch-mcp-list-design-systems`
diff --git a/skills/stitch-mcp-create-design-system/SKILL.md b/skills/stitch-mcp-create-design-system/SKILL.md
index b9d07fb..53714af 100644
--- a/skills/stitch-mcp-create-design-system/SKILL.md
+++ b/skills/stitch-mcp-create-design-system/SKILL.md
@@ -1,6 +1,6 @@
---
name: stitch-mcp-create-design-system
-description: Creates a reusable Stitch Design System from theme tokens — colors, fonts, roundness, saturation. Can be applied to future screens for visual consistency.
+description: Creates a reusable Stitch Design System from theme tokens — colors, fonts, roundness. Can be applied to future screens for visual consistency.
allowed-tools:
- "stitch*:*"
---
@@ -35,7 +35,6 @@ Creates a new Stitch Design System — a reusable theme configuration that can b
"bodyFont": "DM_SANS",
"labelFont": "DM_SANS",
"roundness": "ROUND_EIGHT",
- "saturation": 3,
"customColor": "#6366F1",
"backgroundLight": "#FFFFFF",
"backgroundDark": "#18181B",
@@ -69,19 +68,27 @@ Creates a new Stitch Design System — a reusable theme configuration that can b
| `headlineFont` | enum | See font list below | Typeface for headings and titles |
| `bodyFont` | enum | See font list below | Typeface for body text and paragraphs |
| `labelFont` | enum | See font list below | Typeface for labels, captions, and UI chrome |
-| `roundness` | enum | `ROUND_FOUR`, `ROUND_EIGHT`, `ROUND_TWELVE`, `ROUND_FULL` | Border radius scale |
-| `saturation` | int | 1–4 | Color vibrancy (1 = muted, 4 = vivid) |
+| `roundness` | enum | `ROUND_FOUR`, `ROUND_EIGHT`, `ROUND_TWELVE`, `ROUND_FULL` (`ROUND_TWO` also exists but is deprecated/unused) | Border radius scale |
| `customColor` | string | Hex color | Primary brand color |
| `backgroundLight` | string | Hex color | Light mode background |
| `backgroundDark` | string | Hex color | Dark mode background |
| `preset` | string | — | Optional preset theme name |
| `description` | string | — | Brief aesthetic description |
+| `overridePrimaryColor` / `overrideSecondaryColor` / `overrideTertiaryColor` / `overrideNeutralColor` | string | Hex color | Exact color overrides, take precedence over `customColor` |
+| `spacing` | object | Map of name → CSS value | e.g. `{"sm": "8px"}` |
+| `typography` | object | Map of level name → Typography token | Each token: `fontFamily`, `fontSize`, `fontWeight`, `letterSpacing`, `lineHeight` |
-### Available fonts (28 options)
+### Available fonts (68 options)
-**Sans-serif:** `INTER`, `DM_SANS`, `GEIST`, `SORA`, `MANROPE`, `RUBIK`, `MONTSERRAT`, `WORK_SANS`, `SPACE_GROTESK`, `PLUS_JAKARTA_SANS`, `PUBLIC_SANS`, `SOURCE_SANS_THREE`, `NUNITO_SANS`, `ARIMO`, `HANKEN_GROTESK`, `IBM_PLEX_SANS`, `SPLINE_SANS`, `LEXEND`, `EPILOGUE`, `BE_VIETNAM_PRO`, `METROPOLIS`
+**Sans-serif:** `INTER`, `DM_SANS`, `GEIST`, `SORA`, `MANROPE`, `RUBIK`, `MONTSERRAT`, `WORK_SANS`, `SPACE_GROTESK`, `PLUS_JAKARTA_SANS`, `PUBLIC_SANS`, `SOURCE_SANS_3`, `NUNITO_SANS`, `ARIMO`, `HANKEN_GROTESK`, `IBM_PLEX_SANS`, `SPLINE_SANS`, `LEXEND`, `EPILOGUE`, `BE_VIETNAM_PRO`, `GOOGLE_SANS`, `GOOGLE_SANS_FLEX`, `GOOGLE_SANS_TEXT`, `NOTO_SANS`, `OPEN_SANS`, `KARLA`, `LIBRE_FRANKLIN`, `FIRA_SANS`, `CHIVO`, `QUESTRIAL`, `OUTFIT`, `BRICOLAGE_GROTESQUE`, `COMFORTAA`, `QUICKSAND`, `RALEWAY`, `ROBOTO_FLEX`, `SYNE`, `OSWALD`, `ANYBODY`, `ATKINSON_HYPERLEGIBLE_NEXT`
-**Serif:** `NOTO_SERIF`, `NEWSREADER`, `DOMINE`, `LIBRE_CASLON_TEXT`, `EB_GARAMOND`, `LITERATA`, `SOURCE_SERIF_FOUR`
+**Serif:** `NOTO_SERIF`, `NEWSREADER`, `DOMINE`, `LIBRE_CASLON_TEXT`, `EB_GARAMOND`, `LITERATA`, `SOURCE_SERIF_4`, `IBM_PLEX_SERIF`, `MERRIWEATHER`, `PLAYFAIR_DISPLAY`, `BODONI_MODA`, `VOLLKORN`
+
+**Mono / code:** `JETBRAINS_MONO`, `GOOGLE_SANS_CODE`, `GOOGLE_SANS_MONO`, `SPACE_MONO`, `COURIER_PRIME`
+
+**Condensed / display:** `BEBAS_NEUE`, `ANTON`, `ARCHIVO_NARROW`, `BARLOW_CONDENSED`, `CLIMATE_CRISIS`, `POIRET_ONE`, `METROPHOBIC`
+
+**Deprecated aliases (still valid, prefer the replacement):** `SOURCE_SERIF_FOUR` → `SOURCE_SERIF_4`, `SOURCE_SANS_THREE` → `SOURCE_SANS_3`, `METROPOLIS` → no direct successor
### `projectId` — optional, numeric only
diff --git a/skills/stitch-mcp-get-project/SKILL.md b/skills/stitch-mcp-get-project/SKILL.md
index 71057be..6a93fa7 100644
--- a/skills/stitch-mcp-get-project/SKILL.md
+++ b/skills/stitch-mcp-get-project/SKILL.md
@@ -63,11 +63,15 @@ The user may provide the project reference in several formats — always extract
"customColor": "#6366F1",
"colorVariant": "TONAL_SPOT",
"roundness": "ROUND_TWELVE",
+ "saturation": 3,
"spacingScale": 1,
- "headlineFont": "ROBOTO",
- "bodyFont": "ROBOTO",
- "labelFont": "ROBOTO",
- "font": "ROBOTO",
+ "headlineFont": "INTER",
+ "bodyFont": "INTER",
+ "labelFont": "INTER",
+ "font": "INTER",
+ "headlineFontFamily": "Inter",
+ "bodyFontFamily": "Inter",
+ "labelFontFamily": "Inter",
"namedColors": {
"primary": "#5B5FC7",
"on_primary": "#FFFFFF",
@@ -134,9 +138,9 @@ The user may provide the project reference in several formats — always extract
| `colorVariant` | enum | `MONOCHROME`, `NEUTRAL`, `TONAL_SPOT`, `VIBRANT`, `EXPRESSIVE`, `FIDELITY`, `CONTENT`, `RAINBOW`, `FRUIT_SALAD` |
| `roundness` | enum | `ROUND_FOUR`, `ROUND_EIGHT`, `ROUND_TWELVE`, `ROUND_FULL` |
| `spacingScale` | number | `0`–`3` (density multiplier) |
-| `headlineFont` | enum | 28-font set: `ROBOTO`, `OPEN_SANS`, `LATO`, `MONTSERRAT`, `POPPINS`, `INTER`, `PLAYFAIR_DISPLAY`, `MERRIWEATHER`, `RALEWAY`, `NUNITO`, `SOURCE_SANS_3`, `OSWALD`, `QUICKSAND`, `CABIN`, `BARLOW`, `WORK_SANS`, `DM_SANS`, `SPACE_GROTESK`, `SORA`, `OUTFIT`, `PLUS_JAKARTA_SANS`, `MANROPE`, `ALBERT_SANS`, `FIGTREE`, `GEIST`, `ONEST`, `INSTRUMENT_SANS`, `GENERAL_SANS` |
-| `bodyFont` | enum | Same 28-font set |
-| `labelFont` | enum | Same 28-font set |
+| `headlineFont` | enum | 68-font set: `INTER`, `GEIST`, `DM_SANS`, `MANROPE`, `PLUS_JAKARTA_SANS`, `WORK_SANS`, `SPACE_GROTESK`, `SORA`, `OUTFIT`, `RALEWAY`, `QUICKSAND`, `MONTSERRAT`, `OSWALD`, `PLAYFAIR_DISPLAY`, `MERRIWEATHER`, `NOTO_SERIF`, `EB_GARAMOND`, `LITERATA`, `SOURCE_SERIF_4`, `SOURCE_SANS_3`, `NUNITO_SANS`, `JETBRAINS_MONO`, `BEBAS_NEUE`, `ANTON`, `ARCHIVO_NARROW` — see `stitch-ued-guide` for the full 68-value list |
+| `bodyFont` | enum | Same 68-font set |
+| `labelFont` | enum | Same 68-font set |
| `font` | enum | **Deprecated** — legacy single-font field, same enum |
| `namedColors` | object | 40+ semantic color tokens (`primary`, `on_primary`, `surface`, `surface_container`, `outline`, `error`, etc.) |
| `overridePrimaryColor` | string | Hex override, empty string if unused |
@@ -147,6 +151,8 @@ The user may provide the project reference in several formats — always extract
| `backgroundDark` | string | Hex background for dark mode |
| `description` | string | Brief aesthetic description of the theme |
| `designMd` | string | Auto-generated design system markdown — the full token spec. Can be very long |
+| `spacing` | object | Optional. Map of spacing token name → CSS value (e.g. `{"sm": "8px"}`) |
+| `typography` | object | Optional. Map of typography level name (e.g. `h1`, `body`) → Typography token (`fontFamily`, `fontSize`, `fontWeight`, `letterSpacing`, `lineHeight`, all optional strings) |
## Project-level fields
diff --git a/skills/stitch-mcp-list-design-systems/SKILL.md b/skills/stitch-mcp-list-design-systems/SKILL.md
index 774bc19..2c84d0b 100644
--- a/skills/stitch-mcp-list-design-systems/SKILL.md
+++ b/skills/stitch-mcp-list-design-systems/SKILL.md
@@ -7,7 +7,7 @@ allowed-tools:
# Stitch MCP — List Design Systems
-Lists all available Stitch Design Systems. These are reusable theme configurations (colors, fonts, roundness, saturation) that can be applied to screens for visual consistency across a project.
+Lists all available Stitch Design Systems. These are reusable theme configurations (colors, fonts, roundness) that can be applied to screens for visual consistency across a project.
## Critical prerequisite
@@ -55,7 +55,6 @@ Returns an array of Asset objects:
"colorMode": "LIGHT",
"font": "DM_SANS",
"roundness": "ROUND_EIGHT",
- "saturation": 3,
"customColor": "#6366F1",
"backgroundLight": "#FFFFFF",
"backgroundDark": "#18181B"
diff --git a/skills/stitch-mcp-update-design-system/SKILL.md b/skills/stitch-mcp-update-design-system/SKILL.md
index fee7629..8ecbdab 100644
--- a/skills/stitch-mcp-update-design-system/SKILL.md
+++ b/skills/stitch-mcp-update-design-system/SKILL.md
@@ -39,7 +39,6 @@ You must have the design system's asset `name` before calling this. If you don't
"bodyFont": "GEIST",
"labelFont": "GEIST",
"roundness": "ROUND_TWELVE",
- "saturation": 2,
"customColor": "#818CF8",
"backgroundLight": "#F9FAFB",
"backgroundDark": "#09090B"
diff --git a/skills/stitch-mcp-upload-design-md/SKILL.md b/skills/stitch-mcp-upload-design-md/SKILL.md
new file mode 100644
index 0000000..d436226
--- /dev/null
+++ b/skills/stitch-mcp-upload-design-md/SKILL.md
@@ -0,0 +1,94 @@
+---
+name: stitch-mcp-upload-design-md
+description: Uploads a DESIGN.md file to a Stitch project as the first half of turning it into a Stitch Design System. Always paired with stitch-mcp-create-design-system-from-design-md, which must be called immediately after.
+allowed-tools:
+ - "stitch*:*"
+ - "Bash"
+ - "Read"
+---
+
+# Stitch MCP — Upload DESIGN.md
+
+Uploads a DESIGN.md file into a Stitch project. This is step one of a two-step pair: the upload creates a screen instance holding the design doc, and `create_design_system_from_design_md` then turns that instance into a real Design System.
+
+**On its own, this tool does nothing useful.** Uploading without the follow-up leaves an orphan screen instance and no design system. Always run both.
+
+## Critical prerequisite
+
+**Only use this skill when the user explicitly mentions "Stitch"** in their request. Never trigger Stitch operations silently during regular conversation.
+
+## When to use
+
+- The user has a DESIGN.md and wants it applied as a Stitch Design System
+- You've just produced a DESIGN.md with `stitch-design-md` and want it driving generation
+- The user says "use my design doc in Stitch", "make a design system from DESIGN.md"
+
+## Step 1: Read and encode the file
+
+The tool takes base64, not raw markdown. The decoded content **must be valid UTF-8** — uploads with invalid bytes are rejected outright.
+
+```bash
+# macOS (BSD base64 — no -w flag, and it does not wrap by default)
+base64 -i DESIGN.md
+```
+
+```bash
+# Linux (GNU base64 — -w 0 disables line wrapping)
+base64 -w 0 DESIGN.md
+```
+
+> Google's tool description says `base64 -w 0`, which fails on macOS with `invalid option -- w`. Use `-i` there. Getting this wrong produces a confusing shell error rather than an API error, so check your platform first.
+
+Wrapped base64 (with embedded newlines) is a common cause of rejected uploads. Both commands above emit a single unbroken line.
+
+## Step 2: Call the MCP tool
+
+```json
+{
+ "name": "upload_design_md",
+ "arguments": {
+ "projectId": "3780309359108792857",
+ "designMdBase64": "IyBEZXNpZ24gU3lzdGVtCgpDb2xvcnM6IC4uLg=="
+ }
+}
+```
+
+`projectId` is **numeric only** — no `projects/` prefix. Passing the prefixed path here fails.
+
+## Step 3: Capture the screen instance — CRITICAL
+
+The upload creates a **screen instance**, and the next tool needs two identifiers from it. Fetch them with `get_project` (which does take the `projects/` prefix):
+
+```json
+{
+ "name": "get_project",
+ "arguments": { "name": "projects/3780309359108792857" }
+}
+```
+
+From the returned `screenInstances`, take the newest entry and record both:
+
+| Field | Example | Notes |
+|-------|---------|-------|
+| `id` | `a1b2c3d4e5f6` | The **screen instance** id |
+| `sourceScreen` | `projects/3780.../screens/98b5...` | Full resource path |
+
+**The trap:** `id` is the screen *instance* id, **not** the source screen id. They are different values and passing the source screen id as `id` fails. Google's own schema calls this out in bold, which is usually a sign it bites people.
+
+## Step 4: Immediately call the follow-up
+
+Hand both values straight to `stitch-mcp-create-design-system-from-design-md`. Don't stop between the two steps or report success to the user yet — there's no design system until the second call returns.
+
+## ID format rules (critical — different tools need different formats)
+
+| Tool | ID format required |
+|------|-------------------|
+| `upload_design_md` | Numeric only: `3780309359108792857` |
+| `create_design_system_from_design_md` | Numeric only, plus the screen-instance pair |
+| `get_project` | Full path: `projects/3780309359108792857` |
+
+## Integration
+
+- Produce the DESIGN.md first with `stitch-design-md`
+- Always follow with `stitch-mcp-create-design-system-from-design-md`
+- Once the design system exists, apply it with `stitch-mcp-apply-design-system` or pass its asset id to `generate_screen_from_text`
diff --git a/skills/stitch-mcp-upload-screens-from-images/SKILL.md b/skills/stitch-mcp-upload-screens-from-images/SKILL.md
deleted file mode 100644
index 67a2979..0000000
--- a/skills/stitch-mcp-upload-screens-from-images/SKILL.md
+++ /dev/null
@@ -1,95 +0,0 @@
----
-name: stitch-mcp-upload-screens-from-images
-description: Uploads screenshots or mockup images into a Stitch project as new screens. Enables the "redesign from screenshot" workflow — import existing UI and then edit or convert.
-allowed-tools:
- - "stitch*:*"
- - "Bash"
- - "Read"
----
-
-# Stitch MCP — Upload Screens from Images
-
-Uploads one or more images (screenshots, mockups, wireframes) into a Stitch project as new screens. This is the entry point for the "redesign existing UI" workflow — import what you have, then use `edit_screens` to iterate or convert directly to code.
-
-## Critical prerequisite
-
-**Only use this skill when the user explicitly mentions "Stitch".**
-
-You must have a `projectId` before calling this. If you don't have one:
-- Create a new project via `stitch-mcp-create-project`
-- Or find an existing project via `stitch-mcp-list-projects`
-
-## When to use
-
-- User provides a screenshot and wants to redesign it in Stitch
-- User wants to import existing mockups into Stitch for editing
-- The orchestrator classifies intent as "Upload screenshot"
-- User says "import this design", "upload this image", or "redesign this screen"
-
-## Step 1: Encode the image to base64
-
-Use the helper script to convert a local image file to base64:
-
-```bash
-bash scripts/encode-image.sh "path/to/screenshot.png"
-```
-
-The script outputs raw base64 to stdout. Capture it for the API call.
-
-Supported formats and their MIME types:
-| Extension | MIME type |
-|-----------|----------|
-| `.png` | `image/png` |
-| `.jpg`, `.jpeg` | `image/jpeg` |
-| `.webp` | `image/webp` |
-| `.gif` | `image/gif` |
-
-## Step 2: Call the MCP tool
-
-```json
-{
- "name": "upload_screens_from_images",
- "arguments": {
- "projectId": "3780309359108792857",
- "images": [
- {
- "fileContentBase64": "[base64-encoded-image-data]",
- "mimeType": "image/png"
- }
- ]
- }
-}
-```
-
-### `projectId` — numeric ID only, no prefix
-
-```
-✅ "3780309359108792857"
-❌ "projects/3780309359108792857"
-```
-
-### `images` — array of image objects
-
-Each image needs:
-| Field | Type | Description |
-|-------|------|-------------|
-| `fileContentBase64` | string | Base64-encoded image data (no `data:` prefix) |
-| `mimeType` | string | MIME type matching the image format |
-
-You can upload multiple images in a single call — each becomes a separate screen.
-
-## Output
-
-Returns session info similar to `generate_screen_from_text`. The uploaded images appear as new screens in the project.
-
-## After uploading
-
-1. Call `stitch-mcp-list-screens` to find the new screen IDs
-2. Offer the user:
- - "Edit this screen (change colors, layout, content)?" → `stitch-mcp-edit-screens`
- - "Convert directly to code?" → `stitch-mcp-get-screen` → framework conversion
- - "Generate variants based on this design?" → `stitch-mcp-generate-variants`
-
-## References
-
-- `scripts/encode-image.sh` — Base64 encoding helper
diff --git a/skills/stitch-mcp-upload-screens-from-images/scripts/encode-image.sh b/skills/stitch-mcp-upload-screens-from-images/scripts/encode-image.sh
deleted file mode 100644
index 3dce3a6..0000000
--- a/skills/stitch-mcp-upload-screens-from-images/scripts/encode-image.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env bash
-# encode-image.sh — Encodes an image file to base64 for the Stitch upload API.
-#
-# Usage: bash encode-image.sh "path/to/image.png"
-# Output: Raw base64 string to stdout (no wrapping, no data: prefix)
-#
-# Supports: PNG, JPG, JPEG, WebP, GIF
-
-set -euo pipefail
-
-if [[ $# -lt 1 ]]; then
- echo "Usage: bash encode-image.sh " >&2
- exit 1
-fi
-
-IMAGE_PATH="$1"
-
-# Validate the file exists
-if [[ ! -f "$IMAGE_PATH" ]]; then
- echo "Error: File not found: $IMAGE_PATH" >&2
- exit 1
-fi
-
-# Validate the file is an image by extension
-EXT="${IMAGE_PATH##*.}"
-EXT_LOWER=$(echo "$EXT" | tr '[:upper:]' '[:lower:]')
-
-case "$EXT_LOWER" in
- png|jpg|jpeg|webp|gif)
- ;;
- *)
- echo "Error: Unsupported image format: .$EXT_LOWER (expected png, jpg, jpeg, webp, or gif)" >&2
- exit 1
- ;;
-esac
-
-# Encode to base64 — macOS and Linux compatible
-# macOS base64 doesn't support --wrap, uses -b 0 instead
-if base64 --wrap=0 "$IMAGE_PATH" 2>/dev/null; then
- : # Linux: --wrap=0 disables line wrapping
-else
- base64 -i "$IMAGE_PATH" # macOS: no wrapping by default with -i
-fi
diff --git a/skills/stitch-nextjs-components/SKILL.md b/skills/stitch-nextjs-components/SKILL.md
index 9a00285..7906c47 100644
--- a/skills/stitch-nextjs-components/SKILL.md
+++ b/skills/stitch-nextjs-components/SKILL.md
@@ -58,7 +58,7 @@ bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html"
Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch.
-**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above.
+**From a screenshot:** there's no upload route — the Stitch MCP API has no image-upload tool. Either recreate the design from a text prompt via `stitch-mcp-generate-screen-from-text`, or hand-write the HTML and use the local-file route above.
> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all.
diff --git a/skills/stitch-orchestrator/SKILL.md b/skills/stitch-orchestrator/SKILL.md
index 61d2c8f..82714a2 100644
--- a/skills/stitch-orchestrator/SKILL.md
+++ b/skills/stitch-orchestrator/SKILL.md
@@ -22,7 +22,6 @@ Trigger phrases:
- "Create a Stitch project for..."
- "Generate a Stitch screen for..."
- "Edit my Stitch screen..."
-- "Upload this screenshot to Stitch..."
## Preflight — Step 0
@@ -116,7 +115,6 @@ Determine what the user wants:
|--------|---------|
| **New screen** — design from scratch | Full workflow: Steps 2 → 9 |
| **Edit existing** — iterate on a screen | Skip Steps 2–3. Call `stitch-mcp-edit-screens` with edit instruction. Then offer Step 5b menu. |
-| **Upload screenshot** — import existing UI | Call `stitch-mcp-upload-screens-from-images`, then offer edit or convert (Step 5b). |
| **Refine existing** — iterate on a screen | Skip Step 2 (reuse project ID). Preserve layout structure in new prompt. |
| **Export existing** — just get the code | Skip Steps 2-5. Go to Step 6 (get screen) → Step 8 (convert). |
| **Convert non-Stitch HTML** — user already has markup | Skip Steps 2-7 entirely. Go straight to Step 8. The conversion skills accept a local HTML file or a URL as well as a Stitch screen, and that route needs no Stitch account. Do not push the user through generation to manufacture a screen they didn't ask for. |
@@ -382,7 +380,6 @@ This is the #1 source of bugs. Every MCP tool has specific ID format requirement
| `list_screens` | `projects/ID` | — | — | Returns full paths |
| `get_screen` | Numeric | Numeric | — | No prefixes |
| `generate_screen_from_text` | Numeric | — | — | No prefix |
-| `upload_screens_from_images` | Numeric | — | — | No prefix |
| `edit_screens` | Numeric | Numeric array | — | No prefixes |
| `generate_variants` | Numeric | Numeric array | — | No prefixes |
| `create_design_system` | Numeric (optional) | — | — | Returns Asset `name` |
@@ -392,7 +389,7 @@ This is the #1 source of bugs. Every MCP tool has specific ID format requirement
**Rules of thumb:**
- **Read operations** (`get_project`, `list_screens`, `delete_project`) → `projects/ID` full path
-- **Generation operations** (`generate_screen_from_text`, `edit_screens`, `generate_variants`, `upload_screens_from_images`, `apply_design_system`) → numeric only
+- **Generation operations** (`generate_screen_from_text`, `edit_screens`, `generate_variants`, `apply_design_system`) → numeric only
- **Design system operations** → numeric `projectId` (optional), asset `name` for identity
---
diff --git a/skills/stitch-react-components/SKILL.md b/skills/stitch-react-components/SKILL.md
index 437e8c9..c9bc6ac 100644
--- a/skills/stitch-react-components/SKILL.md
+++ b/skills/stitch-react-components/SKILL.md
@@ -63,7 +63,7 @@ bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html"
Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch.
-**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above.
+**From a screenshot:** there's no upload route — the Stitch MCP API has no image-upload tool. Either recreate the design from a text prompt via `stitch-mcp-generate-screen-from-text`, or hand-write the HTML and use the local-file route above.
> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all.
diff --git a/skills/stitch-react-native-components/SKILL.md b/skills/stitch-react-native-components/SKILL.md
index 572ad54..adb6a16 100644
--- a/skills/stitch-react-native-components/SKILL.md
+++ b/skills/stitch-react-native-components/SKILL.md
@@ -67,7 +67,7 @@ bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html"
Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch. Confirm the page is a mobile layout before converting.
-**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above.
+**From a screenshot:** there's no upload route — the Stitch MCP API has no image-upload tool. Either recreate the design from a text prompt via `stitch-mcp-generate-screen-from-text`, or hand-write the HTML and use the local-file route above.
> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all.
diff --git a/skills/stitch-svelte-components/SKILL.md b/skills/stitch-svelte-components/SKILL.md
index 34fe4e2..0a2ceb6 100644
--- a/skills/stitch-svelte-components/SKILL.md
+++ b/skills/stitch-svelte-components/SKILL.md
@@ -60,7 +60,7 @@ bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html"
Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch.
-**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above.
+**From a screenshot:** there's no upload route — the Stitch MCP API has no image-upload tool. Either recreate the design from a text prompt via `stitch-mcp-generate-screen-from-text`, or hand-write the HTML and use the local-file route above.
> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all.
diff --git a/skills/stitch-swiftui-components/SKILL.md b/skills/stitch-swiftui-components/SKILL.md
index 01141de..06790be 100644
--- a/skills/stitch-swiftui-components/SKILL.md
+++ b/skills/stitch-swiftui-components/SKILL.md
@@ -67,7 +67,7 @@ bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html"
Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch. Confirm the page is a mobile layout before converting.
-**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above.
+**From a screenshot:** there's no upload route — the Stitch MCP API has no image-upload tool. Either recreate the design from a text prompt via `stitch-mcp-generate-screen-from-text`, or hand-write the HTML and use the local-file route above.
> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all.
diff --git a/skills/stitch-ued-guide/SKILL.md b/skills/stitch-ued-guide/SKILL.md
index 5c03307..fbc76e5 100644
--- a/skills/stitch-ued-guide/SKILL.md
+++ b/skills/stitch-ued-guide/SKILL.md
@@ -74,12 +74,14 @@ Quick reference for all DesignTheme fields returned by `get_project`:
| `colorMode` | LIGHT / DARK | Base theme mode |
| `customColor` | hex string | Seed color for palette generation |
| `colorVariant` | enum (9 values) | How palette is derived from seed |
-| `headlineFont` | font enum (28 values) | Display/headline typeface |
+| `headlineFont` | font enum (68 values) | Display/headline typeface |
| `bodyFont` | font enum | Body text typeface |
| `labelFont` | font enum | Labels, captions, metadata typeface |
| `font` | font enum | **Deprecated** — use headlineFont/bodyFont/labelFont |
-| `roundness` | ROUND_FOUR/EIGHT/TWELVE/FULL | Corner radius preset |
+| `roundness` | ROUND_FOUR/EIGHT/TWELVE/FULL (`ROUND_TWO` exists but is deprecated/unused) | Corner radius preset |
| `spacingScale` | integer 0-3 | Layout density |
+| `spacing` | object | Optional. Map of spacing token name → CSS value (e.g. `{"sm": "8px"}`) |
+| `typography` | object | Optional. Map of typography level name (e.g. `h1`, `body`) → Typography token (`fontFamily`, `fontSize`, `fontWeight`, `letterSpacing`, `lineHeight`) |
| `namedColors` | object (40+ tokens) | Full semantic color map (Material 3) |
| `designMd` | string | Auto-generated design system markdown |
| `description` | string | Brief aesthetic description |
diff --git a/skills/stitch-ui-design-spec-generator/SKILL.md b/skills/stitch-ui-design-spec-generator/SKILL.md
index 734e8ce..d392e85 100644
--- a/skills/stitch-ui-design-spec-generator/SKILL.md
+++ b/skills/stitch-ui-design-spec-generator/SKILL.md
@@ -114,7 +114,7 @@ The API supports three separate font roles. Default behavior: all three = same f
| Editorial / magazine | `EB_GARAMOND` or `LITERATA` | `INTER` or `DM_SANS` | `INTER` or `DM_SANS` |
| Brutalist / hacker | `SPACE_GROTESK` | `INTER` | `IBM_PLEX_SANS` |
| Luxury / high-end | `LIBRE_CASLON_TEXT` | `MANROPE` | `MANROPE` |
-| Data-heavy dashboard | `INTER` | `INTER` | `IBM_PLEX_SANS` or `SOURCE_SANS_THREE` |
+| Data-heavy dashboard | `INTER` | `INTER` | `IBM_PLEX_SANS` or `SOURCE_SANS_3` |
**Font selection guide — use Stitch enum names exactly:**
@@ -124,15 +124,24 @@ The API supports three separate font roles. Default behavior: all three = same f
| Clean modern / startup | `GEIST`, `MANROPE`, `PLUS_JAKARTA_SANS`, `WORK_SANS` |
| Editorial / expressive | `SPACE_GROTESK`, `EPILOGUE`, `SORA`, `RUBIK` |
| Friendly / consumer app | `NUNITO_SANS`, `LEXEND`, `BE_VIETNAM_PRO` |
-| Luxury / serif | `EB_GARAMOND`, `LITERATA`, `SOURCE_SERIF_FOUR`, `LIBRE_CASLON_TEXT` |
-| Dense data / admin | `SOURCE_SANS_THREE`, `PUBLIC_SANS`, `ARIMO` |
+| Luxury / serif | `EB_GARAMOND`, `LITERATA`, `SOURCE_SERIF_4`, `LIBRE_CASLON_TEXT` |
+| Dense data / admin | `SOURCE_SANS_3`, `PUBLIC_SANS`, `ARIMO` |
| News / reading | `NEWSREADER`, `DOMINE`, `NOTO_SERIF` |
+| Code / technical | `JETBRAINS_MONO`, `GOOGLE_SANS_CODE`, `SPACE_MONO` |
+| Editorial / high-fashion display | `PLAYFAIR_DISPLAY`, `BODONI_MODA`, `EB_GARAMOND` |
+| Condensed / bold impact | `BEBAS_NEUE`, `ANTON`, `ARCHIVO_NARROW` |
-Full font list: `BE_VIETNAM_PRO`, `EPILOGUE`, `INTER`, `LEXEND`, `MANROPE`, `NEWSREADER`,
+Full font list (68 values — SOURCE_SERIF_FOUR, SOURCE_SANS_THREE, and METROPOLIS are deprecated aliases, prefer SOURCE_SERIF_4/SOURCE_SANS_3):
+`BE_VIETNAM_PRO`, `EPILOGUE`, `INTER`, `LEXEND`, `MANROPE`, `NEWSREADER`,
`NOTO_SERIF`, `PLUS_JAKARTA_SANS`, `PUBLIC_SANS`, `SPACE_GROTESK`, `SPLINE_SANS`,
-`WORK_SANS`, `DOMINE`, `LIBRE_CASLON_TEXT`, `EB_GARAMOND`, `LITERATA`, `SOURCE_SERIF_FOUR`,
-`MONTSERRAT`, `METROPOLIS`, `SOURCE_SANS_THREE`, `NUNITO_SANS`, `ARIMO`, `HANKEN_GROTESK`,
-`RUBIK`, `GEIST`, `DM_SANS`, `IBM_PLEX_SANS`, `SORA`
+`WORK_SANS`, `DOMINE`, `LIBRE_CASLON_TEXT`, `EB_GARAMOND`, `LITERATA`, `SOURCE_SERIF_4`, `SOURCE_SERIF_FOUR`,
+`MONTSERRAT`, `METROPHOBIC`, `METROPOLIS`, `SOURCE_SANS_3`, `SOURCE_SANS_THREE`, `NUNITO_SANS`, `ARIMO`, `HANKEN_GROTESK`,
+`RUBIK`, `GEIST`, `DM_SANS`, `IBM_PLEX_SANS`, `SORA`, `ANYBODY`, `ANTON`, `ARCHIVO_NARROW`,
+`ATKINSON_HYPERLEGIBLE_NEXT`, `BARLOW_CONDENSED`, `BEBAS_NEUE`, `BODONI_MODA`, `BRICOLAGE_GROTESQUE`, `CHIVO`, `CLIMATE_CRISIS`,
+`COMFORTAA`, `COURIER_PRIME`, `FIRA_SANS`, `GOOGLE_SANS`, `GOOGLE_SANS_CODE`, `GOOGLE_SANS_FLEX`, `GOOGLE_SANS_MONO`, `GOOGLE_SANS_TEXT`,
+`IBM_PLEX_SERIF`, `JETBRAINS_MONO`, `KARLA`, `LIBRE_FRANKLIN`, `MERRIWEATHER`, `NOTO_SANS`, `OPEN_SANS`, `OSWALD`,
+`OUTFIT`, `PLAYFAIR_DISPLAY`, `POIRET_ONE`, `QUESTRIAL`, `QUICKSAND`, `RALEWAY`, `ROBOTO_FLEX`, `SPACE_MONO`,
+`SYNE`, `VOLLKORN`
### 8. Determine background colors