From 409712780f16f38eb79ce011469ba456d39d1940 Mon Sep 17 00:00:00 2001 From: Guillermo Pineda <13656292+memo-pineda@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:23:25 -0700 Subject: [PATCH 1/5] Add create_blank_component and open_component_canvas schemas --- src/tools/deComponents.ts | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/tools/deComponents.ts b/src/tools/deComponents.ts index 16fd61e..2d32089 100644 --- a/src/tools/deComponents.ts +++ b/src/tools/deComponents.ts @@ -241,6 +241,34 @@ export function registerDEComponentsTools( .describe( "Unregister a component. DANGEROUS ACTION. USE WITH CAUTION.", ), + create_blank_component: z + .object({ + name: z + .string() + .describe("The name of the blank component to create"), + group: z + .string() + .optional() + .describe("Optional group/folder to place the component in"), + description: z + .string() + .optional() + .describe("Optional description for the component"), + }) + .optional() + .describe( + "[BETA] Create a blank component with no root element. Equivalent to 'Create blank' in the Designer's New Component menu.", + ), + open_component_canvas: z + .object({ + component_id: z + .string() + .describe("The id of the component to open in the canvas"), + }) + .optional() + .describe( + "[BETA] Open a component's canvas directly by component ID, without needing a component instance on the page.", + ), }) .strict() .refine( @@ -257,10 +285,12 @@ export function registerDEComponentsTools( d.set_component_metadata, d.rename_component, d.unregister_component, + d.create_blank_component, + d.open_component_canvas, ].filter(Boolean).length >= 1, { message: - "Provide at least one of check_if_inside_component_view, transform_element_to_component, insert_component_instance, open_component_view, close_component_view, get_all_components, get_component, get_component_metadata, set_component_metadata, rename_component, unregister_component.", + "Provide at least one of check_if_inside_component_view, transform_element_to_component, insert_component_instance, open_component_view, close_component_view, get_all_components, get_component, get_component_metadata, set_component_metadata, rename_component, unregister_component, create_blank_component, open_component_canvas.", }, ), ), From 061b5eaf8d6c410cc34200d90c99b5654e3cf375 Mon Sep 17 00:00:00 2001 From: Guillermo Pineda <13656292+memo-pineda@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:30:06 -0700 Subject: [PATCH 2/5] Add open_page_canvas schema and expand open_component_canvas with instance ID support --- src/tools/deComponents.ts | 18 +++++++++++++++--- src/tools/dePages.ts | 13 ++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/tools/deComponents.ts b/src/tools/deComponents.ts index 2d32089..fcd8786 100644 --- a/src/tools/deComponents.ts +++ b/src/tools/deComponents.ts @@ -257,17 +257,29 @@ export function registerDEComponentsTools( }) .optional() .describe( - "[BETA] Create a blank component with no root element. Equivalent to 'Create blank' in the Designer's New Component menu.", + "Create a blank component with no root element. Equivalent to 'Create blank' in the Designer's New Component menu.", ), open_component_canvas: z .object({ component_id: z .string() - .describe("The id of the component to open in the canvas"), + .optional() + .describe("The id of the component to open in the canvas. Use this or component_instance_id."), + component_instance_id: z + .object({ + component: z + .string() + .describe("The component id of the instance element."), + element: z + .string() + .describe("The element id of the instance element."), + }) + .optional() + .describe("The element ID of a component instance to open in the canvas. Use this or component_id."), }) .optional() .describe( - "[BETA] Open a component's canvas directly by component ID, without needing a component instance on the page.", + "Open a component's canvas directly by component ID or component instance element ID.", ), }) .strict() diff --git a/src/tools/dePages.ts b/src/tools/dePages.ts index b90e94e..f4ebfaf 100644 --- a/src/tools/dePages.ts +++ b/src/tools/dePages.ts @@ -75,6 +75,16 @@ export function registerDEPagesTools(server: McpServer, rpc: RPCType) { }) .optional() .describe("Switch to a page on webflow designer"), + open_page_canvas: z + .object({ + page_id: z + .string() + .describe("The id of the page to open in the canvas"), + }) + .optional() + .describe( + "Navigate the Designer canvas to a specific page by page ID.", + ), }) .strict() .refine( @@ -84,10 +94,11 @@ export function registerDEPagesTools(server: McpServer, rpc: RPCType) { d.create_page_folder, d.get_current_page, d.switch_page, + d.open_page_canvas, ].filter(Boolean).length >= 1, { message: - "Provide at least one of create_page, create_page_folder, get_current_page, switch_page.", + "Provide at least one of create_page, create_page_folder, get_current_page, switch_page, open_page_canvas.", } ) ), From 0471864c59727ec3fea7c91e6dde7d61e13dded3 Mon Sep 17 00:00:00 2001 From: Guillermo Pineda <13656292+memo-pineda@users.noreply.github.com> Date: Wed, 1 Apr 2026 10:02:44 -0700 Subject: [PATCH 3/5] Add search_components, get_instance_count, get_current_component, get_parent_component schemas Co-Authored-By: Claude Opus 4.6 (1M context) --- src/tools/deComponents.ts | 41 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/tools/deComponents.ts b/src/tools/deComponents.ts index fcd8786..be4896f 100644 --- a/src/tools/deComponents.ts +++ b/src/tools/deComponents.ts @@ -281,6 +281,41 @@ export function registerDEComponentsTools( .describe( "Open a component's canvas directly by component ID or component instance element ID.", ), + search_components: z + .object({ + q: z + .string() + .optional() + .describe("Optional fuzzy search query matching Component panel search behavior. Searches both name and description fields."), + }) + .optional() + .describe( + "Search all components in the project. Returns component metadata including name, group, description, instance count, editability, and library info. When called without a query, returns all components.", + ), + get_instance_count: z + .object({ + component_id: z + .string() + .describe("The id of the component to get the instance count for"), + }) + .optional() + .describe( + "Get the number of instances of a component across the site. Returns the same count shown in the Components panel.", + ), + get_current_component: z + .boolean() + .optional() + .describe( + "Get the component currently being edited on the canvas (in-context editing or component canvas). Returns null if on a regular page.", + ), + get_parent_component: z + .object({ + ...DEElementIDSchema, + }) + .optional() + .describe( + "Get the component that contains the specified element. Returns null if the element is at page level (not inside a component).", + ), }) .strict() .refine( @@ -299,10 +334,14 @@ export function registerDEComponentsTools( d.unregister_component, d.create_blank_component, d.open_component_canvas, + d.search_components, + d.get_instance_count, + d.get_current_component, + d.get_parent_component, ].filter(Boolean).length >= 1, { message: - "Provide at least one of check_if_inside_component_view, transform_element_to_component, insert_component_instance, open_component_view, close_component_view, get_all_components, get_component, get_component_metadata, set_component_metadata, rename_component, unregister_component, create_blank_component, open_component_canvas.", + "Provide at least one of check_if_inside_component_view, transform_element_to_component, insert_component_instance, open_component_view, close_component_view, get_all_components, get_component, get_component_metadata, set_component_metadata, rename_component, unregister_component, create_blank_component, open_component_canvas, search_components, get_instance_count, get_current_component, get_parent_component.", }, ), ), From 471165ce986e399645935d1842ac0b9d644708d6 Mon Sep 17 00:00:00 2001 From: Guillermo Pineda <13656292+memo-pineda@users.noreply.github.com> Date: Wed, 1 Apr 2026 12:06:00 -0700 Subject: [PATCH 4/5] Add insert_slot schema for Slot element insertion into components Co-Authored-By: Claude Opus 4.6 (1M context) --- src/tools/deComponents.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/tools/deComponents.ts b/src/tools/deComponents.ts index be4896f..bdcca3b 100644 --- a/src/tools/deComponents.ts +++ b/src/tools/deComponents.ts @@ -316,6 +316,18 @@ export function registerDEComponentsTools( .describe( "Get the component that contains the specified element. Returns null if the element is at page level (not inside a component).", ), + insert_slot: z + .object({ + parent_element_id: DEElementIDSchema.id, + position: z + .enum(["append", "prepend", "before", "after"]) + .optional() + .describe("Insertion position relative to the parent element. Defaults to 'append'."), + }) + .optional() + .describe( + "Insert a Slot element into the currently-editing component. Must be inside component editing context (use open_component_canvas or open_component_view first). A SlotContent prop is automatically created.", + ), }) .strict() .refine( @@ -338,10 +350,11 @@ export function registerDEComponentsTools( d.get_instance_count, d.get_current_component, d.get_parent_component, + d.insert_slot, ].filter(Boolean).length >= 1, { message: - "Provide at least one of check_if_inside_component_view, transform_element_to_component, insert_component_instance, open_component_view, close_component_view, get_all_components, get_component, get_component_metadata, set_component_metadata, rename_component, unregister_component, create_blank_component, open_component_canvas, search_components, get_instance_count, get_current_component, get_parent_component.", + "Provide at least one of check_if_inside_component_view, transform_element_to_component, insert_component_instance, open_component_view, close_component_view, get_all_components, get_component, get_component_metadata, set_component_metadata, rename_component, unregister_component, create_blank_component, open_component_canvas, search_components, get_instance_count, get_current_component, get_parent_component, insert_slot.", }, ), ), From f50d4b045f8f23148d447e36d05e73e3c8aa0d88 Mon Sep 17 00:00:00 2001 From: Guillermo Pineda <13656292+memo-pineda@users.noreply.github.com> Date: Wed, 1 Apr 2026 14:50:35 -0700 Subject: [PATCH 5/5] Rename open_component_canvas to open_canvas with page navigation support, update rules Co-Authored-By: Claude Opus 4.6 (1M context) --- src/tools/deComponents.ts | 25 +++++++++---------------- src/tools/rules.ts | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/tools/deComponents.ts b/src/tools/deComponents.ts index bdcca3b..dc93fb0 100644 --- a/src/tools/deComponents.ts +++ b/src/tools/deComponents.ts @@ -259,27 +259,20 @@ export function registerDEComponentsTools( .describe( "Create a blank component with no root element. Equivalent to 'Create blank' in the Designer's New Component menu.", ), - open_component_canvas: z + open_canvas: z .object({ component_id: z .string() .optional() - .describe("The id of the component to open in the canvas. Use this or component_instance_id."), - component_instance_id: z - .object({ - component: z - .string() - .describe("The component id of the instance element."), - element: z - .string() - .describe("The element id of the instance element."), - }) + .describe("The id of the component to open in the canvas. Use this or page_id."), + page_id: z + .string() .optional() - .describe("The element ID of a component instance to open in the canvas. Use this or component_id."), + .describe("The id of the page to navigate to. Use this to exit the component canvas and return to a page."), }) .optional() .describe( - "Open a component's canvas directly by component ID or component instance element ID.", + "Navigate the Designer canvas to a component or page. Use component_id to open a component canvas, or page_id to navigate to a page (e.g. to exit component canvas). Provide exactly one of component_id or page_id.", ), search_components: z .object({ @@ -326,7 +319,7 @@ export function registerDEComponentsTools( }) .optional() .describe( - "Insert a Slot element into the currently-editing component. Must be inside component editing context (use open_component_canvas or open_component_view first). A SlotContent prop is automatically created.", + "Insert a Slot element into the currently-editing component. Must be inside component editing context (use open_canvas or open_component_view first). A SlotContent prop is automatically created.", ), }) .strict() @@ -345,7 +338,7 @@ export function registerDEComponentsTools( d.rename_component, d.unregister_component, d.create_blank_component, - d.open_component_canvas, + d.open_canvas, d.search_components, d.get_instance_count, d.get_current_component, @@ -354,7 +347,7 @@ export function registerDEComponentsTools( ].filter(Boolean).length >= 1, { message: - "Provide at least one of check_if_inside_component_view, transform_element_to_component, insert_component_instance, open_component_view, close_component_view, get_all_components, get_component, get_component_metadata, set_component_metadata, rename_component, unregister_component, create_blank_component, open_component_canvas, search_components, get_instance_count, get_current_component, get_parent_component, insert_slot.", + "Provide at least one of check_if_inside_component_view, transform_element_to_component, insert_component_instance, open_component_view, close_component_view, get_all_components, get_component, get_component_metadata, set_component_metadata, rename_component, unregister_component, create_blank_component, open_canvas, search_components, get_instance_count, get_current_component, get_parent_component, insert_slot.", }, ), ), diff --git a/src/tools/rules.ts b/src/tools/rules.ts index de367e7..afcbc95 100644 --- a/src/tools/rules.ts +++ b/src/tools/rules.ts @@ -54,13 +54,25 @@ export function registerRulesTools(server: McpServer) { `\n` + `Component Tool (Designer):\n` + `-- To get all components in the site, use de_component_tool > get_all_components.\n` + + `-- To search components by name or description, use de_component_tool > search_components. Pass an optional query string. Returns rich metadata including name, group, description, instance count, editability, and library info.\n` + `-- To insert a component instance by component ID, use de_component_tool > insert_component_instance. Pass parent_element_id, component_id, and creation_position.\n` + `-- To transform an existing element into a component, use de_component_tool > transform_element_to_component. Pass the element ID and component name.\n` + - `-- To open a component view for editing, use de_component_tool > open_component_view. Pass the component_instance_id.\n` + - `-- To close a component view and return to page view, use de_component_tool > close_component_view.\n` + + `-- To create a new blank component, use de_component_tool > create_blank_component. Pass name, and optionally group and description.\n` + + `-- To get the number of instances of a component, use de_component_tool > get_instance_count. Pass the component_id.\n` + + `-- To get the component currently being edited, use de_component_tool > get_current_component. Returns null if on a regular page.\n` + + `-- To get the component that contains a specific element, use de_component_tool > get_parent_component. Pass the element ID. Returns null if the element is at page level.\n` + + `-- To insert a Slot element into a component, use de_component_tool > insert_slot. Pass parent_element_id. You must be in component editing context first (use open_canvas with a component_id).\n` + `-- To rename a component, use de_component_tool > rename_component. Pass component_id and new_name.\n` + `-- To check if you are currently inside a component view, use de_component_tool > check_if_inside_component_view.\n` + `\n` + + `Canvas Navigation (Designer):\n` + + `-- To navigate the Designer canvas, use de_component_tool > open_canvas. This is the primary way to switch between component canvas and page canvas.\n` + + `---- To open a component canvas: pass component_id.\n` + + `---- To exit component canvas and return to a page: pass page_id.\n` + + `-- open_canvas is different from open_component_view/close_component_view. open_canvas switches the entire canvas context (like clicking a component in the Components panel). open_component_view/close_component_view enters/exits in-context editing of a component instance on the current page.\n` + + `-- To enter in-context editing of a component instance, use de_component_tool > open_component_view. Pass the component_instance_id.\n` + + `-- To exit in-context editing and return to page view, use de_component_tool > close_component_view.\n` + + `\n` + `Element Snapshot Tool Usage:\n` + `-- To get a visual snapshot of an element, section, or component, use element_snapshot_tool. Pass the element ID to capture its current visual state as an image.\n` + `-- Use this tool to verify visual changes after creating or updating elements. It provides immediate visual feedback without requiring manual inspection.\n` +