Skip to content

Composite

The composite tool. Takes a single JSON structure describing the entire page layout (sections, containers, widgets, settings, even global styles) and emits a finished Elementor page in one call. Most “AI builds an entire landing page” demos use this tool exclusively.

Input:

{
post_id: number, // target page (create-page first if needed)
globals?: { // optional, apply globals before building
colors?: [...], // same shape as update-global-colors
typography?: [...] // same shape as update-global-typography
},
elements: Container[] // top-level containers
}
type Container = {
type: 'container',
settings?: Record<string, any>,
children?: (Container | Widget)[]
}
type Widget = {
type: 'widget',
widget_type: string,
settings?: Record<string, any>
}

Returns: { post_id, root_element_ids: [...], total_elements }.

Three reasons over individual add-container / add-free-widget calls:

  1. One MCP round-trip instead of dozens. Big speed win for any non-trivial page.
  2. Atomic. Either the whole page builds or nothing does. No half-built page if a single widget fails.
  3. Layout rules enforced automatically. Row children get content_width: 'full' with calculated percentage widths. flex_wrap and _flex_size get stripped. Column containers get align_items: center. These are the same rules described in Layout & Structure; build-page applies them so the AI doesn’t have to remember.
{
"post_id": 42,
"globals": {
"colors": [
{ "_id": "primary", "title": "Primary", "color": "#2C1810" },
{ "_id": "secondary", "title": "Secondary", "color": "#D4A574" }
]
},
"elements": [
{
"type": "container",
"settings": { "padding": { "size": 80, "unit": "px" } },
"children": [
{ "type": "widget", "widget_type": "heading", "settings": { "title": "Welcome", "header_size": "h1" } },
{ "type": "widget", "widget_type": "text-editor", "settings": { "editor": "<p>Lead paragraph...</p>" } }
]
},
{
"type": "container",
"settings": { "flex_direction": "row", "gap": { "size": 24 } },
"children": [
{ "type": "container", "children": [ /* column 1 */ ] },
{ "type": "container", "children": [ /* column 2 */ ] },
{ "type": "container", "children": [ /* column 3 */ ] }
]
}
]
}

Each inner container in the row layout will auto-get content_width: 'full' and width: { size: 33.33, unit: '%' }. You don’t set those yourself.

For surgical edits on an existing page, update-element and batch-update are better; build-page is for greenfield construction. The premium prompts library and all the sample prompts use build-page end-to-end.