sonance-brand-mcp 1.2.4 → 1.2.5

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 +138 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1009,7 +1009,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1009
1009
  // Apply smart defaults and track what was defaulted
1010
1010
  const defaultsUsed = [];
1011
1011
  const brand = rawArgs.brand || (() => { defaultsUsed.push("brand → Sonance"); return "sonance"; })();
1012
- const theme = rawArgs.theme || (() => { defaultsUsed.push("theme → Light"); return "light"; })();
1013
1012
  const logoPreference = rawArgs.logo_preference || (() => { defaultsUsed.push("logo → Default lockup"); return "default"; })();
1014
1013
  const component_description = rawArgs.component_description;
1015
1014
  // Smart output type detection
@@ -1017,6 +1016,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1017
1016
  if (!rawArgs.output_type) {
1018
1017
  defaultsUsed.push(`output type → ${detectedOutputType} (auto-detected)`);
1019
1018
  }
1019
+ // Dual-theme mode: For UI outputs without explicit theme, provide BOTH themes by default
1020
+ const isDualThemeMode = detectedOutputType === "ui" && !rawArgs.theme;
1021
+ const theme = rawArgs.theme || "light";
1022
+ if (isDualThemeMode) {
1023
+ defaultsUsed.push("theme → Light AND Dark (dual-theme default for UI)");
1024
+ }
1025
+ else if (!rawArgs.theme) {
1026
+ defaultsUsed.push("theme → Light");
1027
+ }
1020
1028
  // Logo path mapping based on preference and theme
1021
1029
  // Light theme = dark logo (for light backgrounds), Dark theme = light logo (for dark backgrounds)
1022
1030
  const logoMap = {
@@ -1205,17 +1213,20 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1205
1213
  \`\`\``,
1206
1214
  },
1207
1215
  };
1208
- const tokens = brandTokens[brand]?.[theme];
1209
- if (!tokens) {
1210
- return {
1211
- content: [{ type: "text", text: `Invalid brand/theme combination: ${brand}/${theme}` }],
1212
- isError: true,
1213
- };
1214
- }
1215
1216
  // Build defaults notice if any were applied
1216
1217
  const defaultsNotice = defaultsUsed.length > 0
1217
1218
  ? `\n> **Note**: Defaults applied: ${defaultsUsed.join(", ")}. Specify \`brand\`, \`theme\`, \`logo_preference\`, or \`output_type\` explicitly for different styling.\n`
1218
1219
  : "";
1220
+ // For dual-theme mode (UI without explicit theme), get both themes
1221
+ const lightTokens = brandTokens[brand]?.light;
1222
+ const darkTokens = brandTokens[brand]?.dark;
1223
+ const singleThemeTokens = brandTokens[brand]?.[theme];
1224
+ if (!lightTokens || !darkTokens) {
1225
+ return {
1226
+ content: [{ type: "text", text: `Invalid brand: ${brand}` }],
1227
+ isError: true,
1228
+ };
1229
+ }
1219
1230
  // Get live brand colors for document formats
1220
1231
  const docColors = getBrandColorsForDocs();
1221
1232
  // Output-type-specific implementation guidance
@@ -1370,14 +1381,130 @@ const example = "Sonance";
1370
1381
  - Use dark variant for GitHub (light mode default)
1371
1382
  - Path: \`${logoPath}\``,
1372
1383
  };
