@diviops/mcp-server 0.2.28 → 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 +66 -59
- package/dist/compatibility.d.ts +1 -1
- package/dist/compatibility.js +1 -1
- package/dist/index.js +387 -118
- package/dist/wp-cli-fs-validator.d.ts +6 -2
- package/dist/wp-cli-fs-validator.js +64 -2
- package/dist/wp-cli.d.ts +19 -3
- package/dist/wp-cli.js +95 -56
- package/dist/wp-client.js +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ claude mcp add diviops-mcp \
|
|
|
41
41
|
|
|
42
42
|
> **Use `--env` flags, not the `env` command.** Claude Code's native `--env KEY=VALUE` flags survive copy-paste; the older `-- env KEY=VALUE` form (piping through unix `env`) breaks silently when any value contains a space. Quote any value with spaces (e.g. `--env "WP_PATH=/Users/you/Local Sites/site/app/public"`) — no backslash escaping needed inside quotes.
|
|
43
43
|
|
|
44
|
-
**With WP-CLI** (optional — enables `
|
|
44
|
+
**With WP-CLI** (optional — enables `diviops_meta_wp_cli` tool):
|
|
45
45
|
```bash
|
|
46
46
|
claude mcp add diviops-mcp \
|
|
47
47
|
--env WP_URL=http://your-site.local \
|
|
@@ -96,80 +96,86 @@ The server connects via standard WordPress REST API and works with any environme
|
|
|
96
96
|
|
|
97
97
|
> **WP-CLI note:** `WP_PATH` keeps the existing Local by Flywheel behavior by running `wp` directly on the host filesystem. For Docker-based environments (DDEV, wp-env, DevKinsta, WordPress Studio), set `WP_CLI_CMD` to the wrapper command instead. When `WP_CLI_CMD` is set, the server executes the wrapper from `WP_PATH` if provided, otherwise from its current working directory. The MCP server still validates the requested WP-CLI subcommand against its allowlist before executing either path.
|
|
98
98
|
|
|
99
|
-
## Available Tools (
|
|
99
|
+
## Available Tools (63)
|
|
100
100
|
|
|
101
|
-
### Read (
|
|
101
|
+
### Read (30)
|
|
102
102
|
| Tool | Description |
|
|
103
103
|
|------|-------------|
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
104
|
+
| `diviops_meta_ping` | Test WordPress connection and Divi version |
|
|
105
|
+
| `diviops_meta_info` | DiviOps server identity, version, license type, capabilities |
|
|
106
|
+
| `diviops_page_list` | List pages/posts with Divi status |
|
|
107
|
+
| `diviops_page_get` | Get page details and raw content |
|
|
108
|
+
| `diviops_page_get_layout` | Get parsed block tree (layout structure) |
|
|
109
|
+
| `diviops_section_get` | Get a single section's markup by admin label |
|
|
110
|
+
| `diviops_schema_list_modules` | List all available Divi modules |
|
|
111
|
+
| `diviops_schema_get_module` | Get attribute schema for a module (optimized by default, `raw: true` for full) |
|
|
112
|
+
| `diviops_schema_get_settings` | Get Divi site settings and theme options |
|
|
113
|
+
| `diviops_global_color_list` | Get global color palette |
|
|
114
|
+
| `diviops_global_font_list` | Get global font definitions |
|
|
115
|
+
| `diviops_meta_find_icon` | Search 1,989 icons by keyword (FA + Divi) |
|
|
116
|
+
| `diviops_template_list` | List available MCP prompt templates |
|
|
117
|
+
| `diviops_template_get` | Get a specific template's block markup |
|
|
118
118
|
| `diviops_preset_audit` | Audit presets with referenced/unreferenced analysis. Walks both page content and in-registry `groupPresets` chains; exposes `block_ref_count`, `group_ref_count`, `referenced_by_presets`. Also reports `orphan_default_pointers` — per-bucket `default` pointers referencing UUIDs missing from `items[]` (legacy damage from past unsafe deletes; clear via `diviops_preset_set_default` in bucket-addressed mode: `type` + `module` + `unset=true`) |
|
|
119
119
|
| `diviops_preset_scan_orphans` | List page-referenced preset UUIDs missing from the D5 registry (separates dangling orphans from D4-legacy refs) |
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
120
|
+
| `diviops_library_list` | List saved Divi Library items |
|
|
121
|
+
| `diviops_library_get` | Get a library item's block markup |
|
|
122
122
|
| `diviops_render_preview` | Render block markup to HTML for preview |
|
|
123
123
|
| `diviops_validate_blocks` | Validate block markup (structure, required attrs, known pitfalls) |
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
|
|
132
|
-
|
|
124
|
+
| `diviops_tb_template_list` | List Theme Builder templates with conditions and layout IDs |
|
|
125
|
+
| `diviops_tb_layout_get` | Get a Theme Builder layout's block markup (header/body/footer) |
|
|
126
|
+
| `diviops_variable_list` | List design token variables (filter by type or prefix) |
|
|
127
|
+
| `diviops_variable_scan_orphans` | Find `gvid-`/`gcid-` refs with no backing Variable Manager entry (orphans render as invalid CSS) + unused variables (defined, never referenced). Scans pages, Theme Builder layouts (header/body/footer), Divi Library items, canvas pages, and the preset registry |
|
|
128
|
+
| `diviops_variable_used_on_page` | Detect which `gvid-` (numeric/font) IDs a single page emits — the exact set Divi 5.4.0+ uses to scope selective `:root{--gvid-*}` CSS variable emission. Walks the same content stack the frontend assembles (post_content + active TB header/body/footer + appended canvases + presets). `gcid-` colors are out of scope (separate emission path). Use for per-page orphan validation, preflight before bulk variable rename, or to debug why a numeric/font variable doesn't render on a specific page. Read-only |
|
|
129
|
+
| `diviops_canvas_list` | List all canvas pages |
|
|
130
|
+
| `diviops_canvas_get` | Get canvas content |
|
|
131
|
+
| `diviops_scf_status` | Show SCF (Secure Custom Fields) sync status — pending JSON-vs-DB drift across field groups, post types, taxonomies, options pages. Wraps `wp scf json status` |
|
|
132
|
+
| `diviops_scf_field_group_list` | List all SCF/ACF field groups (post_name = ACF key, post_title, post_status, post_modified). Queries the `acf-field-group` post type via `wp post list` (works on SCF 6.8.4+ and older ACF) |
|
|
133
|
+
| `diviops_scf_field_group_get` | Fetch a single SCF/ACF field-group post by ACF key (`group_abc123` → post_name) or numeric WP post ID. For the parsed/structured field tree, use `diviops_scf_export --field-groups=<key> --stdout` |
|
|
134
|
+
|
|
135
|
+
### Write (31)
|
|
133
136
|
| Tool | Description |
|
|
134
137
|
|------|-------------|
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
138
|
+
| `diviops_page_create` | Create a new page with optional Divi content |
|
|
139
|
+
| `diviops_page_update_content` | Full page content rewrite |
|
|
140
|
+
| `diviops_section_append` | Append a section to existing page (start or end) |
|
|
141
|
+
| `diviops_section_replace` | Replace a section by admin label |
|
|
142
|
+
| `diviops_section_remove` | Remove a section by admin label |
|
|
143
|
+
| `diviops_module_update` | Update specific module attributes by label or text match |
|
|
144
|
+
| `diviops_module_move` | Move a block before/after another block (reorder modules, sections) |
|
|
145
|
+
| `diviops_module_lock` | Lock a module so VB users cannot edit it (frontend renders normally) |
|
|
146
|
+
| `diviops_module_unlock` | Unlock a module by removing `attrs.locked` (matches VB's absence convention) |
|
|
147
|
+
| `diviops_module_clone` | Deep-copy a module + insert next to source within the same parent |
|
|
148
|
+
| `diviops_global_color_create` | Add a new global color to Divi's palette (writes canonical shape; closes ET's bundle Zod gap that drops `label`) |
|
|
149
|
+
| `diviops_global_color_update` | Update an existing global color by gcid (only provided fields change) |
|
|
150
|
+
| `diviops_global_color_delete` | Delete a global color (refuses if `usedInPosts` non-empty unless `force=true`; customizer-bound defaults always protected) |
|
|
148
151
|
| `diviops_preset_cleanup` | Remove spam/duplicate presets, bulk rename |
|
|
149
152
|
| `diviops_preset_create` | Write a new preset to the D5 registry (module or group type, supports `divi/column` etc.). Optional `make_default: true` sets it as the bucket's default; optional `priority` controls stack-merge order |
|
|
150
153
|
| `diviops_preset_reassign` | Rewrite `modulePreset` references across pages (dry-run by default; optional `strip_inline` removes redundant inline attrs) |
|
|
151
154
|
| `diviops_preset_update` | Update a specific preset (name, attrs, priority) |
|
|
152
155
|
| `diviops_preset_delete` | Delete a preset by ID. Refuses with HTTP 409 `preset_is_default` when the target is the registered default for its bucket — clear the pointer first via `diviops_preset_set_default` with `unset=true`, or pass `force=true` to delete and clear the pointer in one write |
|
|
153
156
|
| `diviops_preset_set_default` | Set or clear the per-module/group default preset. Two modes: by `preset_id` (UUID-addressed; auto-resolves bucket) or by `type` + `module` + `unset=true` (bucket-addressed clear, used to repair orphan default pointers when the UUID is gone from `items[]`). Defaults apply to NEW instances only — use `diviops_preset_reassign` for retroactive swaps |
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
162
|
-
| `
|
|
157
|
+
| `diviops_library_save` | Save block markup to Divi Library |
|
|
158
|
+
| `diviops_tb_layout_update` | Update a Theme Builder layout's block markup |
|
|
159
|
+
| `diviops_tb_template_create` | Create Theme Builder template with header/footer and conditions |
|
|
160
|
+
| `diviops_variable_create` | Create a design token variable. For `type=numbers` fluid tokens, pass `min`+`max` shorthand (anchors default to 320px/1920px) or explicit `targets` like `{"320px":"20px","1920px":"60px"}` — server generates arithmetically-correct `clamp()` instead of hand-written math that silently under-reaches the stated max. All-px inputs emit px (root-agnostic). Rem inputs OR rem output require explicit opt-in: pass `output_unit="rem"` (accepts the 1rem=16px default) or `root_font_size_px:N` (declares your site's actual root font-size, e.g. `10` for `html { font-size: 62.5% }`, `20` for `html { font-size: 20px }`) |
|
|
161
|
+
| `diviops_variable_create_fluid_system` | Batch-emit a fluid typography + spacing + radius variable set in one call. Mirrors Divi 5.4.0's Variable Generator Modal at the algorithm level (clamp() math is identical to `diviops_variable_create`'s fluid mode) but layers profile-selectable anchors over it: `divi-default` (360→1350) matches ET's defaults, `wide` (320→1920) matches the diviops convention, `custom` takes explicit anchors. Each category is independent and optional. Typography uses modular-scale chains (named ratios `major-third`/`perfect-fifth`/`golden`/etc., or raw numbers) — h1 = largest, hN = base. Spacing/radius support `linear` or `geometric` step distributions. `dry_run: true` returns the full plan without persisting; `overwrite: false` (default) skips existing IDs. Single atomic write to the registry — mid-batch failures roll back cleanly |
|
|
162
|
+
| `diviops_variable_delete` | Delete a variable by ID. Returns HTTP 409 when live references exist unless `force=true` (use `diviops_variable_scan_orphans` to find reference locations). Returns HTTP 403 for Divi's customizer-bound defaults (`gcid-primary-color`, `gcid-secondary-color`, `gcid-heading-color`, `gcid-body-color`, `gcid-link-color` — managed via WP Customizer) |
|
|
163
|
+
| `diviops_canvas_create` | Create a canvas page |
|
|
164
|
+
| `diviops_canvas_update` | Update canvas content |
|
|
165
|
+
| `diviops_canvas_delete` | Delete a canvas page |
|
|
166
|
+
| `diviops_scf_export` | Export SCF schema (field groups, post types, taxonomies, options pages) as JSON to a directory under the safe-root, or to stdout. Wraps `wp scf json export` |
|
|
167
|
+
| `diviops_scf_import` | Import SCF schema from a JSON file (mutates DB; idempotent — existing items are updated). Wraps `wp scf json import <file>` |
|
|
168
|
+
| `diviops_scf_sync` | Apply pending JSON-on-disk SCF changes to the DB. Defaults to `dry_run: true` for safety. Wraps `wp scf json sync` |
|
|
163
169
|
|
|
164
170
|
### Utility (2)
|
|
165
171
|
| Tool | Description |
|
|
166
172
|
|------|-------------|
|
|
167
|
-
| `
|
|
168
|
-
| `
|
|
173
|
+
| `diviops_meta_wp_cli` | Run WP-CLI commands (allowlisted, requires `WP_PATH` or `WP_CLI_CMD`) |
|
|
174
|
+
| `diviops_meta_flush_cache` | Flush Divi's compiled CSS cache under `wp-content/et-cache/`. `wp cache flush` does NOT touch these files — the frontend can keep serving stale CSS after mutations. Delegates to Divi's native clearer (`ET_Core_PageResource::remove_static_resources`) when available — also clears Theme Builder / archive / taxonomy / home / notfound CSS, object cache, module features cache, post features cache, dynamic assets cache, Google Fonts cache, post meta caches. Falls back to a filesystem walk of numeric-named subdirs when Divi is inactive. Response includes `backend: "divi_native"` or `"fs_fallback"`. Exactly one selector required: `post_id`, `all`, or `after` (unix ts) — no default to `all` |
|
|
169
175
|
|
|
170
176
|
## WP-CLI Security
|
|
171
177
|
|
|
172
|
-
The `
|
|
178
|
+
The `diviops_meta_wp_cli` tool validates every command against a safety allowlist before execution. Commands not on the list are rejected.
|
|
173
179
|
|
|
174
180
|
### Default allowlist (always available)
|
|
175
181
|
|
|
@@ -182,7 +188,7 @@ Read-only commands plus non-destructive writes needed for core MCP functionality
|
|
|
182
188
|
| Post meta | `post meta get`, `post meta list`, `post meta set`, `post meta update` |
|
|
183
189
|
| Post types | `post-type list`, `post-type get` |
|
|
184
190
|
| Taxonomies | `taxonomy list`, `term list`, `term create`, `term update` |
|
|
185
|
-
| ACF / SCF | `acf export`, `acf import`, `acf field-group list`, `acf field-group get` |
|
|
191
|
+
| ACF / SCF | `acf export`, `acf import`, `acf field-group list`, `acf field-group get`, `scf json {status,sync,import,export}` (also aliased as `acf json …` per SCF 6.8.4+) |
|
|
186
192
|
| Users | `user list` |
|
|
187
193
|
| Cache | `cache flush`, `transient delete`, `rewrite flush` |
|
|
188
194
|
| Export | `export` (WXR data export to file) |
|
|
@@ -237,12 +243,13 @@ The sentinel grants exactly the extended set above — it does NOT unlock anythi
|
|
|
237
243
|
|
|
238
244
|
### Filesystem flag validation
|
|
239
245
|
|
|
240
|
-
The
|
|
246
|
+
The DEFAULT-tier filesystem commands (`wp export`, `acf export <path>`, `acf import <path>`, `scf json export --dir=<path>`, `scf json import <file>`, plus the `acf json …` aliases) are second-pass validated against a safe root so wrong-path arguments can't write WXR / schema JSON to the web root or read configs from arbitrary locations.
|
|
241
247
|
|
|
242
248
|
- **Safe root**: `<WP_PATH>/.diviops-tmp/` by default (auto-created on first use in host mode). Override with `DIVIOPS_WP_CLI_SAFE_FS_ROOT=/absolute/path`. All path arguments must canonicalize under this directory; symlinks are resolved via `realpath` so a planted symlink inside the safe root pointing outside it is caught.
|
|
243
249
|
- **`wp export` must pass `--dir=<path-under-safe-root>`** (or `--stdout`). Without `--dir`, wp-cli writes to the current working directory; on prod that's typically the web root.
|
|
244
250
|
- **`--filename_format=` must be a filename template**, not a path — separators (`/`, `\`) are rejected so a crafted template can't escape `--dir`'s scope.
|
|
245
251
|
- **`acf export/import`'s positional path** must resolve under the safe root.
|
|
252
|
+
- **`scf json export`'s `--dir=` flag** must resolve under the safe root (or pass `--stdout` for in-memory transfer). **`scf json import`'s positional `<file>` path** must resolve under the safe root.
|
|
246
253
|
- **Wrapper mode (`WP_CLI_CMD`)**: the host-derived safe root doesn't correspond to the wrapper's filesystem (e.g., container paths like `/www/app`), so `DIVIOPS_WP_CLI_SAFE_FS_ROOT` is **required** and must be set to the container-namespace path. FS-sensitive commands are rejected with a clear error if it's missing.
|
|
247
254
|
- **Escape hatch**: `DIVIOPS_WP_CLI_UNSAFE_FS=1` disables validation entirely. Appropriate for trusted single-user local-dev setups that don't want the guard.
|
|
248
255
|
|
|
@@ -250,7 +257,7 @@ The three DEFAULT-tier filesystem commands (`wp export`, `acf export <path>`, `a
|
|
|
250
257
|
|
|
251
258
|
## Safety Patterns
|
|
252
259
|
|
|
253
|
-
High-risk or bulk destructive tools follow one of two conventions to guard against unintended mutation. Both are stateless (no session tokens between calls), but they guard differently: Pattern A is a **stateless gate** — the first call mutates when the safety check passes, refuses with an explanatory error when it fires. Pattern B is **preview-before-commit** — the first call never mutates; an explicit apply step is required. Tools without a gate (e.g., `
|
|
260
|
+
High-risk or bulk destructive tools follow one of two conventions to guard against unintended mutation. Both are stateless (no session tokens between calls), but they guard differently: Pattern A is a **stateless gate** — the first call mutates when the safety check passes, refuses with an explanatory error when it fires. Pattern B is **preview-before-commit** — the first call never mutates; an explicit apply step is required. Tools without a gate (e.g., `diviops_page_update_content`) execute their mutation directly — whether to adopt a pattern is a per-tool design decision, not a retrofit requirement.
|
|
254
261
|
|
|
255
262
|
### Pattern A — `force: false/true` (refuse-with-override)
|
|
256
263
|
|
|
@@ -265,7 +272,7 @@ Tool refuses the operation with an explanatory error when a safety check fails;
|
|
|
265
272
|
**Current tools:**
|
|
266
273
|
| Tool | Guard | Override |
|
|
267
274
|
|------|-------|----------|
|
|
268
|
-
| `
|
|
275
|
+
| `diviops_variable_delete` | HTTP 409 when live references exist | `force=true` |
|
|
269
276
|
| `diviops_preset_delete` | HTTP 409 `preset_is_default` when target is the registered default for its bucket | `force=true` (deletes + clears the `default` pointer in the same write) |
|
|
270
277
|
|
|
271
278
|
### Pattern B — `mode: "dry-run"/"apply"` (preview-then-commit)
|
|
@@ -308,7 +315,7 @@ After setup, Claude can:
|
|
|
308
315
|
Ensure `WP_URL`, `WP_USER`, and `WP_APP_PASSWORD` are all set. Check your `claude mcp add` command.
|
|
309
316
|
|
|
310
317
|
### "Connection failed" error
|
|
311
|
-
- Verify the WP plugin is active: visit `{WP_URL}/wp-json/diviops/v1/settings` in your browser
|
|
318
|
+
- Verify the WP plugin is active: visit `{WP_URL}/wp-json/diviops/v1/schema/settings` in your browser
|
|
312
319
|
- Check Application Password is correct (try with curl first)
|
|
313
320
|
|
|
314
321
|
### "Version mismatch" error
|
|
@@ -320,7 +327,7 @@ The MCP server and WP plugin versions are incompatible. Update whichever side is
|
|
|
320
327
|
|
|
321
328
|
### Testing manually
|
|
322
329
|
```bash
|
|
323
|
-
curl -u "username:apppassword" http://site.local/wp-json/diviops/v1/settings
|
|
330
|
+
curl -u "username:apppassword" http://site.local/wp-json/diviops/v1/schema/settings
|
|
324
331
|
```
|
|
325
332
|
|
|
326
333
|
### Preset edits not visible on the frontend
|
package/dist/compatibility.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Version compatibility between MCP server and WP plugin.
|
|
3
3
|
*/
|
|
4
4
|
/** Minimum WP plugin version this server requires. */
|
|
5
|
-
export declare const MIN_PLUGIN_VERSION = "1.0.0
|
|
5
|
+
export declare const MIN_PLUGIN_VERSION = "1.0.0";
|
|
6
6
|
/**
|
|
7
7
|
* Compare two semver-like version strings (supports pre-release tags).
|
|
8
8
|
*
|
package/dist/compatibility.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Version compatibility between MCP server and WP plugin.
|
|
3
3
|
*/
|
|
4
4
|
/** Minimum WP plugin version this server requires. */
|
|
5
|
-
export const MIN_PLUGIN_VERSION = '1.0.0
|
|
5
|
+
export const MIN_PLUGIN_VERSION = '1.0.0';
|
|
6
6
|
/**
|
|
7
7
|
* Compare two semver-like version strings (supports pre-release tags).
|
|
8
8
|
*
|