@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.
Files changed (2) hide show
  1. package/dist/index.js +19 -59
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { McpServer, ResourceTemplate, } from "@modelcontextprotocol/sdk/server/mcp.js";
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.resource("Storybookの情報を返します", "storybook://stories", async (uri) => {
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 (Array.isArray(query)) {
106
- return inf.filter((entry) => query.some((q) => isMatch(entry, q)));
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
- return processNext();
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, "worker.js"));
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(`Failed to get component info for ${event.filepath}:`, event.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.log(`${this.componentInformation.length} components loaded.`);
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.5",
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": "^3.3.3",
23
- "react-docgen": "^7.1.1",
22
+ "fast-glob": "3.3.3",
23
+ "react-docgen": "7.1.1",
24
24
  "zod": "3.24.3"
25
25
  },
26
26
  "devDependencies": {