@diviops/mcp-server 0.2.6 → 0.2.8
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 +44 -1
- package/dist/compatibility.d.ts +1 -1
- package/dist/compatibility.js +1 -1
- package/dist/index.js +29 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -141,7 +141,7 @@ The server connects via standard WordPress REST API and works with any environme
|
|
|
141
141
|
| `diviops_save_to_library` | Save block markup to Divi Library |
|
|
142
142
|
| `diviops_update_tb_layout` | Update a Theme Builder layout's block markup |
|
|
143
143
|
| `diviops_create_tb_template` | Create Theme Builder template with header/footer and conditions |
|
|
144
|
-
| `diviops_create_variable` | Create a design token variable |
|
|
144
|
+
| `diviops_create_variable` | 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. Px inputs only in this MVP; rem inputs should be converted to px (1rem=16px) before calling |
|
|
145
145
|
| `diviops_delete_variable` | Delete a variable by ID. Returns HTTP 409 when live references exist unless `force=true` (use `diviops_variables_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) |
|
|
146
146
|
| `diviops_create_canvas` | Create a canvas page |
|
|
147
147
|
| `diviops_update_canvas` | Update canvas content |
|
|
@@ -208,6 +208,49 @@ Only list the specific commands you need. Unknown entries are ignored with a war
|
|
|
208
208
|
|
|
209
209
|
> **Known limitation — filesystem access**: Validation is prefix-based, not flag-aware. Commands that read from or write to the filesystem (`acf export`/`acf import`, `export`, opt-in `import`/`eval-file`) can target any path reachable by the WP-CLI user. For shared or multi-tenant environments, consider wrapping the MCP server with a stricter proxy or running it under an account with limited filesystem permissions. Flag-level validation is a candidate future enhancement.
|
|
210
210
|
|
|
211
|
+
## Safety Patterns
|
|
212
|
+
|
|
213
|
+
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_preset_delete`, `diviops_update_page_content`) execute their mutation directly — whether to adopt a pattern is a per-tool design decision, not a retrofit requirement.
|
|
214
|
+
|
|
215
|
+
### Pattern A — `force: false/true` (refuse-with-override)
|
|
216
|
+
|
|
217
|
+
Tool refuses the operation with an explanatory error when a safety check fails; caller reviews the reason and retries with `force=true` to commit. Single round-trip on the happy path, single retry on the override path.
|
|
218
|
+
|
|
219
|
+
**Fit criteria:**
|
|
220
|
+
- Operation targets a **single item** (one variable, one preset, one page)
|
|
221
|
+
- Safety check is **binary** (safe / not safe)
|
|
222
|
+
- The reason for blocking is compact enough to fit in the error body (e.g., "3 live references")
|
|
223
|
+
- The caller can decide from the error alone — no full diff needed
|
|
224
|
+
|
|
225
|
+
**Current tools:**
|
|
226
|
+
| Tool | Guard | Override |
|
|
227
|
+
|------|-------|----------|
|
|
228
|
+
| `diviops_delete_variable` | HTTP 409 when live references exist | `force=true` |
|
|
229
|
+
|
|
230
|
+
### Pattern B — `mode: "dry-run"/"apply"` (preview-then-commit)
|
|
231
|
+
|
|
232
|
+
Tool returns a preview of the changes it would make; caller reviews the diff, then re-invokes with the apply flag to commit. Two round-trips by design — the preview itself is the value.
|
|
233
|
+
|
|
234
|
+
**Fit criteria:**
|
|
235
|
+
- Operation touches **many items** (bulk reassign, bulk cleanup)
|
|
236
|
+
- The *preview is the value* — caller wants the full list of changes before committing
|
|
237
|
+
- Side effects don't fit in a one-line reason (e.g., "142 preset refs across 18 pages rewritten from UUID X to UUID Y")
|
|
238
|
+
- Two round-trips are acceptable because the caller is already in review mode
|
|
239
|
+
|
|
240
|
+
**Current tools:**
|
|
241
|
+
| Tool | Preview flag | Commit flag |
|
|
242
|
+
|------|--------------|-------------|
|
|
243
|
+
| `diviops_preset_reassign` | `mode: "dry-run"` (default) | `mode: "apply"` |
|
|
244
|
+
| `diviops_preset_cleanup` | `dry_run: true` (default) | `dry_run: false` |
|
|
245
|
+
|
|
246
|
+
> Both preview-then-commit tools share the same semantic pattern but use different parameter shapes (`mode` enum vs `dry_run` bool). Both predate this convention and stay as-is for caller compatibility. **New bulk tools should use the enum form** (`mode: "dry-run" | "apply"`) — it's more extensible if future modes are needed (`"interactive"`, `"selective"`, etc.) and keeps the interface consistent as the tool set grows.
|
|
247
|
+
|
|
248
|
+
### Picking a pattern for a new tool
|
|
249
|
+
|
|
250
|
+
Ask: **single item or many?** If single, Pattern A. If many, Pattern B.
|
|
251
|
+
|
|
252
|
+
Don't introduce a third pattern (`confirmation_token`, session-based preview, etc.) unless a tool has a genuine need that neither A nor B covers — both patterns above are stateless and flexible enough for most cases.
|
|
253
|
+
|
|
211
254
|
## Example Usage
|
|
212
255
|
|
|
213
256
|
After setup, Claude can:
|
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-beta.
|
|
5
|
+
export declare const MIN_PLUGIN_VERSION = "1.0.0-beta.28";
|
|
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-beta.
|
|
5
|
+
export const MIN_PLUGIN_VERSION = '1.0.0-beta.28';
|
|
6
6
|
/**
|
|
7
7
|
* Compare two semver-like version strings (supports pre-release tags).
|
|
8
8
|
*
|
package/dist/index.js
CHANGED
|
@@ -1285,7 +1285,7 @@ server.registerTool("diviops_list_variables", {
|
|
|
1285
1285
|
};
|
|
1286
1286
|
});
|
|
1287
1287
|
server.registerTool("diviops_create_variable", {
|
|
1288
|
-
description: 'Create a design token variable in the Divi Variable Manager. Colors (type "colors") use gcid-* IDs and hex values. Numbers/strings/etc use gvid-* IDs.',
|
|
1288
|
+
description: 'Create a design token variable in the Divi Variable Manager. Colors (type "colors") use gcid-* IDs and hex values. Numbers/strings/etc use gvid-* IDs. For type="numbers" fluid tokens, pass min+max shorthand (anchors default to 320px/1920px) or explicit targets — server generates arithmetically-correct clamp() formulas. Px inputs only in this MVP; rem inputs must be converted to px (1rem=16px) before calling. Mutually exclusive with value.',
|
|
1289
1289
|
inputSchema: {
|
|
1290
1290
|
type: z
|
|
1291
1291
|
.enum(["colors", "numbers", "strings", "images", "links", "fonts"])
|
|
@@ -1299,12 +1299,36 @@ server.registerTool("diviops_create_variable", {
|
|
|
1299
1299
|
.describe("Human-readable label shown in the VB Variable Manager"),
|
|
1300
1300
|
value: z
|
|
1301
1301
|
.string()
|
|
1302
|
-
.
|
|
1302
|
+
.optional()
|
|
1303
|
+
.describe('Variable value (required unless using fluid min/max/targets for type=numbers): hex color for colors (e.g. "#3a7a6a"), CSS value for numbers (e.g. "clamp(30px, 8vw, 100px)" or "2rem")'),
|
|
1304
|
+
min: z
|
|
1305
|
+
.string()
|
|
1306
|
+
.optional()
|
|
1307
|
+
.describe('Fluid minimum value in px (e.g. "20px"). Paired with max. Anchors default to 320px/1920px. type="numbers" only. Rem not supported — convert to px (1rem=16px) before calling.'),
|
|
1308
|
+
max: z
|
|
1309
|
+
.string()
|
|
1310
|
+
.optional()
|
|
1311
|
+
.describe('Fluid maximum value in px (e.g. "60px"). Paired with min.'),
|
|
1312
|
+
targets: z
|
|
1313
|
+
.record(z.string(), z.string())
|
|
1314
|
+
.refine((m) => !m || Object.keys(m).length === 2, {
|
|
1315
|
+
message: "targets must contain exactly 2 viewport entries",
|
|
1316
|
+
})
|
|
1317
|
+
.optional()
|
|
1318
|
+
.describe('Explicit two-anchor fluid spec, px only. Example: {"320px":"20px","1920px":"60px"} → clamp(20px, 12px + 2.5vw, 60px). Exactly 2 entries required. type="numbers" only. Mutually exclusive with min/max.'),
|
|
1303
1319
|
},
|
|
1304
|
-
}, async ({ type, id, label, value }) => {
|
|
1305
|
-
const body = { type, label
|
|
1320
|
+
}, async ({ type, id, label, value, min, max, targets }) => {
|
|
1321
|
+
const body = { type, label };
|
|
1322
|
+
if (value !== undefined)
|
|
1323
|
+
body.value = value;
|
|
1306
1324
|
if (id)
|
|
1307
1325
|
body.id = id;
|
|
1326
|
+
if (min !== undefined)
|
|
1327
|
+
body.min = min;
|
|
1328
|
+
if (max !== undefined)
|
|
1329
|
+
body.max = max;
|
|
1330
|
+
if (targets !== undefined)
|
|
1331
|
+
body.targets = targets;
|
|
1308
1332
|
const result = await wp.request("/variable/create", {
|
|
1309
1333
|
method: "POST",
|
|
1310
1334
|
body,
|
|
@@ -1367,7 +1391,7 @@ server.registerTool("diviops_flush_static_cache", {
|
|
|
1367
1391
|
.int()
|
|
1368
1392
|
.positive()
|
|
1369
1393
|
.optional()
|
|
1370
|
-
.describe("Unix timestamp —
|
|
1394
|
+
.describe("Unix timestamp — flush Divi CSS files (et-*.css) with mtime strictly greater than this value. Useful for flushing entries touched since a known deployment or mutation batch. Native backend does a single-pass filesystem sweep covering numeric post dirs AND archive/taxonomy/home/notfound/global subtrees in one walk (Visual Builder -vb-* runtime CSS preserved); fs_fallback iterates numeric post dirs whose latest file mtime > after. `flushed` lists numeric post_ids whose files were actually deleted; `skipped` lists numeric post_ids that exist but had no files pass the filter."),
|
|
1371
1395
|
},
|
|
1372
1396
|
}, async ({ post_id, all, after }) => {
|
|
1373
1397
|
const body = {};
|