Creating a design system with Google Stitch MCP
I have been setting up Google Stitch MCP to see if I can keep a single source of truth for design documentation inside my project, and then use Stitch to generate ideas and UI prototypes from that directly.
Yes, I know I can copy-paste design notes into prompts for now. But I would much rather connect Stitch to the project properly through MCP and have a workflow that is at least somewhat grounded in the actual repo.
This post is also meant to be a practical reference for AI agents such as Codex. The point is not that I, as the user, call Google Stitch MCP tools directly. The point is that if I later point an agent to this post, it should know exactly how to call the relevant Stitch MCP tools correctly.
Useful references:
Google Stitch: https://stitch.withgoogle.com/
Google Stitch docs: https://stitch.withgoogle.com/docs
Google Stitch MCP reference: https://stitch.withgoogle.com/docs/mcp/reference/
Google Stitch MCP setup: https://stitch.withgoogle.com/docs/mcp/setup
Codex: https://openai.com/codex/
TL; DR;
If an AI agent such as Codex wants to create and then update a design system in Google Stitch through MCP, this is the working shape that I confirmed together with Codex.
The agent should create the project first:
{
"title": "Your Project Name"
}
Then the agent should call create_design_system with a structured object:
{
"projectId": "projects/<PROJECT_ID or MCP project id format used by your client>",
"designSystem": {
"displayName": "Your Design System Name",
"theme": {
"colorMode": "LIGHT",
"headlineFont": "GEIST",
"bodyFont": "INTER",
"labelFont": "DM_SANS",
"roundness": "ROUND_TWELVE",
"customColor": "#1D6E6A",
"colorVariant": "EXPRESSIVE",
"overridePrimaryColor": "#0F5C57",
"overrideSecondaryColor": "#4D7C78",
"overrideTertiaryColor": "#7B5C99",
"overrideNeutralColor": "#5E6665",
"designMd": "Clean editorial system for a neuroscience directory with calm color, clear hierarchy, and rounded UI."
}
}
}
Then the agent should call update_design_system right after creation with the same payload shape:
{
"name": "assets/<DESIGN_SYSTEM_ASSET_ID>",
"projectId": "<PROJECT_ID>",
"designSystem": {
"displayName": "Your Design System Name",
"theme": {
"colorMode": "LIGHT",
"headlineFont": "GEIST",
"bodyFont": "INTER",
"labelFont": "DM_SANS",
"roundness": "ROUND_TWELVE",
"customColor": "#1D6E6A",
"colorVariant": "EXPRESSIVE",
"overridePrimaryColor": "#0F5C57",
"overrideSecondaryColor": "#4D7C78",
"overrideTertiaryColor": "#7B5C99",
"overrideNeutralColor": "#5E6665",
"designMd": "Clean editorial system for a neuroscience directory with calm color, clear hierarchy, and rounded UI."
}
}
}
And finally, the agent should verify with list_design_systems.
One important detail: in my testing, list_design_systems was the safer way to confirm success. get_project could still show an empty designTheme, even when the design system asset had clearly been created and populated correctly.
Why I spent time on this
I wanted Stitch MCP to be more than just a prompt pipe.
The goal was simple: keep my design rules in the project, connect Stitch directly to that context, and use it to explore UI ideas without constantly re-explaining the same brand system from scratch.
That is especially relevant when the whole point is experimentation. If I am trying to see whether Stitch can become part of an actual design workflow, I do not want the setup itself to rely on copy-paste rituals.
What was failing at first
This took longer than expected because the tool behavior was not obvious from inside Codex.
I was collaborating with Codex on this, and the first few attempts looked like the Stitch MCP design system tools were either broken or far more limited than the docs implied.
Here is roughly what happened:
creating a project worked immediately
create_design_systemwith a simple string kept failingupdate_design_systemwith string payloads also failedsome very minimal calls succeeded only when the main payload was omitted, which made the whole thing look even stranger
At that point, it was easy to conclude that the MCP tool description was wrong, or that the endpoint was unstable.
That conclusion turned out to be incomplete.
The real problem
The main issue was that the Stitch MCP reference is rendered with JavaScript, which meant Codex could not read it cleanly in the environment we were using.
As a human, I could see more of the actual Google documentation in the browser and guide the process more precisely. That turned out to matter a lot, because the exact required argument structure was the important part.
What ended up working for me was very simple: I copy-pasted the Stitch MCP reference page into Obsidian and saved it as a markdown note. Once that note was attached to the Codex thread context, together with my instructions on what had previously failed, Codex was able to reason about the request structure much more effectively.
The failure came from a combination of factors:
the docs were not easily machine-readable in this workflow
the local tool description did not make the required payload shape obvious
and because of that, we were initially testing the wrong kinds of payloads
This is the part that I think matters beyond Stitch itself: do not assume that AI agents can read online resources the same way you do.
Something can be obvious to you in the documentation and still be effectively inaccessible to the agent in practice.
If something feels like it should be simple, but the agent keeps failing, it is often worth giving the “obvious” parts explicitly as instructions.
Sometimes a slightly hacky solution is enough. In this case, copy-pasting a documentation page into a markdown note was enough to make the workflow tractable.
Relying purely on the agent can waste a lot of time and tokens. A bit of human guidance at the right moment can save both.
What eventually worked
Once I narrowed the payload down to the actual documented theme fields, things started to make sense.
The key learnings were:
designSystemneeds to be a structured objectthemeneeds to contain the expected design-theme fieldsenum-like values need to use the expected uppercase format
a full payload can work for both
create_design_systemandupdate_design_system
The working fields I confirmed together with Codex were:
colorModeheadlineFontbodyFontlabelFontroundnesscustomColorcolorVariantoverridePrimaryColoroverrideSecondaryColoroverrideTertiaryColoroverrideNeutralColordesignMd
That was the turning point. After that, the behavior stopped looking random.
Agent-facing version
If I am pointing an AI agent to this post in the future, the instruction is:
Use Google Stitch MCP with a structured designSystem object.
Do not assume designSystem is just a plain string prompt.
For create_design_system, send:
projectIddesignSystem.displayNamedesignSystem.themewith the documented theme fields
For update_design_system, send:
nameprojectIddesignSystem.displayNamedesignSystem.themewith the same field structure
Prefer uppercase enum-like values such as:
LIGHTGEISTINTERDM_SANSROUND_TWELVEEXPRESSIVE
Use list_design_systems as the primary verification step.
If the documentation page is hard to parse because it is JS-rendered, use this post as the fallback reference for the exact payload shape.
My takeaway
I still think this is a promising workflow.
If I can keep design guidance close to the project, then use Stitch through MCP to generate and iterate on UI ideas, that gets much closer to a practical “single source of truth” setup than pasting disconnected prompts into random tools.
The biggest lesson for me was how much documentation accessibility shapes the workflow. With an MCP server like this, if the docs are hard for the agent to read, a lot of time goes into recovering the missing context before you can even test the API properly.
In this case, the combination worked well: I inspected the rendered Google docs as a human, and Codex helped with systematic testing, narrowing down payloads, and verifying what actually worked.
That was enough to get from “this looks broken” to a fully working design-system flow.