@vizejs/musea-mcp-server 0.32.0 → 0.34.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.
@@ -1,7 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { startServer } from "./src-BY8aIu75.js";
3
-
2
+ import { n as startServer } from "./src-DqveCZc0.mjs";
4
3
  //#region src/cli.ts
4
+ /**
5
+ * Musea MCP Server CLI.
6
+ *
7
+ * Usage:
8
+ * musea-mcp [project-root] [--tokens-path <path>]
9
+ *
10
+ * Environment:
11
+ * MUSEA_PROJECT_ROOT - Project root directory (default: cwd)
12
+ * MUSEA_TOKENS_PATH - Path to design tokens file/directory
13
+ */
5
14
  let projectRoot = process.env.MUSEA_PROJECT_ROOT || process.cwd();
6
15
  let tokensPath = process.env.MUSEA_TOKENS_PATH;
7
16
  const args = process.argv.slice(2);
@@ -13,5 +22,5 @@ startServer(projectRoot, { tokensPath }).catch((error) => {
13
22
  console.error("[musea-mcp] Failed to start:", error);
14
23
  process.exit(1);
15
24
  });
16
-
17
- //#endregion
25
+ //#endregion
26
+ export {};
@@ -1,7 +1,6 @@
1
1
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
2
 
3
3
  //#region src/index.d.ts
4
-
5
4
  declare function createMuseaServer(config: {
6
5
  projectRoot: string;
7
6
  include?: string[];
@@ -10,5 +9,6 @@ declare function createMuseaServer(config: {
10
9
  }): Server;
11
10
  declare function startServer(projectRoot: string, options?: {
12
11
  tokensPath?: string;
13
- }): Promise<void>; //#endregion
12
+ }): Promise<void>;
13
+ //#endregion
14
14
  export { createMuseaServer, createMuseaServer as default, startServer };
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { n as startServer, t as createMuseaServer } from "./src-DqveCZc0.mjs";
2
+ export { createMuseaServer, createMuseaServer as default, startServer };
@@ -1,10 +1,9 @@
1
+ import { createRequire } from "node:module";
1
2
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
4
  import { CallToolRequestSchema, ErrorCode, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";
4
5
  import fs from "node:fs";
5
6
  import path from "node:path";
6
- import { createRequire } from "node:module";
7
-
8
7
  //#region src/native.ts
9
8
  let native = null;
10
9
  function loadNative() {
@@ -17,7 +16,6 @@ function loadNative() {
17
16
  throw new Error(`Failed to load @vizejs/native. Make sure it's installed: ${String(e)}`);
18
17
  }
19
18
  }
20
-
21
19
  //#endregion
22
20
  //#region src/scanner.ts
23
21
  async function findArtFiles(root, include, exclude) {
@@ -49,7 +47,6 @@ function matchGlob(filepath, pattern) {
49
47
  const regex = pattern.replace(/\*\*/g, "{{DOUBLE_STAR}}").replace(/\*/g, "[^/]*").replace(/{{DOUBLE_STAR}}/g, ".*").replace(/\./g, "\\.");
50
48
  return new RegExp(`^${regex}$`).test(filepath);
51
49
  }
52
-
53
50
  //#endregion
54
51
  //#region src/tools/definitions.ts
55
52
  /**
@@ -243,9 +240,13 @@ const toolDefinitions = [
243
240
  }
244
241
  }
245
242
  ];
246
-
247
243
  //#endregion
248
244
  //#region src/tools/handler/analysis.ts
245
+ /**
246
+ * MCP tool handlers for component analysis.
247
+ *
248
+ * Handles `analyze_component` and `get_palette` tool calls.
249
+ */
249
250
  async function handleAnalyzeComponent(ctx, binding, args) {
250
251
  const vuePath = args?.path;
251
252
  if (!vuePath) throw new McpError(ErrorCode.InvalidParams, "path is required");
@@ -293,9 +294,14 @@ async function handleGetPalette(ctx, binding, args) {
293
294
  }, null, 2)
294
295
  }] };
295
296
  }
296
-
297
297
  //#endregion
298
298
  //#region src/tools/handler/registry.ts
