sonance-brand-mcp 1.3.117 → 1.3.119
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 +238 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2635,6 +2635,25 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
2635
2635
|
required: ["logo_path"],
|
|
2636
2636
|
},
|
|
2637
2637
|
},
|
|
2638
|
+
{
|
|
2639
|
+
name: "get_logo_base64",
|
|
2640
|
+
description: "Returns a logo as base64-encoded data URL ready for embedding in React artifacts, HTML, or web applications. USE THIS for artifacts instead of drawing/approximating logos. Returns a data URL that works directly in <img src='...'> tags. CRITICAL: NEVER draw, recreate, or approximate logos with SVG, CSS, or styled text - always use this tool to get the actual image data.",
|
|
2641
|
+
inputSchema: {
|
|
2642
|
+
type: "object",
|
|
2643
|
+
properties: {
|
|
2644
|
+
logo_path: {
|
|
2645
|
+
type: "string",
|
|
2646
|
+
description: "Path to the logo from list_logos output (e.g., 'sonance/Sonance_Logo_2C_Dark_RGB.png')",
|
|
2647
|
+
},
|
|
2648
|
+
format: {
|
|
2649
|
+
type: "string",
|
|
2650
|
+
enum: ["dataUrl", "base64", "both"],
|
|
2651
|
+
description: "Output format. 'dataUrl' for img src (default), 'base64' for raw data, 'both' for both formats",
|
|
2652
|
+
},
|
|
2653
|
+
},
|
|
2654
|
+
required: ["logo_path"],
|
|
2655
|
+
},
|
|
2656
|
+
},
|
|
2638
2657
|
{
|
|
2639
2658
|
name: "diagnose_logos",
|
|
2640
2659
|
description: "Diagnose logo loading issues. Returns validation status, path resolution examples, and environment info. Use this when logos fail to embed or appear in responses.",
|
|
@@ -2892,6 +2911,15 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
2892
2911
|
required: ["category"],
|
|
2893
2912
|
},
|
|
2894
2913
|
},
|
|
2914
|
+
{
|
|
2915
|
+
name: "get_version",
|
|
2916
|
+
description: "Returns the current version and info about the Sonance Brand MCP server.",
|
|
2917
|
+
inputSchema: {
|
|
2918
|
+
type: "object",
|
|
2919
|
+
properties: {},
|
|
2920
|
+
required: [],
|
|
2921
|
+
},
|
|
2922
|
+
},
|
|
2895
2923
|
],
|
|
2896
2924
|
};
|
|
2897
2925
|
});
|
|
@@ -3109,6 +3137,8 @@ ${formatCodeBlock(content, { language: "typescript", filename: "lib/utils.ts" })
|
|
|
3109
3137
|
const base64Data = imageBuffer.toString('base64');
|
|
3110
3138
|
const mimeType = getImageMimeType(resolvedPath);
|
|
3111
3139
|
const fileName = path.basename(resolvedPath);
|
|
3140
|
+
// Create data URL for artifact use
|
|
3141
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
3112
3142
|
// Determine logo variant info for recommendations
|
|
3113
3143
|
const isLightLogo = /light|reverse|white/i.test(fileName);
|
|
3114
3144
|
const isDarkLogo = /dark|black/i.test(fileName);
|
|
@@ -3139,28 +3169,45 @@ ${variantSuggestion}
|
|
|
3139
3169
|
|
|
3140
3170
|
---
|
|
3141
3171
|
|
|
3142
|
-
|
|
3172
|
+
## CRITICAL: Logo Usage Rules
|
|
3173
|
+
|
|
3174
|
+
> **NEVER draw, recreate, or approximate this logo.** This includes:
|
|
3175
|
+
> - SVG drawings or paths
|
|
3176
|
+
> - Styled text (e.g., colored letters spelling "SONANCE")
|
|
3177
|
+
> - CSS recreations or shapes
|
|
3178
|
+
> - Unicode character approximations
|
|
3179
|
+
>
|
|
3180
|
+
> **ALWAYS use the actual image data provided below.**
|
|
3181
|
+
|
|
3182
|
+
---
|
|
3183
|
+
|
|
3184
|
+
### For React Artifacts (USE THIS - includes actual image data)
|
|
3185
|
+
\`\`\`tsx
|
|
3186
|
+
<img
|
|
3187
|
+
src="${dataUrl}"
|
|
3188
|
+
alt="${brandName}"
|
|
3189
|
+
className="h-10 w-auto"
|
|
3190
|
+
/>
|
|
3191
|
+
\`\`\`
|
|
3192
|
+
|
|
3193
|
+
### For Next.js Projects (with file system access)
|
|
3143
3194
|
\`\`\`tsx
|
|
3144
3195
|
import Image from 'next/image';
|
|
3145
3196
|
|
|
3146
|
-
// In your component:
|
|
3147
3197
|
<Image
|
|
3148
3198
|
src="${normalizedPath}"
|
|
3149
3199
|
alt="${brandName}"
|
|
3150
3200
|
width={150}
|
|
3151
3201
|
height={40}
|
|
3152
3202
|
className="h-10 w-auto"
|
|
3153
|
-
priority
|
|
3203
|
+
priority
|
|
3154
3204
|
/>
|
|
3155
3205
|
\`\`\`
|
|
3156
3206
|
|
|
3157
|
-
###
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
alt="${brandName}"
|
|
3162
|
-
className="h-10 w-auto"
|
|
3163
|
-
/>
|
|
3207
|
+
### Base64 Data URL (copy for artifacts)
|
|
3208
|
+
Use this data URL directly in img src for artifacts:
|
|
3209
|
+
\`\`\`
|
|
3210
|
+
${dataUrl}
|
|
3164
3211
|
\`\`\`
|
|
3165
3212
|
|
|
3166
3213
|
### With Dark Mode Support
|
|
@@ -3169,12 +3216,12 @@ import Image from 'next/image';
|
|
|
3169
3216
|
<img
|
|
3170
3217
|
src="${normalizedPath}"
|
|
3171
3218
|
alt="${brandName}"
|
|
3172
|
-
className="h-10 w-auto dark:hidden"
|
|
3219
|
+
className="h-10 w-auto dark:hidden"
|
|
3173
3220
|
/>
|
|
3174
3221
|
<img
|
|
3175
3222
|
src="${normalizedPath.replace(/dark/gi, 'Light').replace(/black/gi, 'Reverse')}"
|
|
3176
3223
|
alt="${brandName}"
|
|
3177
|
-
className="h-10 w-auto hidden dark:block"
|
|
3224
|
+
className="h-10 w-auto hidden dark:block"
|
|
3178
3225
|
/>
|
|
3179
3226
|
\`\`\`
|
|
3180
3227
|
|
|
@@ -3211,6 +3258,98 @@ import Image from 'next/image';
|
|
|
3211
3258
|
};
|
|
3212
3259
|
}
|
|
3213
3260
|
}
|
|
3261
|
+
case "get_logo_base64": {
|
|
3262
|
+
const logoArgs = args;
|
|
3263
|
+
const logoPath = logoArgs.logo_path;
|
|
3264
|
+
const format = logoArgs.format || "dataUrl";
|
|
3265
|
+
if (!logoPath) {
|
|
3266
|
+
return {
|
|
3267
|
+
content: [{ type: "text", text: "Error: logo_path is required. Use list_logos to see available logos." }],
|
|
3268
|
+
isError: true,
|
|
3269
|
+
};
|
|
3270
|
+
}
|
|
3271
|
+
try {
|
|
3272
|
+
const resolvedPath = resolveLogoPath(logoPath);
|
|
3273
|
+
if (!resolvedPath) {
|
|
3274
|
+
return {
|
|
3275
|
+
content: [{ type: "text", text: `Error: Invalid logo path: ${logoPath}` }],
|
|
3276
|
+
isError: true,
|
|
3277
|
+
};
|
|
3278
|
+
}
|
|
3279
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
3280
|
+
return {
|
|
3281
|
+
content: [{ type: "text", text: `Error: Logo not found: ${logoPath}. Use list_logos to see available logos.` }],
|
|
3282
|
+
isError: true,
|
|
3283
|
+
};
|
|
3284
|
+
}
|
|
3285
|
+
// Read and encode the image
|
|
3286
|
+
const imageBuffer = fs.readFileSync(resolvedPath);
|
|
3287
|
+
const base64Data = imageBuffer.toString('base64');
|
|
3288
|
+
const mimeType = getImageMimeType(resolvedPath);
|
|
3289
|
+
const fileName = path.basename(resolvedPath);
|
|
3290
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
3291
|
+
// Determine brand for alt text
|
|
3292
|
+
const brandMatch = logoPath.match(/\/(sonance|iport|blaze|james|trufig)/i);
|
|
3293
|
+
const brandName = brandMatch ? brandMatch[1].charAt(0).toUpperCase() + brandMatch[1].slice(1) : "Brand";
|
|
3294
|
+
// Build response based on format
|
|
3295
|
+
let responseText = `## Logo for Artifacts: ${fileName}
|
|
3296
|
+
|
|
3297
|
+
> **CRITICAL:** Use ONLY this image data. NEVER draw, recreate, or approximate this logo with SVG, CSS, styled text, or any other method.
|
|
3298
|
+
|
|
3299
|
+
### Ready-to-Use Code (copy this directly)
|
|
3300
|
+
\`\`\`tsx
|
|
3301
|
+
<img
|
|
3302
|
+
src="${dataUrl}"
|
|
3303
|
+
alt="${brandName}"
|
|
3304
|
+
className="h-10 w-auto"
|
|
3305
|
+
/>
|
|
3306
|
+
\`\`\`
|
|
3307
|
+
`;
|
|
3308
|
+
if (format === "dataUrl" || format === "both") {
|
|
3309
|
+
responseText += `
|
|
3310
|
+
### Data URL (use in img src)
|
|
3311
|
+
\`\`\`
|
|
3312
|
+
${dataUrl}
|
|
3313
|
+
\`\`\`
|
|
3314
|
+
`;
|
|
3315
|
+
}
|
|
3316
|
+
if (format === "base64" || format === "both") {
|
|
3317
|
+
responseText += `
|
|
3318
|
+
### Raw Base64 Data
|
|
3319
|
+
\`\`\`
|
|
3320
|
+
${base64Data}
|
|
3321
|
+
\`\`\`
|
|
3322
|
+
|
|
3323
|
+
**MIME Type:** ${mimeType}
|
|
3324
|
+
`;
|
|
3325
|
+
}
|
|
3326
|
+
responseText += `
|
|
3327
|
+
---
|
|
3328
|
+
|
|
3329
|
+
**File:** ${fileName}
|
|
3330
|
+
**Size:** ${imageBuffer.length} bytes
|
|
3331
|
+
`;
|
|
3332
|
+
return {
|
|
3333
|
+
content: [
|
|
3334
|
+
{
|
|
3335
|
+
type: "image",
|
|
3336
|
+
data: base64Data,
|
|
3337
|
+
mimeType: mimeType,
|
|
3338
|
+
},
|
|
3339
|
+
{
|
|
3340
|
+
type: "text",
|
|
3341
|
+
text: responseText,
|
|
3342
|
+
},
|
|
3343
|
+
],
|
|
3344
|
+
};
|
|
3345
|
+
}
|
|
3346
|
+
catch (e) {
|
|
3347
|
+
return {
|
|
3348
|
+
content: [{ type: "text", text: `Error reading logo: ${e}` }],
|
|
3349
|
+
isError: true,
|
|
3350
|
+
};
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3214
3353
|
case "diagnose_logos": {
|
|
3215
3354
|
// Run validation and collect diagnostic info
|
|
3216
3355
|
const validation = validateLogoMap();
|
|
@@ -3994,6 +4133,28 @@ Now design the **${component_description}** following these tokens and principle
|
|
|
3994
4133
|
// Single-theme mode: embed the appropriate logo
|
|
3995
4134
|
await embedLogoWithFeedback(logoPath, `Brand Logo (${theme === "light" ? "for Light Backgrounds" : "for Dark Backgrounds"})`, contentBlocks);
|
|
3996
4135
|
}
|
|
4136
|
+
// Add critical logo usage warning
|
|
4137
|
+
contentBlocks.push({
|
|
4138
|
+
type: "text",
|
|
4139
|
+
text: `## Logo Usage Warning
|
|
4140
|
+
|
|
4141
|
+
> **CRITICAL:** The logo image(s) shown above are the ONLY acceptable representations.
|
|
4142
|
+
>
|
|
4143
|
+
> **NEVER:**
|
|
4144
|
+
> - Draw the logo with SVG paths or shapes
|
|
4145
|
+
> - Recreate it with styled text or colored letters
|
|
4146
|
+
> - Approximate it with CSS or Unicode characters
|
|
4147
|
+
>
|
|
4148
|
+
> **ALWAYS:**
|
|
4149
|
+
> - Use the embedded image directly in your artifact
|
|
4150
|
+
> - Or use \`get_logo_base64\` for a ready-to-use data URL
|
|
4151
|
+
> - If you cannot embed the image, use placeholder text: "[Logo: ${brand.charAt(0).toUpperCase() + brand.slice(1)}]"
|
|
4152
|
+
|
|
4153
|
+
To get the logo as a base64 data URL for artifacts, use:
|
|
4154
|
+
\`\`\`
|
|
4155
|
+
get_logo_base64({ logo_path: "${logoPath}" })
|
|
4156
|
+
\`\`\``,
|
|
4157
|
+
});
|
|
3997
4158
|
// Add the main response text
|
|
3998
4159
|
contentBlocks.push({ type: "text", text: response });
|
|
3999
4160
|
return {
|
|
@@ -5031,6 +5192,23 @@ ${palette.preferredTheme === "dark" ? `- **Note**: ${palette.name} prefers dark
|
|
|
5031
5192
|
type: "text",
|
|
5032
5193
|
text: `## Logo Usage\n\nTo add the logo to your document:\n1. Save the appropriate logo image above (right-click → Save as)\n2. Use the saved path in your code:\n\n**Word (python-docx):**\n\`\`\`python\ndoc.add_picture('logo_dark.png', width=Inches(2)) # For light backgrounds\n\`\`\`\n\n**PDF (ReportLab):**\n\`\`\`python\ncontent.append(Image('logo_dark.png', width=2*inch, height=0.5*inch))\n\`\`\`\n`,
|
|
5033
5194
|
});
|
|
5195
|
+
// Add critical logo usage warning
|
|
5196
|
+
templateContentBlocks.push({
|
|
5197
|
+
type: "text",
|
|
5198
|
+
text: `## Logo Warning
|
|
5199
|
+
|
|
5200
|
+
> **CRITICAL:** Use ONLY the actual logo image files shown above.
|
|
5201
|
+
>
|
|
5202
|
+
> **NEVER:**
|
|
5203
|
+
> - Draw the logo with shapes or vector tools in your document
|
|
5204
|
+
> - Recreate it with styled text or colored letters
|
|
5205
|
+
> - Use any visual approximation or placeholder
|
|
5206
|
+
>
|
|
5207
|
+
> **ALWAYS:**
|
|
5208
|
+
> - Save and embed the actual PNG image file
|
|
5209
|
+
> - Use the code snippets above that reference the saved image file
|
|
5210
|
+
> - The logo images are embedded above - save them directly`,
|
|
5211
|
+
});
|
|
5034
5212
|
// Add the main template text
|
|
5035
5213
|
templateContentBlocks.push({ type: "text", text: template });
|
|
5036
5214
|
return {
|
|
@@ -5322,6 +5500,23 @@ ${rebrandArgs.source_format === "word" ? `
|
|
|
5322
5500
|
text: `> **Logo Note:** Brand logos could not be embedded automatically. Download the appropriate ${palette.name} logo from your brand assets folder or use the \`get_logo\` tool.`,
|
|
5323
5501
|
});
|
|
5324
5502
|
}
|
|
5503
|
+
// Add critical logo usage warning
|
|
5504
|
+
rebrandContentBlocks.push({
|
|
5505
|
+
type: "text",
|
|
5506
|
+
text: `## Logo Usage Warning
|
|
5507
|
+
|
|
5508
|
+
> **CRITICAL:** When adding the logo to your document, use the ACTUAL image files shown above.
|
|
5509
|
+
>
|
|
5510
|
+
> **NEVER:**
|
|
5511
|
+
> - Draw the logo with shapes or vector tools
|
|
5512
|
+
> - Recreate it with styled text or colored letters
|
|
5513
|
+
> - Use any visual approximation
|
|
5514
|
+
>
|
|
5515
|
+
> **ALWAYS:**
|
|
5516
|
+
> - Download and embed the actual logo image
|
|
5517
|
+
> - Or use \`get_logo_base64\` for a data URL for web/HTML
|
|
5518
|
+
> - For Word/PDF: Save the image above and use it directly`,
|
|
5519
|
+
});
|
|
5325
5520
|
// Add the main guide text
|
|
5326
5521
|
rebrandContentBlocks.push({ type: "text", text: rebrandGuide });
|
|
5327
5522
|
return {
|
|
@@ -6057,6 +6252,37 @@ ${formatCodeBlock(content, { language: "tsx", filename: `components/ui/${compNam
|
|
|
6057
6252
|
content: contentBlocks,
|
|
6058
6253
|
};
|
|
6059
6254
|
}
|
|
6255
|
+
case "get_version": {
|
|
6256
|
+
// Read version from package.json
|
|
6257
|
+
const packageJsonPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
6258
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
6259
|
+
const versionInfo = {
|
|
6260
|
+
name: "sonance-brand-mcp",
|
|
6261
|
+
version: packageJson.version,
|
|
6262
|
+
lastUpdated: new Date().toISOString().split("T")[0],
|
|
6263
|
+
features: [
|
|
6264
|
+
"brand guidelines",
|
|
6265
|
+
"logo management",
|
|
6266
|
+
"component library",
|
|
6267
|
+
"document templates",
|
|
6268
|
+
"design evaluation",
|
|
6269
|
+
"app design/redesign"
|
|
6270
|
+
]
|
|
6271
|
+
};
|
|
6272
|
+
return {
|
|
6273
|
+
content: [{
|
|
6274
|
+
type: "text",
|
|
6275
|
+
text: `# Sonance Brand MCP
|
|
6276
|
+
|
|
6277
|
+
**Version:** ${versionInfo.version}
|
|
6278
|
+
**Name:** ${versionInfo.name}
|
|
6279
|
+
|
|
6280
|
+
## Features
|
|
6281
|
+
${versionInfo.features.map(f => `- ${f}`).join("\n")}
|
|
6282
|
+
`
|
|
6283
|
+
}],
|
|
6284
|
+
};
|
|
6285
|
+
}
|
|
6060
6286
|
default:
|
|
6061
6287
|
return {
|
|
6062
6288
|
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sonance-brand-mcp",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.119",
|
|
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",
|