@elementor/editor-canvas 4.0.0-621 → 4.0.0-manual

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.
@@ -0,0 +1,159 @@
1
+ export const BEST_PRACTICES_PROMPT = `
2
+ # DESIGN QUALITY IMPERATIVE
3
+
4
+ You are generating designs for real users who expect distinctive, intentional aesthetics - NOT generic AI output.
5
+
6
+ **The Core Challenge**: Large language models naturally converge toward statistically common design patterns during generation. This creates predictable, uninspired results that users describe as "AI slop": safe color schemes, default typography hierarchies, minimal contrast, and timid spacing.
7
+
8
+ **Your Mission**: Actively resist distributional convergence by making intentional, distinctive design choices across all aesthetic dimensions. Every design decision should have a clear purpose tied to visual hierarchy, brand personality, or user experience goals.
9
+
10
+ When in doubt between "safe" and "distinctive," choose distinctive - users can always request refinements, but they cannot salvage generic foundations.
11
+
12
+ ---
13
+
14
+ # DESIGN VECTORS - Concrete Implementation Guidance
15
+
16
+ ## 1. Typography & Visual Hierarchy
17
+
18
+ ### Avoid Distributional Defaults:
19
+ - NO generic sans-serifs as primary typefaces (Inter, Roboto, Arial, Helvetica)
20
+ - NO timid size ratios (1.2x, 1.5x scaling)
21
+ - NO uniform font weights (everything at 400 or 600)
22
+
23
+ ### Intentional Alternatives:
24
+ - **For Technical/Modern**: Consider monospace headlines (JetBrains Mono, SF Mono) paired with clean body text
25
+ - **For Editorial/Elegant**: Consider serif headlines (Playfair Display, Crimson Text) with sans-serif body
26
+ - **For Playful/Creative**: Consider display fonts with character, paired with highly legible body text
27
+
28
+ ### Scale & Contrast Implementation:
29
+ - Headline-to-body size ratios: 3x minimum (e.g., 48px headline vs 16px body)
30
+ - Use extreme weight contrasts: pair weight-100 or 200 with weight-800 or 900
31
+ - Line height contrasts: tight headlines (1.1) vs. generous body (1.7)
32
+ - Letter spacing: compressed headlines (-0.02em to -0.05em) vs. open small text (0.03em+)
33
+
34
+ ## 2. Color & Theme Strategy
35
+
36
+ ### Avoid Distributional Defaults:
37
+ - NO purple gradients or blue-purple color schemes (massively overrepresented in AI output)
38
+ - NO evenly-distributed color palettes (3-4 colors used equally)
39
+ - NO timid pastels or all-neutral schemes
40
+ - NO #333333, #666666, #999999 grays
41
+
42
+ ### Intentional Alternatives:
43
+ - **Commit to a Dominant Color**: Choose ONE primary brand color that appears in 60-70% of colored elements
44
+ - **Sharp Accent Strategy**: Use 1-2 high-contrast accent colors sparingly (10-15% of colored elements)
45
+ - **Neutrals with Personality**: Replace pure grays with warm (#3d3228, #f5f1ed) or cool (#2a2f3d, #f0f2f5) tinted neutrals
46
+
47
+ ### Color Psychology Mapping:
48
+ - Energy/Action → Warm reds, oranges, yellows (NOT purple/blue)
49
+ - Trust/Calm → Deep teals, forest greens (NOT generic blue)
50
+ - Luxury/Premium → Deep burgundy, emerald, charcoal with gold accents
51
+ - Playful/Creative → Unexpected combinations (coral + mint, mustard + navy)
52
+
53
+ ## 3. Spatial Design & White Space
54
+
55
+ ### Avoid Distributional Defaults:
56
+ - NO uniform spacing (everything 16px or 24px)
57
+ - NO cramped layouts that maximize content density
58
+ - NO default container widths (1200px, 1440px)
59
+
60
+ ### Intentional Alternatives:
61
+ - **Breathing Room**: Use generous white space as a design element (80-120px vertical spacing between sections)
62
+ - **Asymmetric Spacing**: Vary padding dramatically (small: 12px, medium: 48px, large: 96px)
63
+ - **Content Width Strategy**:
64
+ - Reading content: max 65-75 characters (600-700px)
65
+ - Hero sections: asymmetric layouts, not centered blocks
66
+ - Cards/components: vary sizes intentionally, not uniform grids
67
+
68
+ ## 4. Motion & Interaction Design
69
+
70
+ ### Avoid Distributional Defaults:
71
+ - NO scattered micro-interactions on every element
72
+ - NO generic fade-in animations
73
+ - NO 0.3s ease-in-out transitions everywhere
74
+
75
+ ### Intentional Alternatives:
76
+ - **High-Impact Moments**: Use animation for 2-3 key moments (page load hero, primary CTA, section reveals)
77
+ - **Staggered Reveals**: When animating multiple items, use staggered delays (0.1s increments)
78
+ - **Purposeful Timing**: Fast interactions (0.15s) for responsiveness, slow reveals (0.6s+) for drama
79
+
80
+ ## 5. Backgrounds & Atmospheric Depth
81
+
82
+ ### Avoid Distributional Defaults:
83
+ - NO solid white or light gray backgrounds
84
+ - NO single-color backgrounds
85
+ - NO generic gradient overlays
86
+
87
+ ### Intentional Alternatives:
88
+ - **Layered Gradients**: Combine 2-3 subtle gradients for depth
89
+ - **Geometric Patterns**: SVG patterns, mesh gradients, or subtle noise textures
90
+ - **Strategic Contrast**: Alternate between light and dark sections for rhythm
91
+
92
+ ## 6. Visual Hierarchy Principles
93
+
94
+ ### Clear Priority System:
95
+ 1. **Primary Focus (1 element)**: Largest, highest contrast, most visual weight
96
+ 2. **Secondary Elements (2-3 elements)**: 40-60% of primary size, reduced contrast
97
+ 3. **Tertiary/Support (everything else)**: Minimal visual weight, muted colors
98
+
99
+ ### Contrast Techniques:
100
+ - Size: 3x+ differences between hierarchy levels
101
+ - Weight: 300+ difference in font-weight values
102
+ - Color: Primary gets brand color, secondary gets neutral, tertiary gets muted
103
+ - Space: Primary gets 2x+ surrounding white space vs. secondary
104
+
105
+
106
+ # IMPLEMENTATION WORKFLOW
107
+
108
+ When building a composition:
109
+
110
+ 1. **Define the Visual Goal First**
111
+ - What emotion/brand personality? (Professional, playful, elegant, bold)
112
+ - What's the single most important element?
113
+ - What color family (warm/cool/neutral) supports the goal?
114
+
115
+ 2. **Choose Typography Personality**
116
+ - Select font pairings that match the personality (NOT defaults)
117
+ - Define scale (3x+ headline ratio)
118
+ - Set weight extremes (light/heavy contrast)
119
+
120
+ 3. **Commit to Color Strategy**
121
+ - Pick ONE dominant color (NOT purple, NOT generic blue)
122
+ - Choose 1 sharp accent
123
+ - Define warm or cool neutrals
124
+
125
+ 4. **Design Spatial Rhythm**
126
+ - Use generous white space (3-6rem between sections)
127
+ - Create asymmetry (not everything centered)
128
+ - Vary component sizes intentionally
129
+
130
+ 5. **Add Strategic Motion**
131
+ - Identify 2-3 high-impact animation moments
132
+ - Use staggered timing for multiple elements
133
+ - Keep interactions purposeful, not decorative
134
+
135
+ 6. **Layer Atmospheric Depth**
136
+ - Use gradient combinations for backgrounds
137
+ - Add subtle patterns or textures
138
+ - Alternate light/dark sections for rhythm
139
+
140
+
141
+ # CONTEXT-AWARE DESIGN PERSONALITIES
142
+
143
+ Brand personality should influence your choices:
144
+
145
+ - **Corporate/Professional**: Deep neutrals, serif headlines, structured spacing
146
+ - **Creative/Agency**: Bold color, display fonts, asymmetric layouts
147
+ - **Tech/Startup**: Monospace accents, sharp colors, modern spacing
148
+ - **Elegant/Luxury**: Serif dominance, muted colors with metallic accents, generous white space
149
+
150
+ # USER OVERRIDE CAPABILITY
151
+
152
+ Always respect user specifications:
153
+
154
+ If user specifies:
155
+ - Specific colors → use them
156
+ - Specific fonts → use them
157
+ - Specific spacing → use it
158
+ - "Minimal/simple" → reduce ornamentation but maintain quality principles
159
+ `;
@@ -28,7 +28,13 @@ Prefer using "em" and "rem" values for text-related sizes, padding and spacing.
28
28
  This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema.
