@forgespace/branding-mcp 0.6.2 → 0.7.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.
- package/README.md +41 -5
- package/dist/index.js +1 -1
- package/package.json +27 -9
- package/server.json +29 -0
- package/.env.example +0 -3
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -22
- package/.github/workflows/ci.yml +0 -73
- package/.github/workflows/release-automation.yml +0 -56
- package/.github/workflows/security-scan.yml +0 -37
- package/.gitleaks.toml +0 -14
- package/.prettierrc.json +0 -10
- package/CHANGELOG.md +0 -92
- package/CONTRIBUTING.md +0 -203
- package/data/README.md +0 -13
- package/docs/API.md +0 -110
- package/docs/DATA_SOURCES.md +0 -69
- package/docs/INTEGRATION.md +0 -58
- package/eslint.config.js +0 -52
- package/jest.config.js +0 -40
- package/src/__tests__/integration/brand-generation.test.ts +0 -84
- package/src/__tests__/integration/mcp-server.test.ts +0 -18
- package/src/__tests__/unit/ai-interpreter.test.ts +0 -172
- package/src/__tests__/unit/border-system.test.ts +0 -77
- package/src/__tests__/unit/color-palette.test.ts +0 -161
- package/src/__tests__/unit/contrast-checker.test.ts +0 -124
- package/src/__tests__/unit/design-system-tool.test.ts +0 -176
- package/src/__tests__/unit/design-tokens.test.ts +0 -184
- package/src/__tests__/unit/favicon-generator.test.ts +0 -80
- package/src/__tests__/unit/gradient-system.test.ts +0 -122
- package/src/__tests__/unit/logo-generator.test.ts +0 -146
- package/src/__tests__/unit/motion-system.test.ts +0 -91
- package/src/__tests__/unit/og-image-generator.test.ts +0 -115
- package/src/__tests__/unit/shadow-system.test.ts +0 -63
- package/src/__tests__/unit/spacing-scale.test.ts +0 -60
- package/src/__tests__/unit/typography-system.test.ts +0 -71
- package/src/index.ts +0 -76
- package/src/lib/branding-core/ai/brand-interpreter.ts +0 -30
- package/src/lib/branding-core/ai/claude-interpreter.ts +0 -76
- package/src/lib/branding-core/ai/intent-applier.ts +0 -59
- package/src/lib/branding-core/ai/keyword-interpreter.ts +0 -95
- package/src/lib/branding-core/ai/prompts.ts +0 -93
- package/src/lib/branding-core/ai/types.ts +0 -36
- package/src/lib/branding-core/documents/html-generator.ts +0 -32
- package/src/lib/branding-core/documents/pdf-generator.ts +0 -21
- package/src/lib/branding-core/exporters/css-variables.ts +0 -71
- package/src/lib/branding-core/exporters/design-tokens.ts +0 -86
- package/src/lib/branding-core/exporters/figma-tokens.ts +0 -87
- package/src/lib/branding-core/exporters/react-theme.ts +0 -69
- package/src/lib/branding-core/exporters/sass-variables.ts +0 -74
- package/src/lib/branding-core/exporters/tailwind-preset.ts +0 -67
- package/src/lib/branding-core/generators/border-system.ts +0 -41
- package/src/lib/branding-core/generators/color-palette.ts +0 -147
- package/src/lib/branding-core/generators/favicon-generator.ts +0 -33
- package/src/lib/branding-core/generators/gradient-system.ts +0 -120
- package/src/lib/branding-core/generators/logo-generator.ts +0 -152
- package/src/lib/branding-core/generators/motion-system.ts +0 -98
- package/src/lib/branding-core/generators/og-image-generator.ts +0 -97
- package/src/lib/branding-core/generators/shadow-system.ts +0 -66
- package/src/lib/branding-core/generators/spacing-scale.ts +0 -29
- package/src/lib/branding-core/generators/typography-system.ts +0 -128
- package/src/lib/branding-core/index.ts +0 -28
- package/src/lib/branding-core/validators/brand-consistency.ts +0 -79
- package/src/lib/branding-core/validators/contrast-checker.ts +0 -37
- package/src/lib/branding-core/validators/token-schema.ts +0 -50
- package/src/lib/config.ts +0 -13
- package/src/lib/logger.ts +0 -12
- package/src/lib/types.ts +0 -236
- package/src/resources/brand-knowledge.ts +0 -60
- package/src/resources/brand-templates.ts +0 -385
- package/src/tools/create-brand-guidelines.ts +0 -94
- package/src/tools/export-design-tokens.ts +0 -52
- package/src/tools/generate-brand-assets.ts +0 -48
- package/src/tools/generate-brand-identity.ts +0 -115
- package/src/tools/generate-color-palette.ts +0 -43
- package/src/tools/generate-design-system.ts +0 -163
- package/src/tools/generate-typography-system.ts +0 -42
- package/src/tools/refine-brand-element.ts +0 -65
- package/src/tools/validate-brand-consistency.ts +0 -32
- package/tsconfig.json +0 -21
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import {
|
|
4
|
-
generateColorPalette,
|
|
5
|
-
generateTypographySystem,
|
|
6
|
-
generateSpacingScale,
|
|
7
|
-
generateShadowSystem,
|
|
8
|
-
generateBorderSystem,
|
|
9
|
-
generateMotionSystem,
|
|
10
|
-
generateGradientSystem,
|
|
11
|
-
generateSvgLogo,
|
|
12
|
-
defaultLogoConfig,
|
|
13
|
-
} from '../lib/branding-core/index.js';
|
|
14
|
-
import {
|
|
15
|
-
brandStyleSchema,
|
|
16
|
-
colorHarmonySchema,
|
|
17
|
-
colorThemeSchema,
|
|
18
|
-
fontCategorySchema,
|
|
19
|
-
hexColorSchema,
|
|
20
|
-
typeScaleRatioSchema,
|
|
21
|
-
} from '../lib/branding-core/validators/token-schema.js';
|
|
22
|
-
import type { BrandIdentity, BrandStyle, FontCategory } from '../lib/types.js';
|
|
23
|
-
import { logger } from '../lib/logger.js';
|
|
24
|
-
|
|
25
|
-
const STYLE_DEFAULTS: Record<BrandStyle, { heading: FontCategory; body: FontCategory }> = {
|
|
26
|
-
minimal: { heading: 'sans-serif', body: 'sans-serif' },
|
|
27
|
-
bold: { heading: 'display', body: 'sans-serif' },
|
|
28
|
-
elegant: { heading: 'serif', body: 'serif' },
|
|
29
|
-
playful: { heading: 'display', body: 'sans-serif' },
|
|
30
|
-
corporate: { heading: 'sans-serif', body: 'sans-serif' },
|
|
31
|
-
tech: { heading: 'sans-serif', body: 'monospace' },
|
|
32
|
-
organic: { heading: 'serif', body: 'sans-serif' },
|
|
33
|
-
retro: { heading: 'display', body: 'serif' },
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export function registerGenerateBrandIdentity(server: McpServer): void {
|
|
37
|
-
server.tool(
|
|
38
|
-
'generate_brand_identity',
|
|
39
|
-
'Generate a complete brand identity including colors, typography, spacing, and logo. Provide a brand name and style preferences to get a cohesive identity system.',
|
|
40
|
-
{
|
|
41
|
-
brandName: z.string().min(1).max(100).describe('Brand name'),
|
|
42
|
-
industry: z.string().min(1).max(100).describe('Industry or sector (e.g. "tech", "health")'),
|
|
43
|
-
style: brandStyleSchema.describe('Visual style direction'),
|
|
44
|
-
tagline: z.string().max(200).optional().describe('Brand tagline'),
|
|
45
|
-
baseColor: hexColorSchema.optional().describe('Base color preference'),
|
|
46
|
-
harmony: colorHarmonySchema.optional().describe('Color harmony type'),
|
|
47
|
-
theme: colorThemeSchema.optional().describe('Light/dark/both'),
|
|
48
|
-
headingCategory: fontCategorySchema.optional().describe('Heading font category'),
|
|
49
|
-
bodyCategory: fontCategorySchema.optional().describe('Body font category'),
|
|
50
|
-
scaleRatio: typeScaleRatioSchema.optional().describe('Typography scale ratio'),
|
|
51
|
-
},
|
|
52
|
-
async ({
|
|
53
|
-
brandName,
|
|
54
|
-
industry,
|
|
55
|
-
style,
|
|
56
|
-
tagline,
|
|
57
|
-
baseColor,
|
|
58
|
-
harmony,
|
|
59
|
-
theme,
|
|
60
|
-
headingCategory,
|
|
61
|
-
bodyCategory,
|
|
62
|
-
scaleRatio,
|
|
63
|
-
}) => {
|
|
64
|
-
try {
|
|
65
|
-
logger.info({ brandName, industry, style }, 'Generating brand identity');
|
|
66
|
-
|
|
67
|
-
const defaults = STYLE_DEFAULTS[style];
|
|
68
|
-
const colors = generateColorPalette(baseColor, harmony ?? 'complementary', theme);
|
|
69
|
-
const typography = generateTypographySystem(
|
|
70
|
-
headingCategory ?? defaults.heading,
|
|
71
|
-
bodyCategory ?? defaults.body,
|
|
72
|
-
scaleRatio ?? 'major-third'
|
|
73
|
-
);
|
|
74
|
-
const spacing = generateSpacingScale();
|
|
75
|
-
const shadows = generateShadowSystem(colors.primary.hex, theme);
|
|
76
|
-
const borders = generateBorderSystem(style);
|
|
77
|
-
const motion = generateMotionSystem(style);
|
|
78
|
-
const gradients = generateGradientSystem(colors, style);
|
|
79
|
-
const logoConfig = {
|
|
80
|
-
...defaultLogoConfig(brandName, colors.primary.hex),
|
|
81
|
-
font: typography.headingFont,
|
|
82
|
-
style,
|
|
83
|
-
};
|
|
84
|
-
const logo = generateSvgLogo(logoConfig);
|
|
85
|
-
|
|
86
|
-
const identity: BrandIdentity = {
|
|
87
|
-
id: `brand_${Date.now().toString(36)}`,
|
|
88
|
-
name: brandName,
|
|
89
|
-
tagline,
|
|
90
|
-
industry,
|
|
91
|
-
style,
|
|
92
|
-
colors,
|
|
93
|
-
typography,
|
|
94
|
-
spacing,
|
|
95
|
-
shadows,
|
|
96
|
-
borders,
|
|
97
|
-
motion,
|
|
98
|
-
gradients,
|
|
99
|
-
logo,
|
|
100
|
-
createdAt: new Date().toISOString(),
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
content: [{ type: 'text', text: JSON.stringify(identity, null, 2) }],
|
|
105
|
-
};
|
|
106
|
-
} catch (error) {
|
|
107
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
108
|
-
return {
|
|
109
|
-
content: [{ type: 'text', text: `Error generating brand: ${message}` }],
|
|
110
|
-
isError: true,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
);
|
|
115
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { generateColorPalette } from '../lib/branding-core/index.js';
|
|
3
|
-
import {
|
|
4
|
-
colorHarmonySchema,
|
|
5
|
-
colorThemeSchema,
|
|
6
|
-
hexColorSchema,
|
|
7
|
-
} from '../lib/branding-core/validators/token-schema.js';
|
|
8
|
-
import { logger } from '../lib/logger.js';
|
|
9
|
-
|
|
10
|
-
export function registerGenerateColorPalette(server: McpServer): void {
|
|
11
|
-
server.tool(
|
|
12
|
-
'generate_color_palette',
|
|
13
|
-
'Generate a harmonious color palette with WCAG contrast validation. Supports complementary, analogous, triadic, split-complementary, tetradic, and monochromatic harmonies.',
|
|
14
|
-
{
|
|
15
|
-
baseColor: hexColorSchema
|
|
16
|
-
.optional()
|
|
17
|
-
.describe('Base hex color to build palette from (e.g. #6B4CE6)'),
|
|
18
|
-
harmony: colorHarmonySchema.optional().describe('Color harmony type'),
|
|
19
|
-
theme: colorThemeSchema.optional().describe('Light, dark, or both neutral scales'),
|
|
20
|
-
},
|
|
21
|
-
async ({ baseColor, harmony, theme }) => {
|
|
22
|
-
try {
|
|
23
|
-
logger.info({ baseColor, harmony, theme }, 'Generating color palette');
|
|
24
|
-
const palette = generateColorPalette(baseColor, harmony, theme);
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
content: [
|
|
28
|
-
{
|
|
29
|
-
type: 'text',
|
|
30
|
-
text: JSON.stringify(palette, null, 2),
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
};
|
|
34
|
-
} catch (error) {
|
|
35
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
-
return {
|
|
37
|
-
content: [{ type: 'text', text: `Error generating palette: ${message}` }],
|
|
38
|
-
isError: true,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
);
|
|
43
|
-
}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
|
-
import {
|
|
5
|
-
generateColorPalette,
|
|
6
|
-
generateTypographySystem,
|
|
7
|
-
generateSpacingScale,
|
|
8
|
-
generateShadowSystem,
|
|
9
|
-
generateBorderSystem,
|
|
10
|
-
generateMotionSystem,
|
|
11
|
-
generateGradientSystem,
|
|
12
|
-
generateSvgLogo,
|
|
13
|
-
defaultLogoConfig,
|
|
14
|
-
exportDesignTokens,
|
|
15
|
-
exportCssVariables,
|
|
16
|
-
exportTailwindPreset,
|
|
17
|
-
exportFigmaTokens,
|
|
18
|
-
exportReactTheme,
|
|
19
|
-
exportSassVariables,
|
|
20
|
-
} from '../lib/branding-core/index.js';
|
|
21
|
-
import {
|
|
22
|
-
brandStyleSchema,
|
|
23
|
-
colorHarmonySchema,
|
|
24
|
-
colorThemeSchema,
|
|
25
|
-
exportFormatSchema,
|
|
26
|
-
fontCategorySchema,
|
|
27
|
-
hexColorSchema,
|
|
28
|
-
typeScaleRatioSchema,
|
|
29
|
-
} from '../lib/branding-core/validators/token-schema.js';
|
|
30
|
-
import type { BrandIdentity, BrandStyle, ExportFormat, FontCategory } from '../lib/types.js';
|
|
31
|
-
import { logger } from '../lib/logger.js';
|
|
32
|
-
|
|
33
|
-
const STYLE_DEFAULTS: Record<BrandStyle, { heading: FontCategory; body: FontCategory }> = {
|
|
34
|
-
minimal: { heading: 'sans-serif', body: 'sans-serif' },
|
|
35
|
-
bold: { heading: 'display', body: 'sans-serif' },
|
|
36
|
-
elegant: { heading: 'serif', body: 'serif' },
|
|
37
|
-
playful: { heading: 'display', body: 'sans-serif' },
|
|
38
|
-
corporate: { heading: 'sans-serif', body: 'sans-serif' },
|
|
39
|
-
tech: { heading: 'sans-serif', body: 'monospace' },
|
|
40
|
-
organic: { heading: 'serif', body: 'sans-serif' },
|
|
41
|
-
retro: { heading: 'display', body: 'serif' },
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const EXPORTERS: Record<ExportFormat, (brand: BrandIdentity) => string | object> = {
|
|
45
|
-
json: exportDesignTokens,
|
|
46
|
-
css: exportCssVariables,
|
|
47
|
-
tailwind: exportTailwindPreset,
|
|
48
|
-
figma: exportFigmaTokens,
|
|
49
|
-
react: exportReactTheme,
|
|
50
|
-
sass: exportSassVariables,
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
function buildIdentity(params: {
|
|
54
|
-
brandName: string;
|
|
55
|
-
industry: string;
|
|
56
|
-
style: BrandStyle;
|
|
57
|
-
tagline?: string;
|
|
58
|
-
baseColor?: string;
|
|
59
|
-
harmony?: string;
|
|
60
|
-
theme?: string;
|
|
61
|
-
headingCategory?: FontCategory;
|
|
62
|
-
bodyCategory?: FontCategory;
|
|
63
|
-
scaleRatio?: string;
|
|
64
|
-
}): BrandIdentity {
|
|
65
|
-
const defaults = STYLE_DEFAULTS[params.style];
|
|
66
|
-
const harmony = (params.harmony ?? 'complementary') as Parameters<typeof generateColorPalette>[1];
|
|
67
|
-
const theme = params.theme as Parameters<typeof generateColorPalette>[2];
|
|
68
|
-
const scaleRatio = (params.scaleRatio ?? 'major-third') as Parameters<
|
|
69
|
-
typeof generateTypographySystem
|
|
70
|
-
>[2];
|
|
71
|
-
|
|
72
|
-
const colors = generateColorPalette(params.baseColor, harmony, theme);
|
|
73
|
-
const typography = generateTypographySystem(
|
|
74
|
-
params.headingCategory ?? defaults.heading,
|
|
75
|
-
params.bodyCategory ?? defaults.body,
|
|
76
|
-
scaleRatio
|
|
77
|
-
);
|
|
78
|
-
const spacing = generateSpacingScale();
|
|
79
|
-
const shadows = generateShadowSystem(colors.primary.hex, theme);
|
|
80
|
-
const borders = generateBorderSystem(params.style);
|
|
81
|
-
const motion = generateMotionSystem(params.style);
|
|
82
|
-
const gradients = generateGradientSystem(colors, params.style);
|
|
83
|
-
const logoConfig = {
|
|
84
|
-
...defaultLogoConfig(params.brandName, colors.primary.hex),
|
|
85
|
-
font: typography.headingFont,
|
|
86
|
-
style: params.style,
|
|
87
|
-
};
|
|
88
|
-
const logo = generateSvgLogo(logoConfig);
|
|
89
|
-
|
|
90
|
-
return {
|
|
91
|
-
id: `brand_${randomUUID().slice(0, 8)}`,
|
|
92
|
-
name: params.brandName,
|
|
93
|
-
tagline: params.tagline,
|
|
94
|
-
industry: params.industry,
|
|
95
|
-
style: params.style,
|
|
96
|
-
colors,
|
|
97
|
-
typography,
|
|
98
|
-
spacing,
|
|
99
|
-
shadows,
|
|
100
|
-
borders,
|
|
101
|
-
motion,
|
|
102
|
-
gradients,
|
|
103
|
-
logo,
|
|
104
|
-
createdAt: new Date().toISOString(),
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export function registerGenerateDesignSystem(server: McpServer): void {
|
|
109
|
-
server.tool(
|
|
110
|
-
'generate_design_system',
|
|
111
|
-
'Generate a complete design system with brand identity and exported tokens in one call. ' +
|
|
112
|
-
'Combines generate_brand_identity + export_design_tokens for a streamlined workflow.',
|
|
113
|
-
{
|
|
114
|
-
brandName: z.string().min(1).max(100).describe('Brand name'),
|
|
115
|
-
industry: z.string().min(1).max(100).describe('Industry or sector'),
|
|
116
|
-
style: brandStyleSchema.describe('Visual style direction'),
|
|
117
|
-
tagline: z.string().max(200).optional().describe('Brand tagline'),
|
|
118
|
-
baseColor: hexColorSchema.optional().describe('Base color preference'),
|
|
119
|
-
harmony: colorHarmonySchema.optional().describe('Color harmony type'),
|
|
120
|
-
theme: colorThemeSchema.optional().describe('Light/dark/both'),
|
|
121
|
-
headingCategory: fontCategorySchema.optional().describe('Heading font category'),
|
|
122
|
-
bodyCategory: fontCategorySchema.optional().describe('Body font category'),
|
|
123
|
-
scaleRatio: typeScaleRatioSchema.optional().describe('Typography scale ratio'),
|
|
124
|
-
exportFormats: z
|
|
125
|
-
.array(exportFormatSchema)
|
|
126
|
-
.min(1)
|
|
127
|
-
.max(6)
|
|
128
|
-
.describe('Token export formats to include'),
|
|
129
|
-
},
|
|
130
|
-
async (params) => {
|
|
131
|
-
try {
|
|
132
|
-
logger.info(
|
|
133
|
-
{ brandName: params.brandName, formats: params.exportFormats },
|
|
134
|
-
'Generating design system'
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
const identity = buildIdentity(params);
|
|
138
|
-
const exports: Record<string, string> = {};
|
|
139
|
-
|
|
140
|
-
for (const format of params.exportFormats) {
|
|
141
|
-
const exporter = EXPORTERS[format];
|
|
142
|
-
const result = exporter(identity);
|
|
143
|
-
exports[format] = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const output = {
|
|
147
|
-
identity,
|
|
148
|
-
exports,
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
return {
|
|
152
|
-
content: [{ type: 'text' as const, text: JSON.stringify(output, null, 2) }],
|
|
153
|
-
};
|
|
154
|
-
} catch (error) {
|
|
155
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
156
|
-
return {
|
|
157
|
-
content: [{ type: 'text' as const, text: `Error generating design system: ${message}` }],
|
|
158
|
-
isError: true,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
);
|
|
163
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import { generateTypographySystem } from '../lib/branding-core/index.js';
|
|
4
|
-
import {
|
|
5
|
-
fontCategorySchema,
|
|
6
|
-
typeScaleRatioSchema,
|
|
7
|
-
} from '../lib/branding-core/validators/token-schema.js';
|
|
8
|
-
import { logger } from '../lib/logger.js';
|
|
9
|
-
|
|
10
|
-
export function registerGenerateTypographySystem(server: McpServer): void {
|
|
11
|
-
server.tool(
|
|
12
|
-
'generate_typography_system',
|
|
13
|
-
'Generate a typography system with font pairing, modular type scale, and line heights. Uses curated font pairings for visual harmony.',
|
|
14
|
-
{
|
|
15
|
-
headingCategory: fontCategorySchema.optional().describe('Font category for headings'),
|
|
16
|
-
bodyCategory: fontCategorySchema.optional().describe('Font category for body text'),
|
|
17
|
-
scaleRatio: typeScaleRatioSchema.optional().describe('Modular scale ratio'),
|
|
18
|
-
baseSize: z.number().min(12).max(24).optional().describe('Base font size in pixels'),
|
|
19
|
-
},
|
|
20
|
-
async ({ headingCategory, bodyCategory, scaleRatio, baseSize }) => {
|
|
21
|
-
try {
|
|
22
|
-
logger.info({ headingCategory, bodyCategory, scaleRatio }, 'Generating typography system');
|
|
23
|
-
const system = generateTypographySystem(
|
|
24
|
-
headingCategory,
|
|
25
|
-
bodyCategory,
|
|
26
|
-
scaleRatio,
|
|
27
|
-
baseSize
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
content: [{ type: 'text', text: JSON.stringify(system, null, 2) }],
|
|
32
|
-
};
|
|
33
|
-
} catch (error) {
|
|
34
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
35
|
-
return {
|
|
36
|
-
content: [{ type: 'text', text: `Error generating typography: ${message}` }],
|
|
37
|
-
isError: true,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
);
|
|
42
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import { interpretFeedback, applyIntent } from '../lib/branding-core/index.js';
|
|
4
|
-
import type { BrandIdentity } from '../lib/types.js';
|
|
5
|
-
import type { InterpreterStrategy } from '../lib/branding-core/index.js';
|
|
6
|
-
import { loadConfig } from '../lib/config.js';
|
|
7
|
-
import { logger } from '../lib/logger.js';
|
|
8
|
-
|
|
9
|
-
export function registerRefineBrandElement(server: McpServer): void {
|
|
10
|
-
server.tool(
|
|
11
|
-
'refine_brand_element',
|
|
12
|
-
'Refine a specific element of an existing brand identity using natural language feedback. Uses AI interpretation when available, keyword matching as fallback.',
|
|
13
|
-
{
|
|
14
|
-
brand: z.string().describe('Full BrandIdentity JSON'),
|
|
15
|
-
element: z.enum(['colors', 'typography', 'spacing']).describe('Element to refine'),
|
|
16
|
-
feedback: z
|
|
17
|
-
.string()
|
|
18
|
-
.describe(
|
|
19
|
-
'Natural language feedback (e.g. "make it feel more premium and understated", "use serif headings with dramatic scale")'
|
|
20
|
-
),
|
|
21
|
-
strategy: z
|
|
22
|
-
.enum(['keyword', 'ai', 'auto'])
|
|
23
|
-
.optional()
|
|
24
|
-
.describe(
|
|
25
|
-
'Interpretation strategy: keyword (fast), ai (Claude API), auto (ai if key available)'
|
|
26
|
-
),
|
|
27
|
-
},
|
|
28
|
-
async ({ brand, element, feedback, strategy }) => {
|
|
29
|
-
try {
|
|
30
|
-
logger.info({ element, feedback, strategy }, 'Refining brand element');
|
|
31
|
-
const brandData: BrandIdentity = JSON.parse(brand);
|
|
32
|
-
const config = loadConfig();
|
|
33
|
-
|
|
34
|
-
const intent = await interpretFeedback(
|
|
35
|
-
feedback,
|
|
36
|
-
element,
|
|
37
|
-
brandData,
|
|
38
|
-
(strategy as InterpreterStrategy) ?? 'auto',
|
|
39
|
-
{ anthropicApiKey: config.anthropicApiKey }
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
const refined = applyIntent(brandData, intent);
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
content: [
|
|
46
|
-
{
|
|
47
|
-
type: 'text',
|
|
48
|
-
text: JSON.stringify(
|
|
49
|
-
{ ...refined, _interpretation: { strategy: strategy ?? 'auto', ...intent } },
|
|
50
|
-
null,
|
|
51
|
-
2
|
|
52
|
-
),
|
|
53
|
-
},
|
|
54
|
-
],
|
|
55
|
-
};
|
|
56
|
-
} catch (error) {
|
|
57
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
58
|
-
return {
|
|
59
|
-
content: [{ type: 'text', text: `Error refining element: ${message}` }],
|
|
60
|
-
isError: true,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
);
|
|
65
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import { validateBrandConsistency } from '../lib/branding-core/index.js';
|
|
4
|
-
import type { BrandIdentity } from '../lib/types.js';
|
|
5
|
-
import { logger } from '../lib/logger.js';
|
|
6
|
-
|
|
7
|
-
export function registerValidateBrandConsistency(server: McpServer): void {
|
|
8
|
-
server.tool(
|
|
9
|
-
'validate_brand_consistency',
|
|
10
|
-
'Validate a brand identity for completeness, WCAG contrast compliance, and typography best practices. Returns a score (0-100) and actionable issues.',
|
|
11
|
-
{
|
|
12
|
-
brand: z.string().describe('Full BrandIdentity JSON to validate'),
|
|
13
|
-
},
|
|
14
|
-
async ({ brand }) => {
|
|
15
|
-
try {
|
|
16
|
-
logger.info('Validating brand consistency');
|
|
17
|
-
const brandData: BrandIdentity = JSON.parse(brand);
|
|
18
|
-
const result = validateBrandConsistency(brandData);
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
22
|
-
};
|
|
23
|
-
} catch (error) {
|
|
24
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
25
|
-
return {
|
|
26
|
-
content: [{ type: 'text', text: `Error validating brand: ${message}` }],
|
|
27
|
-
isError: true,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
);
|
|
32
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"lib": ["ES2022"],
|
|
5
|
-
"module": "NodeNext",
|
|
6
|
-
"moduleResolution": "NodeNext",
|
|
7
|
-
"strict": true,
|
|
8
|
-
"declaration": true,
|
|
9
|
-
"declarationMap": true,
|
|
10
|
-
"sourceMap": true,
|
|
11
|
-
"outDir": "./dist",
|
|
12
|
-
"rootDir": "./src",
|
|
13
|
-
"esModuleInterop": true,
|
|
14
|
-
"forceConsistentCasingInFileNames": true,
|
|
15
|
-
"skipLibCheck": true,
|
|
16
|
-
"resolveJsonModule": true,
|
|
17
|
-
"isolatedModules": true
|
|
18
|
-
},
|
|
19
|
-
"include": ["src/**/*.ts"],
|
|
20
|
-
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
21
|
-
}
|