Everything below comes from one run on 2026-10-02: Storybook 10.6.1, @storybook/addon-mcp 10.6.1, Claude Code 2.1.280, Node 22.23.3, React 19, in a throwaway Vite project rather than this blog's own workspace. Our earlier setup article probed 10.5.10 with addon-mcp 0.7.0, and the tool names have changed since.
TL;DR: Storybook 10.6.1 exposes eight MCP tools to Claude Code.
test-runlists a story with a contrast failure under "Passing Stories" and puts the violation in a separate section, so a green list proves less than it looks like. The stocka11y.testmode istodo, which never fails anything.
How Do You Connect Claude Code to Storybook?
Scaffold, install, start the server, register it. I ran the first two scaffolds through npm create, which prints npx create-storybook as its next step. The npx spelling needs no argument separator, so that's what I show:
npx create-vite@latest demo --template react-ts
cd demo && npm install
CI=1 npx create-storybook@latest --yes --no-dev --disable-telemetry --features docs test a11y ai
npx storybook dev -p 6021 --no-open --ci
claude mcp add --transport http --scope project storybook http://localhost:6021/mcp
The Storybook installer wrote @storybook/addon-mcp, addon-vitest, addon-a11y and addon-docs into .storybook/main.ts. It wrote no MCP config and no CLAUDE.md. The claude mcp add line produced the only agent-side file, a .mcp.json holding "type": "http" and the URL.
Storybook's docs use npx mcp-add for this step. I didn't run it, because it's a separate package that writes into agent config, and I wanted the registration visible. The Claude Code docs describe project scope as shared through version control, with an approval prompt in interactive sessions. claude mcp list showed my server as "Pending approval". Non-interactive claude -p loaded it anyway, as documented.
What Do the Tools Return?
Eight tools, and I called them with claude -p ... --strict-mcp-config --mcp-config .mcp.json --allowedTools "mcp__storybook", so no other server could muddy the output.
| Toolset | Tools on my server |
|---|---|
| Docs | docs-list, docs-show, docs-show-story |
| Development | get-storybook-story-instructions, stories-changed, stories-find-by-component, stories-preview |
| Testing | test-run |
docs-show on a component I'd written, SplitPane, returned its stories and typed props with the JSDoc and defaults intact:
/**
Smallest size of the left panel, in percent of the group.
*/
minLeft?: number = 20;
I never set componentsManifest in main.ts. The addon's own preset does it, which I confirmed by reading dist/preset.js after the docs page said the flag was off by default.
stories-preview is where docs and reality part. The overview says it returns previews "rendered in the agent's chat interface". In headless mode I got this and nothing else:
{"stories":[{"title":"Layout/SplitPane","name":"Default","previewUrl":"http://localhost:6021/?path=/story/layout-splitpane--default"}]}
A URL. Whether an interactive client draws it inline, I didn't test.
Does a Story Catch What a Snippet Gets Wrong?
Partly, and the partial answer is the useful one. Our library majors article had to correct a react-resizable-panels v4 snippet that used PanelGroup, which 4.12.3 doesn't export. So I pasted that v3 shape into SplitPane (PanelGroup, PanelResizeHandle) and asked for test-run.
The MCP result was close to useless: Failed to import test file .../SplitPane.stories.tsx, an empty Error: line, and a stack through the Vitest browser runner. The real cause sat in the Storybook server log: the module "does not provide an export named 'PanelGroup'". A plain type check named it outright, error TS2724: ... has no exported member named 'PanelGroup'.
So the story didn't beat the compiler on this one. What it adds is the render: contrast, roles, the interaction. And the transport swallowed the error text, so keep the dev server's terminal visible. My opinion, and you can argue with it: an agent loop is only as good as the error messages that survive the trip back to the agent.
A story that fails to import tells the agent only that it failed. The reason stayed in the server log, so a loop that never reads the log can't fix it.
Why Does test-run Call a Failing Story Passing?
I added a second story, PaleTitles, with #aaa text on white, and ran both:
## Passing Stories
- layout-splitpane--default
- layout-splitpane--pale-titles
## Accessibility Violations
### layout-splitpane--pale-titles - color-contrast
Element has insufficient color contrast of 2.32 ... Expected contrast ratio of 4.5:1
Same story, listed as passing and as a violation. The scaffold's preview.tsx ships a11y: { test: 'todo' }, which shows violations in the UI and never fails a test. Switching to 'error' changed what the other runners did. npx vitest run --project storybook failed Pale Titles with toHaveNoViolations. npx storybook tools test run exited 1 instead of 0. The MCP report text still listed the story under Passing.
I restarted the server between those runs to rule out a stale cache. What does that mean for a rule file? Don't write "tests pass". Write "no failing stories and no accessibility violations", because those are two different sentences.
What Else Changed in 10.6?
Two things that matter for CLAUDE.md. First, the same tools exist as a CLI. npx storybook tools docs list works without a dev server, and npx storybook tools --help marks each command as local or requiring a running Storybook. Second, npx storybook skills stories prints a workflow block written for agents: find affected stories, run the tests, and don't report completion while any fail. It beats a hand-written "never hallucinate props" line, because Storybook maintains it.
stories-changed has a trap as well. My first server started before git init, logged "Change detection unavailable: not a git repository", and answered "No new, modified, or related stories detected" after I'd edited a component. After a restart inside the repo it returned "Detected 2 changed stories (0 new, 2 modified, 0 related)", by name.
The rule block I'd put in CLAUDE.md:
## UI work
- Run `npx storybook skills stories` before touching a component and follow it.
- Take props from docs-show, never from source or node_modules.
- Done means test-run shows no failing stories and no accessibility violations.
What Doesn't This Loop Do?
Storybook labels its AI features as preview and says the API may change. The docs toolset covers React, Angular and Vue frameworks only. Nothing in this loop compares screenshots, so a visual regression passes if the story still renders. I ran one small project, not a monorepo, and I didn't run the interactive chat preview.
Is it faster than asking the agent to just write the component? No. It's more truthful, because the agent reads the props that exist and the tests answer back. For pairing it with the rest of a Claude Code setup, see our React workflow guide and the MCP primer. For the authoring rules behind good stories, the setup guide on Art of Styleframe goes deeper than I will here.