29
29
 
30
30
  When applicable for styles, apply style PropValues using the ${ STYLE_SCHEMA_URI }.
31
- The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.`,
31
+ The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.
32
+
33
+ ** CRITICAL - VARIABLES **
34
+ When using global variables, ensure that the variables are defined in the ${ 'elementor://global-variables' } resource.
35
+ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
36
+
37
+ `,
32
38
  },
33
39
  ],
34
40
  };
@@ -1,167 +1,143 @@
1
1
  import { toolPrompts } from '@elementor/editor-mcp';
2
2
 
3
- import { STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
4
-
5
3
  export const generatePrompt = () => {
6
4
  const buildCompositionsToolPrompt = toolPrompts( 'build-compositions' );
7
5
 
8
6
  buildCompositionsToolPrompt.description( `
9
- # REQUIRED RESOURCES (Read before use)
10
- 1. [${ WIDGET_SCHEMA_URI }] - Widget types, configuration schemas, and PropType definitions
11
- 2. [${ STYLE_SCHEMA_URI }] - Common styles schema shared by all widgets
12
- 3. [elementor://global-classes] - Existing global classes (check FIRST to reuse)
13
-
14
- # THREE-PHASE WORKFLOW (MANDATORY)
15
-
16
- ## Phase 1: Create Global Classes
17
- 1. Analyze requirements → identify reusable patterns (typography, colors, spacing)
18
- 2. Check [elementor://global-classes] for existing classes
19
- 3. Use "create-global-class" tool for NEW reusable styles BEFORE building
20
-
21
- ## Phase 2: Build Composition (THIS TOOL)
22
- 4. Build valid XML with minimal inline styles (layout/positioning only)
23
- 5. Avoid duplicating styles that should be global classes
24
-
25
- ## Phase 3: Apply Classes
26
- 6. Use "apply-global-class" tool to apply global classes to elements
27
-
28
- # CORE INSTRUCTIONS
29
-
30
- **Structure:**
31
- - Build valid XML using allowed widget tags (e.g., \`<e-button configuration-id="btn1"></e-button>\`)
32
- - Containers only: "e-flexbox", "e-div-block", "e-tabs"
33
- - Every element MUST have unique "configuration-id" attribute
7
+ # RESOURCES (Read before use)
8
+ - [elementor://global-classes] - Check FIRST for reusable classes
9
+ - [elementor://global-variables] - ONLY use variables defined here
10
+
11
+ # WORKFLOW
12
+ 1. Check/create global classes via "create-global-class" tool
13
+ 2. Build composition (THIS TOOL) - minimal inline styles
14
+ 3. Apply classes via "apply-global-class" tool
15
+
16
+ # XML STRUCTURE
17
+ - Use widget tags: \`<e-button configuration-id="btn1"></e-button>\`
18
+ - Containers: "e-flexbox", "e-div-block", "e-tabs"
19
+ - Every element needs unique "configuration-id"
34
20
  - No attributes, classes, IDs, or text nodes in XML
35
21
 
36
- **Configuration:**
37
- - Map each configuration-id to elementConfig (widget props) and stylesConfig (styles)
38
- - Follow exact PropType schemas from resources above
39
- - All PropValues need \`$$type\` property matching schema
40
- - Keep stylesConfig MINIMAL - layout only, NOT reusable styles
41
-
42
- **Validation:**
43
- - Parse XML before submission
44
- - Match all PropValues to schema (\`$$type\` required)
45
- - NO LINKS in any configuration
46
- - Retry on errors up to 10x, reading error messages carefully
47
-
48
- # DESIGN QUALITY: AVOID AI SLOP
49
-
50
- **Problem:** LLMs default to generic patterns (purple gradients, #333 grays, 24px headings, uniform spacing)
51
- **Solution:** Make intentional, distinctive choices. When unsure, choose bold over safe.
52
-
53
- ## Typography Rules
54
- AVOID: Inter/Roboto/Arial, small ratios (1.5x), medium weights (500-700)
55
- USE: 3x+ size ratios, extreme weight contrasts (100/200 vs 800/900), tight headlines (1.1 line-height)
56
-
57
- ## Color Rules
58
- AVOID: Purple gradients, pure grays (#333/#666/#999), even distribution
59
- ✅ USE: ONE dominant color (60-70%), 1-2 accent colors (10-15%), tinted neutrals (warm/cool grays)
60
-
61
- ## Spacing Rules
62
- AVOID: Uniform spacing (all 16px/24px), cramped layouts, centered everything
63
- USE: Generous spacing (80-120px sections), dramatic variation (12px/48px/96px), asymmetric layouts
64
-
65
- ## Background Rules
66
- AVOID: Solid white/gray, single colors
67
- ✅ USE: Layered gradients (2-3 layers), subtle patterns, alternating light/dark sections
68
-
69
- ## Visual Hierarchy
70
- 1. **Primary** (1 element): Largest, highest contrast, most space
71
- 2. **Secondary** (2-3 elements): 40-60% of primary size
72
- 3. **Tertiary** (rest): Minimal weight, muted
73
-
74
- **Contrast techniques:** 3x size differences, 300+ weight differences, color hierarchy (brand neutral → muted)
75
-
76
- # DESIGN CONSTRAINTS (NEVER VIOLATE)
77
-
78
- **Typography:**
79
- - NEVER use Inter, Roboto, Arial, Helvetica as primary display fonts
80
- - NEVER use font-size ratios < 2.5x between headlines and body
81
- - NEVER use font-weight 500-700 for headlines (go lighter or heavier)
82
-
83
- **Color:**
84
- - PREFER not to use pure grays - use tinted neutrals (#2d2622, #faf8f6, not #333/#f5f5f5)
85
- - NEVER distribute colors evenly - commit to ONE dominant
86
- - NEVER use more than 3 core colors - except for info/alert/badges
87
-
88
- **Spacing:**
89
- - NEVER use uniform spacing
90
- - NEVER use < 4rem (64px) padding for major sections
91
- - NEVER center everything
92
- - PRIORITIZE rem based values over pixel based
93
-
94
- **Background:**
95
- - NEVER use solid #ffffff or #f5f5f5 without texture/gradients
96
- - ALWAYS layer 2+ gradient/color elements
97
-
98
- # WIDGET NOTES
99
- - Check \`llm_guidance\` property in widget schemas for context
100
- - Avoid SVG widgets (require content upload tools) - when must, prior to execution ensure assets uploaded
101
- - Apply style schema to containers for layout control
102
-
103
- # PARAMETERS (ALL MANDATORY)
22
+ # CONFIGURATION
23
+ - Map configuration-id elementConfig (props) + stylesConfig (layout only)
24
+ - All PropValues require \`$$type\` matching schema
25
+ - NO LINKS in configuration
26
+ - Retry on errors up to 10x
27
+
28
+ Note about configuration ids: These names are visible to the end-user, make sure they make sense, related and relevant.
29
+
30
+ # DESIGN PHILOSOPHY: CONTEXT-DRIVEN CREATIVITY
31
+
32
+ **Use the user's context aggressively.** Business type, brand personality, target audience, and purpose should drive every design decision. A law firm needs gravitas; a children's app needs playfulness. Don't default to generic.
33
+
34
+ ## SIZING: DEFAULT IS NO SIZE (CRITICAL)
35
+
36
+ **DO NOT specify height or width unless you have a specific visual reason.**
37
+
38
+ Flexbox and CSS already handle sizing automatically:
39
+ - Containers grow to fit their content
40
+ - Flex children distribute space via flex properties, not width/height
41
+ - Text elements size to their content
42
+
43
+ WHEN TO SPECIFY SIZE:
44
+ - min-height on ROOT section for viewport-spanning hero (use min-height, NOT height)
45
+ - max-width for contained content areas (e.g., max-width: 60rem)
46
+ - Explicit aspect ratios for media containers
47
+
48
+ NEVER SPECIFY:
49
+ - height on nested containers (causes overflow)
50
+ - width on flex children (use flex-basis or gap instead)
51
+ - 100vh on anything except root-level sections
52
+ - Any size "just to be safe" - if unsure, OMIT IT
53
+
54
+ vh units are VIEWPORT-relative. Nested 100vh inside 100vh = 200vh overflow.
55
+
56
+ GOOD: \`<e-flexbox>content naturally sizes</e-flexbox>\`
57
+ BAD: \`<e-flexbox style="height:100vh"><e-div-block style="height:100vh">overflow</e-div-block></e-flexbox>\`
58
+
59
+ ## Layout Variety (Break the Template)
60
+ - AVOID: Full-width 100vh hero three columns testimonials → CTA (every AI does this)
61
+ - VARY heights: Use auto-height sections with generous padding (6rem+). Let content breathe
62
+ - VARY widths: Not everything spans full width. Use contained sections (max-width: 960px) mixed with edge-to-edge
63
+ - ASYMMETRIC grids: 2:1, 1:3, offset layouts. Avoid equal column widths
64
+ - Negative space as design element: Large margins create focus and sophistication
65
+ - Break alignment intentionally: Offset headings, overlapping elements, broken grids
66
+
67
+ ## Visual Depth & Effects
68
+ - Layer elements: Overlapping cards, text over images, floating elements
69
+ - Subtle shadows with color tint (not pure black): \`box-shadow: 0 20px 60px rgba(<brand-color-here>, 0.15)\`
70
+ - Gradient overlays on images for text readability
71
+ - Border radius variation: Mix sharp (0) and soft (1rem+) corners purposefully
72
+ - Backdrop blur for glassmorphism where appropriate
73
+ - Micro-interactions via CSS: hover transforms, transitions (0.3s ease)
74
+
75
+ ## Typography with Character
76
+ - Display fonts for headlines (from user's brand or contextually appropriate)
77
+ - Size contrast: 4rem+ headlines vs 1rem body. Make hierarchy unmistakable
78
+ - Letter-spacing: Tight for large headlines (-0.02em), loose for small caps (0.1em)
79
+ - Line-height: Tight for headlines (1.1), generous for body (1.6-1.8)
80
+ - Text decoration: Underlines, highlights, gradient text for emphasis
81
+
82
+ ## Color with Purpose
83
+ - Extract palette from user context (brand colors, industry norms, mood)
84
+ - 60-30-10 rule: dominant, secondary, accent
85
+ - Tinted neutrals over pure grays: warm (#faf8f5, #2d2a26) or cool (#f5f7fa, #1e2430)
86
+ - Color blocking: Large colored sections create visual rhythm
87
+ - Gradient directions: Diagonal (135deg, 225deg) feel more dynamic than vertical
88
+
89
+ ## Spacing Strategy
90
+ - Section padding: 6rem-10rem vertical, creating breathing room
91
+ - Rhythm variation: Tight groups (2rem) with generous gaps between (6rem)
92
+ - Use rem/em exclusively for responsive scaling
93
+ - Generous padding on CTAs: min 1rem 2.5rem
94
+
95
+ # HARD CONSTRAINTS
96
+ - Variables ONLY from [elementor://global-variables] (others throw errors)
97
+ - Avoid SVG widgets unless assets are pre-uploaded
98
+ - Check \`llm_guidance\` in widget schemas
99
+
100
+ # PARAMETERS
104
101
  - **xmlStructure**: Valid XML with configuration-id attributes
105
- - **elementConfig**: Record of configuration-id → widget PropValues
106
- - **stylesConfig**: Record of configuration-id → style PropValues (layout only)
102
+ - **elementConfig**: configuration-id → widget PropValues
103
+ - **stylesConfig**: configuration-id → style PropValues (layout only)
104
+ - **customCSS**: configuration-id → CSS rules (no selectors, semicolon-separated)
107
105
  ` );
108
106
 
109
107
  buildCompositionsToolPrompt.example( `
110
- A Heading and a button inside a flexbox
108
+ Section with heading + button (NO explicit heights - content sizes naturally):
111
109
  {
112
- xmlStructure: "<e-flexbox configuration-id="flex1"><e-heading configuration-id="heading1"></e-heading><e-button configuration-id="button1"></e-button></e-flexbox>"
110
+ xmlStructure: "<e-flexbox configuration-id="Main Section"><e-heading configuration-id="Section Title"></e-heading><e-button configuration-id="Call to Action"></e-button></e-flexbox>",
113
111
  elementConfig: {
114
- "flex1": {
115
- "tag": {
116
- "$$type": "string",
117
- "value": "section"
118
- },
112
+ "section1": { "tag": { "$$type": "string", "value": "section" } }
113
+ },
114
+ customCSS: {
115
+ "Section Title": "padding: 6rem 4rem; background: linear-gradient(135deg, #faf8f5 0%, #f0ebe4 100%);"
119
116
  },
120
117
  stylesConfig: {
121
- "heading1": {
122
- "font-size": {
123
- "$$type": "size",
124
- "value": {
125
- "size": { "$$type": "number", "value": 24 },
126
- "unit": { "$$type": "string", "value": "px" }
127
- }
128
- },
129
- "color": {
130
- "$$type": "color",
131
- "value": { "$$type": "string", "value": "#333" }
132
- }
118
+ "Section Title": {
119
+ "font-size": { "$$type": "size", "value": { "size": { "$$type": "number", "value": 3.5 }, "unit": { "$$type": "string", "value": "rem" } } },
120
+ "color": { "$$type": "color", "value": { "$$type": "string", "value": "#2d2a26" } }
133
121
  }
134
- },
122
+ }
135
123
  }
124
+ Note: No height/width specified on any element - flexbox handles layout automatically.
136
125
  ` );
137
126
 
138
127
  buildCompositionsToolPrompt.parameter(
139
128
  'xmlStructure',
140
- `**MANDATORY** A valid XML structure representing the composition to be built, using custom elementor tags, styling and configuration PropValues.`
129
+ `Valid XML structure with custom elementor tags and configuration-id attributes.`
141
130
  );
142
131
 
143
- buildCompositionsToolPrompt.parameter(
144
- 'elementConfig',
145
- `**MANDATORY** A record mapping configuration IDs to their corresponding configuration objects, defining the PropValues for each element created.`
146
- );
132
+ buildCompositionsToolPrompt.parameter( 'elementConfig', `Record mapping configuration IDs to widget PropValues.` );
147
133
 
148
134
  buildCompositionsToolPrompt.parameter(
149
135
  'stylesConfig',
150
- `**MANDATORY** A record mapping style PropTypes to their corresponding style configuration objects, defining the PropValues for styles to be applied to elements.`
136
+ `Record mapping configuration IDs to style PropValues (layout/positioning only).`
151
137
  );
152
138
 
153
139
  buildCompositionsToolPrompt.instruction(
154
- `You will be provided the XML structure with element IDs. These IDs represent the actual elementor widgets created on the page/post.
155
- You should use these IDs as reference for further configuration, styling or changing elements later on.`
156
- );
157
-
158
- buildCompositionsToolPrompt.instruction(
159
- `**CRITICAL WORKFLOW REMINDER**:
160
- 1. FIRST: Create reusable global classes for typography, colors, spacing patterns using "create-global-class" tool
161
- 2. SECOND: Use THIS tool with minimal inline styles (only layout & unique properties)
162
- 3. THIRD: Apply global classes to elements using "apply-global-class" tool
163
-
164
- This ensures maximum reusability and consistency across your design system. ALWAYS check [elementor://global-classes] for existing classes before creating new ones.`
140
+ `Element IDs in the returned XML represent actual widgets. Use these IDs for subsequent styling or configuration changes.`
165
141
  );
166
142
 
167
143
  return buildCompositionsToolPrompt.prompt();
@@ -1,4 +1,4 @@
1
- import { z } from '@elementor/schema';
1
+ import { zod as z } from '@elementor/editor-mcp';
2
2
 
3
3
  import { STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
4
4
 
@@ -25,6 +25,13 @@ export const inputSchema = {
25
25
  `A record mapping element IDs to their styles configuration objects. Use the actual styles schema from [${ STYLE_SCHEMA_URI }].`
26
26
  )
27
27
  .default( {} ),
28
+ customCSS: z
29
+ .record(
30
+ z.string().describe( 'The configuration id' ),
31
+ z.string().describe( 'The custom CSS for the element. MANDATORY' )
32
+ )
33
+ .describe( 'A record mapping element IDs to their custom CSS.' )
34
+ .default( {} ),
28
35
  };
29
36
 
30
37
  export const outputSchema = {
@@ -32,7 +32,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
32
32
  hints: [ { name: 'claude-sonnet-4-5' } ],
33
33
  },
34
34
  handler: async ( params ) => {
35
- const { xmlStructure, elementConfig, stylesConfig } = params;
35
+ const { xmlStructure, elementConfig, stylesConfig, customCSS } = params;
36
36
  let generatedXML: string = '';
37
37
  const errors: Error[] = [];
38
38
  const rootContainers: V1Element[] = [];
@@ -44,6 +44,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
44
44
  } );
45
45
  compositionBuilder.setElementConfig( elementConfig );
46
46
  compositionBuilder.setStylesConfig( stylesConfig );
47
+ compositionBuilder.setCustomCSS( customCSS );
47
48
 
48
49
  const {
49
50
  configErrors,
@@ -51,6 +52,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
51
52
  rootContainers: generatedRootContainers,
52
53
  } = compositionBuilder.build( documentContainer );
53
54
 
55
+ rootContainers.push( ...generatedRootContainers );
54
56
  generatedXML = new XMLSerializer().serializeToString( compositionBuilder.getXML() );
55
57
 
56
58
  if ( configErrors.length ) {
@@ -58,8 +60,6 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
58
60
  throw new Error( 'Configuration errors occurred during composition building.' );
59
61
  }
60
62
 
61
- rootContainers.push( ...generatedRootContainers );
62
-
63
63
  Object.entries( invalidStyles ).forEach( ( [ elementId, rawCssRules ] ) => {
64
64
  const customCss = {
65
65
  value: rawCssRules.join( ';\n' ),
@@ -113,7 +113,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
113
113
 
114
114
  const errorText = `Failed to build composition with the following errors:\n\n${ errorMessages.join(
115
115
  '\n\n'
116
- ) }\n\n"Missing $$type" errors indicate that the configuration objects are invalid. Try again and apply **ALL** object entries with correct $$type.\nNow that you have these errors, fix them and try again. Errors regarding configuration objects, please check against the PropType schemas`;
116
+ ) }`;
117
117
  throw new Error( errorText );
118
118
  }
119
119
  return {