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.
Files changed (2) hide show
  1. package/dist/index.js +238 -12
  2. 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
- ### Implementation (Next.js with next/image)
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 // Add if logo is above the fold
3203
+ priority
3154
3204
  />
3155
3205
  \`\`\`
3156
3206
 
3157
- ### Implementation (React/HTML)
3158
- \`\`\`tsx
3159
- <img
3160
- src="${normalizedPath}"
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" {/* Light mode */}
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" {/* Dark mode */}
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.117",
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",