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.
- package/dist/index.js +138 -10
- 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
|
-
|
|
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
|
-
${
|
|
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.
|
|
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",
|