AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Elementor Mcp

skill-emersimeon-claude-elementor-kit-files · by emersimeon

Helps with WordPress + Elementor work via the elementor-mcp MCP server — building new pages, editing existing ones, inspecting site state, or exploring what's possible. Asks what the user wants before acting. Use when the user references the Elementor MCP, invokes `/elementor-mcp`, or runs `mcp__elementor__elementor-mcp-*` tools. Also covers initial install of the MCP Adapter + elementor-mcp plug…

No reviews yet
0 installs
13 views
0.0% view→install

Install

$ agentstack add skill-emersimeon-claude-elementor-kit-files

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-emersimeon-claude-elementor-kit-files)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Elementor Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Elementor MCP Skill

You are operating against a WordPress site with the elementor-mcp server (https://github.com/msrbuilds/elementor-mcp) connected via the WordPress MCP Adapter. This skill captures everything I learned the hard way the first time through, so subsequent sessions start at expertise level.

🛑 First Action Protocol — ASK BEFORE DOING

When this skill is invoked, do not start running tools. Ask the user what they want first.

If the user's invocation message already contains a clear task — "build me a hero section from index.html", "show me my current global colors", "change the burgundy to navy" — proceed with that task directly.

Otherwise (invocations like /elementor-mcp alone, or "use the Elementor MCP" with no follow-up), respond with this menu and wait for the user to pick:

What would you like to do with your Elementor site?

  1. Build       — create new pages or sections from a design
  2. Edit        — change something on an existing page
  3. Reference   — inspect current state (pages, colors, fonts, content)
  4. Explore     — show me what's possible / what can the MCP do here

Do not silently default to "build" — that's the most destructive action and forces a path the user may not want. Wait for the user to choose 1/2/3/4 (or describe their task in their own words) before invoking any MCP tool other than the harmless read-only ones at the bottom of this section.

Read-only "smoke test" calls that are always safe to run

When the user picks any option, you can run these before asking follow-up questions, since they help frame the next response:

  • mcp__elementor__elementor-mcp-list-pages — confirms auth + lists what's there
  • mcp__elementor__elementor-mcp-get-global-settings — current colors/fonts kit

That's it for unprompted tool calls. Anything that creates, modifies, or deletes data requires the user to have explicitly asked for it.

When this skill applies

  • The user mentions Elementor MCP, types /elementor-mcp, or says "use the Elementor MCP"
  • A .mcp.json in the project registers an MCP server pointing at wp-json/mcp/elementor-mcp-server
  • The user asks to build, edit, inspect, or troubleshoot an Elementor page
  • Tools beginning with mcp__elementor__elementor-mcp-* are available

First-session setup (when MCP not yet connected)

If the user has a WordPress site but no .mcp.json and no elementor MCP loaded:

  1. Check whether they're using Local-by-Flywheel or a live host. Setup paths differ.
  2. Run the bundled setup script at ~/.claude/scripts/setup-elementor-mcp.sh — it handles plugin install, auth wiring, and .mcp.json generation interactively for both flavors.

``bash bash ~/.claude/scripts/setup-elementor-mcp.sh ``

  1. After the script completes, instruct the user to quit and reopen Claude Code in the project directory so the new .mcp.json is picked up.
  2. On reopen, the deferred MCP tools will be exposed via ToolSearch — load the ones you need with select: queries.

If something fails, see "Setup gotchas" below.

Working session conventions

Always do this first

mcp__elementor__elementor-mcp-list-pages   # confirms auth + lists existing pages
mcp__elementor__elementor-mcp-get-global-settings   # see existing colors/fonts kit
mcp__elementor__elementor-mcp-get-container-schema  # ground truth on flex_* key names

The container schema is large (~50KB). Read it once, then write down the keys you'll use in your reply text so you don't need to re-fetch it. Critical keys:

  • flex_direction, flex_justify_content, flex_align_items, flex_gap, flex_wrap — note the flex_ prefix on justify/align (issue #32 was about these being written under wrong keys in older versions)
  • content_width: "boxed"|"full" + boxed_width: {unit, size, sizes}
  • min_height: {unit, size, sizes} — use unit vh for full-screen heroes
  • padding/margin: {unit, top, right, bottom, left, isLinked}isLinked: false when sides differ
  • background_background: "classic"|"gradient"|"video" — must be set first or other background_* keys are ignored
  • background_overlay_* — separate parallel set for overlays. background_overlay_opacity: {unit:"px", size: 0.5} (yes, the unit is px even for opacity — quirk of the schema)

Widget call convention — flat params, NOT nested in settings

This bit me hard the first time. The add-* shortcut tools take their settings as top-level parameters, not inside a settings: {} object:

// ✓ CORRECT
mcp__elementor__elementor-mcp-add-heading({
  post_id: 11,
  parent_id: "abc123",
  title: "where estates are entrusted",
  header_size: "h1",
  title_color: "#FFFFFF",
  typography_typography: "custom",       // ← required to enable typography
  typography_font_family: "Cormorant Garamond",
  typography_font_size: {size: 110, unit: "px"},
  typography_font_weight: "300",
  typography_line_height: {size: 0.98, unit: "em"},
})

// ✗ WRONG — silently fails or returns "title is required"
mcp__elementor__elementor-mcp-add-heading({
  post_id: 11,
  parent_id: "abc123",
  settings: {title: "...", typography_font_family: "..."}
})

add-container is the exception — it takes a settings: {} object. Don't generalize from one to the other.

Always set typography_typography: "custom"

Without this, the other typography_* keys are ignored. Same applies to css_filters_css_filter: "custom" for image filters, etc. — these "enable" flags are how Elementor knows you want to override defaults.

Italic emphasis pattern

Display headings often need a single italic-emphasized word. Don't use a separate widget — just inline `` in the title:

title: "A quiet practice for an uncommon clientele."

Cormorant Garamond and most luxury serifs have italic variants that auto-load when `` appears. Confirm via the rendered page; if italics fail, the global typography needs the italic variant explicitly enabled.

The widget-vs-HTML decision — DEFAULT TO NATIVE WIDGETS

> 🚨 CRITICAL ANTI-PATTERN — read this first. > > Do NOT paste an entire HTML page into one HTML widget. Do NOT build a homepage that is "1 container with 3 HTML widgets inside." That is not building with Elementor — that is using Elementor as a wrapper around a static webpage. The user cannot edit it in the Elementor visual editor, cannot reuse the design tokens, and cannot iterate on it without going back to source code. > > If you find yourself thinking "I'll just dump this section as HTML, it's faster," STOP. Break it into native widgets.

Always default to native widgets

For every section the user wants, build it from native Elementor widgets:

  • Headingsadd-heading widget (supports inline `` for italic emphasis)
  • Body copyadd-text-editor widget
  • Imagesadd-image widget (NOT an `` tag inside an HTML widget)
  • Buttons / CTAsadd-button widget (NOT an `` styled as a button)
  • Layout / spacingadd-container with proper flex_* settings (NOT ``s with CSS flex)
  • Listsadd-icon-list widget
  • Tabsadd-tabs widget
  • Accordions / FAQsadd-accordion widget
  • Forms → Fluent Forms shortcode via add-shortcode widget
  • Nav menu in headers → UAE Nav Menu widget (uael-nav-menu)

When HTML widget IS allowed (narrow list — exceptions only)

Only reach for an HTML widget in these specific cases. Anything not on this list goes through native widgets.

  1. Tab/accordion content with rich layout. add-tabs only accepts tab_content as a string of HTML, so a multi-card grid inside a tab MUST be HTML. (But the wrapping Tabs widget itself is still native.)
  2. Decorative-only flourishes with no native equivalent — a thin gold rule with a CSS-pseudo-element flourish, an animated underline that grows on hover, a gradient overlay on a child element. Even then, prefer to pair it with a native widget rather than replacing one.
  3. Form HTML as a flagged placeholder when no real form plugin is wired up yet — and you must explicitly tell the user "form is visual only, doesn't capture submissions."
  4. Site-wide CSS overrides scoped to a specific Elementor element ID (e.g., styling the tab strip of an add-tabs widget that the widget controls don't expose). These should be small style blocks, not whole sections of markup.

What about card grids of 4+ items?

Earlier versions of this skill said "use one HTML widget for card grids — it's faster than 50 widget calls." That advice was wrong because it led to non-editable pages.

The correct path for card grids:

  • Build the first card with native widgets (Container → Image → Heading → Text Editor → Button)
  • Use duplicate-element to copy it 3+ more times
  • Use update-element to change the copy/image on each duplicate
  • Wrap them in a parent Container with flex_direction: row and flex_wrap: wrap

This is more widget calls, yes, but the result is a real Elementor card grid the user can edit, restyle globally, or reuse as a template.

Cross-widget styling — ``-only HTML widgets

When you need to style a native widget from outside (e.g., overriding the Tabs widget tab strip styles that the widget controls don't expose), use a **`-only HTML widget**: it contains ONLY a ` block — no markup, no rendered content. Scope every selector to the parent Elementor element ID:


.elementor-element-f8d1545 .elementor-tab-title {
  text-transform: uppercase !important;
  letter-spacing: .26em !important;
}
.elementor-element-f8d1545 .elementor-tab-title.elementor-active {
  border-bottom-color: #171615 !important;
}

The f8d1545 is the element_id returned when you created the tabs widget. Always grab and remember these IDs — they're the only stable selector across page reloads.

> ⚠️ An HTML widget used for cross-widget styling MUST contain only ``. If you find yourself adding HTML markup (divs, anchors, spans with text content) alongside the style block, you're falling back into the anti-pattern at the top of this section. Stop. That markup belongs in native widgets.

When the user asks to BUILD — building order

> Use this section only when the user has explicitly asked you to build something. Do not run this flow on a bare /elementor-mcp invocation.

For a new page, build top-down section by section, in small commits, verifying after each:

  1. update-global-colors + update-global-typography — establish design tokens
  2. create-page({title, status: "publish", template: "elementor_canvas"}) — Canvas template removes theme header/footer chrome so your design is the only thing on the page
  3. (Via WP-CLI) Set as static front page: wp option update show_on_front page; wp option update page_on_front
  4. Build sections — outer container → inner content container (boxed, max-width 1360px-ish) → content
  5. After each section: get-page-structure(post_id) to verify nesting, or just curl the front page
  6. Pause for human review before building header/footer (which use Header Footer Elementor templates, a different flow)

When the user asks to EDIT

Approach existing pages surgically — don't rebuild what you don't have to:

  1. list-pages to find the page they're editing
  2. get-page-structure(post_id) to see the current widget tree and grab element IDs
  3. For a specific element they describe ("the hero headline", "the third listing card"), use find-element if needed, then update-element with only the fields that change
  4. Verify the edit by re-reading get-page-structure or curling the rendered page
  5. Never delete a section unless they explicitly ask — even when restructuring. Use move-element or update-element first.

When the user asks to REFERENCE / INSPECT

Read-only tools, no writes. Useful for "show me", "tell me", "what's", "list" requests:

  • list-pages — what pages exist
  • get-global-settings — colors, typography, layout settings
  • get-page-structure(post_id) — what's on a page
  • get-element-settings(element_id) — exact settings of one widget
  • find-element(post_id, ...) — locate a widget by content/type

Format the response as a clear summary, not a JSON dump. The user wants understanding, not raw data.

When the user asks to EXPLORE / "what can you do?"

Give a short menu (don't dump all 75 tools). Point them at the four modes from the First Action Protocol with concrete examples:

  • "Build a homepage from this HTML mockup" → mode 1
  • "Make the hero text 20% smaller" → mode 2
  • "Show me what colors are currently set globally" → mode 3
  • "What pages exist on the site?" → mode 3

Then ask which mode they want.

Header/Footer notes

The MCP plugin's create-theme-template tool requires Elementor Pro. With Elementor Free, headers and footers are built using Ultimate Addons for Elementor (UAE) by Brainstorm Force (the kit's setup wizard auto-installs this; alternatively the lighter Header Footer Elementor (HFE) plugin from the same company also works — both share the same elementor-hf post type).

Building a site-wide header

  1. Create the WordPress menu first. Tell the user to go to WP Admin → Appearance → Menus, name it (e.g. "Main"), add the pages they want, and save. The MCP cannot create WP nav menus directly — this step is a one-minute manual action.
  1. Create the header template post. Use create-page with post_type: "elementor-hf" and a title like "Site Header". Then set the following post meta via WP-CLI or the update-element flow:
  • ehf_template_type = "type_header" (or "type_footer" for footers)
  • display-on-canvas = "yes" (displays site-wide; alternative meta keys like ehf_target_include_locations may apply for narrower scopes)
  1. Build the layout. A row container with three children:
  • Left: logo (Heading widget with brand name in display serif, OR Site Logo widget if UAE is installed)
  • Center: UAE Nav Menu widget (uael-nav-menu) pointed at the WordPress menu by name. UAE's nav menu widget is free and handles mobile hamburger, dropdowns, hover states, active-page highlighting automatically — much cleaner than rendering nav as raw HTML.
  • Right: Button widget with "Contact" or "Get In Touch" CTA
  1. Verify display. After building, instruct the user to check WP Admin → Appearance → Header Footer Builder → confirm the Display On rule is set to "Entire Website."

When UAE Nav Menu isn't available

If only HFE (the lighter plugin) is installed without UAE: use the Shortcode widget calling [wp_nav_menu menu="Main" container=""] — WordPress's built-in shortcode renders the menu as a real `` with all the right classes for active-page highlighting and responsive styling.

Do not fall back to manually listing the menu items inside an HTML widget — that hard-codes the navigation in two places (the WP menu AND the Elementor template) which means future menu edits won't reflect in the header. Always render the menu through [wp_nav_menu] or the UAE widget.

Footer pattern

Identical post type (elementor-hf) but ehf_template_type = "type_footer". Layout is typically a 4-column container (brand block + 3 link columns) on a dark background, with a bottom row containing copyright + social icons.

Forms — Fluent Forms (the recommended path)

Elementor's native Form widget is Pro. The kit's wizard auto-installs Fluent Forms as the free workaround. The flow is split: the user builds the form, then Claude wires it into the page and styles it.

The split — what Claude does vs. what the user does

The user does (manual, ~2-3 min in WP Admin):

  1. Fluent Forms → New Form → pick the Contact Form template (pre-built with Name / Email / Subject / Message) OR start from blank
  2. (optional) Drag in extra fields — Phone, dropdown, etc.
  3. **Save

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.