Storybook MCP + Amazon Bedrock + Strands: Teaching your LLM to build UI from your real design system catalog

Teach your LLM your design system: Storybook MCP + Amazon Bedrock + Strands

AI/ML
August 04, 2026
10-15 min

Share blog

Introduction

Most "AI UI" demos look great until you paste the markup into a real product. Props don't exist. Tokens are wrong. The model invents a parallel design system.

The fix is not a smarter prompt. It's giving the model tools that return your actual components the same ones you already document in Storybook.

This tutorial walks through that pattern:

  • Publish a design-system catalog (from Storybook) over MCP.
  • Connect an agent running on Amazon Bedrock via the Strands Agents SDK.
  • Force the agent to look up components before it writes UI.

You can follow it with your own Storybook; the examples use a TypeScript / Angular-style catalog, but the shape works for React or any other stack.

Why MCP?

Model Context Protocol is a standard way for tools (and catalogs) to show up inside an agent loop. Instead of stuffing every component prop into the system prompt, you expose small tools:

ToolJob
list-all-documentationWhat's in the design system?
get-documentationExact inputs, outputs, examples for one component
get-documentation-for-storyStory variants + preview URLs
get-design-tokensColors, spacing, typography rules
get-storybook-story-instructionsHow to author new stories correctly

The model discovers the library, then drills into only what it needs for the screen it's building.

Note: Storybook's official MCP addon (http://localhost:6006/mcp) is useful for some React setups. For Angular (and for a stable production API), prefer a custom catalog MCP backed by a JSON catalog exported from Storybook not a live dependency on Storybook being up.

Architecture (big picture)

Architecture diagram showing the three-layer approach

Three layers, cleanly separated:

  • Catalog documentation the design system already owns.
  • MCP how any agent (Cursor, Bedrock, CI) reads that catalog.
  • Agent Bedrock model + Strands loop that must call tools before inventing markup.

Part 1: Expose your Storybook as MCP

1. Maintain a catalog, not just stories

Stories are for humans. Agents need a structured catalog: selectors, input names, allowed values, examples, do/don't rules.

Minimal shape:

json
1{
2 "name": "Acme Design System",
3 "framework": "angular",
4 "storybookUrl": "https://storybook.example.com/",
5 "guidelines": [
6 "Never invent component properties.",
7 "Call get-documentation before using a component."
8 ],
9 "components": [
10 {
11 "id": "button",
12 "name": "Button",
13 "selector": "acme-button",
14 "className": "AcmeButtonComponent",
15 "import": "@acme/design-system",
16 "category": "actions",
17 "description": "Primary action control",
18 "storybookPath": "?path=/docs/button--docs",
19 "inputs": [
20 { "name": "variant", "type": "'primary' | 'danger' | 'secondary'", "required": false },
21 { "name": "disabled", "type": "boolean", "required": false }
22 ],
23 "outputs": [{ "name": "pressed", "type": "EventEmitter<void>" }],
24 "examples": [
25 "<acme-button variant=\"primary\">Save</acme-button>"
26 ]
27 }
28 ],
29 "tokensCss": ":root { --color-primary: #2563eb; }"
30}

Generate or sync this from Storybook (script, CI step, or hand-maintained for a small library). The important part: the catalog must match production components.

2. Implement the five tools

A stdio MCP server (great for Cursor) is enough to start:

javascript
1// mcp/server.mjs (sketch)
2import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4import { z } from 'zod';
5import catalog from './catalog.json' with { type: 'json' };
6
7const server = new McpServer({ name: 'acme-ds-mcp', version: '1.0.0' });
8
9server.tool('list-all-documentation', 'List design-system components', {}, async () => ({
10 content: [{ type: 'text', text: JSON.stringify({
11 components: catalog.components.map(({ id, name, selector, description }) => ({
12 id, name, selector, description,
13 })),
14 }, null, 2) }],
15}));
16
17server.tool(
18 'get-documentation',
19 'Full docs for one component (props, examples)',
20 { component: z.string() },
21 async ({ component }) => {
22 const match = catalog.components.find((c) =>
23 [c.id, c.name, c.selector].includes(component),
24 );
25 return {
26 content: [{
27 type: 'text',
28 text: JSON.stringify(match ?? { error: 'not found' }, null, 2),
29 }],
30 };
31 },
32);
33
34// …get-documentation-for-story, get-design-tokens, get-storybook-story-instructions
35
36await server.connect(new StdioServerTransport());

