@miyucy/storybook-mcp 1.0.5 → 1.0.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/dist/index.js +19 -59
- package/package.json +4 -4
package/dist/index.js
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
import { McpServer,
|
2
|
+
import { McpServer, } from "@modelcontextprotocol/sdk/server/mcp.js";
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
4
|
-
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
5
4
|
import path from "node:path";
|
6
5
|
import fs from "node:fs/promises";
|
7
6
|
import process from "node:process";
|
@@ -28,17 +27,8 @@ class Storybook {
|
|
28
27
|
await this.server.connect(new StdioServerTransport());
|
29
28
|
}
|
30
29
|
registerStorybook() {
|
31
|
-
this.server.
|
32
|
-
const inf = [...this.componentInformation];
|
33
|
-
if (inf.length === 0) {
|
34
|
-
return { contents: [{ uri: uri.href, text: "No stories found." }] };
|
35
|
-
}
|
36
|
-
return {
|
37
|
-
contents: [{ uri: uri.href, text: JSON.stringify(inf, null, 2) }],
|
38
|
-
};
|
39
|
-
});
|
40
|
-
this.server.tool("get_storybooks", "Storybookの情報を返します", {}, async () => {
|
41
|
-
const inf = [...this.componentInformation];
|
30
|
+
this.server.tool("get_storybooks", "Storybookの情報を返します\nクエリーは大文字・小文字を区別しません", { query: z.string().nullish() }, async ({ query }) => {
|
31
|
+
const inf = this.queryComponentInformation([...this.componentInformation], query ?? null);
|
42
32
|
if (inf.length === 0) {
|
43
33
|
return {
|
44
34
|
content: [{ type: "text", text: "No stories found." }],
|
@@ -51,41 +41,6 @@ class Storybook {
|
|
51
41
|
})),
|
52
42
|
};
|
53
43
|
});
|
54
|
-
this.server.resource("Storybookのタイトルや説明をクエリーします\nクエリーは大文字・小文字を区別しません", new ResourceTemplate("storybook://stories?{query}", { list: undefined }), async (uri, { query }) => {
|
55
|
-
const inf = [...this.componentInformation];
|
56
|
-
if (inf.length === 0) {
|
57
|
-
return { contents: [{ uri: uri.href, text: "No stories found." }] };
|
58
|
-
}
|
59
|
-
// queryがない場合はエラー
|
60
|
-
if (!query) {
|
61
|
-
throw new McpError(ErrorCode.InvalidParams, "Query is required.");
|
62
|
-
}
|
63
|
-
const filtered = this.queryComponentInformation(inf, query);
|
64
|
-
return {
|
65
|
-
contents: [
|
66
|
-
{ uri: uri.href, text: JSON.stringify(filtered, null, 2) },
|
67
|
-
],
|
68
|
-
};
|
69
|
-
});
|
70
|
-
this.server.tool("query_storybooks", "Storybookのタイトルや説明をクエリーします\nクエリーは大文字・小文字を区別しません", { query: z.string() }, async ({ query }) => {
|
71
|
-
const inf = [...this.componentInformation];
|
72
|
-
if (inf.length === 0) {
|
73
|
-
return {
|
74
|
-
content: [{ type: "text", text: "No stories found." }],
|
75
|
-
};
|
76
|
-
}
|
77
|
-
// queryがない場合はエラー
|
78
|
-
if (!query) {
|
79
|
-
throw new McpError(ErrorCode.InvalidParams, "Query is required.");
|
80
|
-
}
|
81
|
-
const filtered = this.queryComponentInformation(inf, query);
|
82
|
-
return {
|
83
|
-
content: filtered.map((entry) => ({
|
84
|
-
type: "text",
|
85
|
-
text: JSON.stringify(entry, null, 2),
|
86
|
-
})),
|
87
|
-
};
|
88
|
-
});
|
89
44
|
}
|
90
45
|
queryComponentInformation(inf, query) {
|
91
46
|
const isMatch = (entry, q) => {
|
@@ -102,17 +57,17 @@ class Storybook {
|
|
102
57
|
return false;
|
103
58
|
}));
|
104
59
|
};
|
105
|
-
if (
|
106
|
-
return inf
|
60
|
+
if (!query) {
|
61
|
+
return inf;
|
107
62
|
}
|
108
63
|
return inf.filter((entry) => isMatch(entry, query));
|
109
64
|
}
|
110
65
|
async loadStorybookData() {
|
111
66
|
// storybook-static/index.jsonを読み込む
|
112
|
-
console.debug("Loading storybook data...");
|
67
|
+
// console.debug("Loading storybook data...");
|
113
68
|
const content = await fs.readFile(path.resolve(this.storybookRoot, "storybook-static", "index.json"), "utf-8");
|
114
69
|
const data = JSON.parse(content);
|
115
|
-
console.debug("Loaded storybook data successfully.");
|
70
|
+
// console.debug("Loaded storybook data successfully.");
|
116
71
|
if (data.v !== 5) {
|
117
72
|
throw new Error("Invalid version (expected 5)");
|
118
73
|
}
|
@@ -145,9 +100,9 @@ class Storybook {
|
|
145
100
|
}
|
146
101
|
entries.push(entry);
|
147
102
|
}
|
148
|
-
console.debug(`Found ${entries.length} entries.`);
|
103
|
+
// console.debug(`Found ${entries.length} entries.`);
|
149
104
|
this.loadStorybookEntries(entries);
|
150
|
-
console.debug("Component information loaded successfully.");
|
105
|
+
// console.debug("Component information loaded successfully.");
|
151
106
|
}
|
152
107
|
//
|
153
108
|
async loadStorybookEntries(entries) {
|
@@ -182,19 +137,23 @@ class Storybook {
|
|
182
137
|
const task = tasks.pop();
|
183
138
|
if (!task) {
|
184
139
|
worker.terminate();
|
185
|
-
|
140
|
+
processNext();
|
141
|
+
return;
|
186
142
|
}
|
187
143
|
worker.postMessage(task);
|
188
144
|
};
|
189
145
|
for (let i = 0; i < this.AVAILABLE_PARALLELISM; i++) {
|
190
146
|
const __filename = fileURLToPath(import.meta.url);
|
191
147
|
const __dirname = path.dirname(__filename);
|
192
|
-
const worker = new Worker(path.resolve(__dirname, "
|
148
|
+
const worker = new Worker(path.resolve(__dirname, "parser.js"));
|
193
149
|
worker.on("message", (event) => {
|
194
150
|
// console.log("message", event);
|
195
|
-
const { componentPath, data } = event;
|
151
|
+
const { componentPath, data, content } = event;
|
196
152
|
if (event.type === "error") {
|
197
|
-
console.error(
|
153
|
+
// console.error(
|
154
|
+
// `Failed to get component info for ${event.filepath}:`,
|
155
|
+
// event.error,
|
156
|
+
// );
|
198
157
|
}
|
199
158
|
for (const entry of entries) {
|
200
159
|
if (entry.componentPath === componentPath) {
|
@@ -204,11 +163,12 @@ class Storybook {
|
|
204
163
|
name: entry.name,
|
205
164
|
importPath: entry.importPath,
|
206
165
|
componentPath: entry.componentPath,
|
166
|
+
component: content,
|
207
167
|
docgenInfo: data || [],
|
208
168
|
});
|
209
169
|
}
|
210
170
|
}
|
211
|
-
console.
|
171
|
+
// console.error(`${this.componentInformation.length} components loaded.`);
|
212
172
|
workers.push(worker);
|
213
173
|
processNext();
|
214
174
|
});
|
package/package.json
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
{
|
2
2
|
"name": "@miyucy/storybook-mcp",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.7",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"scripts": {
|
7
|
-
"build": "rm -rf dist && tsc",
|
7
|
+
"build": "rm -rf dist && tsc && chmod +x dist/index.js",
|
8
8
|
"start": "node dist/index.js"
|
9
9
|
},
|
10
10
|
"author": "miyucy",
|
@@ -19,8 +19,8 @@
|
|
19
19
|
"type": "module",
|
20
20
|
"dependencies": {
|
21
21
|
"@modelcontextprotocol/sdk": "1.10.1",
|
22
|
-
"fast-glob": "
|
23
|
-
"react-docgen": "
|
22
|
+
"fast-glob": "3.3.3",
|
23
|
+
"react-docgen": "7.1.1",
|
24
24
|
"zod": "3.24.3"
|
25
25
|
},
|
26
26
|
"devDependencies": {
|