element_builder
Create elements on a Webflow page by specifying parent element, position, and element schema. Supports various element types and styling.
Instructions
Designer Tool - Element builder to create element on current active page.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| siteId | Yes | The ID of the site. DO NOT ASSUME site id. ALWAYS ask user for site id if not already provided or known. use sites_list tool to fetch all sites and then ask user to select one of them. | |
| actions | Yes |
Implementation Reference
- src/tools/deElement.ts:24-45 (helper)elementBuilderRPCCall: Validates element_schema for each action via Zod parsing, then delegates to the RPC callTool('element_builder', ...). This is the internal helper that performs pre-call schema validation and dispatches to the backend RPC.
const elementBuilderRPCCall = async ( siteId: string, actions: any, ) => { const actionsArray = actions || []; for (const action of actionsArray) { if (action.element_schema) { const result = ElementSchemaValidator.safeParse( action.element_schema, ); if (!result.success) { throw new Error( `Invalid element_schema: ${result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`, ); } } } return rpc.callTool("element_builder", { siteId, actions: actionsArray, }); }; - src/tools/deElement.ts:14-22 (helper)ElementSchemaValidator: A lazy recursive Zod schema that wraps DEElementSchema with optional children (self-referencing), used to validate element_schema before RPC calls.
export const registerDEElementTools = ( server: McpServer, rpc: RPCType, ) => { const ElementSchemaValidator: z.ZodType = z.lazy(() => DEElementSchema.extend({ children: z.array(ElementSchemaValidator).optional(), }), ); - src/tools/deElement.ts:78-147 (handler)Registration and handler for the 'element_builder' tool. Registers the tool with McpServer including input schema (siteId + actions array with parent_element_id, creation_position, element_schema, etc.) and the async handler that calls elementBuilderRPCCall and formats the response.
server.registerTool( "element_builder", { annotations: { openWorldHint: true, readOnlyHint: false, }, description: "Designer Tool - Element builder to create element on current active page.", inputSchema: { ...SiteIdSchema, actions: z.array( z.object({ build_label: z .string() .optional() .describe( "A label to identify this build action in the results.", ), parent_element_id: z .object({ component: z .string() .describe( "The component id of the element to perform action on.", ), element: z .string() .describe( "The element id of the element to perform action on.", ), }) .describe( "The id of the parent element to create element on, you can find it from id field on element. e.g id:{component:123,element:456}.", ), creation_position: z .enum(["append", "prepend", "before", "after"]) .describe( "The position to create element on. append/prepend insert as child of the parent element. before/after insert as sibling adjacent to the target element.", ), element_schema: DEElementSchema.extend({ children: z .array(z.any()) .optional() .describe( "Array of ElementSchema objects (same shape as element_schema with optional children)..", ), }).describe( "ElementSchema - element schema of element to create. Children are recursive ElementSchema objects.", ), return_element_info: z .boolean() .optional() .describe( "Whether to return full element info for the created element. Defaults to false.", ), }), ), }, }, async ({ actions, siteId }) => { try { return formatResponse( await elementBuilderRPCCall(siteId, actions), ); } catch (error) { return formatErrorResponse(error); } }, ); - src/schemas/DEElementSchema.ts:1-97 (schema)DEElementSchema: Zod validation schema for element definitions. Defines valid element types (Container, Section, DivBlock, Heading, etc.) and optional fields like set_style, set_text, set_link, set_heading_level, set_image_asset, set_dom_config, set_attributes.
import { z } from "zod/v3"; export const DEElementSchema = z.object({ type: z .enum([ "Container", "Section", "DivBlock", "Heading", "TextBlock", "Paragraph", "Button", "TextLink", "LinkBlock", "Image", "DOM", ]) .describe( "The type of element to create. with DOM type you can create any element. make sure you pass dom_config if you are creating a DOM element." ), set_style: z .object({ style_names: z .array(z.string()) .describe("The style names to set on the element."), }) .optional() .describe( "Set style on the element. it will remove all other styles on the element. and set only the styles passed in style_names." ), set_text: z .object({ text: z.string().describe("The text to set on the element."), }) .optional() .describe( "Set text on the element. only valid for text block, paragraph, heading, button, text link, link block." ), set_link: z .object({ link_type: z .enum(["url", "file", "page", "element", "email", "phone"]) .describe("The type of link to set on the element."), link: z.string().describe("The link to set on the element."), }) .optional() .describe( "Set link on the element. only valid for button, text link, link block." ), set_heading_level: z .object({ heading_level: z .number() .min(1) .max(6) .describe("The heading level to set on the element."), }) .optional() .describe("Set heading level on the element. only valid for heading."), set_image_asset: z .object({ image_asset_id: z .string() .describe("The image asset id to set on the element."), alt_text: z .string() .optional() .describe( "The alt text to set on the image. if not provided it will inherit from the image asset." ), }) .optional() .describe("Set image asset on the element. only valid for image."), set_dom_config: z .object({ dom_tag: z .string() .describe( "The tag of the DOM element to create. for example span, code, etc." ), }) .optional() .describe("Set DOM config on the element. only valid for DOM element."), set_attributes: z .object({ attributes: z .array( z.object({ name: z.string().describe("The name of the attribute to set."), value: z.string().describe("The value of the attribute to set."), }) ) .describe("The attributes to set on the element."), }) .optional() .describe("Set attributes on the element."), }); - src/schemas/SiteIdSchema.ts:1-9 (schema)SiteIdSchema: Shared Zod schema for the required siteId string parameter, used as spread input in the element_builder tool registration.
import { z } from "zod/v3"; export const SiteIdSchema = { siteId: z .string() .describe( "The ID of the site. DO NOT ASSUME site id. ALWAYS ask user for site id if not already provided or known. use sites_list tool to fetch all sites and then ask user to select one of them." ), };