@czi-sds/mcp 0.2.1 → 0.3.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.
Files changed (50) hide show
  1. package/data/zeroheight-cache.json +5195 -0
  2. package/data/zeroheight-exports/Accordion.md +675 -0
  3. package/data/zeroheight-exports/Banner.md +576 -0
  4. package/data/zeroheight-exports/Borders.md +118 -0
  5. package/data/zeroheight-exports/Buttons.md +2260 -0
  6. package/data/zeroheight-exports/Callout.md +756 -0
  7. package/data/zeroheight-exports/Colors.md +633 -0
  8. package/data/zeroheight-exports/Content-Card.md +162 -0
  9. package/data/zeroheight-exports/Contributing-to-SDS.md +99 -0
  10. package/data/zeroheight-exports/Control-Inputs.md +2066 -0
  11. package/data/zeroheight-exports/Corners.md +112 -0
  12. package/data/zeroheight-exports/Cover-page.md +4 -0
  13. package/data/zeroheight-exports/Dialog.md +1133 -0
  14. package/data/zeroheight-exports/Downloads.md +121 -0
  15. package/data/zeroheight-exports/Drop-Shadows.md +80 -0
  16. package/data/zeroheight-exports/Dropdown-Input.md +1149 -0
  17. package/data/zeroheight-exports/Dropdown-Menu.md +3787 -0
  18. package/data/zeroheight-exports/Element-Status-Tracker.md +268 -0
  19. package/data/zeroheight-exports/Field-Inputs.md +965 -0
  20. package/data/zeroheight-exports/Filters.md +868 -0
  21. package/data/zeroheight-exports/Getting-Started.md +1296 -0
  22. package/data/zeroheight-exports/Hero.md +256 -0
  23. package/data/zeroheight-exports/Icons.md +432 -0
  24. package/data/zeroheight-exports/Intent.md +47 -0
  25. package/data/zeroheight-exports/Introduction-to-Bases.md +36 -0
  26. package/data/zeroheight-exports/Introduction-to-Cells.md +36 -0
  27. package/data/zeroheight-exports/Introduction-to-DNA.md +36 -0
  28. package/data/zeroheight-exports/Introduction-to-Genes.md +36 -0
  29. package/data/zeroheight-exports/Introduction.md +116 -0
  30. package/data/zeroheight-exports/Link.md +373 -0
  31. package/data/zeroheight-exports/Lists.md +617 -0
  32. package/data/zeroheight-exports/Loading-Indicator.md +38 -0
  33. package/data/zeroheight-exports/Navigation.md +853 -0
  34. package/data/zeroheight-exports/Notification.md +858 -0
  35. package/data/zeroheight-exports/Panel.md +862 -0
  36. package/data/zeroheight-exports/README.md +124 -0
  37. package/data/zeroheight-exports/Responsive-Design.md +275 -0
  38. package/data/zeroheight-exports/Search-Input.md +54 -0
  39. package/data/zeroheight-exports/Search.md +609 -0
  40. package/data/zeroheight-exports/Segmented-Control.md +561 -0
  41. package/data/zeroheight-exports/Spacing.md +298 -0
  42. package/data/zeroheight-exports/Table.md +4832 -0
  43. package/data/zeroheight-exports/Tabs.md +773 -0
  44. package/data/zeroheight-exports/Tags.md +1025 -0
  45. package/data/zeroheight-exports/Text-Link.md +185 -0
  46. package/data/zeroheight-exports/Theming.md +313 -0
  47. package/data/zeroheight-exports/Tooltips.md +1564 -0
  48. package/data/zeroheight-exports/Typography.md +769 -0
  49. package/dist/stdio.js +515 -12
  50. package/package.json +4 -3
package/dist/stdio.js CHANGED
@@ -3,9 +3,8 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
3
3
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
4
  import { z } from 'zod';
5
5
  import fs from 'fs';
6
- import path, { join } from 'path';
6
+ import path from 'path';
7
7
  import { fileURLToPath } from 'url';
8
- import { readFile } from 'fs/promises';
9
8
 
