@diviops/mcp-server 0.2.7 → 0.2.9
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 +43 -0
- package/dist/index.js +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -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/index.js
CHANGED
|
@@ -670,7 +670,7 @@ server.registerTool("diviops_preset_create", {
|
|
|
670
670
|
name: z.string().describe("Display name for the new preset"),
|
|
671
671
|
attrs: z
|
|
672
672
|
.record(z.string(), z.any())
|
|
673
|
-
.describe("Full module attribute bag (same shape as a module's top-level attrs in block markup). Saved to
|
|
673
|
+
.describe("Full module attribute bag (same shape as a module's top-level attrs in block markup). Saved to attrs, styleAttrs, and renderAttrs — matches VB save semantics so render cache stays in sync with edit state."),
|
|
674
674
|
type: z
|
|
675
675
|
.enum(["module", "group"])
|
|
676
676
|
.optional()
|
|
@@ -1391,7 +1391,7 @@ server.registerTool("diviops_flush_static_cache", {
|
|
|
1391
1391
|
.int()
|
|
1392
1392
|
.positive()
|
|
1393
1393
|
.optional()
|
|
1394
|
-
.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."),
|
|
1395
1395
|
},
|
|
1396
1396
|
}, async ({ post_id, all, after }) => {
|
|
1397
1397
|
const body = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diviops/mcp-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "MCP server exposing Divi 5 Visual Builder as tools for Claude",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
32
|
-
"url": "https://github.com/oaris-dev/diviops.git",
|
|
32
|
+
"url": "git+https://github.com/oaris-dev/diviops.git",
|
|
33
33
|
"directory": "diviops-server"
|
|
34
34
|
},
|
|
35
35
|
"bugs": {
|