WordPress Plugins
Free Tools
Claude Skills
Pricing Blog Case Studies Switch to Royal Plugin Graveyard Support My Account Cart
Support Royal MCP Elementor Tools Reference

Royal MCP’s Elementor Tools — Reference

Royal MCP ships eleven Elementor tools today. This page is the per-tool reference: what each one does, what arguments it takes, what to ask Claude, and the gotchas worth knowing. The design philosophy behind the deliberately narrow tool surface is on the blog; this page is the how. For the tested workflow patterns that compose these tools into safe sequences (clone-and-customize, bulk find-and-replace, template application), load our Elementor Claude Skill.

Prerequisites

Royal MCP is installed and connected to your AI client of choice (Claude, ChatGPT, or another MCP-capable tool). Elementor (free or Pro) is active on your site. When both are present, all eleven Elementor tools auto-register — no configuration.

Why the Tool Set Stays Narrow

The design commitment: never generate Elementor JSON from scratch — always work from an existing-known-good source. Every tool below either reads a page, clones a page, or modifies content inside a page that already exists. None of them try to invent Elementor’s widget schemas from a prompt. That commitment is what keeps the tool surface deliberately narrow.

Atomic widgets (Elementor 4.0+ Editor V4 elements) pass through opaquely on clones. We don’t decode atomic schemas because Elementor itself may shift them — and shift them they have (the 4.1 Classes API refactor broke direct _elementor_data writes in third-party tools that decode). Working from a known-good source survives that.

Tools at a Glance

Tool Purpose Best used when
elementor_clone_page Duplicate a page with fresh element IDs Building a variant of an existing page
elementor_replace_text Bulk text substitution across widget settings Retargeting a cloned page (city, brand, product)
elementor_replace_image Swap image URLs across image-bearing widgets Retargeting hero, gallery, background images on a clone
elementor_get_page_outline Compact structural summary of a page (~2KB) Letting Claude reason over a page’s shape before editing
elementor_get_widget_settings Read full settings JSON for a single widget by element ID Inspecting an element before a targeted modification
elementor_list_local_templates Enumerate saved templates from the Library Finding an existing template to import into a page
elementor_import_template Create a new template from a JSON payload Storing a design in the Library for reuse
elementor_add_widget Insert a new widget or container into a page Adding a specific widget to a specific spot
elementor_apply_template_to_page Insert an existing library template onto a target page Reusing a saved section or layout on another page in one call
elementor_rebuild_post_content Rebuild a page’s post_content from its Elementor tree Restoring WP search / RSS visibility for a page with empty post_content
elementor_rebuild_post_content_bulk Batch-rebuild post_content for every affected page Sitewide fix for empty post_content after past clone operations

The Eleven Tools

elementor_clone_page

Duplicate an existing Elementor page or post as a new draft, with all element IDs regenerated.

What it does

Reads the full _elementor_data tree from the source post, deep-clones the JSON, regenerates every element’s id so the new page opens cleanly in the Elementor editor (Elementor requires unique IDs per document; collisions break the editor). Preserves the Container model, legacy section/column trees, and atomic widgets as-is. Returns the new post ID.

Arguments

  • source_post_id (integer, required) — post or page ID to clone from. Must have Elementor data.
  • new_title (string, required) — title for the new post.
  • new_status (string, optional) — one of draft, publish, private, pending. Defaults to draft.

Example prompt

“Clone the ‘New York Services’ page as a new draft titled ‘Los Angeles Services’.”

Returns

New post ID + edit URL. Draft by default so you can review before publishing.

Gotchas

  • Featured images copy over; large numbers of unique element IDs are regenerated in memory (fine for any real-world page but not tuned for pathological ID counts).
  • Atomic widgets pass through opaquely — their internal IDs are regenerated at the outer element level.

elementor_replace_text

Bulk text substitution across every text-bearing widget on a page.

What it does

