Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions src/tools/deElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,94 @@ export const registerDEElementTools = (
},
);

const whtmlBuilderRPCCall = async (
siteId: string,
actions: any,
) => {
return rpc.callTool("whtml_builder", {
siteId,
actions: actions || [],
});
};

server.registerTool(
"whtml_builder",
{
annotations: {
openWorldHint: true,
readOnlyHint: false,
},
description:
"Designer Tool - WHTML builder to insert elements from HTML and CSS strings on the current active page. Accepts HTML markup and optional CSS rules, constructs WHTML, and inserts into a parent element.",
inputSchema: {
...SiteIdSchema,
actions: z.array(
z.object({
build_label: z
.string()
.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 insert WHTML into. e.g id:{component:123,element:456}.",
),
creation_position: z
.enum(["append", "prepend"])
.describe(
"The position to insert the element. append to the end of the parent element or prepend to the beginning of the parent element.",
),
html: z
.string()
.min(1)
.describe(
"HTML markup string to insert. Must not contain <style> tags. CSS should be provided via the css parameter instead.",
),
css: z
.string()
.optional()
.describe(
"Optional CSS rules to apply. Must not contain <style> tags. Provide raw CSS rules only (e.g. '.my-class { color: red; }').",
),
get_children_info: z
.boolean()
.optional()
.describe(
"Whether to return children info of the inserted element. Defaults to false.",
),
children_depth: z
.number()
.optional()
.describe(
"Depth of children to include when get_children_info is true. Defaults to 1.",
),
}),
).min(1).max(5),
},
},
async ({ actions, siteId }) => {
try {
return formatResponse(
await whtmlBuilderRPCCall(siteId, actions),
);
} catch (error) {
return formatErrorResponse(error);
}
},
);

server.registerTool(
"element_snapshot_tool",
{
Expand Down
17 changes: 16 additions & 1 deletion src/tools/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,22 @@ export function registerRulesTools(server: McpServer) {
`-- Always plan out your actions before calling element_builder. Know exactly what type of element to create, what styles or attributes to apply, and how you will use it.\n` +
`-- Once an element is created using element_builder, it is not automatically selected. To inspect or modify it, use element_tool > select_element and pass the element ID returned from the creation response.\n` +
`-- Only Container, Section, DivBlock, some valid DOM elements can have children.\n` +
`-- Only component instances are allowed inside slots. Do not attempt to create or insert regular elements into a slot. Use component_builder to create a component instance and place it inside a slot.\n`,
`-- Only component instances are allowed inside slots. Do not attempt to create or insert regular elements into a slot. Use component_builder to create a component instance and place it inside a slot.\n` +
`\n` +
`WHTML Builder Tool:\n` +
`-- To insert elements from HTML and CSS strings, use whtml_builder. Pass html and optionally css along with parent_element_id and creation_position.\n` +
`-- HTML Rules:\n` +
`---- The html field must be a single root element (no fragments). For example, <div><p>Hello</p></div> is valid, but <div>First</div><div>Second</div> is not allowed.\n` +
`---- The html field must not contain <style> tags. CSS should be provided via the css parameter.\n` +
`-- CSS Rules:\n` +
`---- The css field must contain raw CSS rules only. Do not wrap in <style> tags.\n` +
`---- @keyframes are not allowed.\n` +
`---- Custom media queries are not allowed. Only the following Webflow breakpoint media queries are valid:\n` +
`------ Desktop (main): No media query needed (default breakpoint).\n` +
`------ Tablet (medium): @media screen and (max-width: 991px)\n` +
`------ Mobile Landscape (small): @media screen and (max-width: 767px)\n` +
`------ Mobile Portrait (tiny): @media screen and (max-width: 479px)\n` +
`-- After insertion, the tool returns element info. Use get_children_info and children_depth to control the depth of children info returned.\n`,
},
],
}),
Expand Down
Loading