10
9
  var server = new McpServer({
11
10
  name: "sds-mcp",
@@ -124,6 +123,37 @@ async function fetchComponentPropsStorybook(component) {
124
123
  );
125
124
  }
126
125
  }
126
+ async function fetchTailwindTokens() {
127
+ try {
128
+ const possiblePaths = [
129
+ path.join(dirname, "../../data/tailwind.json"),
130
+ // From src/lib in dev
131
+ path.join(dirname, "../data/tailwind.json"),
132
+ // From dist in prod
133
+ path.join(process.cwd(), "data/tailwind.json")
134
+ // From current working directory
135
+ ];
136
+ let dataPath = "";
137
+ for (const p of possiblePaths) {
138
+ if (fs.existsSync(p)) {
139
+ dataPath = p;
140
+ break;
141
+ }
142
+ }
143
+ if (!dataPath) {
144
+ throw new Error(
145
+ "Component list not found in any expected location. Please run 'yarn generate:tailwind-tokens' first."
146
+ );
147
+ }
148
+ const fileContent = fs.readFileSync(dataPath, "utf-8");
149
+ const tailwindTokens = JSON.parse(fileContent);
150
+ return tailwindTokens;
151
+ } catch (error) {
152
+ throw new Error(
153
+ `Failed to load tailwind tokens: ${error instanceof Error ? error.message : `Unknown error ${error}`}`
154
+ );
155
+ }
156
+ }
127
157
 
128
158
  // src/tools/get-component-props.ts
129
159
  var getComponentPropsTool = {
@@ -254,13 +284,293 @@ var getComponentPropsStorybookTool = {
254
284
  );
255
285
  }
256
286
  };