Walks the _elementor_data tree and replaces every occurrence of a target string inside known text fields — heading title, text-editor content, button text, image caption/alt, testimonial content, icon-list items, tab labels, accordion titles, call-to-action text, and more. Atomic widgets are skipped (opaque passthrough by design). Case-sensitive by default.

Arguments

  • post_id (integer, required)
  • find (string, required) — text to search for.
  • replace (string, required) — text to substitute.
  • case_insensitive (boolean, optional) — defaults to false.

Example prompt

“On the Los Angeles Services page draft, replace ‘New York’ with ‘Los Angeles’ everywhere.”

Returns

Count of replacements made, so Claude knows how much actually changed.

Gotchas

  • Substring-based, not word-boundary-aware. If “New York” appears inside a longer phrase you don’t want changed, be more specific with the target string.
  • Only rewrites text-field values. Doesn’t touch link URLs, image URLs (that’s elementor_replace_image), or CSS.

elementor_replace_image

Swap image URLs across every image-bearing widget on a page.

What it does

Walks the page and rewrites matching image URLs in the image widget, image-box, background image (on sections, columns, and containers), gallery items, and other image-carrying widgets. Optionally also remaps the corresponding WordPress attachment ID so the Media Library reference stays clean.

Arguments

  • post_id (integer, required)
  • old_url (string, required) — URL to find.
  • new_url (string, required) — URL to replace with.
  • old_id (integer, optional) — old WP attachment ID.
  • new_id (integer, optional) — new WP attachment ID. Passing both old_id and new_id keeps the attachment reference consistent.

Example prompt

“On the LA Services page draft, swap the hero image from hero-nyc.jpg to the LA skyline photo I uploaded on Tuesday.”

Returns

Count of URL replacements. If you passed attachment IDs, the attachment reference count is included too.

Gotchas

  • Only swaps image URLs. Doesn’t touch <a href> destinations or video URLs.
  • WebP conversions and Elementor’s image size variants aren’t automatically regenerated — if the new image needs different derivative sizes, an image-optimizer or force-regen may still be worth running.

elementor_get_page_outline

A ~2KB structural summary of a page for AI reasoning.

What it does

Returns a simplified outline — section/container hierarchy, widget types per slot, and short text snippets pulled from text-bearing widgets. Small enough for an AI to reason over a full page without consuming the entire _elementor_data budget. Useful before calling clone or replace to understand what you’re about to touch.

Arguments

  • post_id (integer, required)
  • No filters — the outline is intentionally compact.

Example prompt

“Show me the outline of the New York Services page so I can decide which sections to change before cloning.”

Returns

Nested JSON: sections/containers with type, layout, child widget types, and short text snippets.

Gotchas

  • Not a full serialization. If you need every setting on every widget, this isn’t the tool — use it as a map, not the territory.
  • Atomic widgets show as opaque nodes (widget type only, no snippet).

elementor_get_widget_settings

Read the full settings object for a single Elementor widget, container, section, or column by element ID.

What it does

Returns the complete raw settings JSON for any element on an Elementor page — the same settings object Elementor’s editor stores in _elementor_data. Complements elementor_get_page_outline (which returns a compact structural summary): use the outline to find the element ID you want, then read this to see exactly what that widget contains before modifying it. Works for widgets, containers, sections, and columns.

Arguments

  • post_id (integer, required) — the Elementor-edited post or page.
  • element_id (string, required) — the element ID (from elementor_get_page_outline output).

Example prompt

“Read the settings for element abc12345 on the Home page so I can see exactly what the hero heading contains before I change it.”

Returns

The element’s full settings JSON, its widget type (or container / section / column type), and its position in the page tree. Ideal precursor to a targeted write via elementor_replace_text, elementor_replace_image, or a raw _elementor_data modification.

Gotchas

  • Cap-checked via read_post on the target.
  • Returns raw settings JSON with no format normalization — you get exactly what Elementor stores, including any nested repeater rows or dynamic-tag markers.
  • Atomic widgets (Editor V4, prefixed a- or e-) return their opaque settings blob unchanged — we don’t decode atomic schemas.

