sonance-brand-mcp 1.2.5 → 1.3.1

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 (90) hide show
  1. package/dist/assets/components/alert-dialog.stories.tsx +142 -0
  2. package/dist/assets/components/alert-dialog.tsx +142 -0
  3. package/dist/assets/components/aspect-ratio.stories.tsx +67 -0
  4. package/dist/assets/components/aspect-ratio.tsx +8 -0
  5. package/dist/assets/components/avatar.tsx +64 -20
  6. package/dist/assets/components/carousel.stories.tsx +158 -0
  7. package/dist/assets/components/carousel.tsx +262 -0
  8. package/dist/assets/components/chart.stories.tsx +376 -0
  9. package/dist/assets/components/chart.tsx +384 -0
  10. package/dist/assets/components/checkbox.tsx +12 -2
  11. package/dist/assets/components/code.tsx +22 -20
  12. package/dist/assets/components/collapsible.stories.tsx +128 -0
  13. package/dist/assets/components/collapsible.tsx +10 -0
  14. package/dist/assets/components/command.stories.tsx +183 -0
  15. package/dist/assets/components/command.tsx +170 -0
  16. package/dist/assets/components/context-menu.stories.tsx +159 -0
  17. package/dist/assets/components/context-menu.tsx +218 -0
  18. package/dist/assets/components/divider.tsx +38 -35
  19. package/dist/assets/components/dropdown-menu.tsx +217 -0
  20. package/dist/assets/components/hover-card.stories.tsx +113 -0
  21. package/dist/assets/components/hover-card.tsx +35 -0
  22. package/dist/assets/components/kbd.tsx +6 -6
  23. package/dist/assets/components/menubar.stories.tsx +208 -0
  24. package/dist/assets/components/menubar.tsx +251 -0
  25. package/dist/assets/components/navigation-menu.stories.tsx +237 -0
  26. package/dist/assets/components/navigation-menu.tsx +135 -0
  27. package/dist/assets/components/resizable.stories.tsx +197 -0
  28. package/dist/assets/components/resizable.tsx +47 -0
  29. package/dist/assets/components/scroll-area.stories.tsx +123 -0
  30. package/dist/assets/components/scroll-area.tsx +48 -0
  31. package/dist/assets/components/scroll-shadow.tsx +29 -7
  32. package/dist/assets/components/separator.tsx +32 -0
  33. package/dist/assets/components/sheet.tsx +141 -0
  34. package/dist/assets/components/sidebar.stories.tsx +351 -0
  35. package/dist/assets/components/sidebar.tsx +760 -0
  36. package/dist/assets/components/toggle-group.stories.tsx +153 -0
  37. package/dist/assets/components/toggle-group.tsx +61 -0
  38. package/dist/assets/components/toggle.stories.tsx +77 -0
  39. package/dist/assets/components/toggle.tsx +46 -0
  40. package/dist/assets/components/tooltip.tsx +23 -90
  41. package/dist/assets/globals.css +30 -0
  42. package/dist/assets/logos/40th-anniversary/Sonance_40_Logo_CMYK_BEAM_BLUE_40_AND_BEAM_DARK.png +0 -0
  43. package/dist/assets/logos/Sonance logo dark mode.png +0 -0
  44. package/dist/assets/logos/Sonance logo light mode.png +0 -0
  45. package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_2C_Light_RGB_05162025.png +0 -0
  46. package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_3C_Dark_RGB_05162025.png +0 -0
  47. package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_White_RGB_05162025.png +0 -0
  48. package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Dark_RGB.png +0 -0
  49. package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Light_RGB.png +0 -0
  50. package/dist/assets/logos/james/James_Logo_Black_CMYK.png +0 -0
  51. package/dist/assets/logos/james/James_Logo_Black_RGB.png +0 -0
  52. package/dist/assets/logos/james/James_Logo_LtGray_CMYK.png +0 -0
  53. package/dist/assets/logos/james/James_Logo_LtGray_RGB.png +0 -0
  54. package/dist/assets/logos/james/James_Logo_Polished_RGB.png +0 -0
  55. package/dist/assets/logos/james/James_Logo_Reverse_CMYK.png +0 -0
  56. package/dist/assets/logos/james/James_Logo_Reverse_RGB.png +0 -0
  57. package/dist/assets/logos/james/James_Logo_White_CMYK.png +0 -0
  58. package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Dark_RGB.png +0 -0
  59. package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Light_RGB.png +0 -0
  60. package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Dark_RGB.png +0 -0
  61. package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Light_RGB.png +0 -0
  62. package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Reverse_RGB.png +0 -0
  63. package/dist/assets/logos/my-sonance/My.Sonance_Logo_Black_RGB.png +0 -0
  64. package/dist/assets/logos/my-sonance/My.Sonance_Logo_Reverse_RGB.png +0 -0
  65. package/dist/assets/logos/sonance/Sonance_Logo_2C_Dark_RGB.png +0 -0
  66. package/dist/assets/logos/sonance/Sonance_Logo_2C_Light_RGB.png +0 -0
  67. package/dist/assets/logos/sonance/Sonance_Logo_2C_Reverse_RGB.png +0 -0
  68. package/dist/assets/logos/sonance/Sonance_Logo_Black_RGB.png +0 -0
  69. package/dist/assets/logos/sonance/Sonance_Logo_Grayscale_RGB.png +0 -0
  70. package/dist/assets/logos/sonance/Sonance_Logo_Reverse_RGB.png +0 -0
  71. package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Dark_CMYK.png +0 -0
  72. package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Light_CMYK.png +0 -0
  73. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Dark_RGB.png +0 -0
  74. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Light_RGB.png +0 -0
  75. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Reverse_RGB.png +0 -0
  76. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Black_RGB.png +0 -0
  77. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Grayscale_RGB.png +0 -0
  78. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Reverse_RGB.png +0 -0
  79. package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Dark.png +0 -0
  80. package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Light.png +0 -0
  81. package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Dark.png +0 -0
  82. package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Light.png +0 -0
  83. package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Dark.png +0 -0
  84. package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Light.png +0 -0
  85. package/dist/assets/logos/trufig/TrufigLogo_Black.png +0 -0
  86. package/dist/assets/logos/trufig/TrufigLogo_Light.png +0 -0
  87. package/dist/assets/logos/trufig/TrufigWatermark_Black.png +0 -0
  88. package/dist/assets/logos/trufig/TrufigWatermark_Light.png +0 -0
  89. package/dist/index.js +278 -7
  90. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -306,6 +306,76 @@ function getAssetPath(assetType) {
306
306
  }
