@vizejs/musea-mcp-server 0.11.0 → 0.12.0
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/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-ZT3oDiIm.js → src-DNZL-15O.js} +102 -92
- package/package.json +2 -2
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -51,98 +51,14 @@ function matchGlob(filepath, pattern) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
//#endregion
|
|
54
|
-
//#region src/
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const content$1 = await fs.promises.readFile(filePath, "utf-8");
|
|
63
|
-
const tokens$1 = JSON.parse(content$1);
|
|
64
|
-
const categoryName = path.basename(entry.name, path.extname(entry.name)).replace(".tokens", "");
|
|
65
|
-
categories.push({
|
|
66
|
-
name: formatCategoryName(categoryName),
|
|
67
|
-
tokens: extractTokenValues(tokens$1),
|
|
68
|
-
subcategories: extractSubcats(tokens$1)
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
return categories;
|
|
72
|
-
}
|
|
73
|
-
const content = await fs.promises.readFile(tokensPath, "utf-8");
|
|
74
|
-
const tokens = JSON.parse(content);
|
|
75
|
-
return flattenTokenStructure(tokens);
|
|
76
|
-
}
|
|
77
|
-
function generateTokensMarkdown(categories) {
|
|
78
|
-
const renderCategory = (category, level = 2) => {
|
|
79
|
-
const heading = "#".repeat(level);
|
|
80
|
-
let md = `\n${heading} ${category.name}\n\n`;
|
|
81
|
-
if (Object.keys(category.tokens).length > 0) {
|
|
82
|
-
md += "| Token | Value | Description |\n";
|
|
83
|
-
md += "|-------|-------|-------------|\n";
|
|
84
|
-
for (const [name, token] of Object.entries(category.tokens)) md += `| \`${name}\` | \`${token.value}\` | ${token.description || "-"} |\n`;
|
|
85
|
-
md += "\n";
|
|
86
|
-
}
|
|
87
|
-
if (category.subcategories) for (const sub of category.subcategories) md += renderCategory(sub, level + 1);
|
|
88
|
-
return md;
|
|
89
|
-
};
|
|
90
|
-
let markdown = "# Design Tokens\n";
|
|
91
|
-
for (const category of categories) markdown += renderCategory(category);
|
|
92
|
-
return markdown;
|
|
93
|
-
}
|
|
94
|
-
function isTokenLeaf(value) {
|
|
95
|
-
if (typeof value !== "object" || value === null) return false;
|
|
96
|
-
const obj = value;
|
|
97
|
-
return "value" in obj && (typeof obj.value === "string" || typeof obj.value === "number");
|
|
98
|
-
}
|
|
99
|
-
function extractTokenValues(obj) {
|
|
100
|
-
const tokens = {};
|
|
101
|
-
for (const [key, value] of Object.entries(obj)) if (isTokenLeaf(value)) {
|
|
102
|
-
const raw = value;
|
|
103
|
-
tokens[key] = {
|
|
104
|
-
value: raw.value,
|
|
105
|
-
type: raw.type,
|
|
106
|
-
description: raw.description
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
return tokens;
|
|
110
|
-
}
|
|
111
|
-
function extractSubcats(obj) {
|
|
112
|
-
const subcategories = [];
|
|
113
|
-
for (const [key, value] of Object.entries(obj)) if (!isTokenLeaf(value) && typeof value === "object" && value !== null) {
|
|
114
|
-
const tokens = extractTokenValues(value);
|
|
115
|
-
const nested = extractSubcats(value);
|
|
116
|
-
if (Object.keys(tokens).length > 0 || nested && nested.length > 0) subcategories.push({
|
|
117
|
-
name: formatCategoryName(key),
|
|
118
|
-
tokens,
|
|
119
|
-
subcategories: nested
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
return subcategories.length > 0 ? subcategories : void 0;
|
|
123
|
-
}
|
|
124
|
-
function flattenTokenStructure(tokens) {
|
|
125
|
-
const categories = [];
|
|
126
|
-
for (const [key, value] of Object.entries(tokens)) {
|
|
127
|
-
if (isTokenLeaf(value)) continue;
|
|
128
|
-
if (typeof value === "object" && value !== null) {
|
|
129
|
-
const categoryTokens = extractTokenValues(value);
|
|
130
|
-
const subcategories = flattenTokenStructure(value);
|
|
131
|
-
if (Object.keys(categoryTokens).length > 0 || subcategories.length > 0) categories.push({
|
|
132
|
-
name: formatCategoryName(key),
|
|
133
|
-
tokens: categoryTokens,
|
|
134
|
-
subcategories: subcategories.length > 0 ? subcategories : void 0
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return categories;
|
|
139
|
-
}
|
|
140
|
-
function formatCategoryName(name) {
|
|
141
|
-
return name.replace(/[-_]/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
//#endregion
|
|
145
|
-
//#region src/tools.ts
|
|
54
|
+
//#region src/tools/definitions.ts
|
|
55
|
+
/**
|
|
56
|
+
* MCP tool definitions for Musea.
|
|
57
|
+
*
|
|
58
|
+
* Declares the schema (name, description, input parameters) for each tool
|
|
59
|
+
* exposed by the MCP server: component analysis, registry, code generation,
|
|
60
|
+
* documentation, and design tokens.
|
|
61
|
+
*/
|
|
146
62
|
const toolDefinitions = [
|
|
147
63
|
{
|
|
148
64
|
name: "analyze_component",
|
|
@@ -327,6 +243,100 @@ const toolDefinitions = [
|
|
|
327
243
|
}
|
|
328
244
|
}
|
|
329
245
|
];
|
|
246
|
+
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/tokens.ts
|
|
249
|
+
async function parseTokensFromPath(tokensPath) {
|
|
250
|
+
const stat = await fs.promises.stat(tokensPath);
|
|
251
|
+
if (stat.isDirectory()) {
|
|
252
|
+
const entries = await fs.promises.readdir(tokensPath, { withFileTypes: true });
|
|
253
|
+
const categories = [];
|
|
254
|
+
for (const entry of entries) if (entry.isFile() && (entry.name.endsWith(".json") || entry.name.endsWith(".tokens.json"))) {
|
|
255
|
+
const filePath = path.join(tokensPath, entry.name);
|
|
256
|
+
const content$1 = await fs.promises.readFile(filePath, "utf-8");
|
|
257
|
+
const tokens$1 = JSON.parse(content$1);
|
|
258
|
+
const categoryName = path.basename(entry.name, path.extname(entry.name)).replace(".tokens", "");
|
|
259
|
+
categories.push({
|
|
260
|
+
name: formatCategoryName(categoryName),
|
|
261
|
+
tokens: extractTokenValues(tokens$1),
|
|
262
|
+
subcategories: extractSubcats(tokens$1)
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
return categories;
|
|
266
|
+
}
|
|
267
|
+
const content = await fs.promises.readFile(tokensPath, "utf-8");
|
|
268
|
+
const tokens = JSON.parse(content);
|
|
269
|
+
return flattenTokenStructure(tokens);
|
|
270
|
+
}
|
|
271
|
+
function generateTokensMarkdown(categories) {
|
|
272
|
+
const renderCategory = (category, level = 2) => {
|
|
273
|
+
const heading = "#".repeat(level);
|
|
274
|
+
let md = `\n${heading} ${category.name}\n\n`;
|
|
275
|
+
if (Object.keys(category.tokens).length > 0) {
|
|
276
|
+
md += "| Token | Value | Description |\n";
|
|
277
|
+
md += "|-------|-------|-------------|\n";
|
|
278
|
+
for (const [name, token] of Object.entries(category.tokens)) md += `| \`${name}\` | \`${token.value}\` | ${token.description || "-"} |\n`;
|
|
279
|
+
md += "\n";
|
|
280
|
+
}
|
|
281
|
+
if (category.subcategories) for (const sub of category.subcategories) md += renderCategory(sub, level + 1);
|
|
282
|
+
return md;
|
|
283
|
+
};
|
|
284
|
+
let markdown = "# Design Tokens\n";
|
|
285
|
+
for (const category of categories) markdown += renderCategory(category);
|
|
286
|
+
return markdown;
|
|
287
|
+
}
|
|
288
|
+
function isTokenLeaf(value) {
|
|
289
|
+
if (typeof value !== "object" || value === null) return false;
|
|
290
|
+
const obj = value;
|
|
291
|
+
return "value" in obj && (typeof obj.value === "string" || typeof obj.value === "number");
|
|
292
|
+
}
|
|
293
|
+
function extractTokenValues(obj) {
|
|
294
|
+
const tokens = {};
|
|
295
|
+
for (const [key, value] of Object.entries(obj)) if (isTokenLeaf(value)) {
|
|
296
|
+
const raw = value;
|
|
297
|
+
tokens[key] = {
|
|
298
|
+
value: raw.value,
|
|
299
|
+
type: raw.type,
|
|
300
|
+
description: raw.description
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
return tokens;
|
|
304
|
+
}
|
|
305
|
+
function extractSubcats(obj) {
|
|
306
|
+
const subcategories = [];
|
|
307
|
+
for (const [key, value] of Object.entries(obj)) if (!isTokenLeaf(value) && typeof value === "object" && value !== null) {
|
|
308
|
+
const tokens = extractTokenValues(value);
|
|
309
|
+
const nested = extractSubcats(value);
|
|
310
|
+
if (Object.keys(tokens).length > 0 || nested && nested.length > 0) subcategories.push({
|
|
311
|
+
name: formatCategoryName(key),
|
|
312
|
+
tokens,
|
|
313
|
+
subcategories: nested
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
return subcategories.length > 0 ? subcategories : void 0;
|
|
317
|
+
}
|
|
318
|
+
function flattenTokenStructure(tokens) {
|
|
319
|
+
const categories = [];
|
|
320
|
+
for (const [key, value] of Object.entries(tokens)) {
|
|
321
|
+
if (isTokenLeaf(value)) continue;
|
|
322
|
+
if (typeof value === "object" && value !== null) {
|
|
323
|
+
const categoryTokens = extractTokenValues(value);
|
|
324
|
+
const subcategories = flattenTokenStructure(value);
|
|
325
|
+
if (Object.keys(categoryTokens).length > 0 || subcategories.length > 0) categories.push({
|
|
326
|
+
name: formatCategoryName(key),
|
|
327
|
+
tokens: categoryTokens,
|
|
328
|
+
subcategories: subcategories.length > 0 ? subcategories : void 0
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return categories;
|
|
333
|
+
}
|
|
334
|
+
function formatCategoryName(name) {
|
|
335
|
+
return name.replace(/[-_]/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region src/tools/handler.ts
|
|
330
340
|
async function handleToolCall(ctx, name, args) {
|
|
331
341
|
const binding = ctx.loadNative();
|
|
332
342
|
switch (name) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vizejs/musea-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "MCP server for building Vue.js design systems - component analysis, documentation, variant generation, and design tokens",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@modelcontextprotocol/sdk": "^0.5.0",
|
|
38
|
-
"@vizejs/native": "0.
|
|
38
|
+
"@vizejs/native": "0.12.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^22.14.0",
|