299
+ /**
300
+ * MCP tool handlers for the component registry.
301
+ *
302
+ * Handles `list_components`, `get_component`, `get_variant`, and
303
+ * `search_components` tool calls.
304
+ */
299
305
  async function handleListComponents(ctx, args) {
300
306
  const arts = await ctx.scanArtFiles();
301
307
  let results = Array.from(arts.values());
@@ -342,8 +348,7 @@ async function handleGetVariant(ctx, binding, args) {
342
348
  if (!artPath || !variantName) throw new McpError(ErrorCode.InvalidParams, "path and variant are required");
343
349
  const absolutePath = path.resolve(ctx.projectRoot, artPath);
344
350
  const source = await fs.promises.readFile(absolutePath, "utf-8");
345
- const parsed = binding.parseArt(source, { filename: absolutePath });
346
- const variant = parsed.variants.find((v) => v.name.toLowerCase() === variantName.toLowerCase());
351
+ const variant = binding.parseArt(source, { filename: absolutePath }).variants.find((v) => v.name.toLowerCase() === variantName.toLowerCase());
347
352
  if (!variant) throw new McpError(ErrorCode.InvalidParams, `Variant "${variantName}" not found`);
348
353
  return { content: [{
349
354
  type: "text",
@@ -372,35 +377,31 @@ async function handleSearchComponents(ctx, args) {
372
377
  })), null, 2)
373
378
  }] };
374
379
  }
375
-
376
380
  //#endregion
377
381
  //#region src/tokens.ts
