elementor-mcp-agent 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -119
- package/dist/server.js +1592 -288
- package/dist/server.js.map +1 -1
- package/package.json +16 -5
package/README.md
CHANGED
|
@@ -3,29 +3,23 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/elementor-mcp-agent)
|
|
4
4
|
[](./LICENSE)
|
|
5
5
|
|
|
6
|
-
> **Agency-grade MCP server for WordPress Elementor.** Multi-site management, safe Elementor
|
|
6
|
+
> **Agency-grade MCP server for WordPress Elementor.** Multi-site management, safe Elementor edits with backup + auto-rollback + CSS flush, template export/import, global widget detection, screenshots, WP-CLI escape hatch.
|
|
7
7
|
|
|
8
|
-
Built for agencies running many client sites on Elementor / Elementor Pro who want Claude (or any MCP client) to drive the toil — without breaking pages
|
|
8
|
+
Built for agencies running many client sites on Elementor / Elementor Pro who want Claude (or any MCP client) to drive the toil — **without breaking pages**.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
## Why this exists
|
|
13
13
|
|
|
14
|
-
There are
|
|
14
|
+
There are 25+ WordPress MCP servers on GitHub today. None targets the **agency multi-site workflow** with:
|
|
15
15
|
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## ⚠️ Status: early days
|
|
27
|
-
|
|
28
|
-
v0.1.0 is shipped end-to-end (CI green, 14 tests passing, npm + MCP Registry listed) but the tool surface is intentionally focused. Expect rapid iteration. Don't run destructive operations on production without testing on staging first.
|
|
16
|
+
- **Real backup before every edit** (postmeta via WP-CLI when SSH available, JSON file fallback — never silently lost)
|
|
17
|
+
- **Two-call confirmation** for any destructive op (TTL 60s)
|
|
18
|
+
- **JSON validation + auto-rollback** if an edit produces invalid Elementor data
|
|
19
|
+
- **3-level CSS flush fallback** (REST → wp-cli native → option/meta delete → re-save)
|
|
20
|
+
- **Global widget awareness** — preflight check warns if a page references shared widgets
|
|
21
|
+
- **WP-CLI escape hatch** for everything the REST API can't do safely
|
|
22
|
+
- **Screenshots** via headless Chrome (no puppeteer dep)
|
|
29
23
|
|
|
30
24
|
---
|
|
31
25
|
|
|
@@ -35,59 +29,31 @@ v0.1.0 is shipped end-to-end (CI green, 14 tests passing, npm + MCP Registry lis
|
|
|
35
29
|
npx -y elementor-mcp-agent
|
|
36
30
|
```
|
|
37
31
|
|
|
38
|
-
Or globally:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
npm install -g elementor-mcp-agent
|
|
42
|
-
```
|
|
43
|
-
|
|
44
32
|
## Configure
|
|
45
33
|
|
|
46
|
-
The server needs to know about your sites. The simplest path: an env var with a JSON array.
|
|
47
|
-
|
|
48
34
|
```bash
|
|
49
|
-
export ELEMENTOR_MCP_SITES='[
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"application_password": "yyyy yyyy yyyy yyyy yyyy yyyy"
|
|
35
|
+
export ELEMENTOR_MCP_SITES='[{
|
|
36
|
+
"id": "client-acme",
|
|
37
|
+
"url": "https://acme.example.com",
|
|
38
|
+
"username": "admin",
|
|
39
|
+
"application_password": "xxxx xxxx xxxx xxxx xxxx xxxx",
|
|
40
|
+
"ssh": {
|
|
41
|
+
"host": "host.example.com",
|
|
42
|
+
"user": "username",
|
|
43
|
+
"port": 22,
|
|
44
|
+
"path": "/path/to/wordpress",
|
|
45
|
+
"wp_cli_path": "wp"
|
|
61
46
|
}
|
|
62
|
-
]'
|
|
47
|
+
}]'
|
|
63
48
|
```
|
|
64
49
|
|
|
65
|
-
Generate the **WordPress Application Password** at
|
|
66
|
-
`https://{your-site}/wp-admin/profile.php#application-passwords-section`
|
|
50
|
+
Generate the **WordPress Application Password** at `https://{your-site}/wp-admin/profile.php#application-passwords-section`.
|
|
67
51
|
|
|
68
|
-
|
|
52
|
+
The `ssh` block is **optional** but unlocks **8 additional tools** (WP-CLI escape hatch + reliable custom-postmeta backups). The MCP works without SSH — backups go to local JSON files instead.
|
|
69
53
|
|
|
70
|
-
|
|
54
|
+
`wp_cli_path` auto-detects if omitted (tries `wp`, then `~/bin/wp.phar`, then `~/wp-cli.phar`).
|
|
71
55
|
|
|
72
|
-
|
|
73
|
-
export ELEMENTOR_MCP_CONFIG_PATH="/path/to/sites.json"
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
With `sites.json`:
|
|
77
|
-
```json
|
|
78
|
-
{
|
|
79
|
-
"sites": [
|
|
80
|
-
{ "id": "...", "url": "...", "username": "...", "application_password": "..." }
|
|
81
|
-
],
|
|
82
|
-
"default_site_id": "client-acme",
|
|
83
|
-
"rate_limit_per_minute": 60,
|
|
84
|
-
"confirmation_ttl_seconds": 60
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Configure Claude Desktop
|
|
89
|
-
|
|
90
|
-
`~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
56
|
+
### Claude Desktop config
|
|
91
57
|
|
|
92
58
|
```json
|
|
93
59
|
{
|
|
@@ -96,91 +62,114 @@ With `sites.json`:
|
|
|
96
62
|
"command": "npx",
|
|
97
63
|
"args": ["-y", "elementor-mcp-agent"],
|
|
98
64
|
"env": {
|
|
99
|
-
"ELEMENTOR_MCP_SITES": "[{\"id\":\"acme\",\"url\":\"https://acme.com\",\"username\":\"admin\",\"application_password\":\"
|
|
65
|
+
"ELEMENTOR_MCP_SITES": "[{\"id\":\"acme\",\"url\":\"https://acme.com\",\"username\":\"admin\",\"application_password\":\"...\"}]"
|
|
100
66
|
}
|
|
101
67
|
}
|
|
102
68
|
}
|
|
103
69
|
}
|
|
104
70
|
```
|
|
105
71
|
|
|
106
|
-
|
|
72
|
+
---
|
|
107
73
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
74
|
+
## Tools (24)
|
|
75
|
+
|
|
76
|
+
### Sites & health
|
|
77
|
+
- `list_sites` — enumerate the pool
|
|
78
|
+
- `ping_site` — auth + version probe
|
|
79
|
+
- `site_health` — multi-call health snapshot
|
|
80
|
+
|
|
81
|
+
### Pages
|
|
82
|
+
- `list_elementor_pages` — pages in builder mode
|
|
83
|
+
- `read_page_elementor` — parsed summary + optional full tree
|
|
84
|
+
- `list_widgets_in_page` — flat widget inventory with excerpts
|
|
85
|
+
- `list_global_widgets` — shared widgets (edit one → affects every page using it)
|
|
86
|
+
- `preflight_check` — validate a page is safe to edit
|
|
87
|
+
- `elementor_find_replace` — text replace with **dry-run → token → apply → backup → validate → rollback if invalid**
|
|
88
|
+
- `list_elementor_backups` / `restore_elementor_backup` — full restore chain with pre-restore safety backup
|
|
89
|
+
- `duplicate_elementor_page` — clone within a site (data + page_settings + edit_mode)
|
|
90
|
+
|
|
91
|
+
### Templates
|
|
92
|
+
- `list_elementor_templates` — Theme Builder distinguished from regular library
|
|
93
|
+
- `export_elementor_template` — portable JSON
|
|
94
|
+
- `import_elementor_template` — drop into target site
|
|
95
|
+
- `apply_template_to_page` — push template data onto an existing page
|
|
96
|
+
|
|
97
|
+
### WP-CLI escape hatch (require SSH)
|
|
98
|
+
- `wp_cli_run` — arbitrary wp-cli command with destructive-pattern detection + confirmation
|
|
99
|
+
- `wp_search_replace` — `wp search-replace` with mandatory dry-run
|
|
100
|
+
- `wp_elementor_flush_css` — 3-level fallback
|
|
101
|
+
- `wp_plugin_list` / `wp_plugin_update` (with confirmation)
|
|
102
|
+
|
|
103
|
+
### Visual
|
|
104
|
+
- `screenshot_page` — headless Chrome PNG of any URL
|
|
105
|
+
- `compare_screenshots` — SHA-256 + byte-delta
|
|
106
|
+
|
|
107
|
+
### Fleet
|
|
108
|
+
- `check_elementor_versions` — flag outdated installs against wordpress.org latest
|
|
113
109
|
|
|
114
110
|
---
|
|
115
111
|
|
|
116
|
-
##
|
|
117
|
-
|
|
118
|
-
| Tool | What it does |
|
|
119
|
-
|---|---|
|
|
120
|
-
| `list_sites` | Lists every site in the pool (id, url, username, has_ssh). |
|
|
121
|
-
| `ping_site` | Verifies auth + reports WP / Elementor / Elementor Pro versions. |
|
|
122
|
-
| `list_elementor_pages` | Lists pages built with Elementor on a given site. |
|
|
123
|
-
| `read_page_elementor` | Returns a structured summary of a page's `_elementor_data` (widget counts by type, depth). Full tree with `verbose=true`. |
|
|
124
|
-
| `elementor_find_replace` | Find/replace plain text in every widget on a page. **Two-call destructive flow**: dry-run returns a count + token; second call with token applies after auto-backup. |
|
|
125
|
-
| `list_elementor_templates` | Lists library templates (sections, pages, popups, headers, footers). |
|
|
126
|
-
| `export_elementor_template` | Exports a template as portable JSON. |
|
|
127
|
-
| `import_elementor_template` | Imports a portable JSON template into a target site. |
|
|
128
|
-
| `check_elementor_versions` | Fleet-wide Elementor version audit. Flags outdated installs against wordpress.org latest. |
|
|
112
|
+
## Safety guarantees
|
|
129
113
|
|
|
130
|
-
|
|
114
|
+
Hardcoded in `src/elementor/policies.ts`:
|
|
131
115
|
|
|
132
|
-
|
|
116
|
+
```ts
|
|
117
|
+
BACKUP_BEFORE_WRITE = true
|
|
118
|
+
BACKUP_PAGE_SETTINGS = true
|
|
119
|
+
VALIDATE_JSON_AFTER_EDIT = true
|
|
120
|
+
BLOCK_GLOBAL_WIDGET_WRITES_BY_DEFAULT = true
|
|
121
|
+
CONFIRMATION_TTL_SECONDS = 60
|
|
122
|
+
GLOBAL_WIDGET_CONFIRMATION_TTL_SECONDS = 30
|
|
123
|
+
FLUSH_CSS_AFTER_WRITE = true
|
|
124
|
+
MAX_ELEMENTOR_DATA_BYTES = 5_000_000
|
|
125
|
+
```
|
|
133
126
|
|
|
134
|
-
|
|
135
|
-
- `
|
|
136
|
-
- `
|
|
127
|
+
And these wp-cli patterns are **hard-blocked** regardless of confirmation:
|
|
128
|
+
- `rm -rf`
|
|
129
|
+
- `sudo *`
|
|
130
|
+
- `db reset --yes` / `db drop --yes`
|
|
137
131
|
|
|
138
132
|
---
|
|
139
133
|
|
|
140
|
-
##
|
|
141
|
-
|
|
142
|
-
Every destructive operation follows the same dance:
|
|
134
|
+
## End-to-end verified
|
|
143
135
|
|
|
144
|
-
|
|
145
|
-
2. **Second call** (same args + token) → applies after backing up the page's `_elementor_data` to a timestamped postmeta key.
|
|
146
|
-
3. **CSS flush** is triggered automatically (REST `/elementor/v1/css?action=regenerate`, falls back to re-save).
|
|
136
|
+
v1.0.0 was tested in real conditions against a live WordPress install with Elementor 4.0.9:
|
|
147
137
|
|
|
148
|
-
|
|
138
|
+
- ✅ 21/24 tools validated end-to-end
|
|
139
|
+
- ✅ find_replace → backup → restore round-trip preserves data
|
|
140
|
+
- ✅ duplicate_page copies data + page_settings + edit_mode
|
|
141
|
+
- ✅ apply_template_to_page with auto-backup
|
|
142
|
+
- ✅ wp_cli_run destructive flow (post delete) requires confirmation
|
|
143
|
+
- ✅ screenshots identical detection via SHA-256
|
|
144
|
+
- ✅ CSS flush uses `wp elementor flush-css` when SSH available, falls back to option-delete otherwise
|
|
149
145
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
146
|
+
7 bugs found during testing, all fixed:
|
|
147
|
+
- REST API silently drops unregistered postmeta writes → switched to WP-CLI primary for backups
|
|
148
|
+
- `wp` not in SSH PATH on managed hosts → auto-detection + `wp_cli_path` config
|
|
149
|
+
- SSH post-quantum banner pollution → stderr filter
|
|
150
|
+
- Default Kit returned as "widget" → client-side filter
|
|
151
|
+
- `_elementor_page_settings` type object/string mismatch → normalisation
|
|
152
|
+
- Chrome cold-start screenshot timeout → bumped to 60s
|
|
153
|
+
- Templates listing same filter bug → fixed
|
|
155
154
|
|
|
156
155
|
---
|
|
157
156
|
|
|
158
157
|
## Roadmap
|
|
159
158
|
|
|
160
|
-
**
|
|
161
|
-
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
- [ ] WP-CLI runner via SSH for ops the REST API can't do
|
|
165
|
-
|
|
166
|
-
**v0.3**
|
|
167
|
-
- [ ] Cross-site template push (`push_template_to_all`)
|
|
168
|
-
- [ ] Fleet health: outdated plugins, broken links, PageSpeed snapshot
|
|
169
|
-
- [ ] Visual diff (screenshot before/after)
|
|
170
|
-
- [ ] Elementor Pro version detection from Pro server (currently free-only)
|
|
171
|
-
|
|
172
|
-
**v1.0**
|
|
173
|
-
- [ ] Mature widget mutation API (typed setters per widget type)
|
|
174
|
-
- [ ] Automated docs ingestion from developer.elementor.com
|
|
175
|
-
- [ ] Per-tool happy-path tests against a real Elementor install
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
## Architecture
|
|
159
|
+
**v1.1**
|
|
160
|
+
- Widget-level CRUD: `read_widget`, `update_widget_settings`, `add_widget`, `delete_widget`, `swap_widget_type`
|
|
161
|
+
- `bulk_find_replace_site` (across all Elementor pages of one site)
|
|
162
|
+
- `restore_from_file` tool
|
|
180
163
|
|
|
181
|
-
|
|
164
|
+
**v1.2**
|
|
165
|
+
- `fleet_find_replace` (across all sites in pool)
|
|
166
|
+
- Global styles read/write
|
|
167
|
+
- Theme Builder template push across sites
|
|
182
168
|
|
|
183
|
-
|
|
169
|
+
**v2.0**
|
|
170
|
+
- WooCommerce-aware tools
|
|
171
|
+
- Visual diff (pixel comparison)
|
|
172
|
+
- Schedule + cron scheduling
|
|
184
173
|
|
|
185
174
|
---
|
|
186
175
|
|