@diviops/mcp-server 1.2.0 → 1.4.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 +5 -4
- package/dist/index.js +68 -5
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -96,7 +96,7 @@ 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 (66)
|
|
100
100
|
|
|
101
101
|
### Read (30)
|
|
102
102
|
| Tool | Description |
|
|
@@ -108,7 +108,7 @@ The server connects via standard WordPress REST API and works with any environme
|
|
|
108
108
|
| `diviops_page_get_layout` | Get parsed block tree (layout structure) |
|
|
109
109
|
| `diviops_section_get` | Get a single section's markup by admin label |
|
|
110
110
|
| `diviops_schema_list_modules` | List all available Divi modules |
|
|
111
|
-
| `diviops_schema_get_module` | Get attribute schema for a module (optimized
|
|
111
|
+
| `diviops_schema_get_module` | Get attribute schema for a module. Default `mode: "single"` returns one module's schema (optimized; `raw: true` for full). `mode: "dump_all"` snapshots every Divi module in one call along with a `schema_version` hash over `*PresetAttrsMap.php` and a `divi_version` field — build-time entry point for the skill regen pipeline. |
|
|
112
112
|
| `diviops_schema_get_settings` | Get Divi site settings and theme options |
|
|
113
113
|
| `diviops_global_color_list` | Get global color palette |
|
|
114
114
|
| `diviops_global_font_list` | Get global font definitions |
|
|
@@ -132,7 +132,7 @@ The server connects via standard WordPress REST API and works with any environme
|
|
|
132
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
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
134
|
|
|
135
|
-
### Write (
|
|
135
|
+
### Write (34)
|
|
136
136
|
| Tool | Description |
|
|
137
137
|
|------|-------------|
|
|
138
138
|
| `diviops_page_create` | Create a new page with optional Divi content |
|
|
@@ -163,7 +163,8 @@ The server connects via standard WordPress REST API and works with any environme
|
|
|
163
163
|
| `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 |
|
|
164
164
|
| `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) |
|
|
165
165
|
| `diviops_canvas_create` | Create a canvas page |
|
|
166
|
-
| `
|
|
166
|
+
| `diviops_canvas_duplicate` | Deep-copy a canvas (content + canvas-specific meta). Default copy title `<source> (Copy)` auto-suffixes on collision (Copy 2, …); explicit `title` collisions return 409. Supports `dry_run` |
|
|
167
|
+
| `diviops_canvas_update` | Update canvas content and/or metadata. Pass any subset of fields — `{canvas_post_id, title}` renames without touching content |
|
|
167
168
|
| `diviops_canvas_delete` | Delete a canvas page |
|
|
168
169
|
| `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` |
|
|
169
170
|
| `diviops_scf_import` | Import SCF schema from a JSON file (mutates DB; idempotent — existing items are updated). Wraps `wp scf json import <file>` |
|
package/dist/index.js
CHANGED
|
@@ -198,18 +198,53 @@ registerPluginTool("diviops_schema_list_modules", {
|
|
|
198
198
|
};
|
|
199
199
|
});
|
|
200
200
|
registerPluginTool("diviops_schema_get_module", {
|
|
201
|
-
description: "Get the attribute schema for a Divi module.
|
|
201
|
+
description: "Get the attribute schema for a Divi module. Default mode 'single' returns one module's schema (optimized, ~70% smaller; pass raw: true for full). Mode 'dump_all' snapshots every Divi module in one call and includes a `schema_version` hash over the canonical *PresetAttrsMap.php files — build-time entry point for the skill regen pipeline; ignores `module_name` and `raw`.",
|
|
202
202
|
inputSchema: {
|
|
203
|
+
mode: z
|
|
204
|
+
.enum(["single", "dump_all"])
|
|
205
|
+
.optional()
|
|
206
|
+
.default("single")
|
|
207
|
+
.describe("'single' (default): return one module's schema. 'dump_all': return every module keyed by name plus schema_version + divi_version."),
|
|
203
208
|
module_name: z
|
|
204
209
|
.string()
|
|
205
|
-
.
|
|
210
|
+
.optional()
|
|
211
|
+
.describe('Module name, e.g. "text", "image", "accordion", or full "divi/text". Required when mode="single"; ignored when mode="dump_all".'),
|
|
206
212
|
raw: z
|
|
207
213
|
.boolean()
|
|
208
214
|
.optional()
|
|
209
215
|
.default(false)
|
|
210
|
-
.describe("Return full schema including CSS selectors and VB metadata"),
|
|
216
|
+
.describe("Return full schema including CSS selectors and VB metadata. Applies to mode='single' only."),
|
|
211
217
|
},
|
|
212
|
-
}, async ({ module_name, raw }) => {
|
|
218
|
+
}, async ({ mode, module_name, raw }) => {
|
|
219
|
+
if (mode === "dump_all") {
|
|
220
|
+
// Capability gate for the dump-all surface: handled here (rather
|
|
221
|
+
// than the wrapper's auto-derived `schema_get_module` key) so older
|
|
222
|
+
// plugins without /schema/module/dump-all surface a clean upgrade
|
|
223
|
+
// hint instead of a 404 from wp.request.
|
|
224
|
+
if (handshakeState.kind === "ok" &&
|
|
225
|
+
!handshakeState.capabilities["schema_get_module_dump_all"]) {
|
|
226
|
+
const err = new MissingCapabilityError("schema_get_module_dump_all", handshakeState.pluginVersion);
|
|
227
|
+
return {
|
|
228
|
+
content: [{ type: "text", text: err.message }],
|
|
229
|
+
isError: true,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
const result = await wp.request("/schema/module/dump-all");
|
|
233
|
+
return {
|
|
234
|
+
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
if (!module_name) {
|
|
238
|
+
return {
|
|
239
|
+
content: [
|
|
240
|
+
{
|
|
241
|
+
type: "text",
|
|
242
|
+
text: "module_name is required when mode='single'",
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
isError: true,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
213
248
|
const result = await wp.request(`/schema/module/${encodeURIComponent(module_name)}`);
|
|
214
249
|
const output = raw ? result : optimizeSchema(result);
|
|
215
250
|
return {
|
|
@@ -1376,7 +1411,7 @@ registerPluginTool("diviops_canvas_get", {
|
|
|
1376
1411
|
};
|
|
1377
1412
|
});
|
|
1378
1413
|
registerPluginTool("diviops_canvas_update", {
|
|
1379
|
-
description: "Update a canvas's content and/or metadata.
|
|
1414
|
+
description: "Update a canvas's content and/or metadata. Pass any subset of fields — e.g. `{canvas_post_id, title}` to rename without touching content. `content` replaces the entire canvas when present. At least one of content/title/append_to_main/z_index is required.",
|
|
1380
1415
|
inputSchema: {
|
|
1381
1416
|
canvas_post_id: z.number().describe("Canvas post ID"),
|
|
1382
1417
|
content: z
|
|
@@ -1410,6 +1445,34 @@ registerPluginTool("diviops_canvas_update", {
|
|
|
1410
1445
|
],
|
|
1411
1446
|
};
|
|
1412
1447
|
});
|
|
1448
|
+
registerPluginTool("diviops_canvas_duplicate", {
|
|
1449
|
+
description: "Deep-copy a canvas (post_content + canvas-specific meta: parent page, append_to_main, z_index). Source canvas untouched. Default copy title is `<source title> (Copy)` with auto-suffix on collision (Copy 2, Copy 3, …) — use this for repeat-clone workflows. Pass an explicit `title` for a deliberate name; collisions return 409 instead of silently auto-suffixing. Pass `dry_run: true` to preview without mutating.",
|
|
1450
|
+
inputSchema: {
|
|
1451
|
+
canvas_post_id: z.number().describe("Source canvas post ID"),
|
|
1452
|
+
title: z
|
|
1453
|
+
.string()
|
|
1454
|
+
.optional()
|
|
1455
|
+
.describe("Optional explicit title for the duplicate. Omit to auto-derive `<source> (Copy [N])`. Explicit collisions return 409."),
|
|
1456
|
+
dry_run: z
|
|
1457
|
+
.boolean()
|
|
1458
|
+
.optional()
|
|
1459
|
+
.default(false)
|
|
1460
|
+
.describe("When true, return the change plan without creating the canvas."),
|
|
1461
|
+
},
|
|
1462
|
+
}, async ({ canvas_post_id, title, dry_run }) => {
|
|
1463
|
+
const body = { dry_run: dry_run ?? false };
|
|
1464
|
+
if (title !== undefined)
|
|
1465
|
+
body.title = title;
|
|
1466
|
+
const result = await wp.request(`/canvas/duplicate/${canvas_post_id}`, {
|
|
1467
|
+
method: "POST",
|
|
1468
|
+
body,
|
|
1469
|
+
});
|
|
1470
|
+
return {
|
|
1471
|
+
content: [
|
|
1472
|
+
{ type: "text", text: JSON.stringify(result) },
|
|
1473
|
+
],
|
|
1474
|
+
};
|
|
1475
|
+
});
|
|
1413
1476
|
registerPluginTool("diviops_canvas_delete", {
|
|
1414
1477
|
description: "Delete a canvas. This permanently removes the canvas post.",
|
|
1415
1478
|
inputSchema: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diviops/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "MCP server exposing Divi 5 Visual Builder as tools for Claude",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"build": "tsc",
|
|
17
17
|
"start": "node dist/index.js",
|
|
18
18
|
"dev": "tsc --watch",
|
|
19
|
-
"prepublishOnly": "npm run build"
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
20
|
+
"regen:skill": "node scripts/regen-module-formats.mjs"
|
|
20
21
|
},
|
|
21
22
|
"keywords": [
|
|
22
23
|
"mcp",
|