Webflow MCP

MCP Capabilities & Limitations

Overview
More Articles AboutΒ 
Webflow MCP
Using Claude Cowork w/ Webflow’s MCP
Published
May 10, 2026
πŸ§ͺ Audit method. Live capability test of the Webflow MCP server (both claude.ai Webflow and webflow_mcp_test installations -- schemas are identical) against the Collection Tests site (id 628848057f4f99d7ae0b8128). Each capability was either exercised (called with real arguments and the result observed) or spec-only (schema present but not exercised live). Reference docs used: Webflow Data API v2.0.0 + Webflow Designer Extension API documentation. Test date 2026-05-10.

Two transports, very different prerequisites

The Webflow MCP exposes two separate surfaces that behave nothing like each other operationally.

Surface

Auth

Designer must be open

Stability

Best for

Data tools (REST)

Site / workspace token

No

Stable, fast

CMS, scripts, webhooks, page settings, publishing

Designer tools (UI bridge)

App linked into Designer

Yes -- user clicks launch link

Sensitive to tab focus and parallel calls

Building/modifying canvas, classes, variables, components

⚠️ Designer prerequisite. Every Designer-tool call returns a hard error containing the launch URL until the user clicks it (https://.design.webflow.com?app=) and brings the Designer tab to the foreground. The bridge then drops if the tab loses focus or if multiple Designer tools are called in parallel. This is the single biggest UX gotcha. There is no headless mode.

TL;DR -- The headlines

  1. The MCP is a curated subset of the public APIs, not a 1:1 wrapper. It gives you the Webflow primitives most often needed for content automation and AI-assisted design -- but Forms, Ecommerce, Memberships, asset upload, interactions/animations, page deletion, and most workspace-level actions are simply absent.
  2. Component definitions cannot be created from scratch by either API. The only way is transform_element_to_component -- convert an existing canvas element. Component properties (the named slots/variables that make a component reusable) cannot be defined or overridden via the MCP at all.
  3. Interactions / Animations / Page Transitions are completely missing from both transports. The Webflow Designer's interactions panel is not addressable through the MCP at all.
  4. Asset binary upload is missing. You can rename, retag, foldering, but no upload tool exists in either transport.
  5. A real bug: every Data-API endpoint that returns 204 No Content (item delete, field delete, webhook delete) reports "undefined" is not valid JSON -- even though the call succeeded. Verify by re-listing.
  6. Localization requires secondary locales to already exist. The Data API explicitly rejects calls with the primary locale ID: "The provided locale must be a secondary locale." Without a configured secondary locale you cannot exercise the localization endpoints.
  7. CMS Collection element is a hollow shell on the Designer side. You can create the wrapper, but cannot bind it to a collection or add an Item template -- dynamic CMS templating cannot be built via the MCP.

Coverage map at a glance

Capability area

Data API

Designer

Notes

Sites -- list, get, publish

βœ…

n/a

Cannot create/duplicate/delete a site

CMS -- collections create/get/list

βœ…

n/a

No collection delete/rename/duplicate

CMS -- fields (16 types) create/update/delete

βœ…

n/a

Update only changes name/help/required; cannot change type or option choices or reference target

CMS -- items create/list/update/archive/publish/delete

βœ…

n/a

Publish blocked until site is first whole-site published

CMS items -- separate live vs staged endpoints

⚠️

n/a

Only the staged path is exposed; can't create-and-publish in one call

Pages -- list, metadata, settings, content (text + props)

βœ…

partial

Designer creates/switches; no delete/duplicate

Components -- list, content, properties (read + per-locale write)

βœ…

βœ…

Definitions only via transform_element_to_component; no prop API

Elements -- read, query, create (32 types), modify, delete

n/a

βœ…

Form fields placement-restricted; CMS collection child Heading rejected

Styles -- class, combo, breakpoints (7), pseudo (16), variable-as-value

n/a

βœ…

Type compatibility enforced (Size cannot bind to padding)

Variables -- collections, modes, 5 types, alias, custom CSS

n/a

βœ…

Rename and delete are BETA and silently no-op in our tests

Assets -- list, folders, update meta

partial

partial

No upload, no delete, no folder delete/rename

Custom code -- register inline, apply to page

partial

n/a

No hosted-URL register; no site-level apply; only delete-all per page/site

Webhooks -- CRUD (17 trigger types)

βœ…

n/a

get_webhook doesn't include lastTriggered

Comments -- read threads/replies

βœ…

n/a

Read-only by design

Enterprise -- 301s, robots.txt, well-known, activity logs

βœ… (plan-gated)

n/a

Returns plan error on non-Enterprise sites

Localization -- secondary-locale content + property edits

βœ…

n/a

Primary locale ID is explicitly rejected

Forms (read submissions, list forms)

❌

❌

Entirely missing

Ecommerce (products, orders, inventory)

❌

n/a

Entirely missing

Users / Memberships

❌

n/a

Entirely missing

Interactions / Animations / Page Transitions

❌

❌

Not addressable at all

Backups, branches, versioning

❌

❌

UI only

Site-level SEO defaults / sitemap / favicon / 404

❌

n/a

Missing

Workspace (sites: create, duplicate, delete, transfer)

❌

n/a

Missing


CMS -- Data API surface

Collections

Action

Status

Notes

get_collection_list

βœ…

Lite list -- no field schema

get_collection_details

βœ…

Full schema with field types, ids, validations

create_collection

βœ…

Auto-creates Name (required) and Slug (required, regex-validated) fields

delete_collection

❌

Webflow REST supports it; MCP omits it

rename_collection / change_slug

❌

No tool

duplicate_collection

❌

Manual: read + create + for-each-field + for-each-item

Field types -- confirmed creatable (16)

PlainText, RichText, Number, Color, DateTime, Email, Phone, Link, VideoLink, Switch, Image, MultiImage, File (via create_collection_static_field); Option (single-select via create_collection_option_field); Reference, MultiReference (via create_collection_reference_field).

Field types not supported via the MCP

  • Set (multi-select / multi-option)
  • Ecommerce-specific (SkuValues, SkuProperties, currency/price)
  • Membership-specific (User)

Field-level operations

Action

Status

Notes

update_collection_field

βœ…

Only changes displayName / helpText / isRequired. Cannot change field type, option list, reference target, number precision.

delete_collection_field

⚠️ bug

Returns "undefined" is not valid JSON" -- but the field is deleted (verified)

Items

Action

Status

Notes

create_collection_items

βœ… (staged)

Always staged regardless of isDraft:false. No create_item_live exposed.

list_collection_items

βœ…

limit, offset, name, slug, sortBy, sortOrder, cmsLocaleId. No filter by field value or lastPublished range.

update_collection_items

βœ…

Bulk array. isArchived, isDraft fields editable. Bad references β†’ 400

publish_collection_items

⚠️ conditional

409 Conflict: "The site is not published." until the site has been whole-site published once

delete_collection_items

⚠️ bug

Same 204 parse error; deletion did happen

unpublish_collection_items

❌

REST has DELETE /items/live; MCP doesn't expose it

Field-value gotchas observed

  • VideoLink is asymmetric: write "https://youtu.be/...", server stores a structured object including metadata.html (embedly iframe), thumb, aspectRatio, videoId etc. Diff tools must normalise.
  • Option requires the option ID (not the name) when writing items.
  • update_collection_items requires name and slug in fieldData even on partial field updates.
  • Every item carries a cmsLocaleId even on single-locale sites (the primary locale's id) -- but get_site does not return a locales array on single-locale workspaces, so the only way to discover the primary id is to read any item or to receive an error from a localized endpoint.

Pages & Components -- Data API

Pages

Action

Status

Notes

list_pages

βœ…

Includes collectionId for CMS template pages, publishedPath, branching flags

get_page_metadata

βœ…

get_page_content

βœ…

Returns flat nodes[] of text/image/etc. -- 121 nodes on the test home page

update_page_settings

βœ… (schema)

Updates SEO/OG, slug, parentId (move), draft, archived, isMembersOnly, canBranch etc.

update_static_content

βœ… (schema)

Per-locale text + component instance prop overrides. Requires secondary locale id

Pages -- confirmed gaps

Capability

In MCP?

Notes

Delete page

❌

Designer Extension API has no documented delete-page either

Duplicate page

❌

Move page (set parentId)

βœ…

Via update_page_settings.body.parentId

Set page is-homepage / set password

❌

Read-only flags only

Branching lifecycle (create branch / merge / discard)

❌

Read-only flags only

Components (Data API)

Action

Status

Notes

list_components, get_component_content, get_component_properties

βœ…

Read access independent of Designer

update_component_content, update_component_properties

βœ…

Per-locale value overrides only -- requires secondary locale id

create_component / delete_component

❌

Only the Designer side has create (via element transform) and delete (via unregister_component)


Scripts, Webhooks, Comments, Enterprise -- Data API

Scripts (custom code)

Action

Status

Notes

list_registered_scripts

βœ…

add_inline_site_script

βœ…

Inline only -- limit 2000 chars. Returns hosted CDN URL

upsert_page_script

βœ…

Replaces all App-applied scripts on that page (header or footer). No granular per-id apply

get_page_script / list_applied_scripts

βœ…

List returns 404 "Custom code block not found" until the App has applied at least one script

delete_all_page_scripts / delete_all_site_scripts

βœ… (schema)

No granular delete by script id

Register hosted (URL) script

❌

REST supports it; MCP doesn't

Apply script at site level

❌

REST has site upsert; MCP only exposes per-page

Webhooks

list_webhooks, get_webhook, create_webhook (17 trigger types), delete_webhook -- all confirmed.

delete_webhook exhibits the 204 parse-error bug (succeeds + reports parse error). get_webhook does not include lastTriggered despite Webflow REST exposing it.

Trigger types accepted (verified enum):

form_submission, site_publish, page_created, page_metadata_updated, page_deleted, ecomm_new_order, ecomm_order_changed, ecomm_inventory_changed, user_account_added, user_account_updated, user_account_deleted, collection_item_created, collection_item_changed, collection_item_deleted, collection_item_published, collection_item_unpublished, comment_created.

Comments

Read-only by design -- list_comment_threads, get_comment_thread, list_comment_replies. No create/reply/resolve in REST or MCP.

Enterprise

Schemas exist for 301_redirects CRUD, robots.txt PUT/PATCH/DELETE/GET, well-known files, site activity logs. Every action returns "This site does not have an Enterprise hosting plan." on non-Enterprise sites -- plan-gated.


Designer surface -- live tests

βš™οΈ Operational notes for the Designer bridge. Foreground-tab requirement, parallel-call sensitivity, and partial-batch returns are reproducible. A write call that times out can still apply its change (create_page did so during testing). See the Quirks table at the bottom for the full list.

Pages (de_page_tool)

Action

Status

get_current_page

βœ… -- id, name, slug, parentId, description, title, kind (static/cms/utility), isHomepage, isDraft

create_page

βœ… -- auto-switches to the new page

create_page_folder

βœ… schema

switch_page

βœ… -- implicit on create

delete_page / rename / SEO write / set homepage / publish single page

❌

Elements (element_tool, element_builder, whtml_builder, element_snapshot_tool)

Section, Container, BlockContainer, Heading (h1-h6), TextBlock, Paragraph, Button, TextLink, LinkBlock, Blockquote, DivBlock, RichText, CodeBlock, HtmlEmbed, Video, YouTubeVideo, Lightbox, Tabs, Slider, Dropdown, DOM (any tag), BY_CUSTOM_TAG, Form (returns as FormWrapper), CMSCollection (returns as DynamoWrapper), ComponentSlot (returns as Slot -- only inside open_component_view).

FormBlockLabel, FormTextInput, FormTextarea, FormCheckboxInput, FormRadioInput, FormSelect, FormFileUploadWrapper, FormButton -- all reject placement outside a Form. Server enforces and fails the entire batch, not just the offending element.

You can create a CMSCollection element (it renders as the design-time placeholder "Double-click to connect to a collection"). You cannot:

  • Bind it to a Webflow CMS collection (no set_collection_source action).
  • Add an Item template inside it. Heading (and most non-Block children) rejected with "Heading can not be placed in a Collection List Wrapper." There is no CMSCollectionItem element type in the enum.

β†’ Dynamic CMS templating cannot be built via the MCP.

Action

Status

set_text / set_link / add_or_update_attribute / update_id_attribute / set_heading_level

βœ…

set_image_asset

⚠️ unverified (no assets to bind on this site)

set_style / select_element / remove_element

⚠️ schema present, not exercised destructively

query_elements

βœ… -- filters by type / text / style / tag / attribute / component_name / slot_name; supports scope, depth, return_parent (parent or ancestor). Text filter does not match content of elements created by element_builder (text lives in a child String node)

get_all_elements

βœ… -- heavy: full body of test page = 175 KB

Setting key

Result

domId (static_text)

βœ…

attributes (with attribute array, even all-static)

❌ "Setting "attributes" is not applicable to this element"

textContent (static_text)

❌ Not applicable even on

DOM tag

Bindings (source_type of prop/cms/page/locale/localeItem)

⚠️ Schema present; not exercisable for CMS-bound elements because the only target (CMS Item template) is not creatable

βœ… Confirmed working. Single root element required. CSS may use Webflow breakpoint media queries (max-width: 991px, 767px, 479px). @keyframes and arbitrary @media ranges are documented as not allowed. Classes referenced in CSS are auto-created as Webflow style classes.

element_snapshot_tool βœ… returns inline PNG. Confirmed for both a single element and the entire page body.

Styles (style_tool)

Action

Status

create_style (base + combo via parent_style_names)

βœ…

update_style per breakpoint_id and per pseudo

βœ…

update_styleremove_properties

βœ…

update_style with properties[].variable_as_value

βœ… -- but type-compatible only (Size variable rejected on padding with "Property padding does not support setting a variable of type length")

get_styles / query_styles (BETA)

βœ… list / spec only

remove_style (base)

βœ…

remove_style (combo with parent_style_names)

⚠️ Returned "Style is-large, mcp-test-class not found" even though both existed; cascaded with base removal

Breakpoint enum:xxl, xl, large, main, medium, small, tiny. Pseudo enum:noPseudo, nth-child(odd), nth-child(even), first-child, last-child, hover, active, pressed, visited, focus, focus-visible, focus-within, placeholder, empty, before, after.

Variables (variable_tool)

Action

Status

create_variable_collection / create_variable_mode

βœ…

All five types: create_color_variable / create_size_variable / create_number_variable / create_percentage_variable / create_font_family_variable

βœ…

Static value, alias (existing_variable_id), and custom CSS expression (calc(100vh - 80px))

βœ…

update_*_variable (with optional mode_id)

βœ…

query_variables (BETA)

βœ… -- filters by name / css_name / type / collection

rename_variable (BETA)

❌ Returned no result; standalone retry returned empty array; variable name unchanged

delete_variable (BETA)

❌ Same -- silently no-op

Delete variable mode / collection / reorder / move between collections

❌ Not exposed

Components (de_component_tool, component_builder)

Action

Status

get_all_components / get_component / get_component_metadata

βœ…

transform_element_to_component (the only definition-create path)

βœ… -- optional replace:false keeps original

insert_component_instance / set_component_metadata / rename_component

βœ…

open_component_view / check_if_inside_component_view / close_component_view

βœ…

unregister_component (DANGEROUS)

⚠️ schema only

component_builderinsert_in_slot

βœ… -- slot named "Slot" by default; no slot-rename action found

Define component properties (props with defaults)

❌ Inserted instances always returned props:[]. Designer Extension API has component properties; the MCP does not wrap them.

Set per-instance prop overrides

❌ Schema mentions source_type:"prop" for elements created inside a component -- but no API to define the prop or override it on an instance

Assets (asset_tool, get_image_preview)

Action

Status

get_all_assets_and_folders / update_asset (name, alt, parent folder)

βœ… list; update untested (no assets exist)

create_folder

βœ…

get_image_preview (any URL)

⚠️ untested

Upload binary asset

❌ Missing entirely. Designer Extension API has create-an-asset but the MCP omits it

Delete asset / delete folder / rename folder / move folder

❌ Missing


Localization

Both the Data API and the underlying REST require a secondary locale id for content updates:

  • get_page_metadata and get_page_content accept localeId, but if you supply the primary locale id you get "The provided locale must be a secondary locale."
  • update_static_content and update_component_content and update_component_properties are all per-locale write operations, all secondary-locale-only.
  • The site under test (Collection Tests) has no secondary locales -- so the write paths cannot be exercised end-to-end here.

Everything should work given a configured secondary locale; the surface itself is wired correctly.


Confirmed bugs and quirks


What is completely missing from the MCP

Surfaces documented in the Webflow Data API or Designer Extension API but not wrapped at all by the MCP:

Absent transports / surfaces

  • Forms -- list forms, get form, list/get/update/delete submissions, list submissions by site.
  • Ecommerce -- products, SKUs, orders (list/get/update/fulfill/unfulfill/refund), inventory, ecommerce settings.
  • Users / Memberships -- list/get/update/delete user, invite user, list access groups.
  • Asset upload -- REST POST /sites/:id/assets; Designer Extension create-an-asset. No MCP equivalent.
  • Asset delete, asset folder delete/rename/move.
  • Custom code: register hosted (URL) script.
  • Custom code: site-level apply (only per-page apply is exposed).
  • Granular delete of a single applied script (only delete-all per page or per site).
  • Token introspection / authorized-by.
  • Workspace audit logs get action.
  • Workspace management -- create/update/delete workspace, get site plan.
  • Site lifecycle -- cannot create, duplicate, transfer, or delete a site.

Absent capabilities within wrapped surfaces

  • CMS -- collection delete / rename / duplicate; field type change; option-list edit; reference-target change; create-and-publish in one call; unpublish item; filter items by field value or lastPublished range; full-text search.
  • Pages -- delete page; duplicate page; set is-homepage; set password; per-page publish; branching lifecycle; site-level SEO defaults; sitemap config; favicon / webclip; 404 page.
  • Components -- define a component definition from scratch; define component properties; override properties on a specific instance; detach a component instance; rename a slot.
  • Variables -- rename (BETA tool exists but no-ops); delete (same); delete a mode; delete a collection; reorder; move variables between collections.
  • Styles -- rename a class; reorder classes; duplicate a class; detach a class from a single element override.
  • Elements -- move an element; reorder children; duplicate an element. (Workaround: read schema + recreate in target.)
  • Interactions / Animations / Page Transitions -- completely absent. The Webflow Designer's Interactions 2.0 and Webflow Animations are not addressable.
  • Backups, branches, versioning -- UI only.

Recommended workflows & gotchas

βœ… For content automation (the strongest use case): CMS via Data API is reliable. Build collections + fields + items + publish. Just remember to (a) publish the site once via UI before publish-items will succeed, (b) ignore the empty-body parse error on deletes, and (c) treat the staged endpoint as the only writer.
πŸ› οΈ For AI-assisted design via Designer: keep the Designer tab in the foreground at all times. Issue Designer calls serially -- parallelism is the most common cause of timeouts. Treat write timeouts as "may have succeeded" -- re-query before retrying. Build component definitions by first creating an element on the canvas, then calling transform_element_to_component.
🚫 Don't try to: build dynamic CMS templates (CMS Collection element is a hollow shell), wire up interactions/animations, upload images, define component props, or operate on Forms/Ecommerce/Memberships through the MCP. None of those paths exist.

Test artifacts left on the site

These artifacts were created during the audit and remain on the site (the MCP does not expose delete tools for them):

  • PageMCP Test Page (id 6a00417e68bd8a66e81e7413) -- no delete-page action in either MCP transport.
  • ComponentsMCP Card (id 8ba3db6a-ea58-13b5-6d20-13698393f937) and MCP Chip (id 53b3c687-2718-269a-d2b8-74d902b865a2) -- unregister_component not exercised.
  • Asset folderMCP Test Folder -- no delete-folder action.
  • Variable collectionMCP Test Tokens and MCP variables (Brand Color, Spacing Lg, Z Index Modal, Hero Width, Body Font, Hero Height, Brand Alias) -- delete_variable BETA action returned empty.
  • CMS collectionMCP Capability Test (id 6a0022ef57fc602a9927b09d) and one item Test Item One -- no delete_collection action.
  • Inline scriptMCPTest (id mcptest, hosted CDN URL) -- no per-id delete; the delete_all_site_scripts action would be needed.
  • Webhook for collection_item_created was created and successfully deleted (verified).
  • Style classmcp-test-class was successfully deleted; combo is-large reported "not found" (likely cascaded).

These can be cleaned up manually in the Webflow UI when convenient.


Reported (unverified) -- pending verification

πŸ“£ Provenance. The items below were relayed by a third party (a CMS-to-Webflow migration team) and have not yet been reproduced against a live test. They are logged here for tracking and should be promoted into the verified audit above once confirmed -- or removed if they fail to reproduce. Reported: 2026-07-17.

1. JSON-LD structured data -- not writable via REST (Reported -- 2026-07-17)

Reported that the Webflow REST API cannot add structured data (JSON-LD) in the dedicated page section. This is not currently covered by the live audit above (the closest existing row is the missing site-level SEO defaults, which is a different capability). To verify: attempt a JSON-LD write via the page SEO / update_page_settings path on the Collection Tests site.

2. Rich Text component-property values -- not writable (Reported -- 2026-07-17)

Reported that Rich Text-type component property values cannot be written:

  • Via the MCP -- cannot write to a component property of type Rich Text.
  • Via the Designer Extension API (underlying) -- component properties can be updated except Rich Text, where an HTML structure cannot be inserted.

This refines rather than contradicts the verified findings above. The audit records that update_component_properties (Data API) works for per-locale value overrides, and that component props cannot be defined/overridden on the Designer side at all. The reported nuance adds a property-type exception (Rich Text) that the audit did not test. To verify: attempt a Rich Text prop value write in a secondary locale via update_component_properties.

πŸ”€ Layer note (reconciliation). The reporter distinguishes three layers -- the underlying REST API, the MCP wrapper, and the underlying Designer Extension API -- whereas the audit above models two transports inside the MCP (Data tools / Designer tools). The reporter's "Designer API can update props except Rich Text" describes the raw Designer Extension API, not the MCP; the audit's "props can't be touched" describes the MCP wrapper, which does not expose that capability. The two are consistent: the MCP simply does not wrap the Designer Extension API's component-property support.
Table of Contents
Comments
Did we just make your life better?
Passion drives our long hours and late nights supporting the Webflow community. Click the button to show your love.