307
307
  }
308
308
  }
309
+ // ============================================
310
+ // LOGO PATH RESOLUTION
311
+ // ============================================
312
+ /**
313
+ * Resolve a logo path to an absolute file path
314
+ * Handles both bundled and dev mode, with path sanitization
315
+ */
316
+ function resolveLogoPath(logoPath) {
317
+ // Sanitize path to prevent directory traversal
318
+ const sanitized = logoPath
319
+ .replace(/^\/+/, '') // Remove leading slashes
320
+ .replace(/\.{2,}/g, '') // Remove .. sequences
321
+ .replace(/\/+/g, '/'); // Normalize multiple slashes
322
+ // Remove "logos/" prefix if present (manifest has /logos/xxx format)
323
+ const normalizedPath = sanitized.replace(/^logos\//, '');
324
+ if (IS_BUNDLED) {
325
+ // In bundled mode, logos are in dist/assets/logos/
326
+ const logosDir = path.join(BUNDLED_ASSETS, "logos");
327
+ return path.join(logosDir, normalizedPath);
328
+ }
329
+ else {
330
+ // In dev mode, logos are in public/logos/
331
+ const logosDir = path.join(DEV_PROJECT_ROOT, "public/logos");
332
+ return path.join(logosDir, normalizedPath);
333
+ }
334
+ }
335
+ /**
336
+ * Get MIME type for image file based on extension
337
+ */
338
+ function getImageMimeType(filePath) {
339
+ const ext = path.extname(filePath).toLowerCase();
340
+ switch (ext) {
341
+ case '.png': return 'image/png';
342
+ case '.jpg':
343
+ case '.jpeg': return 'image/jpeg';
344
+ case '.svg': return 'image/svg+xml';
345
+ case '.gif': return 'image/gif';
346
+ case '.webp': return 'image/webp';
347
+ default: return 'application/octet-stream';
348
+ }
349
+ }
350
+ /**
351
+ * Embed a logo as base64 image content for MCP responses
352
+ * Returns an MCP-compatible image content block or null if logo not found
353
+ */
354
+ async function embedLogo(logoPath) {
355
+ try {
356
+ const resolvedPath = resolveLogoPath(logoPath);
357
+ if (!resolvedPath)
358
+ return null;
359
+ // Check if file exists
360
+ if (!fs.existsSync(resolvedPath)) {
361
+ console.error(`Logo not found: ${resolvedPath}`);
362
+ return null;
363
+ }
364
+ // Read file as base64
365
+ const fileBuffer = fs.readFileSync(resolvedPath);
366
+ const base64Data = fileBuffer.toString('base64');
367
+ const mimeType = getImageMimeType(resolvedPath);
368
+ return {
369
+ type: "image",
370
+ data: base64Data,
371
+ mimeType,
372
+ };
373
+ }
374
+ catch (error) {
375
+ console.error(`Error embedding logo: ${error}`);
376
+ return null;
377
+ }
378
+ }
309
379
  /**
310
380
  * Detect output type from user's request/prompt
311
381
  */
@@ -545,6 +615,50 @@ server.setRequestHandler(ListResourcesRequestSchema, async () => {
545
615
  catch (e) {
546
616
  // Components directory might not exist
547
617
  }
618
+ // Add logo resources
619
+ try {
620
+ let logoList;
621
+ if (IS_BUNDLED) {
622
+ const manifestPath = getAssetPath("logos");
623
+ logoList = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
624
+ }
625
+ else {
626
+ // Scan directory in development
627
+ const logosDir = getAssetPath("logos");
628
+ function listLogoFiles(dir, prefix = "") {
629
+ let results = [];
630
+ if (!fs.existsSync(dir))
631
+ return results;
632
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
633
+ for (const entry of entries) {
634
+ if (entry.isDirectory()) {
635
+ results = [...results, ...listLogoFiles(path.join(dir, entry.name), `${prefix}${entry.name}/`)];
636
+ }
637
+ else if (/\.(png|svg|jpg|jpeg)$/i.test(entry.name)) {
638
+ results.push(`/logos/${prefix}${entry.name}`);
639
+ }
640
+ }
641
+ return results;
642
+ }
643
+ logoList = listLogoFiles(logosDir);
644
+ }
645
+ for (const logoPath of logoList) {
646
+ // Convert /logos/sonance/file.png to sonance/file.png for URI
647
+ const uriPath = logoPath.replace(/^\/logos\//, '');
648
+ const fileName = path.basename(logoPath, path.extname(logoPath));
649
+ const folder = path.dirname(uriPath);
650
+ const mimeType = getImageMimeType(logoPath);
651
+ resources.push({
652
+ uri: `sonance://logo/${uriPath}`,
653
+ name: `${fileName} Logo`,
654
+ description: `${folder !== '.' ? folder + ' - ' : ''}Brand logo image file`,
655
+ mimeType: mimeType,
656
+ });
657
+ }
658
+ }
659
+ catch (e) {
660
+ // Logo resources might not be available
661
+ }
548
662
  return { resources };
549
663
  });
550
664
  server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
@@ -572,6 +686,24 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
572
686
  };
573
687
  }
