@storybook/addon-mcp 0.1.1 → 0.1.2
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 +48 -2
- package/dist/preset.js +39 -11
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -33,6 +33,52 @@ npm run storybook
|
|
|
33
33
|
|
|
34
34
|
The MCP server will be available at `<your_storybook_dev_server_origin>/mcp` when Storybook is running.
|
|
35
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, requires experimental feature)
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Available Toolsets:**
|
|
60
|
+
|
|
61
|
+
- `dev`: Enables [Dev Tools](#dev-tools)
|
|
62
|
+
- `docs`: Enables [Documentation Tools](#docs-tools-experimental)
|
|
63
|
+
|
|
64
|
+
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.
|
|
65
|
+
|
|
66
|
+
#### Configuring toolsets with headers
|
|
67
|
+
|
|
68
|
+
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):
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"storybook-mcp": {
|
|
73
|
+
"url": "http://localhost:6006/mcp",
|
|
74
|
+
"type": "http",
|
|
75
|
+
"headers": {
|
|
76
|
+
"X-MCP-Toolsets": "docs"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
36
82
|
### Configuring Your Agent
|
|
37
83
|
|
|
38
84
|
> [!NOTE]
|
|
@@ -88,7 +134,7 @@ This addon provides MCP tools that your agent can use. The goal is that the agen
|
|
|
88
134
|
|
|
89
135
|
**If you are prompting from an IDE like VSCode or Cursor, be sure to use `Agent` mode and `sonnet-4.5` or better.**
|
|
90
136
|
|
|
91
|
-
###
|
|
137
|
+
### Dev Tools
|
|
92
138
|
|
|
93
139
|
These tools are always available when the addon is installed:
|
|
94
140
|
|
|
@@ -119,7 +165,7 @@ Agent calls tool, gets response:
|
|
|
119
165
|
http://localhost:6006/?path=/story/example-button--primary
|
|
120
166
|
```
|
|
121
167
|
|
|
122
|
-
###
|
|
168
|
+
### Docs Tools (Experimental)
|
|
123
169
|
|
|
124
170
|
These additional tools are available when the **experimental** component manifest feature is enabled. They provide agents with detailed documentation about your UI components.
|
|
125
171
|
|
package/dist/preset.js
CHANGED
|
@@ -11,7 +11,7 @@ import { buffer } from "node:stream/consumers";
|
|
|
11
11
|
|
|
12
12
|
//#region package.json
|
|
13
13
|
var name = "@storybook/addon-mcp";
|
|
14
|
-
var version = "0.1.
|
|
14
|
+
var version = "0.1.2";
|
|
15
15
|
var description = "Help agents automatically write and test stories for your UI components";
|
|
16
16
|
|
|
17
17
|
//#endregion
|
|
@@ -69,6 +69,13 @@ const errorToMCPContent = (error) => {
|
|
|
69
69
|
|
|
70
70
|
//#endregion
|
|
71
71
|
//#region src/types.ts
|
|
72
|
+
const AddonOptions = v.object({ toolsets: v.optional(v.object({
|
|
73
|
+
dev: v.exactOptional(v.boolean(), true),
|
|
74
|
+
docs: v.exactOptional(v.boolean(), true)
|
|
75
|
+
}), {
|
|
76
|
+
dev: true,
|
|
77
|
+
docs: true
|
|
78
|
+
}) });
|
|
72
79
|
/**
|
|
73
80
|
* Schema for a single story input when requesting story URLs.
|
|
74
81
|
*/
|
|
@@ -95,7 +102,8 @@ async function addGetStoryUrlsTool(server) {
|
|
|
95
102
|
name: GET_STORY_URLS_TOOL_NAME,
|
|
96
103
|
title: "Get stories' URLs",
|
|
97
104
|
description: `Get the URL for one or more stories.`,
|
|
98
|
-
schema: GetStoryUrlsInput
|
|
105
|
+
schema: GetStoryUrlsInput,
|
|
106
|
+
enabled: () => server.ctx.custom?.toolsets?.dev ?? true
|
|
99
107
|
}, async (input) => {
|
|
100
108
|
try {
|
|
101
109
|
const { origin: origin$1, disableTelemetry } = server.ctx.custom ?? {};
|
|
@@ -155,7 +163,8 @@ async function addGetUIBuildingInstructionsTool(server) {
|
|
|
155
163
|
description: `Instructions on how to do UI component development.
|
|
156
164
|
|
|
157
165
|
ALWAYS call this tool before doing any UI/frontend/React/component development, including but not
|
|
158
|
-
limited to adding or updating new components, pages, screens or layouts
|
|
166
|
+
limited to adding or updating new components, pages, screens or layouts.`,
|
|
167
|
+
enabled: () => server.ctx.custom?.toolsets?.dev ?? true
|
|
159
168
|
}, async () => {
|
|
160
169
|
try {
|
|
161
170
|
const { options, disableTelemetry } = server.ctx.custom ?? {};
|
|
@@ -217,25 +226,23 @@ const initializeMCPServer = async (options) => {
|
|
|
217
226
|
const [features, componentManifestGenerator] = await Promise.all([options.presets.apply("features"), options.presets.apply("experimental_componentManifestGenerator")]);
|
|
218
227
|
if (features.experimentalComponentsManifest && componentManifestGenerator) {
|
|
219
228
|
logger.info("Experimental components manifest feature detected - registering component tools");
|
|
220
|
-
|
|
221
|
-
await
|
|
229
|
+
const contextAwareEnabled = () => server.ctx.custom?.toolsets?.docs ?? true;
|
|
230
|
+
await addListAllComponentsTool(server, contextAwareEnabled);
|
|
231
|
+
await addGetComponentDocumentationTool(server, contextAwareEnabled);
|
|
222
232
|
}
|
|
223
233
|
transport = new HttpTransport(server, { path: null });
|
|
224
234
|
origin = `http://localhost:${options.port}`;
|
|
225
235
|
logger.debug("MCP server origin:", origin);
|
|
226
236
|
return server;
|
|
227
237
|
};
|
|
228
|
-
|
|
229
|
-
* Vite middleware handler that wraps the MCP handler.
|
|
230
|
-
* This converts Node.js IncomingMessage/ServerResponse to Web API Request/Response.
|
|
231
|
-
*/
|
|
232
|
-
const mcpServerHandler = async (req, res, next, options) => {
|
|
238
|
+
const mcpServerHandler = async ({ req, res, next, options, addonOptions }) => {
|
|
233
239
|
const disableTelemetry = options.disableTelemetry ?? false;
|
|
234
240
|
if (!initialize) initialize = initializeMCPServer(options);
|
|
235
241
|
const server = await initialize;
|
|
236
242
|
const webRequest = await incomingMessageToWebRequest(req);
|
|
237
243
|
const addonContext = {
|
|
238
244
|
options,
|
|
245
|
+
toolsets: getToolsets(webRequest, addonOptions),
|
|
239
246
|
origin,
|
|
240
247
|
disableTelemetry,
|
|
241
248
|
source: `${origin}/manifests/components.json`,
|
|
@@ -297,11 +304,32 @@ async function webResponseToServerResponse(webResponse, nodeResponse) {
|
|
|
297
304
|
}
|
|
298
305
|
nodeResponse.end();
|
|
299
306
|
}
|
|
307
|
+
function getToolsets(request, addonOptions) {
|
|
308
|
+
const toolsetHeader = request.headers.get("X-MCP-Toolsets");
|
|
309
|
+
if (!toolsetHeader || toolsetHeader.trim() === "") return addonOptions.toolsets;
|
|
310
|
+
const toolsets = {
|
|
311
|
+
dev: false,
|
|
312
|
+
docs: false
|
|
313
|
+
};
|
|
314
|
+
const enabledToolsets = toolsetHeader.split(",");
|
|
315
|
+
for (const enabledToolset of enabledToolsets) {
|
|
316
|
+
const trimmedToolset = enabledToolset.trim();
|
|
317
|
+
if (trimmedToolset in toolsets) toolsets[trimmedToolset] = true;
|
|
318
|
+
}
|
|
319
|
+
return toolsets;
|
|
320
|
+
}
|
|
300
321
|
|
|
301
322
|
//#endregion
|
|
302
323
|
//#region src/preset.ts
|
|
303
324
|
const experimental_devServer = (app, options) => {
|
|
304
|
-
|
|
325
|
+
const addonOptions = v.parse(AddonOptions, { toolsets: options.toolsets ?? {} });
|
|
326
|
+
app.use("/mcp", (req, res, next) => mcpServerHandler({
|
|
327
|
+
req,
|
|
328
|
+
res,
|
|
329
|
+
next,
|
|
330
|
+
options,
|
|
331
|
+
addonOptions
|
|
332
|
+
}));
|
|
305
333
|
return app;
|
|
306
334
|
};
|
|
307
335
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/addon-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Help agents automatically write and test stories for your UI components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook-addon",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@tmcp/adapter-valibot": "^0.1.4",
|
|
30
|
-
"@tmcp/transport-http": "^0.
|
|
31
|
-
"tmcp": "^1.
|
|
30
|
+
"@tmcp/transport-http": "^0.8.0",
|
|
31
|
+
"tmcp": "^1.16.0",
|
|
32
32
|
"valibot": "^1.1.0",
|
|
33
|
-
"@storybook/mcp": "0.0.
|
|
33
|
+
"@storybook/mcp": "0.0.6"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "20.19.0",
|