elementor_list_local_templates

Enumerate saved templates from the Elementor Library.

What it does

Lists entries from the elementor_library custom post type — the Elementor Template Library. Returns id, name, type, and last-modified date for each. Filter by type if you’re looking for something specific.

Arguments

  • type (string, optional) — filter: page, section, widget, popup, header, footer, single, archive.
  • limit (integer, optional) — max templates to return. Defaults to 50.

Example prompt

“List my saved section templates so I can pick one to import.”

Returns

Array of templates with id, name, type, and date_modified.

Gotchas

  • Returns metadata only, not the template payload. To use a template, call elementor_import_template with the exported JSON — the Library entries here are references you can inspect in the Elementor editor.

elementor_import_template

Create a new template in the Elementor Library from a JSON payload.

What it does

Accepts the JSON shape the Elementor editor exports (an array of section/container elements), validates the top-level structure, and stores it as _elementor_data on a new post in the elementor_library CPT. Returns the new template post ID.

Arguments

  • title (string, required) — template name.
  • template_type (string, optional)page, section, widget, popup, header, footer, single, or archive. Defaults to page.
  • template_json (string, required) — JSON-encoded array of Elementor elements (the export shape).

Example prompt

“Save this Elementor JSON I exported as a section template called ‘Pricing Grid v2’.”

Returns

New template post ID. Templates land in the Library and are usable from the Elementor editor immediately.

Gotchas

  • Top-level shape validation only — malformed nested settings will still store but may produce editor warnings.
  • Element IDs from the source JSON are preserved; if you’re copying between sites, that’s fine (templates live in their own namespace).

elementor_add_widget

Add a new widget or container to an existing Elementor page.

What it does

Dual-surface tool. The curated path takes high-frequency widget types (container, heading, text-editor, button, image, image-box, icon-box, icon-list, video, divider, spacer) with flat parameters — the tool expands them into Elementor’s canonical settings object internally, saving tokens on the AI side. The raw path takes any widget type plus a full settings object for widgets outside the curated list. Container widgets can include children inline in a single call. Atomic widgets (Editor V4, prefixed a- or e-) pass through opaquely on the raw path.

Common arguments

  • post_id (integer, required) — target post or page. Must be Elementor-edited.
  • widget_type (string, required) — Elementor widget slug (e.g. heading, button, html), or container for a Flexbox container.
  • parent_id (string, optional) — element ID to insert under. Must be a container, section, or column. Omit to append at document top level.
  • position (integer, optional) — zero-indexed position within parent. Omit to append at end.

Curated shortcut arguments (used per widget_type)

  • container: flex_direction (row/column), content_width (boxed/full), children (array of inline child definitions).
  • heading: title, header_size (h1–h6, div, span, p; default h2).
  • text-editor: editor (HTML content).
  • button: text, link_url, link_target (_blank/_self).
  • image / image-box: image_url, image_alt, link_url, link_target.
  • …plus curated params for icon-box, icon-list, video, divider, spacer.

Raw fallback

For any widget type outside the curated list, supply settings as a full Elementor settings object. When settings is provided, raw wins — curated params are ignored.

Example prompt (curated)

“Add an H2 heading ‘Ready to Get Started?’ at the bottom of the LA Services page, then add a button below it saying ‘Book a Call’ linking to /contact/.”

Returns

New element ID, parent context, and an edit URL you can jump straight to in Elementor.

Gotchas

  • Cap-checked via edit_post on the target post.
  • Elementor’s own core MCP module (out of experimental as of WordCamp US 2026, Aug 26) is building a Create_Element_Ability that will cover this same primitive layer inside Elementor itself. We ship elementor_add_widget because it’s genuinely useful today; the tools that don’t overlap with what Elementor’s core module ships — clone, replace, template ops — are the durable ones. See Editing Elementor with Claude for the full context.

