@storybook/addon-mcp 0.1.5 → 0.1.7
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 +5 -8
- package/dist/preset.js +18 -17
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -191,18 +191,15 @@ export default {
|
|
|
191
191
|
};
|
|
192
192
|
```
|
|
193
193
|
|
|
194
|
-
#### 3. List All
|
|
194
|
+
#### 3. List All Documentation (`list-all-documentation`)
|
|
195
195
|
|
|
196
|
-
Returns a list of all available UI components in your component library. Useful for the LLM as discovery and understanding what components are available to use.
|
|
196
|
+
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.
|
|
197
197
|
|
|
198
|
-
#### 4. Get
|
|
198
|
+
#### 4. Get Documentation (`get-documentation`)
|
|
199
199
|
|
|
200
|
-
Retrieves detailed documentation for a specific component
|
|
200
|
+
Retrieves detailed documentation for a specific component or docs entry.
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
- Usage examples
|
|
204
|
-
|
|
205
|
-
The agent provides a component ID to retrieve its documentation. To get documentation for multiple components, call this tool multiple times.
|
|
202
|
+
The agent provides a component/docs ID to retrieve its documentation. To get documentation for multiple entries, call this tool multiple times.
|
|
206
203
|
|
|
207
204
|
## Contributing
|
|
208
205
|
|
package/dist/preset.js
CHANGED
|
@@ -6,12 +6,12 @@ import { storyNameFromExport } from "storybook/internal/csf";
|
|
|
6
6
|
import { logger } from "storybook/internal/node-logger";
|
|
7
7
|
import * as v from "valibot";
|
|
8
8
|
import { telemetry } from "storybook/internal/telemetry";
|
|
9
|
-
import {
|
|
9
|
+
import { addGetDocumentationTool, addListAllDocumentationTool } from "@storybook/mcp";
|
|
10
10
|
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.7";
|
|
15
15
|
var description = "Help agents automatically write and test stories for your UI components";
|
|
16
16
|
|
|
17
17
|
//#endregion
|
|
@@ -209,12 +209,12 @@ const frameworkToRendererMap = {
|
|
|
209
209
|
//#endregion
|
|
210
210
|
//#region src/tools/is-manifest-available.ts
|
|
211
211
|
const getManifestStatus = async (options) => {
|
|
212
|
-
const [features,
|
|
213
|
-
const
|
|
212
|
+
const [features, manifests] = await Promise.all([options.presets.apply("features"), options.presets.apply("experimental_manifests", void 0, { manifestEntries: [] })]);
|
|
213
|
+
const hasManifests = !!manifests;
|
|
214
214
|
const hasFeatureFlag = !!features?.experimentalComponentsManifest;
|
|
215
215
|
return {
|
|
216
|
-
available: hasFeatureFlag &&
|
|
217
|
-
|
|
216
|
+
available: hasFeatureFlag && hasManifests,
|
|
217
|
+
hasManifests,
|
|
218
218
|
hasFeatureFlag
|
|
219
219
|
};
|
|
220
220
|
};
|
|
@@ -246,8 +246,8 @@ const initializeMCPServer = async (options) => {
|
|
|
246
246
|
if ((await getManifestStatus(options)).available) {
|
|
247
247
|
logger.info("Experimental components manifest feature detected - registering component tools");
|
|
248
248
|
const contextAwareEnabled = () => server.ctx.custom?.toolsets?.docs ?? true;
|
|
249
|
-
await
|
|
250
|
-
await
|
|
249
|
+
await addListAllDocumentationTool(server, contextAwareEnabled);
|
|
250
|
+
await addGetDocumentationTool(server, contextAwareEnabled);
|
|
251
251
|
}
|
|
252
252
|
transport = new HttpTransport(server, { path: null });
|
|
253
253
|
origin = `http://localhost:${options.port}`;
|
|
@@ -266,21 +266,22 @@ const mcpServerHandler = async ({ req, res, options, addonOptions }) => {
|
|
|
266
266
|
disableTelemetry,
|
|
267
267
|
request: webRequest,
|
|
268
268
|
...!disableTelemetry && {
|
|
269
|
-
|
|
269
|
+
onListAllDocumentation: async ({ manifests }) => {
|
|
270
270
|
await collectTelemetry({
|
|
271
|
-
event: "tool:
|
|
271
|
+
event: "tool:listAllDocumentation",
|
|
272
272
|
server,
|
|
273
273
|
toolset: "docs",
|
|
274
|
-
componentCount: Object.keys(
|
|
274
|
+
componentCount: Object.keys(manifests.componentManifest.components).length,
|
|
275
|
+
docsCount: Object.keys(manifests.docsManifest?.docs || {}).length
|
|
275
276
|
});
|
|
276
277
|
},
|
|
277
|
-
|
|
278
|
+
onGetDocumentation: async ({ input, foundDocumentation }) => {
|
|
278
279
|
await collectTelemetry({
|
|
279
|
-
event: "tool:
|
|
280
|
+
event: "tool:getDocumentation",
|
|
280
281
|
server,
|
|
281
282
|
toolset: "docs",
|
|
282
|
-
componentId: input.
|
|
283
|
-
found: !!
|
|
283
|
+
componentId: input.id,
|
|
284
|
+
found: !!foundDocumentation
|
|
284
285
|
});
|
|
285
286
|
}
|
|
286
287
|
}
|
|
@@ -341,7 +342,7 @@ function getToolsets(request, addonOptions) {
|
|
|
341
342
|
|
|
342
343
|
//#endregion
|
|
343
344
|
//#region src/template.html
|
|
344
|
-
var template_default = "<!doctype html>\n<html>\n <head>\n {{REDIRECT_META}}\n <style>\n @font-face {\n font-family: 'Nunito Sans';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url('./sb-common-assets/nunito-sans-regular.woff2') format('woff2');\n }\n\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n\n html,\n body {\n height: 100%;\n font-family:\n 'Nunito Sans',\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n sans-serif;\n }\n\n body {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n text-align: center;\n padding: 2rem;\n background-color: #ffffff;\n color: rgb(46, 52, 56);\n line-height: 1.6;\n }\n\n p {\n margin-bottom: 1rem;\n }\n\n code {\n font-family: 'Monaco', 'Courier New', monospace;\n background: #f5f5f5;\n padding: 0.2em 0.4em;\n border-radius: 3px;\n }\n\n a {\n color: #1ea7fd;\n }\n\n .container {\n display: flex;\n flex-direction: column;\n align-items: center;\n }\n\n .toolsets {\n margin: 1.5rem 0;\n text-align: left;\n max-width: 500px;\n }\n\n .toolsets h3 {\n font-size: 1rem;\n margin-bottom: 0.75rem;\n text-align: center;\n }\n\n .toolset {\n margin-bottom: 1rem;\n padding: 0.75rem 1rem;\n border-radius: 6px;\n background: #f8f9fa;\n border: 1px solid #e9ecef;\n }\n\n .toolset-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-weight: 600;\n margin-bottom: 0.5rem;\n }\n\n .toolset-status {\n display: inline-block;\n padding: 0.15em 0.5em;\n border-radius: 3px;\n font-size: 0.75rem;\n font-weight: 500;\n text-transform: uppercase;\n }\n\n .toolset-status.enabled {\n background: #d4edda;\n color: #155724;\n }\n\n .toolset-status.disabled {\n background: #f8d7da;\n color: #721c24;\n }\n\n .toolset-tools {\n font-size: 0.875rem;\n color: #6c757d;\n padding-left: 1.5rem;\n margin: 0;\n }\n\n .toolset-tools li {\n margin-bottom: 0.25rem;\n }\n\n .toolset-tools code {\n font-size: 0.8rem;\n }\n\n .toolset-notice {\n font-size: 0.8rem;\n color: #856404;\n background: #fff3cd;\n padding: 0.5rem;\n border-radius: 4px;\n margin-top: 0.5rem;\n }\n\n .toolset-notice a {\n color: #533f03;\n }\n\n @media (prefers-color-scheme: dark) {\n body {\n background-color: rgb(34, 36, 37);\n color: rgb(201, 205, 207);\n }\n\n code {\n background: rgba(255, 255, 255, 0.1);\n }\n\n .toolset {\n background: rgba(255, 255, 255, 0.05);\n border-color: rgba(255, 255, 255, 0.1);\n }\n\n .toolset-tools {\n color: #adb5bd;\n }\n\n .toolset-status.enabled {\n background: rgba(40, 167, 69, 0.2);\n color: #75d67e;\n }\n\n .toolset-status.disabled {\n background: rgba(220, 53, 69, 0.2);\n color: #f5a6ad;\n }\n\n .toolset-notice {\n background: rgba(255, 193, 7, 0.15);\n color: #ffc107;\n }\n\n .toolset-notice a {\n color: #ffe066;\n }\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <p>\n Storybook MCP server successfully running via\n <code>@storybook/addon-mcp</code>.\n </p>\n <p>\n See how to connect to it from your coding agent in\n <a\n target=\"_blank\"\n href=\"https://github.com/storybookjs/mcp/tree/main/packages/addon-mcp#configuring-your-agent\"\n >the addon's README</a\n >.\n </p>\n\n <div class=\"toolsets\">\n <h3>Available Toolsets</h3>\n\n <div class=\"toolset\">\n <div class=\"toolset-header\">\n <span>dev</span>\n <span class=\"toolset-status {{DEV_STATUS}}\">{{DEV_STATUS}}</span>\n </div>\n <ul class=\"toolset-tools\">\n <li><code>get-story-urls</code></li>\n <li><code>get-ui-building-instructions</code></li>\n </ul>\n </div>\n\n <div class=\"toolset\">\n <div class=\"toolset-header\">\n <span>docs</span>\n <span class=\"toolset-status {{DOCS_STATUS}}\">{{DOCS_STATUS}}</span>\n </div>\n <ul class=\"toolset-tools\">\n <li><code>list-all-
|
|
345
|
+
var template_default = "<!doctype html>\n<html>\n <head>\n {{REDIRECT_META}}\n <style>\n @font-face {\n font-family: 'Nunito Sans';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url('./sb-common-assets/nunito-sans-regular.woff2') format('woff2');\n }\n\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n\n html,\n body {\n height: 100%;\n font-family:\n 'Nunito Sans',\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n sans-serif;\n }\n\n body {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n text-align: center;\n padding: 2rem;\n background-color: #ffffff;\n color: rgb(46, 52, 56);\n line-height: 1.6;\n }\n\n p {\n margin-bottom: 1rem;\n }\n\n code {\n font-family: 'Monaco', 'Courier New', monospace;\n background: #f5f5f5;\n padding: 0.2em 0.4em;\n border-radius: 3px;\n }\n\n a {\n color: #1ea7fd;\n }\n\n .container {\n display: flex;\n flex-direction: column;\n align-items: center;\n }\n\n .toolsets {\n margin: 1.5rem 0;\n text-align: left;\n max-width: 500px;\n }\n\n .toolsets h3 {\n font-size: 1rem;\n margin-bottom: 0.75rem;\n text-align: center;\n }\n\n .toolset {\n margin-bottom: 1rem;\n padding: 0.75rem 1rem;\n border-radius: 6px;\n background: #f8f9fa;\n border: 1px solid #e9ecef;\n }\n\n .toolset-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-weight: 600;\n margin-bottom: 0.5rem;\n }\n\n .toolset-status {\n display: inline-block;\n padding: 0.15em 0.5em;\n border-radius: 3px;\n font-size: 0.75rem;\n font-weight: 500;\n text-transform: uppercase;\n }\n\n .toolset-status.enabled {\n background: #d4edda;\n color: #155724;\n }\n\n .toolset-status.disabled {\n background: #f8d7da;\n color: #721c24;\n }\n\n .toolset-tools {\n font-size: 0.875rem;\n color: #6c757d;\n padding-left: 1.5rem;\n margin: 0;\n }\n\n .toolset-tools li {\n margin-bottom: 0.25rem;\n }\n\n .toolset-tools code {\n font-size: 0.8rem;\n }\n\n .toolset-notice {\n font-size: 0.8rem;\n color: #856404;\n background: #fff3cd;\n padding: 0.5rem;\n border-radius: 4px;\n margin-top: 0.5rem;\n }\n\n .toolset-notice a {\n color: #533f03;\n }\n\n @media (prefers-color-scheme: dark) {\n body {\n background-color: rgb(34, 36, 37);\n color: rgb(201, 205, 207);\n }\n\n code {\n background: rgba(255, 255, 255, 0.1);\n }\n\n .toolset {\n background: rgba(255, 255, 255, 0.05);\n border-color: rgba(255, 255, 255, 0.1);\n }\n\n .toolset-tools {\n color: #adb5bd;\n }\n\n .toolset-status.enabled {\n background: rgba(40, 167, 69, 0.2);\n color: #75d67e;\n }\n\n .toolset-status.disabled {\n background: rgba(220, 53, 69, 0.2);\n color: #f5a6ad;\n }\n\n .toolset-notice {\n background: rgba(255, 193, 7, 0.15);\n color: #ffc107;\n }\n\n .toolset-notice a {\n color: #ffe066;\n }\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <p>\n Storybook MCP server successfully running via\n <code>@storybook/addon-mcp</code>.\n </p>\n <p>\n See how to connect to it from your coding agent in\n <a\n target=\"_blank\"\n href=\"https://github.com/storybookjs/mcp/tree/main/packages/addon-mcp#configuring-your-agent\"\n >the addon's README</a\n >.\n </p>\n\n <div class=\"toolsets\">\n <h3>Available Toolsets</h3>\n\n <div class=\"toolset\">\n <div class=\"toolset-header\">\n <span>dev</span>\n <span class=\"toolset-status {{DEV_STATUS}}\">{{DEV_STATUS}}</span>\n </div>\n <ul class=\"toolset-tools\">\n <li><code>get-story-urls</code></li>\n <li><code>get-ui-building-instructions</code></li>\n </ul>\n </div>\n\n <div class=\"toolset\">\n <div class=\"toolset-header\">\n <span>docs</span>\n <span class=\"toolset-status {{DOCS_STATUS}}\">{{DOCS_STATUS}}</span>\n </div>\n <ul class=\"toolset-tools\">\n <li><code>list-all-documentation</code></li>\n <li><code>get-component-documentation</code></li>\n </ul>\n {{DOCS_NOTICE}}\n </div>\n </div>\n\n <p id=\"redirect-message\">\n Automatically redirecting to\n <a href=\"/manifests/components.html\">component manifest</a>\n in <span id=\"countdown\">10</span> seconds...\n </p>\n </div>\n <script>\n let countdown = 10;\n const countdownElement = document.getElementById('countdown');\n if (countdownElement) {\n setInterval(() => {\n countdown -= 1;\n countdownElement.textContent = countdown.toString();\n }, 1000);\n }\n <\/script>\n </body>\n</html>\n";
|
|
345
346
|
|
|
346
347
|
//#endregion
|
|
347
348
|
//#region src/preset.ts
|
|
@@ -368,7 +369,7 @@ const experimental_devServer = async (app, options) => {
|
|
|
368
369
|
});
|
|
369
370
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
370
371
|
let docsNotice = "";
|
|
371
|
-
if (!manifestStatus.
|
|
372
|
+
if (!manifestStatus.hasManifests) docsNotice = `<div class="toolset-notice">
|
|
372
373
|
This toolset is only supported in React-based setups.
|
|
373
374
|
</div>`;
|
|
374
375
|
else if (!manifestStatus.hasFeatureFlag) docsNotice = `<div class="toolset-notice">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/addon-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Help agents automatically write and test stories for your UI components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook-addon",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"@tmcp/adapter-valibot": "^0.1.4",
|
|
29
29
|
"@tmcp/transport-http": "^0.8.0",
|
|
30
30
|
"tmcp": "^1.16.0",
|
|
31
|
-
"valibot": "1.
|
|
32
|
-
"@storybook/mcp": "0.
|
|
31
|
+
"valibot": "1.2.0",
|
|
32
|
+
"@storybook/mcp": "0.2.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"storybook": "10.
|
|
35
|
+
"storybook": "10.2.0-alpha.14"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"storybook": "^9.1.16 || ^10.0.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0"
|