574
688
  }
689
+ // Handle logo resources
690
+ if (uri.startsWith("sonance://logo/")) {
691
+ const logoPath = uri.replace("sonance://logo/", "");
692
+ const resolvedPath = resolveLogoPath(logoPath);
693
+ if (!resolvedPath || !fs.existsSync(resolvedPath)) {
694
+ throw new Error(`Logo not found: ${logoPath}`);
695
+ }
696
+ const imageBuffer = fs.readFileSync(resolvedPath);
697
+ const base64Data = imageBuffer.toString('base64');
698
+ const mimeType = getImageMimeType(resolvedPath);
699
+ return {
700
+ contents: [{
701
+ uri,
702
+ mimeType,
703
+ blob: base64Data, // Use blob for binary resources
704
+ }],
705
+ };
706
+ }
575
707
  throw new Error(`Resource not found: ${uri}`);
576
708
  });
577
709
  // ============================================
@@ -639,6 +771,20 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
639
771
  required: [],
640
772
  },
641
773
  },
774
+ {
775
+ name: "get_logo",
776
+ description: "Returns a brand logo image as base64-encoded data that AI can view and analyze. Use list_logos first to see available logos, then use this tool to retrieve the actual image.",
777
+ inputSchema: {
778
+ type: "object",
779
+ properties: {
780
+ logo_path: {
781
+ type: "string",
782
+ description: "The path to the logo from list_logos output (e.g., '/logos/sonance/Sonance_Logo_2C_Dark_RGB.png' or 'sonance/Sonance_Logo_2C_Dark_RGB.png')",
783
+ },
784
+ },
785
+ required: ["logo_path"],
786
+ },
787
+ },
642
788
  {
643
789
  name: "get_full_library",
644
790
  description: "RECOMMENDED FOR APP REDESIGNS & FULL APPLICATIONS: Returns the complete component library including brand guidelines, CSS theme, utilities, and all component source code. USE THIS TOOL when the user asks to: redesign an application, rebrand an app, build a full application, update an entire codebase to use Sonance/IPORT/Blaze brand, or any multi-file/multi-component project. This is the go-to tool for comprehensive brand implementation across an entire project.",
@@ -650,7 +796,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
650
796
  },