Point Cursor (or any MCP client) at node mcp/server.mjs and try: "What button variants exist?" the answer should come from the tool, not the model's memory.

3. Host it for cloud agents

Local stdio is fine for IDE agents. Bedrock agents in AWS need an HTTP MCP endpoint (Streamable HTTP / your gateway).

In production you can put the same catalog tools on a shared MCP host next to other product tools, and gate them with an OAuth scope such as ds:read so a data agent cannot see design-system tools and a UI agent cannot see SQL tools unless you grant both scopes.

Let's Build Something Great Together

Ready to transform your idea into a powerful software solution? Talk to our experts and get a free consultation.

Contact Us

Sketch of the contract:

http
1POST /exchange
2Authorization: Bearer <your-app-session-token>
3Content-Type: application/json
4
5{ "scope": "ds:read" }
6{
7 "access_token": "<mcp-jwt>",
8 "token_type": "Bearer",
9 "expires_in": 3600,
10 "scope": "ds:read"
11}

Then the agent calls POST /mcp with that JWT. The server registers only tools allowed by the token's scopes.

You don't need this exchange on day one a shared API key for a prototype is fine. Add scoped tokens when multiple tool families share one MCP host.

Part 2: Wire Bedrock + Strands

Strands gives you a small agent loop: model + tools + system prompt. On AWS, the model is Bedrock (Claude, etc.).

1. Open an MCP session per invocation

Conceptually:

  • Exchange (or otherwise obtain) an MCP access token with ds:read.
  • Connect Strands McpClient to your /mcp URL.
  • listTools() trust the server's list for that JWT.
  • Pass those tools into new Agent({ model, systemPrompt, tools }).
  • Always disconnect() in a finally block.

Simplified TypeScript:

typescript
1import { Agent, McpClient } from '@strands-agents/sdk';
2import { createBedrockModel } from './bedrock'; // your Bedrock model factory
3
4async function runUiAgent(userMessage: string, mcpBaseUrl: string, mcpJwt: string) {
5 const client = new McpClient({
6 url: `${mcpBaseUrl.replace(/\/+$/, '')}/mcp`,
7 headers: { Authorization: `Bearer ${mcpJwt}` },
8 });
9
10 try {
11 await client.connect();
12 const tools = await client.listTools();
13
14 const agent = new Agent({
15 model: createBedrockModel({ /* region, model id, guardrails */ }),
16 systemPrompt: SYSTEM_PROMPT,
17 tools,
18 });
19
20 const result = await agent.invoke(userMessage);
21 return result.toString();
22 } finally {
23 await client.disconnect();
24 }
25}

Wrap that in a small helper (exchange → connect → listTools) so every agent gets the same session lifecycle.

2. System prompt: make the catalog mandatory

Tools alone aren't enough. Tell the model how to use them:

text
1You build UI only with the company design system.
2
3Hard rules:
41. Before writing any component markup, call list-all-documentation.
52. For every component you use, call get-documentation and use ONLY documented inputs.
63. If a property is not documented, do not invent it ask the user.
74. Prefer design tokens from get-design-tokens over raw colors.
85. Match existing Storybook patterns from get-documentation-for-story when relevant.
9
10Output: production-ready framework markup (e.g. Angular standalone templates)
11using real selectors from the catalog.

Same rule for IDE agents: never invent component properties; query MCP first.

3. Keep the agent thin

A good UI agent for this pattern:

  • Declares which MCP tools it's allowed to use (governance allowlist).
  • Requests only ds:read (not warehouse / SQL scopes).
  • Does not hardcode the component list in application code the server is the source of truth after exchange.

Part 3: Try an end-to-end request

"User: Build a simple settings header: title, a status pill, and a primary Save button."

Healthy agent loop:

  • list-all-documentation → sees acme-button, acme-status-pill , …
  • get-documentation for button and status pill → learns variant="primary" / "secondary", etc.
  • Optionally get-design-tokens for spacing.
  • Emits markup that only uses documented APIs.

Unhealthy agent (no MCP): <AcmeButton color="purple" size="xl"> pretty, wrong, and expensive to clean up.