elementor_apply_template_to_page

Insert an existing library template onto a target page in one call.

What it does

Bridges elementor_list_local_templates (enumerate) and the raw elementor_add_widget primitive: pass a template ID and a target page, and the template’s sections drop straight onto the page. Same two-click workflow Elementor’s editor exposes, exposed as one MCP call. Element IDs are regenerated on insertion, so re-applying the same template multiple times never collides.

Arguments

  • template_id (integer, required) — template post ID from elementor_list_local_templates (must be an elementor_library CPT entry).
  • target_post_id (integer, required) — page or post to insert into. Must be Elementor-edited (has _elementor_data) or completely empty (will be seeded).
  • position (string, optional)top, bottom, or after_element. Defaults to bottom.
  • after_element_id (string, optional) — required when position="after_element". Element ID (from elementor_get_page_outline) to insert immediately after.

Example prompt

“Apply the ‘Testimonials Section’ template to the LA Services page after the pricing section.”

Returns

List of inserted element IDs + the target’s edit URL and view URL. Emits a 72-hour undo token that restores the target page’s prior _elementor_data if you need to reverse the insertion.

Gotchas

  • Cap-checked as edit_post on target_post_id plus read_post on template_id.
  • Templates apply as-is; if the template was designed for a different brand or layout width, the insertion may need visual review before publish.

elementor_rebuild_post_content

Rebuild a page’s post_content from its Elementor tree.

What it does

Regenerates post_content from _elementor_data using Elementor’s own render pipeline. Fixes pages where post_content is empty — which breaks WordPress core search, RSS excerpts, SEO auto-descriptions, and read-after-write verification. Idempotent by default: skips pages that already have populated post_content unless force=true.

Arguments

  • post_id (integer, required) — post or page ID to rebuild.
  • force (boolean, optional) — defaults to false. When true, rebuild even if post_content is already non-empty (destructive — replaces existing content).

Example prompt

“Rebuild the post_content on the /pricing page — WP search can’t find anything on it.”

Returns

action=repaired with prior_length + new_length, or action=skipped_populated / no_elementor_data depending on the page’s state. Emits a 72-hour undo token capturing the prior post_content.

Gotchas

  • Only rewrites post_content. Doesn’t touch _elementor_data, meta, or any other post field.
  • Use elementor_rebuild_post_content_bulk for sitewide sweeps — single-page calls are for spot repairs.

elementor_rebuild_post_content_bulk

Batch-rebuild post_content across every affected page in one pass.

What it does

Scans every post with _elementor_data + empty post_content and rebuilds them in batch. Fixes bulk SEO / search damage from prior clone operations that shipped without populated post_content. Supports a dry_run preview mode that reports the count + first 20 candidate post IDs without writing anything.

Arguments

  • dry_run (boolean, optional) — defaults to false. When true, report what would be repaired without writing.
  • limit (integer, optional) — max posts to repair per call. Default 50, max 200.
  • post_type (string, optional) — filter to a single post type (e.g. page or post). Default is all post types.

Example prompt (dry run first)

“Dry-run a bulk post_content rebuild across all pages and show me the count.”

Returns

Count of pages repaired (or candidate count in dry-run mode) plus the list of affected post IDs.

Gotchas

  • No undo tokens emitted. Bulk rebuild of empty content is generally not something users want to reverse — take a SiteVault snapshot beforehand if you need reversal capability.
  • Cap-checked as edit_posts.
  • Always dry-run first on a large site to see the candidate count before committing.

Why This Design Survives Elementor Version Boundaries

Elementor 4.1 shipped a Classes API refactor that broke direct _elementor_data write paths for third-party tools decoding widget schemas. The tools that survived that refactor were the ones treating existing pages as opaque known-good sources. That’s the design commitment carried through this whole toolset: read a source, clone it, modify content inside it — never invent structure from a prompt. When Elementor 4.2 or 5.0 shifts the atomic model again (they will), this approach keeps working.