@storybook/addon-mcp 0.3.4 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -219
- package/dist/preset.js +42 -12
- package/dist/preview-stories-app-script.js +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,226 +1,11 @@
|
|
|
1
1
|
# Storybook MCP Addon
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
It enables a workflow where for each UI component created, the agent will automatically generate and link to example stories. These stories let you visually verify the new UI in each of its key states, and provide documentation and component tests.
|
|
6
|
-
|
|
7
|
-
The addon provides tools to improve agents' UI development capabilities, retrieve story URLs, and access component documentation.
|
|
3
|
+
Storybook addon for MCP-powered UI development workflows.
|
|
8
4
|
|
|
9
5
|
<div align="center">
|
|
10
|
-
|
|
6
|
+
<img src="./addon-mcp-claude-code-showcase.gif" alt="Storybook MCP Addon Demo" />
|
|
11
7
|
</div>
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
### Installation and Setup
|
|
16
|
-
|
|
17
|
-
> [!NOTE]
|
|
18
|
-
> This addon requires Storybook version 9.1.16 or higher.
|
|
19
|
-
|
|
20
|
-
Use Storybook's CLI to automatically install and configure the addon:
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npx storybook add @storybook/addon-mcp
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
This command will install the addon and add it to your Storybook configuration automatically.
|
|
27
|
-
|
|
28
|
-
Start your Storybook development server:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npm run storybook
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
The MCP server will be available at `<your_storybook_dev_server_origin>/mcp` when Storybook is running.
|
|
35
|
-
|
|
36
|
-
### Configuration
|
|
37
|
-
|
|
38
|
-
#### Addon Options
|
|
39
|
-
|
|
40
|
-
You can configure which toolsets are enabled by default in your `.storybook/main.js`:
|
|
41
|
-
|
|
42
|
-
```javascript
|
|
43
|
-
// .storybook/main.js
|
|
44
|
-
export default {
|
|
45
|
-
addons: [
|
|
46
|
-
{
|
|
47
|
-
name: '@storybook/addon-mcp',
|
|
48
|
-
options: {
|
|
49
|
-
toolsets: {
|
|
50
|
-
dev: true, // Tools for story URL retrieval and UI building instructions (default: true)
|
|
51
|
-
docs: true, // Tools for component manifest and documentation (default: true)
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
// componentsManifest is enabled by default in recent Storybook versions, no need to set it
|
|
57
|
-
};
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
**Available Toolsets:**
|
|
61
|
-
|
|
62
|
-
- `dev`: Enables [Dev Tools](#dev-tools)
|
|
63
|
-
- `docs`: Enables [Documentation Tools](#docs-tools)
|
|
64
|
-
|
|
65
|
-
Disabling the Dev Tools is useful when you want to try out the same experience that your external component consumers will get, because they only get the Component Documentation Tools.
|
|
66
|
-
|
|
67
|
-
#### Configuring toolsets with headers
|
|
68
|
-
|
|
69
|
-
You can also configure the available toolsets when setting up the MCP Server in your MCP Client by setting the `X-MCP-Toolsets` header. The header is a comma-separated list of toolset names, `X-MCP-Toolsets: dev,docs`. Eg. to configure your client to only have the Component Documentation Tools, the `.mcp.json`-file could look like this (format depends on the exact client you're using):
|
|
70
|
-
|
|
71
|
-
```json
|
|
72
|
-
{
|
|
73
|
-
"storybook-mcp": {
|
|
74
|
-
"url": "http://localhost:6006/mcp",
|
|
75
|
-
"type": "http",
|
|
76
|
-
"headers": {
|
|
77
|
-
"X-MCP-Toolsets": "docs"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Configuring Your Agent
|
|
84
|
-
|
|
85
|
-
> [!NOTE]
|
|
86
|
-
> This addon is primarily tested with Claude Code and GitHub Copilot. While it should work with other MCP clients, Claude Code is our main target for compatibility and testing.
|
|
87
|
-
|
|
88
|
-
#### Claude Code Setup
|
|
89
|
-
|
|
90
|
-
To use this addon with [Claude Code](https://claude.ai/code), use the built-in MCP configuration command:
|
|
91
|
-
|
|
92
|
-
1. **Add the MCP server**: Run the following command in your terminal:
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
claude mcp add storybook-mcp --transport http http://localhost:6006/mcp --scope project
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
2. **Start Storybook**: Make sure your Storybook development server is running:
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
npm run storybook
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
3. **Connect Claude Code**: Claude Code should automatically detect and connect to the MCP server when it's running. You can verify the connection by asking Claude to use Storybook-related tools.
|
|
105
|
-
|
|
106
|
-
4. **Configure Agent Behavior** (Optional but Recommended): Add the following system or project prompt to ensure your agent uses the Storybook tools when appropriate:
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
Before doing any UI, frontend or React development, ALWAYS call the storybook MCP server to get further instructions.
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
#### Other MCP Clients
|
|
113
|
-
|
|
114
|
-
[](https://cursor.com/en-US/install-mcp?name=storybook-mcp&config=eyJ1cmwiOiJodHRwOi8vbG9jYWxob3N0OjYwMDYvbWNwIn0%3D)
|
|
115
|
-
|
|
116
|
-
This addon should work with any MCP-compatible client that supports the `tool` capability and the `streamable-http` transport. Here are setup guides for other popular clients:
|
|
117
|
-
|
|
118
|
-
- [GitHub Copilot](https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend-copilot-chat-with-mcp)
|
|
119
|
-
- [Cursor](https://docs.cursor.com/en/context/mcp#installing-mcp-servers)
|
|
120
|
-
- [opencode](https://opencode.ai/docs/mcp-servers/)
|
|
121
|
-
- [Claude Desktop](https://modelcontextprotocol.io/quickstart/user)
|
|
122
|
-
- [Cline](https://docs.cline.bot/mcp/configuring-mcp-servers)
|
|
123
|
-
- [Zed Editor](https://zed.dev/docs/ai/mcp#as-custom-servers)
|
|
124
|
-
- [Continue](https://docs.continue.dev/customize/deep-dives/mcp#how-to-configure-mcp-servers)
|
|
125
|
-
- [Codex](https://github.com/openai/codex/blob/main/docs/config.md#mcp_servers)
|
|
126
|
-
|
|
127
|
-
For clients not listed above, consult their documentation for MCP server configuration. The server configuration typically requires:
|
|
128
|
-
|
|
129
|
-
- **Server Type**: `http`
|
|
130
|
-
- **URL**: `http://localhost:6006/mcp` (adjust port if your Storybook runs on a different port)
|
|
131
|
-
- ⚠️ Make sure your Storybook development server is running before your agent tries to connect.
|
|
132
|
-
|
|
133
|
-
## Usage
|
|
134
|
-
|
|
135
|
-
This addon provides MCP tools that your agent can use. The goal is that the agent uses these tools automatically when doing UI development, but agents are unreliable and unpredictable, so sometimes you might need to explicitly tell it to use the tools.
|
|
136
|
-
|
|
137
|
-
**If you are prompting from an IDE like VSCode or Cursor, be sure to use `Agent` mode and `sonnet-4.5` or better.**
|
|
138
|
-
|
|
139
|
-
### Dev Tools
|
|
140
|
-
|
|
141
|
-
These tools are always available when the addon is installed:
|
|
142
|
-
|
|
143
|
-
#### 1. UI Building Instructions (`get_ui_building_instructions`)
|
|
144
|
-
|
|
145
|
-
Provides agents with standardized instructions for UI component development within your project. This tool returns guidelines for:
|
|
146
|
-
|
|
147
|
-
- Writing Storybook stories using CSF3 format
|
|
148
|
-
- Component development best practices
|
|
149
|
-
- Story linking requirements
|
|
150
|
-
|
|
151
|
-
The instructions ensure agents follow your project's conventions when creating or modifying UI components and their corresponding stories.
|
|
152
|
-
|
|
153
|
-
#### 2. Preview Stories (`preview-stories`)
|
|
154
|
-
|
|
155
|
-
Allows agents to retrieve direct URLs to specific stories in your Storybook. The agent can request URLs for multiple stories by providing:
|
|
156
|
-
|
|
157
|
-
- **Path-based input** (best when the agent is already editing a `.stories.*` file):
|
|
158
|
-
- `absoluteStoryPath`: Absolute path to the story file
|
|
159
|
-
- `exportName`: The export name of the story
|
|
160
|
-
- `explicitStoryName`: Optional explicit story name
|
|
161
|
-
- **ID-based input** (best when the agent discovered stories via docs tools):
|
|
162
|
-
- `storyId`: Full Storybook story ID (for example `example-button--primary`)
|
|
163
|
-
|
|
164
|
-
Example agent usage:
|
|
165
|
-
|
|
166
|
-
```
|
|
167
|
-
Prompt: I need to see the primary variant of the Button component
|
|
168
|
-
|
|
169
|
-
Agent calls tool, gets response:
|
|
170
|
-
http://localhost:6006/?path=/story/example-button--primary
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Docs Tools
|
|
174
|
-
|
|
175
|
-
These additional tools are available when the component manifest feature is enabled. They provide agents with detailed documentation about your UI components.
|
|
176
|
-
|
|
177
|
-
**Requirements:**
|
|
178
|
-
|
|
179
|
-
- Storybook version 10.1.0 or higher (currently only available as prereleases, `storybook@next`)
|
|
180
|
-
- React-based framework (`react-vite`, `nextjs-vite`, `nextjs`, `react-webpack5`)
|
|
181
|
-
- Feature flag `features.componentsManifest` enabled (defaults to `true` in recent Storybook versions)
|
|
182
|
-
|
|
183
|
-
**To enable:**
|
|
184
|
-
|
|
185
|
-
The `componentsManifest` feature is enabled by default in recent Storybook versions — no configuration needed.
|
|
186
|
-
|
|
187
|
-
If you are on an older Storybook version that doesn't default to `true`, you may need to enable it explicitly. Use the flag that matches your Storybook version:
|
|
188
|
-
|
|
189
|
-
```javascript
|
|
190
|
-
// .storybook/main.js
|
|
191
|
-
export default {
|
|
192
|
-
// ... other config
|
|
193
|
-
features: {
|
|
194
|
-
// For Storybook 10.3.x and later:
|
|
195
|
-
componentsManifest: true,
|
|
196
|
-
// For older Storybook versions (before the flag was renamed):
|
|
197
|
-
// experimentalComponentsManifest: true,
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
#### 3. List All Documentation (`list-all-documentation`)
|
|
203
|
-
|
|
204
|
-
Returns a list of all available UI components as well as standalone docs in your component library. Useful for the LLM as discovery and understanding what components are available to use.
|
|
205
|
-
|
|
206
|
-
You can pass `withStoryIds: true` to include nested story entries (story name + story ID) under each component, which is useful before calling `preview-stories` or `run-story-tests` with `storyId`.
|
|
207
|
-
|
|
208
|
-
#### 4. Get Documentation (`get-documentation`)
|
|
209
|
-
|
|
210
|
-
Retrieves detailed documentation for a specific component or docs entry.
|
|
211
|
-
|
|
212
|
-
Component documentation includes component ID and story IDs for listed stories, so agents can directly feed those IDs into `preview-stories` and `run-story-tests`.
|
|
213
|
-
|
|
214
|
-
The agent provides a component/docs ID to retrieve its documentation. To get documentation for multiple entries, call this tool multiple times.
|
|
215
|
-
|
|
216
|
-
## Contributing
|
|
217
|
-
|
|
218
|
-
We welcome contributions to improve Storybook's agent integration, within or outside of this addon! Here's how you can help:
|
|
219
|
-
|
|
220
|
-
1. **Ideas and feature requests**: If you have ideas for what else we could do to improve the Storybook experience when using agents, please [start a discussion](https://github.com/storybookjs/mcp/discussions/new?category=ideas) in this repository.
|
|
221
|
-
|
|
222
|
-
2. **Report Issues**: If you find bugs, please open an issue on our [GitHub repository](https://github.com/storybookjs/mcp), but keep in mind that this is currently highly experimental, explorative and probably filled with bugs.
|
|
223
|
-
|
|
224
|
-
3. **Development**:
|
|
9
|
+
See [documentation](https://storybook.js.org/docs/next/ai/mcp/overview/?ref=readme) for installation instructions, usage examples, APIs, and more.
|
|
225
10
|
|
|
226
|
-
|
|
11
|
+
Learn more about Storybook at [storybook.js.org](https://storybook.js.org/?ref=readme).
|
package/dist/preset.js
CHANGED
|
@@ -9,13 +9,13 @@ import { stringify } from "picoquery";
|
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { normalizeStoryPath } from "storybook/internal/common";
|
|
11
11
|
import { storyNameFromExport } from "storybook/internal/csf";
|
|
12
|
-
import { ComponentManifestMap, DocsManifestMap, GET_TOOL_NAME, LIST_TOOL_NAME, addGetDocumentationTool, addGetStoryDocumentationTool, addListAllDocumentationTool } from "@storybook/mcp";
|
|
12
|
+
import { ComponentManifestMap, DocsManifestMap, GET_TOOL_NAME, LIST_TOOL_NAME, STORYBOOK_MCP_INSTRUCTIONS, addGetDocumentationTool, addGetStoryDocumentationTool, addListAllDocumentationTool } from "@storybook/mcp";
|
|
13
13
|
import fs from "node:fs/promises";
|
|
14
14
|
import { buffer } from "node:stream/consumers";
|
|
15
15
|
|
|
16
16
|
//#region package.json
|
|
17
17
|
var name = "@storybook/addon-mcp";
|
|
18
|
-
var version = "0.
|
|
18
|
+
var version = "0.4.1";
|
|
19
19
|
var description = "Help agents automatically write and test stories for your UI components";
|
|
20
20
|
|
|
21
21
|
//#endregion
|
|
@@ -768,7 +768,7 @@ const getManifestStatus = async (options) => {
|
|
|
768
768
|
options.presets.apply("experimental_manifests", void 0, { manifestEntries: [] }),
|
|
769
769
|
options.presets.apply("experimental_componentManifestGenerator")
|
|
770
770
|
]);
|
|
771
|
-
const hasManifests =
|
|
771
|
+
const hasManifests = manifests && "components" in manifests || !!legacyComponentManifestGenerator;
|
|
772
772
|
const hasFeatureFlag = !!(features?.componentsManifest ?? features?.experimentalComponentsManifest);
|
|
773
773
|
return {
|
|
774
774
|
available: hasFeatureFlag && hasManifests,
|
|
@@ -831,6 +831,25 @@ function estimateTokens(text) {
|
|
|
831
831
|
return tokenCount;
|
|
832
832
|
}
|
|
833
833
|
|
|
834
|
+
//#endregion
|
|
835
|
+
//#region src/instructions/dev-instructions.md
|
|
836
|
+
var dev_instructions_default = "## UI Building and Story Writing Workflow\n\n- Before creating or editing components or stories, call **get-storybook-story-instructions**.\n- Treat that tool's output as the source of truth for framework-specific imports, story patterns, and testing conventions.\n- After changing any component or story, call **preview-stories**.\n- Always include every returned preview URL in your user-facing response so the user can verify the visual result.\n";
|
|
837
|
+
|
|
838
|
+
//#endregion
|
|
839
|
+
//#region src/instructions/test-instructions.md
|
|
840
|
+
var test_instructions_default = "## Validation Workflow\n\n- After each component or story change, run **run-story-tests**.\n- Use focused runs while iterating, then run a broad pass before final handoff when scope is unclear or wide.\n- Fix failing tests before reporting success. Do not report completion while story tests are failing.\n";
|
|
841
|
+
|
|
842
|
+
//#endregion
|
|
843
|
+
//#region src/instructions/build-server-instructions.ts
|
|
844
|
+
function buildServerInstructions(options) {
|
|
845
|
+
const sections = ["Follow these workflows when working with UI and/or Storybook."];
|
|
846
|
+
if (options.devEnabled) sections.push(dev_instructions_default.trim());
|
|
847
|
+
if (options.testEnabled) sections.push(test_instructions_default.trim());
|
|
848
|
+
if (options.docsEnabled) sections.push(STORYBOOK_MCP_INSTRUCTIONS.trim());
|
|
849
|
+
if (sections.length === 1) return "";
|
|
850
|
+
return sections.join("\n\n");
|
|
851
|
+
}
|
|
852
|
+
|
|
834
853
|
//#endregion
|
|
835
854
|
//#region src/mcp-handler.ts
|
|
836
855
|
let transport;
|
|
@@ -840,17 +859,29 @@ let disableTelemetry;
|
|
|
840
859
|
let a11yEnabled;
|
|
841
860
|
const initializeMCPServer = async (options, multiSource) => {
|
|
842
861
|
disableTelemetry = (await options.presets.apply("core", {}))?.disableTelemetry ?? false;
|
|
843
|
-
const
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
862
|
+
const addonVitestConstants = await getAddonVitestConstants();
|
|
863
|
+
const manifestStatus = await getManifestStatus(options);
|
|
864
|
+
a11yEnabled = await isAddonA11yEnabled(options);
|
|
865
|
+
let server;
|
|
866
|
+
const serverOptions = {
|
|
848
867
|
adapter: new ValibotJsonSchemaAdapter(),
|
|
868
|
+
get instructions() {
|
|
869
|
+
return buildServerInstructions({
|
|
870
|
+
devEnabled: server?.ctx.custom?.toolsets?.dev ?? true,
|
|
871
|
+
testEnabled: (server?.ctx.custom?.toolsets?.test ?? true) && !!addonVitestConstants,
|
|
872
|
+
docsEnabled: (server?.ctx.custom?.toolsets?.docs ?? true) && manifestStatus.available
|
|
873
|
+
});
|
|
874
|
+
},
|
|
849
875
|
capabilities: {
|
|
850
876
|
tools: { listChanged: true },
|
|
851
877
|
resources: { listChanged: true }
|
|
852
878
|
}
|
|
853
|
-
}
|
|
879
|
+
};
|
|
880
|
+
server = new McpServer({
|
|
881
|
+
name,
|
|
882
|
+
version,
|
|
883
|
+
description
|
|
884
|
+
}, serverOptions).withContext();
|
|
854
885
|
if (!disableTelemetry) server.on("initialize", async () => {
|
|
855
886
|
await collectTelemetry({
|
|
856
887
|
event: "session:initialized",
|
|
@@ -859,9 +890,8 @@ const initializeMCPServer = async (options, multiSource) => {
|
|
|
859
890
|
});
|
|
860
891
|
await addPreviewStoriesTool(server);
|
|
861
892
|
await addGetUIBuildingInstructionsTool(server);
|
|
862
|
-
a11yEnabled = await isAddonA11yEnabled(options);
|
|
863
893
|
await addRunStoryTestsTool(server, { a11yEnabled });
|
|
864
|
-
if (
|
|
894
|
+
if (manifestStatus.available) {
|
|
865
895
|
logger.info("Experimental components manifest feature detected - registering component tools");
|
|
866
896
|
const contextAwareEnabled = () => server.ctx.custom?.toolsets?.docs ?? true;
|
|
867
897
|
await addListAllDocumentationTool(server, contextAwareEnabled);
|
|
@@ -1298,7 +1328,7 @@ const experimental_devServer = async (app, options) => {
|
|
|
1298
1328
|
This toolset is only supported in React-based setups.
|
|
1299
1329
|
</div>`;
|
|
1300
1330
|
else if (!manifestStatus.hasFeatureFlag) docsNotice = `<div class="toolset-notice">
|
|
1301
|
-
This toolset requires enabling the
|
|
1331
|
+
This toolset requires enabling the component manifest feature.
|
|
1302
1332
|
<a target="_blank" href="https://github.com/storybookjs/mcp/tree/main/packages/addon-mcp#docs-tools-experimental">Learn how to enable it</a>
|
|
1303
1333
|
</div>`;
|
|
1304
1334
|
const testNoticeLines = [!addonVitestConstants && `This toolset requires Storybook 10.3.0+ with <code>@storybook/addon-vitest</code>. <a target="_blank" href="https://storybook.js.org/docs/writing-tests/test-addon">Learn how to set it up</a>`, !a11yEnabled && `Add <code>@storybook/addon-a11y</code> for accessibility testing. <a target="_blank" href="https://storybook.js.org/docs/writing-tests/accessibility-testing">Learn more</a>`].filter(Boolean);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/addon-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Help agents automatically write and test stories for your UI components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"picoquery": "^2.5.0",
|
|
35
35
|
"tmcp": "^1.16.0",
|
|
36
36
|
"valibot": "1.2.0",
|
|
37
|
-
"@storybook/mcp": "0.
|
|
37
|
+
"@storybook/mcp": "0.6.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@storybook/addon-a11y": "10.3.0-alpha.
|
|
41
|
-
"@storybook/addon-vitest": "10.3.0-alpha.
|
|
42
|
-
"storybook": "10.3.0-alpha.
|
|
40
|
+
"@storybook/addon-a11y": "10.3.0-alpha.16",
|
|
41
|
+
"@storybook/addon-vitest": "10.3.0-alpha.16",
|
|
42
|
+
"storybook": "10.3.0-alpha.16"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@storybook/addon-vitest": "^9.1.16 || ^10.0.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0",
|