651
797
  {
652
798
  name: "design_component",
653
- description: "Returns brand-specific design tokens, colors, implementation rules, and logo assets for designing a component. Smart defaults: Sonance/Light/Default logo lockup if not specified. Auto-detects output type (ui/doc/marketing/tech) if not specified.",
799
+ description: "Returns brand-specific design tokens, colors, implementation rules, and AUTO-EMBEDS the correct logo image(s) for designing a component. For UI outputs, embeds both light and dark theme logos. Smart defaults: Sonance+James+IPORT lockup as default logo. Auto-detects output type (ui/doc/marketing/tech).",
654
800
  inputSchema: {
655
801
  type: "object",
656
802
  properties: {
@@ -666,8 +812,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
666
812
  },
667
813
  logo_preference: {
668
814
  type: "string",
669
- enum: ["default", "sonance", "iport", "blaze"],
670
- description: "Which logo to use. 'default' = Sonance+James+IPORT lockup. Or specify 'sonance', 'iport', or 'blaze' for individual brand logos. Defaults to 'default' if not specified.",
815
+ enum: ["default", "sonance", "iport", "blaze", "james"],
816
+ description: "Which logo to use. 'default' = Sonance+James+IPORT lockup. Or specify 'sonance', 'iport', 'blaze', or 'james' for individual brand logos. Defaults to 'default' if not specified.",
671
817
  },
672
818
  output_type: {
673
819
  type: "string",
@@ -755,7 +901,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
755
901
  },
756
902
  {
757
903
  name: "rebrand_document",
758
- description: "Returns universal rebranding instructions for converting ANY existing document to a specific brand (Sonance, IPORT, or Blaze). Works with any document format - provides color replacements, font substitutions, and logo placement rules that apply regardless of document structure.",
904
+ description: "Returns universal rebranding instructions for converting ANY existing document to a specific brand (Sonance, IPORT, or Blaze) and AUTO-EMBEDS both light and dark logo variants for immediate use. Provides color replacements, font substitutions, and logo placement rules. Default: Sonance+James+IPORT lockup for Sonance brand.",
759
905
  inputSchema: {
760
906
  type: "object",
761
907
  properties: {
@@ -941,6 +1087,66 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
941
1087
  };
942
1088
  }
943
1089
  }
1090
+ case "get_logo": {
1091
+ const logoPath = args.logo_path;
1092
+ if (!logoPath) {
1093
+ return {
1094
+ content: [{ type: "text", text: "Error: logo_path is required. Use list_logos to see available logos." }],
1095
+ isError: true,
1096
+ };
1097
+ }
1098
+ try {
1099
+ const resolvedPath = resolveLogoPath(logoPath);
1100
+ if (!resolvedPath) {
1101
+ return {
1102
+ content: [{ type: "text", text: `Error: Invalid logo path: ${logoPath}` }],
1103
+ isError: true,
1104
+ };
1105
+ }
1106
+ if (!fs.existsSync(resolvedPath)) {
1107
+ // Try to help user find the right logo
1108
+ let suggestion = '\n\nUse list_logos to see available logos.';
1109
+ if (IS_BUNDLED) {
1110
+ try {
1111
+ const manifestPath = getAssetPath("logos");
1112
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
1113
+ suggestion = `\n\nAvailable logos include:\n${manifest.slice(0, 5).map((p) => ` - ${p}`).join('\n')}\n ... and ${manifest.length - 5} more. Use list_logos to see all.`;
1114
+ }
1115
+ catch {
1116
+ // Keep default suggestion
1117
+ }
1118
+ }
1119
+ return {
1120
+ content: [{ type: "text", text: `Error: Logo not found: ${logoPath}${suggestion}` }],
1121
+ isError: true,
1122
+ };
1123
+ }
1124
+ // Read and encode the image
1125
+ const imageBuffer = fs.readFileSync(resolvedPath);
1126
+ const base64Data = imageBuffer.toString('base64');
1127
+ const mimeType = getImageMimeType(resolvedPath);
1128
+ const fileName = path.basename(resolvedPath);
1129
+ return {
1130
+ content: [
1131
+ {
1132
+ type: "image",
1133
+ data: base64Data,
1134
+ mimeType: mimeType,
1135
+ },
1136
+ {
1137
+ type: "text",
1138
+ text: `**Logo:** ${fileName}\n**Path:** ${logoPath}\n**Size:** ${imageBuffer.length} bytes\n**Format:** ${mimeType}`,
1139
+ },
1140
+ ],
1141
+ };
1142
+ }
1143
+ catch (e) {
1144
+ return {
1145
+ content: [{ type: "text", text: `Error reading logo: ${e}` }],
1146
+ isError: true,
1147
+ };
1148
+ }
1149
+ }
944
1150
  case "get_full_library": {
945
1151
  try {
946
1152
  let fullLibrary = "# Sonance Component Library\n\n";
@@ -1044,11 +1250,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1044
1250
  light: "/logos/blaze/BlazeBySonance_Logo_Lockup_3C_Dark_RGB_05162025.png",
1045
1251
  dark: "/logos/blaze/BlazeBySonance_Logo_Lockup_2C_Light_RGB_05162025.png",
1046
1252
  },
1253
+ james: {
1254
+ light: "/logos/james/James_Logo_Black_RGB.png",
1255
+ dark: "/logos/james/James_Logo_Reverse_RGB.png",
1256
+ },
1047
1257
  };
1048
1258
  const logoPath = logoMap[logoPreference]?.[theme] || logoMap.default[theme];
1049
1259
  const logoPreferenceLabel = logoPreference === "default"
1050
1260
  ? "Sonance + James + IPORT Lockup"
1051
- : `${logoPreference.charAt(0).toUpperCase() + logoPreference.slice(1)} Only`;
1261
+ : logoPreference === "james"
1262
+ ? "James Only"
1263
+ : `${logoPreference.charAt(0).toUpperCase() + logoPreference.slice(1)} Only`;
1052
1264
  // Brand-specific design tokens
1053
1265
  const brandTokens = {
1054
1266
  sonance: {
@@ -1524,8 +1736,35 @@ ${outputTypeGuidance[detectedOutputType]}
1524
1736
 
1525
1737
  Now design the **${component_description}** following these tokens and principles.`;
1526
1738
  }
1739
+ // Embed logos in response
1740
+ const contentBlocks = [];
1741
+ if (isDualThemeMode) {
1742
+ // Dual-theme mode: embed both light and dark theme logos
1743
+ const lightLogoPath = logoMap[logoPreference]?.light || logoMap.default.light;
1744
+ const darkLogoPath = logoMap[logoPreference]?.dark || logoMap.default.dark;
1745
+ const lightLogo = await embedLogo(lightLogoPath);
1746
+ const darkLogo = await embedLogo(darkLogoPath);
1747
+ if (lightLogo) {
1748
+ contentBlocks.push({ type: "text", text: `## Logo for Light Backgrounds\n**Path:** \`${lightLogoPath}\`` });
1749
+ contentBlocks.push(lightLogo);
1750
+ }
1751
+ if (darkLogo) {
1752
+ contentBlocks.push({ type: "text", text: `## Logo for Dark Backgrounds\n**Path:** \`${darkLogoPath}\`` });
1753
+ contentBlocks.push(darkLogo);
1754
+ }
1755
+ }
1756
+ else {
1757
+ // Single-theme mode: embed the appropriate logo
1758
+ const embeddedLogo = await embedLogo(logoPath);
1759
+ if (embeddedLogo) {
1760
+ contentBlocks.push({ type: "text", text: `## Brand Logo (${theme === "light" ? "for Light Backgrounds" : "for Dark Backgrounds"})\n**Path:** \`${logoPath}\`` });
1761
+ contentBlocks.push(embeddedLogo);
1762
+ }
1763
+ }
1764
+ // Add the main response text
1765
+ contentBlocks.push({ type: "text", text: response });
1527
1766
  return {
1528
- content: [{ type: "text", text: response }],
1767
+ content: contentBlocks,
1529
1768
  };
1530
1769
  }
1531
1770
  case "evaluate_design": {
@@ -2668,8 +2907,40 @@ ${rebrandArgs.source_format === "word" ? `
2668
2907
 
2669
2908
  **Remember:** The goal is to make the document unmistakably ${palette.name} while preserving its original structure and content.
2670
2909
  `;
2910
+ // Embed logos for rebrand_document
2911
+ // Use the Sonance+James+IPORT lockup as default for Sonance brand
2912
+ const rebrandLogoMap = {
2913
+ sonance: {
2914
+ light: "/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Dark.png",
2915
+ dark: "/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Light.png",
2916
+ },
2917
+ iport: {
2918
+ light: "/logos/iport/IPORT_Sonance_LockUp_2C_Dark_RGB.png",
2919
+ dark: "/logos/iport/IPORT_Sonance_LockUp_2C_Light_RGB.png",
2920
+ },
2921
+ blaze: {
2922
+ light: "/logos/blaze/BlazeBySonance_Logo_Lockup_3C_Dark_RGB_05162025.png",
2923
+ dark: "/logos/blaze/BlazeBySonance_Logo_Lockup_2C_Light_RGB_05162025.png",
2924
+ },
2925
+ };
2926
+ const rebrandContentBlocks = [];
2927
+ // For documents, provide both light and dark logo variants
2928
+ const lightLogoPath = rebrandLogoMap[targetBrand].light;
2929
+ const darkLogoPath = rebrandLogoMap[targetBrand].dark;
2930
+ const lightLogo = await embedLogo(lightLogoPath);
2931
+ const darkLogo = await embedLogo(darkLogoPath);
2932
+ if (lightLogo) {
2933
+ rebrandContentBlocks.push({ type: "text", text: `## Logo for Light Backgrounds\n**Use on white/light document backgrounds**\n**Path:** \`${lightLogoPath}\`` });
2934
+ rebrandContentBlocks.push(lightLogo);
2935
+ }
2936
+ if (darkLogo) {
2937
+ rebrandContentBlocks.push({ type: "text", text: `## Logo for Dark Backgrounds\n**Use on dark/colored document backgrounds**\n**Path:** \`${darkLogoPath}\`` });
2938
+ rebrandContentBlocks.push(darkLogo);
2939
+ }
2940
+ // Add the main guide text
2941
+ rebrandContentBlocks.push({ type: "text", text: rebrandGuide });
2671
2942
  return {
2672
- content: [{ type: "text", text: rebrandGuide }],
2943
+ content: rebrandContentBlocks,
2673
2944
  };
2674
2945
  }
2675
2946
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonance-brand-mcp",
3
- "version": "1.2.5",
3
+ "version": "1.3.1",
4
4
  "description": "MCP Server for Sonance Brand Guidelines and Component Library - gives Claude instant access to brand colors, typography, and UI components.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",