378
382
  async function parseTokensFromPath(tokensPath) {
379
- const stat = await fs.promises.stat(tokensPath);
380
- if (stat.isDirectory()) {
383
+ if ((await fs.promises.stat(tokensPath)).isDirectory()) {
381
384
  const entries = await fs.promises.readdir(tokensPath, { withFileTypes: true });
382
385
  const categories = [];
383
386
  for (const entry of entries) if (entry.isFile() && (entry.name.endsWith(".json") || entry.name.endsWith(".tokens.json"))) {
384
387
  const filePath = path.join(tokensPath, entry.name);
385
- const content$1 = await fs.promises.readFile(filePath, "utf-8");
386
- const tokens$1 = JSON.parse(content$1);
388
+ const content = await fs.promises.readFile(filePath, "utf-8");
389
+ const tokens = JSON.parse(content);
387
390
  const categoryName = path.basename(entry.name, path.extname(entry.name)).replace(".tokens", "");
388
391
  categories.push({
389
392
  name: formatCategoryName(categoryName),
390
- tokens: extractTokenValues(tokens$1),
391
- subcategories: extractSubcats(tokens$1)
393
+ tokens: extractTokenValues(tokens),
394
+ subcategories: extractSubcats(tokens)
392
395
  });
393
396
  }
394
397
  return categories;
395
398
  }
396
399
  const content = await fs.promises.readFile(tokensPath, "utf-8");
397
- const tokens = JSON.parse(content);
398
- return flattenTokenStructure(tokens);
400
+ return flattenTokenStructure(JSON.parse(content));
399
401
  }
400
402
  function generateTokensMarkdown(categories) {
401
403
  const renderCategory = (category, level = 2) => {
402
- const heading = "#".repeat(level);
403
- let md = `\n${heading} ${category.name}\n\n`;
404
+ let md = `\n${"#".repeat(level)} ${category.name}\n\n`;
404
405
  if (Object.keys(category.tokens).length > 0) {
405
406
  md += "| Token | Value | Description |\n";
406
407
  md += "|-------|-------|-------------|\n";
@@ -463,9 +464,14 @@ function flattenTokenStructure(tokens) {
463
464
  function formatCategoryName(name) {
464
465
  return name.replace(/[-_]/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
465
466
  }
466
-
467
467
  //#endregion
468
468
  //#region src/tools/handler/generation.ts
469
+ /**
470
+ * MCP tool handlers for code generation.
471
+ *
472
+ * Handles `generate_variants`, `generate_csf`, `generate_docs`,
473
+ * `generate_catalog`, and `get_tokens` tool calls.
474
+ */
469
475
  async function handleGenerateVariants(ctx, binding, args) {
470
476
  const componentRelPath = args?.componentPath;
471
477
  if (!componentRelPath) throw new McpError(ErrorCode.InvalidParams, "componentPath is required");
@@ -473,8 +479,7 @@ async function handleGenerateVariants(ctx, binding, args) {
473
479
  if (!binding.generateVariants) throw new McpError(ErrorCode.InternalError, "generateVariants not available in native binding");
474
480
  const absolutePath = path.resolve(ctx.projectRoot, componentRelPath);
475
481
  const source = await fs.promises.readFile(absolutePath, "utf-8");
476
- const analysis = binding.analyzeSfc(source, { filename: absolutePath });
477
- const props = analysis.props.map((p) => ({
482
+ const props = binding.analyzeSfc(source, { filename: absolutePath }).props.map((p) => ({
478
483
  name: p.name,
479
484
  prop_type: p.type,
480
485
  required: p.required,
@@ -506,10 +511,9 @@ async function handleGenerateCsf(ctx, binding, args) {
506
511
  if (!artPath) throw new McpError(ErrorCode.InvalidParams, "path is required");
507
512
  const absolutePath = path.resolve(ctx.projectRoot, artPath);
508
513
  const source = await fs.promises.readFile(absolutePath, "utf-8");
509
- const csf = binding.artToCsf(source, { filename: absolutePath });
510
514
  return { content: [{
511
515
  type: "text",
512
- text: csf.code
516
+ text: binding.artToCsf(source, { filename: absolutePath }).code
513
517
  }] };
514
518
  }
515
519
  async function handleGenerateDocs(ctx, binding, args) {
@@ -573,9 +577,14 @@ async function handleGetTokens(ctx, args) {
573
577
  text: JSON.stringify({ categories }, null, 2)
574
578
  }] };
575
579
  }
576
-
577
580
  //#endregion
578
581
  //#region src/tools/handler/index.ts
582
+ /**
583
+ * MCP tool call handler for Musea.
584
+ *
585
+ * Routes incoming tool calls to the appropriate handler logic based on
586
+ * the tool name, using the native Rust binding and server context.
587
+ */
579
588
  async function handleToolCall(ctx, name, args) {
580
589
  const binding = ctx.loadNative();
581
590
  switch (name) {
@@ -593,7 +602,6 @@ async function handleToolCall(ctx, name, args) {
593
602
  default: throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
594
603
  }
595
604
  }
596
-
597
605
  //#endregion
598
606
  //#region src/resources.ts
599
607
  async function listResources(ctx) {
@@ -614,8 +622,7 @@ async function listResources(ctx) {
614
622
  mimeType: "text/markdown"
615
623
  });
616
624
  }
617
- const resolvedTokensPath = await ctx.resolveTokensPath();
618
- if (resolvedTokensPath) resources.push({
625
+ if (await ctx.resolveTokensPath()) resources.push({
619
626
  uri: "musea://tokens",
620
627
  name: "Design Tokens",
621
628
  description: "Project design tokens (colors, spacing, typography, …)",
@@ -629,8 +636,7 @@ async function readResource(ctx, uri) {
629
636
  const absolutePath = path.resolve(ctx.projectRoot, relativePath);
630
637
  try {
631
638
  const source = await fs.promises.readFile(absolutePath, "utf-8");
632
- const binding = ctx.loadNative();
633
- const parsed = binding.parseArt(source, { filename: absolutePath });
639
+ const parsed = ctx.loadNative().parseArt(source, { filename: absolutePath });
634
640
  return { contents: [{
635
641
  uri,
636
642
  mimeType: "application/json",
@@ -659,11 +665,10 @@ async function readResource(ctx, uri) {
659
665
  const source = await fs.promises.readFile(absolutePath, "utf-8");
660
666
  const binding = ctx.loadNative();
661
667
  if (!binding.generateArtDoc) throw new McpError(ErrorCode.InternalError, "generateArtDoc not available in native binding");
662
- const doc = binding.generateArtDoc(source, { filename: absolutePath });
663
668
  return { contents: [{
664
669
  uri,
665
670
  mimeType: "text/markdown",
666
- text: doc.markdown
671
+ text: binding.generateArtDoc(source, { filename: absolutePath }).markdown
667
672
  }] };
668
673
  } catch (e) {
669
674
  if (e instanceof McpError) throw e;
@@ -686,9 +691,17 @@ async function readResource(ctx, uri) {
686
691
  }
687
692
  throw new McpError(ErrorCode.InvalidRequest, `Unknown resource URI: ${uri}`);
688
693
  }
689
-
690
694
  //#endregion
691
695
  //#region src/index.ts
696
+ /**
697
+ * Musea MCP Server — Vue.js design system toolkit.
698
+ *
699
+ * Provides AI assistants with tools to:
700
+ * - Analyze Vue SFC components (props, emits)
701
+ * - Browse and search a component registry
702
+ * - Generate documentation, variants, and Storybook stories
703
+ * - Read and format design tokens
704
+ */
692
705
  function createMuseaServer(config) {
693
706
  const server = new Server({
694
707
  name: "musea-mcp-server",
@@ -701,14 +714,14 @@ function createMuseaServer(config) {
701
714
  const include = config.include ?? ["**/*.art.vue"];
702
715
  const exclude = config.exclude ?? ["node_modules/**", "dist/**"];
703
716
  const tokensPath = config.tokensPath;
704
- let artCache = new Map();
717
+ let artCache = /* @__PURE__ */ new Map();
705
718
  let lastScanTime = 0;
706
719
  async function scanArtFiles() {
707
720
  const now = Date.now();
708
721
  if (now - lastScanTime < 5e3 && artCache.size > 0) return artCache;
709
722
  const binding = loadNative();
710
723
  const files = await findArtFiles(projectRoot, include, exclude);
711
- artCache = new Map();
724
+ artCache = /* @__PURE__ */ new Map();
712
725
  for (const file of files) try {
713
726
  const source = await fs.promises.readFile(file, "utf-8");
714
727
  const parsed = binding.parseArt(source, { filename: file });
@@ -729,12 +742,11 @@ function createMuseaServer(config) {
729
742
  }
730
743
  async function resolveTokensPath() {
731
744
  if (tokensPath) return path.resolve(projectRoot, tokensPath);
732
- const candidates = [
745
+ for (const dir of [
733
746
  "tokens",
734
747
  "design-tokens",
735
748
  "style-dictionary"
736
- ];
737
- for (const dir of candidates) {
749
+ ]) {
738
750
  const candidate = path.join(projectRoot, dir);
739
751
  try {
740
752
  const stat = await fs.promises.stat(candidate);
@@ -764,7 +776,5 @@ async function startServer(projectRoot, options) {
764
776
  await server.connect(transport);
765
777
  console.error("[musea-mcp] Server started");
766
778
  }
767
- var src_default = createMuseaServer;
768
-
769
779
  //#endregion
770
- export { createMuseaServer, src_default, startServer };
780
+ export { startServer as n, createMuseaServer as t };
package/package.json CHANGED
@@ -1,57 +1,56 @@
1
1
  {
2
2
  "name": "@vizejs/musea-mcp-server",
3
- "version": "0.32.0",
3
+ "version": "0.34.0",
4
4
  "description": "MCP server for building Vue.js design systems - component analysis, documentation, variant generation, and design tokens",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "bin": {
9
- "musea-mcp": "./dist/cli.js"
10
- },
11
- "exports": {
12
- ".": {
13
- "import": "./dist/index.js",
14
- "types": "./dist/index.d.ts"
15
- }
16
- },
17
- "files": [
18
- "dist"
19
- ],
20
5
  "keywords": [
6
+ "ai",
7
+ "component-analysis",
8
+ "design-system",
21
9
  "mcp",
22
10
  "model-context-protocol",
23
- "vue",
24
- "design-system",
25
- "component-analysis",
26
11
  "musea",
27
- "ai"
12
+ "vue"
28
13
  ],
29
- "author": "ubugeeei",
30
14
  "license": "MIT",
15
+ "author": "ubugeeei",
31
16
  "repository": {
32
17
  "type": "git",
33
18
  "url": "https://github.com/ubugeeei/vize.git",
34
19
  "directory": "npm/musea-mcp-server"
35
20
  },
21
+ "bin": {
22
+ "musea-mcp": "./dist/cli.js"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "type": "module",
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "import": "./dist/index.js",
33
+ "types": "./dist/index.d.ts"
34
+ }
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
36
39
  "dependencies": {
37
40
  "@modelcontextprotocol/sdk": "^0.5.0",
38
- "@vizejs/native": "0.32.0"
41
+ "@vizejs/native": "0.34.0"
39
42
  },
40
43
  "devDependencies": {
41
44
  "@types/node": "^22.14.0",
42
- "tsdown": "^0.9.0",
43
- "typescript": "^5.7.0"
44
- },
45
- "publishConfig": {
46
- "access": "public"
45
+ "typescript": "^5.7.0",
46
+ "vite-plus": "latest"
47
47
  },
48
48
  "scripts": {
49
- "build": "tsdown",
50
- "dev": "tsdown --watch",
49
+ "build": "vp pack",
50
+ "dev": "vp pack --watch",
51
51
  "start": "node dist/cli.js",
52
- "lint": "oxlint --deny-warnings --type-aware --tsconfig tsconfig.json",
53
- "lint:fix": "oxlint --type-aware --tsconfig tsconfig.json --fix",
54
- "fmt": "oxfmt --write src tsdown.config.ts",
55
- "fmt:check": "oxfmt src tsdown.config.ts"
52
+ "check": "vp check src vite.config.ts",
53
+ "check:fix": "vp check --fix src vite.config.ts",
54
+ "fmt": "vp fmt --write src vite.config.ts"
56
55
  }
57
56
  }
package/dist/index.js DELETED
@@ -1,3 +0,0 @@
1
- import { createMuseaServer, src_default, startServer } from "./src-BY8aIu75.js";
2
-
3
- export { createMuseaServer, src_default as default, startServer };
File without changes