287
+
288
+ // src/lib/tailwind-guidance.ts
289
+ var TAILWIND_TOKEN_GUIDANCE = {
290
+ colors: {
291
+ category: "Colors",
292
+ description: "Theme-aware color tokens with light/dark mode support. Both light and dark mode colors are using the same token name. Use the dark:color-token-name to use the dark mode color.",
293
+ prefixes: [
294
+ "bg-",
295
+ "border-",
296
+ "divide-",
297
+ "outline-",
298
+ "ring-",
299
+ "ring-offset-",
300
+ "text-",
301
+ "placeholder-",
302
+ "caret-",
303
+ "decoration-",
304
+ "accent-",
305
+ "shadow-",
306
+ "fill-",
307
+ "stroke-",
308
+ "from-",
309
+ "via-",
310
+ "to-"
311
+ ],
312
+ examples: [
313
+ {
314
+ description: "Basic text and background colors",
315
+ code: `<div className="bg-sds-color-semantic-base-background-primary dark:bg-sds-color-semantic-base-background-primary text-sds-color-semantic-base-text-primary dark:text-sds-color-semantic-base-text-primary">
316
+ Content with semantic colors
317
+ </div>`
318
+ },
319
+ {
320
+ description: "Dark mode with hover states",
321
+ code: `<button className="bg-sds-color-semantic-accent-fill-primary dark:bg-sds-color-semantic-accent-fill-primary
322
+ hover:bg-sds-color-semantic-accent-fill-hover dark:hover:bg-sds-color-semantic-accent-fill-hover">
323
+ Click me
324
+ </button>`
325
+ },
326
+ {
327
+ description: "Border and focus states",
328
+ code: `<input className="
329
+ border-sds-color-semantic-base-border-primary
330
+ hover:border-sds-color-semantic-base-border-primary-hover
331
+ focus:border-sds-color-semantic-base-border-primary-pressed
332
+ "/>`
333
+ }
334
+ ],
335
+ tips: [
336
+ "Always use semantic colors (e.g., 'sds-color-semantic-base-background-primary') over primitive colors when possible",
337
+ "Include both light and dark variants for proper theme support"
338
+ ]
339
+ },
340
+ typography: {
341
+ category: "Typography",
342
+ description: "Complete text styling presets including font, size, weight, and spacing",
343
+ prefixes: ["font-", "text-", "leading-", "tracking-"],
344
+ examples: [
345
+ {
346
+ description: "Typography presets (recommended). SDS typography tokens come in narrow and wide variants: use token-narrow on screens smaller than md, and token-wide on md and up.",
347
+ code: `<!-- Use typography tokens for complete text styling -->
348
+ <h1 className="prose-sds-title-l-700-wide">Title</h1>
349
+ <h1 className="prose-sds-header-xl-600-wide">Heading</h1>
350
+ <p className="prose-sds-body-m-500-wide">Body text</p>
351
+ <span className="prose-sds-caps-xxs-600-wide">SMALL CAPS TEXT</span>
352
+ <span className="prose-sds-tabular-xxs-600-wide">Tabular Numbers</span>
353
+ <span className="prose-sds-code-s-500-wide">Code</span>
354
+ <span className="prose-sds-link-l-500-wide">Link style</span>`
355
+ },
356
+ {
357
+ description: "Individual typography properties",
358
+ code: `<!-- Or use individual properties when needed -->
359
+ <p className="
360
+ font-sds-body
361
+ text-sds-body-m-400-wide
362
+ leading-sds-body-m-400-wide
363
+ tracking-sds-body-m-400-wide
364
+ ">
365
+ Custom styled text
366
+ </p>`
367
+ }
368
+ ],
369
+ tips: [
370
+ "Use 'narrow' variants for mobile/compact layouts",
371
+ "Use 'wide' variants for desktop/spacious layouts",
372
+ "Font weights: 400 (regular), 500 (medium), 600 (semibold), 700 (bold)"
373
+ ]
374
+ },
375
+ spacing: {
376
+ category: "Spacing",
377
+ description: "Consistent spacing scale for padding, margin, and gaps",
378
+ prefixes: [
379
+ "p-",
380
+ "px-",
381
+ "py-",
382
+ "pt-",
383
+ "pr-",
384
+ "pb-",
385
+ "pl-",
386
+ "m-",
387
+ "mx-",
388
+ "my-",
389
+ "mt-",
390
+ "mr-",
391
+ "mb-",
392
+ "ml-",
393
+ "gap-",
394
+ "gap-x-",
395
+ "gap-y-",
396
+ "space-x-",
397
+ "space-y-"
398
+ ],
399
+ examples: [
400
+ {
401
+ description: "Padding and margin",
402
+ code: `<div className="p-sds-m mx-sds-l my-sds-s">
403
+ Content with medium padding and different margins
404
+ </div>`
405
+ },
406
+ {
407
+ description: "Flexbox and grid gaps",
408
+ code: `<div className="flex gap-sds-m">
409
+ <div>Item 1</div>
410
+ <div>Item 2</div>
411
+ </div>
412
+
413
+ <div className="grid grid-cols-3 gap-sds-l">
414
+ <div>Grid item</div>
415
+ </div>`
416
+ },
417
+ {
418
+ description: "Negative margins for overlapping",
419
+ code: `<div className="-mt-sds-s">
420
+ Overlapping element
421
+ </div>`
422
+ }
423
+ ],
424
+ tips: [
425
+ "Scale: sds-s (small), sds-default (default), sds-m (medium), sds-l (large), sds-xl (extra large)",
426
+ "Use consistent spacing throughout your component",
427
+ "Combine with responsive prefixes: sm:p-sds-m lg:p-sds-l"
428
+ ]
429
+ },
430
+ borderRadius: {
431
+ category: "Border Radius",
432
+ description: "Corner radius values for rounded elements",
433
+ prefixes: [
434
+ "rounded-",
435
+ "rounded-t-",
436
+ "rounded-r-",
437
+ "rounded-b-",
438
+ "rounded-l-"
439
+ ],
440
+ examples: [
441
+ {
442
+ description: "Basic rounded corners",
443
+ code: `<div className="rounded-sds-default">
444
+ Standard rounded corners
445
+ </div>
446
+
447
+ <button className="rounded-sds-m">
448
+ More rounded button
449
+ </button>`
450
+ },
451
+ {
452
+ description: "Directional radius",
453
+ code: `<div className="rounded-t-sds-l rounded-b-none">
454
+ Only top corners rounded
455
+ </div>`
456
+ }
457
+ ],
458
+ tips: [
459
+ "Use sds-default for most UI elements",
460
+ "Larger values (sds-l, sds-xl) for prominent elements",
461
+ "Combine with borders: border rounded-sds-m"
462
+ ]
463
+ },
464
+ boxShadow: {
465
+ category: "Box Shadow",
466
+ description: "Elevation shadows for depth and hierarchy",
467
+ prefixes: ["shadow-", "hover:shadow-", "focus:shadow-"],
468
+ examples: [
469
+ {
470
+ description: "Basic shadows",
471
+ code: `<div className="shadow-sds-s">
472
+ Subtle shadow
473
+ </div>
474
+
475
+ <div className="shadow-sds-m">
476
+ Medium elevation
477
+ </div>`
478
+ },
479
+ {
480
+ description: "Interactive shadows",
481
+ code: `<button className="
482
+ shadow-sds-s
483
+ hover:shadow-sds-m
484
+ active:shadow-sds-xs
485
+ transition-shadow
486
+ ">
487
+ Interactive element
488
+ </button>`
489
+ }
490
+ ],
491
+ tips: [
492
+ "Use smaller shadows (sds-xs, sds-s) for subtle depth",
493
+ "Use larger shadows (sds-l, sds-xl) for modals and popovers",
494
+ "Combine with hover states for interactive feedback"
495
+ ]
496
+ }
497
+ };
498
+ function getTokenGuidance(category) {
499
+ if (!category || category === "all") {
500
+ return `SDS Design System Tokens for Tailwind CSS
501
+
502
+ The Science Design System provides a comprehensive set of design tokens that map directly to Tailwind utilities.
503
+
504
+ QUICK START:
505
+ 1. Request specific categories for detailed guidance: fontFamily, fontSize, fontVariantNumeric, letterSpacing, lineHeight, textDecoration, textTransform, typography, height, width, borderRadius, boxShadow, breakpoints, colors, spacing
506
+ 2. Use semantic tokens over primitive ones when available
507
+ 3. Include responsive and theme variants for robust implementations
508
+ 4. Use the @czi-sds/components/dist/tailwind.json file to get the exact token name and value
509
+ 5. To use the typography tokens, you need to add the @tailwindcss/typography plugin to your tailwind.config.js file and then use the typography tokens in your tailwind classes like prose-[typography-token-name] for example prose-sds-body-m-400-wide.
510
+ 6. Colors have been defined in light and dark mode with the same name. Use the dark:color-token-name to use the dark mode color.
511
+ 7. Use spacing tokens like sds-m for paddings, margins, etc. for example p-sds-m for padding-medium.
512
+ 8. Use borderRadius tokens like sds-default for rounded corners for example rounded-sds-default.
513
+ 9. Use boxShadow tokens like sds-s for subtle shadows for example shadow-sds-s.
514
+ 10. Use breakpoints tokens like sds-m for medium breakpoints for example md:sds-m.
515
+ 11. Use fontFamily tokens like sds-body for body font for example font-sds-body.
516
+ 12. Use fontSize tokens like sds-body-m-400-wide for body font size for example text-sds-body-m-400-wide.
517
+ 13. Use fontVariantNumeric tokens like sds-body-m-400-wide for body font variant numeric for example font-variant-numeric-sds-body-m-400-wide.
518
+ 14. Use letterSpacing tokens like sds-body-m-400-wide for body letter spacing for example tracking-sds-body-m-400-wide.
519
+
520
+ For detailed examples, request a specific category.`;
521
+ }
522
+ const guidance = TAILWIND_TOKEN_GUIDANCE[category];
523
+ if (!guidance) {
524
+ return `Category "${category}" not found. Available categories: ${Object.keys(
525
+ TAILWIND_TOKEN_GUIDANCE
526
+ ).join(", ")}`;
527
+ }
528
+ let output = `## ${guidance.category} Tokens
529
+
530
+ `;
531
+ output += `${guidance.description}
532
+
533
+ `;
534
+ output += `**Tailwind Prefixes:** ${guidance.prefixes.join(", ")}
535
+
536
+ `;
537
+ output += `### Examples:
538
+
539
+ `;
540
+ guidance.examples.forEach((example, index) => {
541
+ output += `${index + 1}. **${example.description}**
542
+ \`\`\`jsx
543
+ ${example.code}
544
+ \`\`\`
545
+
546
+ `;
547
+ });
548
+ if (guidance.tips && guidance.tips.length > 0) {
549
+ output += `### Tips:
550
+ `;
551
+ guidance.tips.forEach((tip) => {
552
+ output += `- ${tip}
553
+ `;
554
+ });
555
+ }
556
+ return output;
557
+ }
558
+
559
+ // src/tools/get-tailwind-tokens.ts
257
560
  var getTailwindTokensTool = {
258
561
  name: "get_tailwind_tokens",
259
- description: "Get all available Tailwind tokens from the SDS design system. Returns design tokens including colors, typography, spacing, borders, shadows, and other design system values formatted for Tailwind CSS.",
562
+ description: "Get all available Tailwind tokens from the SDS design system. Available design tokens include fontFamily, fontSize, fontVariantNumeric, letterSpacing, lineHeight, textDecoration, textTransform, typography, height, width, borderRadius, boxShadow, breakpoints, colors, spacing, and more.",
260
563
  async ctx() {
261
- return {};
564
+ try {
565
+ const tailwindTokens = await fetchTailwindTokens();
566
+ return { tailwindTokens };
567
+ } catch (error) {
568
+ throw new Error(
569
+ `Failed to initialize tailwind tokens tool: ${error instanceof Error ? error.message : "Unknown error"}`
570
+ );
571
+ }
262
572
  },
263
- exec(server2, { name, description }) {
573
+ exec(server2, { ctx, name, description }) {
264
574
  server2.tool(
265
575
  name,
266
576
  description,
@@ -288,18 +598,210 @@ var getTailwindTokensTool = {
288
598
  },
289
599
  async ({ category }) => {
290
600
  try {
291
- const dataPath = join(process.cwd(), "data", "tailwind.json");
292
- const fileContent = await readFile(dataPath, "utf-8");
293
- const tokens = JSON.parse(fileContent);
294
- let result = tokens;
295
- if (category && category !== "all") {
601
+ const tokens = ctx.tailwindTokens;
602
+ let result;
603
+ if (!category || category === "all") {
604
+ result = tokens;
605
+ } else {
296
606
  result = tokens[category] || {};
297
607
  }
608
+ const responseContent = [];
609
+ const guidance = getTokenGuidance(category);
610
+ responseContent.push({
611
+ type: "text",
612
+ text: guidance
613
+ });
614
+ responseContent.push({
615
+ type: "text",
616
+ text: JSON.stringify(result, null, 2)
617
+ });
618
+ return {
619
+ content: responseContent
620
+ };
621
+ } catch (error) {
298
622
  return {
299
623
  content: [
300
624
  {
301
625
  type: "text",
302
- text: JSON.stringify(result, null, 2)
626
+ text: `Failed to get Tailwind tokens: ${error instanceof Error ? error.message : "Unknown error"}`
627
+ }
628
+ ]
629
+ };
630
+ }
631
+ }
632
+ );
633
+ }
634
+ };
635
+ var filename2 = fileURLToPath(import.meta.url);
636
+ var dirname2 = path.dirname(filename2);
637
+ function mapComponentToFile(componentName, exportedFiles) {
638
+ const componentToFileMap = {
639
+ // Button components
640
+ "Button": "Buttons",
641
+ "ButtonDropdown": "Buttons",
642
+ "ButtonIcon": "Buttons",
643
+ "ButtonToggle": "Buttons",
644
+ // Table components
645
+ "TableHeader": "Table",
646
+ "TableRow": "Table",
647
+ // Input components
648
+ "InputCheckbox": "Control-Inputs",
649
+ "InputRadio": "Control-Inputs",
650
+ "InputToggle": "Control-Inputs",
651
+ "InputText": "Field-Inputs",
652
+ "InputDropdown": "Dropdown-Input",
653
+ "InputSearch": "Search-Input",
654
+ "InputSlider": "Control-Inputs",
655
+ // Dropdown components
656
+ "Dropdown": "Dropdown-Menu",
657
+ "DropdownMenu": "Dropdown-Menu",
658
+ // Content components
659
+ "ContentCard": "Content-Card",
660
+ "LoadingIndicator": "Loading-Indicator",
661
+ // Navigation components
662
+ "NavigationFooter": "Navigation",
663
+ "NavigationHeader": "Navigation",
664
+ "NavigationJumpTo": "Navigation",
665
+ // Control components
666
+ "SegmentedControl": "Segmented-Control",
667
+ // List and menu components
668
+ "List": "Lists",
669
+ "Menu": "Dropdown-Menu",
670
+ "MenuItem": "Dropdown-Menu",
671
+ "MenuSelect": "Dropdown-Menu",
672
+ // Tag components
673
+ "Tag": "Tags",
674
+ "TagFilter": "Tags",
675
+ // Tooltip components
676
+ "Tooltip": "Tooltips",
677
+ "TooltipCondensed": "Tooltips",
678
+ "TooltipTable": "Tooltips",
679
+ // Table Cell components
680
+ "CellBasic": "Table",
681
+ "CellComponent": "Table",
682
+ "CellHeader": "Table",
683
+ // Filter components
684
+ "ComplexFilter": "Filters",
685
+ // Other components
686
+ "Icon": "Icons",
687
+ "Chip": "Tags",
688
+ // Chips are often similar to tags
689
+ "Pagination": "Navigation"
690
+ // Pagination is often part of navigation
691
+ };
692
+ const mappedFile = componentToFileMap[componentName];
693
+ if (mappedFile && exportedFiles.includes(mappedFile)) {
694
+ return `${mappedFile}.md`;
695
+ }
696
+ if (exportedFiles.includes(componentName)) {
697
+ return `${componentName}.md`;
698
+ }
699
+ return null;
700
+ }
701
+ function getExportedFiles() {
702
+ try {
703
+ const possiblePaths = [
704
+ path.join(dirname2, "../../data/zeroheight-exports"),
705
+ // From src/lib in dev
706
+ path.join(dirname2, "../data/zeroheight-exports"),
707
+ // From dist in prod
708
+ path.join(process.cwd(), "data/zeroheight-exports")
709
+ // From current working directory
710
+ ];
711
+ let exportDir = "";
712
+ for (const p of possiblePaths) {
713
+ if (fs.existsSync(p)) {
714
+ exportDir = p;
715
+ break;
716
+ }
717
+ }
718
+ if (!exportDir) {
719
+ console.warn("Export directory not found in any expected location. Please run Zeroheight export first.");
720
+ return [];
721
+ }
722
+ const files = fs.readdirSync(exportDir).filter((file) => file.endsWith(".md") && file !== "README.md").map((file) => file.replace(".md", ""));
723
+ return files;
724
+ } catch (error) {
725
+ console.warn("Could not read exported files:", error);
726
+ return [];
727
+ }
728
+ }
729
+ function getComponentsWithDocs(allComponents, exportedFiles) {
730
+ return allComponents.filter((component) => {
731
+ const mappedFile = mapComponentToFile(component, exportedFiles);
732
+ return mappedFile !== null;
733
+ });
734
+ }
735
+ var getComponentDocsTool = {
736
+ name: "get_component_docs",
737
+ description: "Get design system documentation for a specific component. Retrieves the corresponding Zeroheight documentation file for the given component name. Supports all SDS components and maps them to their appropriate documentation files.",
738
+ async ctx() {
739
+ try {
740
+ const componentList = await getAllComponentNames();
741
+ const allComponents = [
742
+ ...componentList.components,
743
+ ...componentList["data-viz"]
744
+ ];
745
+ const exportedFiles = getExportedFiles();
746
+ const componentsWithDocs = getComponentsWithDocs(allComponents, exportedFiles);
747
+ return {
748
+ componentsWithDocs,
749
+ exportedFiles
750
+ };
751
+ } catch (error) {
752
+ throw new Error(
753
+ `Failed to initialize get component docs tool: ${error instanceof Error ? error.message : "Unknown error"}`
754
+ );
755
+ }
756
+ },
757
+ exec(server2, { ctx, name, description }) {
758
+ server2.tool(
759
+ name,
760
+ description,
761
+ {
762
+ component: z.enum(ctx.componentsWithDocs).describe("The name of the SDS component to get documentation for")
763
+ },
764
+ async ({ component }) => {
765
+ try {
766
+ const mappedFile = mapComponentToFile(component, ctx.exportedFiles);
767
+ if (!mappedFile) {
768
+ return {
769
+ content: [
770
+ {
771
+ type: "text",
772
+ text: `No documentation found for component '${component}'. This component may not have design system documentation available.`
773
+ }
774
+ ]
775
+ };
776
+ }
777
+ const possiblePaths = [
778
+ path.join(dirname2, "../../data/zeroheight-exports", mappedFile),
779
+ // From src/lib in dev
780
+ path.join(dirname2, "../data/zeroheight-exports", mappedFile),
781
+ // From dist in prod
782
+ path.join(process.cwd(), "data/zeroheight-exports", mappedFile)
783
+ // From current working directory
784
+ ];
785
+ let filePath = "";
786
+ for (const p of possiblePaths) {
787
+ if (fs.existsSync(p)) {
788
+ filePath = p;
789
+ break;
790
+ }
791
+ }
792
+ if (!filePath) {
793
+ throw new Error(`Documentation file ${mappedFile} not found`);
794
+ }
795
+ const documentation = fs.readFileSync(filePath, "utf8");
796
+ return {
797
+ content: [
798
+ {
799
+ type: "text",
800
+ text: `# Documentation for ${component}
801
+
802
+ Source: ${mappedFile}
803
+
804
+ ${documentation}`
303
805
  }
304
806
  ]
305
807
  };
@@ -308,7 +810,7 @@ var getTailwindTokensTool = {
308
810
  content: [
309
811
  {
310
812
  type: "text",
311
- text: `Failed to get Tailwind tokens: ${error instanceof Error ? error.message : "Unknown error"}`
813
+ text: `Error reading documentation file for '${component}': ${error instanceof Error ? error.message : "Unknown error"}`
312
814
  }
313
815
  ]
314
816
  };
@@ -322,6 +824,7 @@ var getTailwindTokensTool = {
322
824
  var tools = [
323
825
  getComponentPropsTool,
324
826
  getComponentPropsStorybookTool,
827
+ getComponentDocsTool,
325
828
  listComponentsTool,
326
829
  getTailwindTokensTool
327
830
  ];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@czi-sds/mcp",
3
3
  "description": "The official MCP server for SDS",
4
- "version": "0.2.1",
4
+ "version": "0.3.0",
5
5
  "main": "dist/stdio.js",
6
6
  "files": [
7
7
  "dist",
@@ -23,7 +23,8 @@
23
23
  "generate:components-list": "tsx scripts/generate-component-list.ts",
24
24
  "generate:component-props": "tsx scripts/generate-component-props.ts",
25
25
  "generate:component-props-storybook": "tsx scripts/generate-component-props-from-storybook.ts",
26
- "generate:all": "yarn generate:tailwind-tokens && yarn generate:components-list && yarn generate:component-props && yarn generate:component-props-storybook",
26
+ "generate:zeroheight-export": "tsx scripts/export-zeroheight-pages.ts",
27
+ "generate:all": "yarn generate:tailwind-tokens && yarn generate:components-list && yarn generate:component-props && yarn generate:component-props-storybook && yarn generate:zeroheight-export",
27
28
  "prebuild": "yarn generate:all",
28
29
  "build": "yarn prebuild && tsup && chmod 755 dist/stdio.js",
29
30
  "dev": "tsup --watch",
@@ -62,5 +63,5 @@
62
63
  "tsx": "^4.20.3",
63
64
  "typescript": "^5.9.2"
64
65
  },
65
- "gitHead": "fa7e676b7f69b6999cc8d6fe86c04b8069bfdb1e"
66
+ "gitHead": "c4bbb6751f8efd89ff5b6e560d8aea687cf8a84c"
66
67
  }