Storybook and its MCP server
Component docs for humans and for agents, from the same source.
What
Storybook (packages/ds/.storybook/) renders every component in isolation, documents
its props, runs accessibility checks, and exposes all of that to AI agents through an
MCP server at http://localhost:6006/mcp. The server comes from @storybook/addon-mcp
and reads the same data Storybook shows in the browser.
Why
For the design system, Storybook is the documentation: props, examples, a11y results, all generated from the code. For the benchmark, its MCP is one of the context levels in the matrix, the "standard MCP" column: what an agent gets when a team plugs in the tool their design system already ships with.
The "optimized" column is our own server, ds-mcp, built from the same
sources. The difference matters: Storybook's MCP serves the tokens page as raw MDX, so
the live token table reaches the agent as <SemanticTokenTable /> and no token name
gets through (anecdote 04).
Try it
bun run storybook # http://localhost:6006, MCP at /mcpOpen http://localhost:6006/mcp in the browser to see the available tools. To call
them from an agent, point it at that URL as a streamable HTTP MCP server. With Claude
Code, for example:
claude mcp add --transport http vektos-ds http://localhost:6006/mcpThen ask "list the documented components" and you should see a docs-list call that
returns Button (button). docs-show with id: "button" returns:
## Props
variant?: "solid" | "outline" = "solid"; // Visual style. `solid` is the primary action...
size?: "sm" | "md" = "md"; // Size of the button.
## Stories
import { Button } from '@vektos/ds';
const Solid = () => <Button variant="solid" size="md">Run benchmark</Button>;Everything there comes from two files: the interface ButtonProps in button.tsx
(via react-docgen) and button.stories.tsx.
Extend it
- New component. Write
src/<name>.tsxwith an explicitinterface <Name>Propsand a JSDoc line per prop, thensrc/<name>.stories.tsxin CSF3 (copybutton.stories.tsx). Storybook, the manifest and the MCP pick it up on reload. - Prose docs. Add
src/docs/<topic>.mdx. Pages undersrc/**/*.mdxare in thestoriesglob. Pages attached to a component are served bydocs-show. - Accessibility. addon-a11y runs axe on every story.
a11y.testis"error"inpreview.tsx, so a violation fails the story in the Storybook UI. - Styling in stories. Panda runs through
postcss.config.cjsinpackages/ds;src/styles.cssdeclares the layers. Vite resolvesstyled-system/*throughresolve.tsconfigPathsinmain.ts. - Theme.
.storybook/theme.tsbuilds a light and a dark Storybook theme with the Vektos brand;manager.tsandpreview.tsxpick one from the operating system's color scheme. This is the Storybook UI only. Light and dark variants of the components themselves arrive with semantic tokens in week 1. - The
.vektoswrapper. Panda's CSS reset is scoped to.vektos(see 01-tokens). A decorator inpreview.tsxwraps every story in<div className="vektos">, so components get the reset and the MDX pages keep Storybook's own typography. Without it, the docs pages lose list numbers and heading margins.
Known gaps
-
MDX pages are served as source. Anything rendered by a component (the token tables) is invisible to agents, and maintainer sections ("Adding a token") are served too.
-
The tool list is about 18k characters for 7 tools, sent with every request. Four tools are for editing stories, not for using components.
-
The
Cardexample usescss()without importing it. -
The
test-runMCP toolset is off: it requires Vitest, and we usebun test. Agents cannot run story tests through the MCP yet. -
Props inherited from Ark (
onClick,disabled, …) do not appear in the manifest.react-docgenonly expands what is declared in the file, which is also why the props must be declared there. -
storybook buildwarns about chunk sizes. Harmless for now; revisit when the DS grows. -
The theme is chosen once at load. Switching the OS color scheme needs a page reload; there is no toggle in the toolbar.
-
Components that render through a portal (Dialog, Menu, Tooltip) land in
<body>, outside the.vektosdecorator, so they will miss the reset. To handle when those components arrive in week 1: pass acontainerto Ark'sPortal, or add the class to the portal root.