Practical tips

  • Sync the catalog in CI. When Storybook stories change, regenerate catalog.json, rebuild the MCP image/Lambda, deploy. Stale catalogs are how agents "learn" deleted props.
  • Prefer documented examples over free-form CSS. If your guidelines say "no raw hex," put that in the catalog guidelines array and in the system prompt.
  • Scope tools by audience. UI agents get ds:read. Data agents get whatever read scopes you expose for analytics or SQL. Same MCP host, different JWTs.
  • Evaluate with fixtures. Offline evals can stub MCP tools; keep a small suite that asserts the agent calls get-documentation before emitting selectors.
  • Don't confuse Storybook preview MCP with your catalog MCP. Preview/manifest tooling helps some React workflows; a versioned JSON catalog is what holds up for Angular and for non-local agents.

What you get

Without catalog MCPWith Storybook → MCP → Bedrock
Invented props and tokensDocumented inputs only
Prompt stuffed with the whole DSOn-demand tool calls
IDE-only knowledgeSame tools for Cursor and cloud agents
Drift from StorybookCatalog synced from the same source

Closing

Design systems already encode how your product should look. MCP turns that encoding into callable truth for models. Bedrock supplies the reasoning; Strands supplies the tool loop; your Storybook catalog supplies the constraints.

Start small: five tools, one button component, one agent prompt that refuses to invent props. Once that loop is trustworthy, grow the catalog the same way you grow Storybook one documented component at a time.

Further reading

Model Context Protocol

Strands Agents SDK

Amazon Bedrock

● Storybook docs for your framework (Angular / React / Vue)

Blogs

Discover the latest insights and trends in technology with the Omax Tech Blog.

View All Blogs
Omax | Blog | How to Add LiveKit Video Calling to a Next.js App
12-14 min
September 11, 2026

How to Add LiveKit Video Calling to a Next.js App

Add embedded video & audio calling to Next.js with LiveKit Cloud. Compared vs Twilio, Daily, Agora, Zoom — plus token auth, guests & recording.

Read More
Omax | Blog | We chose ECS over EKS: what we gained and what we gave up
8-10 min
September 10, 2026

We chose ECS over EKS: what we gained and what we gave up

An honest comparison of ECS vs EKS the costs, tradeoffs, and real-world reasoning behind choosing ECS for a production platform on AWS.

Read More
Omax | Blog | Upgrading Legacy Systems: From Outdated Technology to Competitive Advantage
8-10 min
September 07, 2026

Upgrading Legacy Systems: From Outdated Technology to Competitive Advantage

Learn how to upgrade legacy systems through application modernization, API integration, cloud migration, security improvements, and incremental system upgrades without disrupting business operations.

Read More
Omax | Blog | Building Distributed Tracing and Observability with AWS X-Ray
12-14 min
September 04, 2026

Building Distributed Tracing and Observability with AWS X-Ray

A practical guide to correlating requests across a multi-tier application using correlation IDs, AWS X-Ray segments, and structured logging for faster incident debugging.

Read More
Omax | Blog | Designing Before and After AI: What Really Changed
6-7 min
September 03, 2026

Designing Before and After AI: What Really Changed

A look at how AI has transformed UI/UX design from manual wireframes and slow research to AI-assisted prototyping, design-to-code, and personalization at scale.

Read More
Omax | Blog | Beyond Prompting: Managing Context and Tokens in AI Coding Tools
12-14 min
September 03, 2026

Beyond Prompting: Managing Context and Tokens in AI Coding Tools

Ever wondered why your AI coding agent starts losing context or hits a hard limit mid-task? The answer lies in tokens and the context window. Good AI coding is not about giving the model the most information. It is about giving it the right information at the right time.

Read More
Omax | Blog | What Is llms.txt? How It Helps Google, AI Search, and Agentic Browsing Find Your Website
10-12 min
August 31, 2026

What Is llms.txt? How It Helps Google, AI Search, and Agentic Browsing Find Your Website

Learn what llms.txt is, how it differs from sitemap.xml and robots.txt, and how it can help your site get found by Google, AI search tools, and AI agents.

Read More
Omax | Blog | Build an Automated Image Compression Script with Sharp and SVGO
7-8 min
August 28, 2026

Build an Automated Image Compression Script with Sharp and SVGO

Compress images from the terminal with a Node.js script powered by Sharp and SVGO a safe, two-step workflow that keeps your site fast without bloating your repo.

Read More
Omax | Blog | The Right Way to Migrate from MySQL to AWS Aurora DSQL
7-8 min
August 25, 2026

The Right Way to Migrate from MySQL to AWS Aurora DSQL

Migrating a production database is one of the highest-risk changes you can make to an application. Moving from MySQL to AWS Aurora DSQL raises the stakes further...

Read More