1373
- const response = `# Design Context for: ${component_description}
1384
+ // Build the response based on single or dual theme mode
1385
+ let response;
1386
+ if (isDualThemeMode) {
1387
+ // DUAL-THEME MODE: Provide both light and dark tokens for UI
1388
+ const lightLogoPath = logoMap[logoPreference]?.light || logoMap.default.light;
1389
+ const darkLogoPath = logoMap[logoPreference]?.dark || logoMap.default.dark;
1390
+ response = `# Design Context for: ${component_description}
1391
+
1392
+ **Brand**: ${brand.toUpperCase()}
1393
+ **Theme**: Light AND Dark Mode (automatically implemented)
1394
+ **Output Type**: ${detectedOutputType.toUpperCase()}
1395
+ **Logo**: ${logoPreferenceLabel}
1396
+ ${defaultsNotice}
1397
+
1398
+ > **Dual-Theme Default**: All UI designs include both light and dark mode tokens by default.
1399
+ > Implement both themes using Tailwind \`dark:\` variants or CSS custom properties.
1400
+
1401
+ ---
1402
+
1403
+ ${lightTokens}
1404
+
1405
+ ---
1406
+
1407
+ ${darkTokens}
1408
+
1409
+ ---
1410
+
1411
+ ## Theme Switching Implementation
1412
+
1413
+ ### Using Tailwind Dark Mode
1414
+ \`\`\`tsx
1415
+ // Components automatically support dark mode with dark: prefix
1416
+ <div className="bg-white dark:bg-sonance-charcoal text-sonance-charcoal dark:text-white">
1417
+ <button className="bg-sonance-blue text-white dark:text-sonance-charcoal px-6 py-3 text-sm font-medium uppercase tracking-wide">
1418
+ Action
1419
+ </button>
1420
+ </div>
1421
+
1422
+ // Cards with theme support
1423
+ <div className="bg-white dark:bg-sonance-charcoal border border-sonance-light-gray dark:border-white/10 rounded-sm p-6 shadow-sm">
1424
+ Content
1425
+ </div>
1426
+ \`\`\`
1427
+
1428
+ ### Using CSS Custom Properties
1429
+ \`\`\`css
1430
+ :root {
1431
+ --background: #FFFFFF;
1432
+ --foreground: #333F48;
1433
+ --primary: #00A3E1;
1434
+ --card: #FFFFFF;
1435
+ --border: #D9D9D6;
1436
+ }
1437
+
1438
+ [data-theme="dark"], .dark {
1439
+ --background: #333F48;
1440
+ --foreground: #FFFFFF;
1441
+ --primary: #00A3E1;
1442
+ --card: #333F48;
1443
+ --border: rgba(255, 255, 255, 0.1);
1444
+ }
1445
+ \`\`\`
1446
+
1447
+ ### Next.js Theme Provider Pattern
1448
+ \`\`\`tsx
1449
+ // Use next-themes for automatic system detection
1450
+ import { ThemeProvider } from 'next-themes'
1451
+
1452
+ export function Providers({ children }) {
1453
+ return (
1454
+ <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
1455
+ {children}
1456
+ </ThemeProvider>
1457
+ )
1458
+ }
1459
+ \`\`\`
1460
+
1461
+ ### Logo Usage for Both Themes
1462
+ - **Light mode (light backgrounds)**: \`${lightLogoPath}\`
1463
+ - **Dark mode (dark backgrounds)**: \`${darkLogoPath}\`
1464
+
1465
+ \`\`\`tsx
1466
+ // Theme-aware logo component
1467
+ import { useTheme } from 'next-themes'
1468
+ import Image from 'next/image'
1469
+
1470
+ function Logo() {
1471
+ const { resolvedTheme } = useTheme()
1472
+ const logoSrc = resolvedTheme === 'dark'
1473
+ ? '${darkLogoPath}'
1474
+ : '${lightLogoPath}'
1475
+
1476
+ return <Image src={logoSrc} alt="${logoPreferenceLabel}" width={200} height={40} />
1477
+ }
1478
+ \`\`\`
1479
+
1480
+ ${outputTypeGuidance[detectedOutputType]}
1481
+
1482
+ ## Typography (All Brands)
1483
+ - **Font Family**: Montserrat
1484
+ - **Headlines**: font-weight 300 (Light) or 500 (Medium)
1485
+ - **Body**: font-weight 400 (Regular), line-height 1.6
1486
+ - **Buttons/CTAs**: font-weight 500, uppercase, letter-spacing 0.08em
1487
+
1488
+ ## Design Principles
1489
+ 1. Generous whitespace — layouts should feel "breathable"
1490
+ 2. Minimal borders — use subtle dividers, not heavy borders
1491
+ 3. Refined shadows — subtle elevation, not aggressive drop shadows
1492
+ 4. Premium feel — every element should feel high-end and intentional
1493
+
1494
+ ---
1495
+
1496
+ Now design the **${component_description}** with **BOTH light and dark mode support** following these tokens and principles.`;
1497
+ }
1498
+ else {
1499
+ // SINGLE-THEME MODE: Backwards compatible for explicit theme or non-UI outputs
1500
+ response = `# Design Context for: ${component_description}
1374
1501
 
1375
1502
  **Brand**: ${brand.toUpperCase()}
1376
1503
  **Theme**: ${theme.charAt(0).toUpperCase() + theme.slice(1)}
1377
1504
  **Output Type**: ${detectedOutputType.toUpperCase()}
1378
1505
  **Logo**: ${logoPreferenceLabel}
1379
1506
  ${defaultsNotice}
1380
- ${tokens}
1507
+ ${singleThemeTokens}
1381
1508
 
1382
1509
  ${outputTypeGuidance[detectedOutputType]}
1383
1510
 
@@ -1396,6 +1523,7 @@ ${outputTypeGuidance[detectedOutputType]}
1396
1523
  ---
1397
1524
 
1398
1525
  Now design the **${component_description}** following these tokens and principles.`;
1526
+ }
1399
1527
  return {
1400
1528
  content: [{ type: "text", text: response }],
1401
1529
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonance-brand-mcp",
3
- "version": "1.2.4",
3
+ "version": "1.2.5",
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",