@wootsup/yt-builder-mcp 1.1.7 → 1.3.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 +14 -10
- package/bin/yt-builder-mcp.js +55 -40
- package/dist/auth.d.ts +18 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +18 -0
- package/dist/auth.js.map +1 -1
- package/dist/catalog/build-catalog.d.ts +63 -0
- package/dist/catalog/build-catalog.d.ts.map +1 -0
- package/dist/catalog/build-catalog.js +166 -0
- package/dist/catalog/build-catalog.js.map +1 -0
- package/dist/cli/invocation-decision.d.ts +57 -0
- package/dist/cli/invocation-decision.d.ts.map +1 -0
- package/dist/cli/invocation-decision.js +86 -0
- package/dist/cli/invocation-decision.js.map +1 -0
- package/dist/client.d.ts +28 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +40 -1
- package/dist/client.js.map +1 -1
- package/dist/clients/claude-code.d.ts.map +1 -1
- package/dist/clients/claude-code.js +3 -1
- package/dist/clients/claude-code.js.map +1 -1
- package/dist/clients/claude-desktop.d.ts.map +1 -1
- package/dist/clients/claude-desktop.js +3 -1
- package/dist/clients/claude-desktop.js.map +1 -1
- package/dist/clients/cline.d.ts.map +1 -1
- package/dist/clients/cline.js +3 -1
- package/dist/clients/cline.js.map +1 -1
- package/dist/clients/codex-cli.d.ts +1 -1
- package/dist/clients/codex-cli.d.ts.map +1 -1
- package/dist/clients/codex-cli.js +98 -0
- package/dist/clients/codex-cli.js.map +1 -1
- package/dist/clients/continue.d.ts.map +1 -1
- package/dist/clients/continue.js +70 -1
- package/dist/clients/continue.js.map +1 -1
- package/dist/clients/cursor.d.ts.map +1 -1
- package/dist/clients/cursor.js +3 -1
- package/dist/clients/cursor.js.map +1 -1
- package/dist/clients/gemini-cli.d.ts.map +1 -1
- package/dist/clients/gemini-cli.js +3 -1
- package/dist/clients/gemini-cli.js.map +1 -1
- package/dist/clients/index.d.ts +104 -0
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +141 -0
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/roo-code.d.ts.map +1 -1
- package/dist/clients/roo-code.js +3 -1
- package/dist/clients/roo-code.js.map +1 -1
- package/dist/clients/zed.d.ts.map +1 -1
- package/dist/clients/zed.js +3 -1
- package/dist/clients/zed.js.map +1 -1
- package/dist/gateway/advanced-read-tool.d.ts +37 -0
- package/dist/gateway/advanced-read-tool.d.ts.map +1 -0
- package/dist/gateway/advanced-read-tool.js +156 -0
- package/dist/gateway/advanced-read-tool.js.map +1 -0
- package/dist/gateway/advanced-tool/domains.d.ts +18 -3
- package/dist/gateway/advanced-tool/domains.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/domains.js +28 -9
- package/dist/gateway/advanced-tool/domains.js.map +1 -1
- package/dist/gateway/advanced-tool/register.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/register.js +43 -11
- package/dist/gateway/advanced-tool/register.js.map +1 -1
- package/dist/gateway/essentials.d.ts +14 -4
- package/dist/gateway/essentials.d.ts.map +1 -1
- package/dist/gateway/essentials.js +55 -5
- package/dist/gateway/essentials.js.map +1 -1
- package/dist/gateway/test-support.d.ts +3 -3
- package/dist/gateway/test-support.js +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/dist/install-skill.js +1 -1
- package/dist/proxy/bridge.d.ts +36 -0
- package/dist/proxy/bridge.d.ts.map +1 -0
- package/dist/proxy/bridge.js +129 -0
- package/dist/proxy/bridge.js.map +1 -0
- package/dist/proxy/mode.d.ts +10 -0
- package/dist/proxy/mode.d.ts.map +1 -0
- package/dist/proxy/mode.js +20 -0
- package/dist/proxy/mode.js.map +1 -0
- package/dist/server.d.ts +6 -4
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +14 -4
- package/dist/server.js.map +1 -1
- package/dist/setup-cli.d.ts +41 -0
- package/dist/setup-cli.d.ts.map +1 -1
- package/dist/setup-cli.js +163 -1
- package/dist/setup-cli.js.map +1 -1
- package/dist/setup-prompts.d.ts +23 -0
- package/dist/setup-prompts.d.ts.map +1 -1
- package/dist/setup-prompts.js +76 -1
- package/dist/setup-prompts.js.map +1 -1
- package/dist/setup-wizard.d.ts.map +1 -1
- package/dist/setup-wizard.js +7 -0
- package/dist/setup-wizard.js.map +1 -1
- package/dist/sites/bootstrap.d.ts +41 -0
- package/dist/sites/bootstrap.d.ts.map +1 -0
- package/dist/sites/bootstrap.js +58 -0
- package/dist/sites/bootstrap.js.map +1 -0
- package/dist/sites/client-pool.d.ts +33 -0
- package/dist/sites/client-pool.d.ts.map +1 -1
- package/dist/sites/client-pool.js +69 -1
- package/dist/sites/client-pool.js.map +1 -1
- package/dist/sites/registry.d.ts +30 -0
- package/dist/sites/registry.d.ts.map +1 -1
- package/dist/sites/registry.js.map +1 -1
- package/dist/sites/store.d.ts +8 -1
- package/dist/sites/store.d.ts.map +1 -1
- package/dist/sites/store.js +17 -2
- package/dist/sites/store.js.map +1 -1
- package/dist/sites/tools/index.d.ts.map +1 -1
- package/dist/sites/tools/index.js +9 -1
- package/dist/sites/tools/index.js.map +1 -1
- package/dist/sites/tools/use-site.d.ts +47 -0
- package/dist/sites/tools/use-site.d.ts.map +1 -0
- package/dist/sites/tools/use-site.js +203 -0
- package/dist/sites/tools/use-site.js.map +1 -0
- package/dist/tools/bind-guidance.d.ts +80 -0
- package/dist/tools/bind-guidance.d.ts.map +1 -0
- package/dist/tools/bind-guidance.js +95 -0
- package/dist/tools/bind-guidance.js.map +1 -0
- package/dist/tools/elements/builders.d.ts.map +1 -1
- package/dist/tools/elements/builders.js +75 -18
- package/dist/tools/elements/builders.js.map +1 -1
- package/dist/tools/elements/handlers-write.d.ts +20 -3
- package/dist/tools/elements/handlers-write.d.ts.map +1 -1
- package/dist/tools/elements/handlers-write.js +372 -10
- package/dist/tools/elements/handlers-write.js.map +1 -1
- package/dist/tools/elements/handlers.d.ts +6 -1
- package/dist/tools/elements/handlers.d.ts.map +1 -1
- package/dist/tools/elements/handlers.js +77 -10
- package/dist/tools/elements/handlers.js.map +1 -1
- package/dist/tools/elements/layout-hierarchy-rules.d.ts +62 -0
- package/dist/tools/elements/layout-hierarchy-rules.d.ts.map +1 -0
- package/dist/tools/elements/layout-hierarchy-rules.js +154 -0
- package/dist/tools/elements/layout-hierarchy-rules.js.map +1 -0
- package/dist/tools/format/elements-format.d.ts +35 -0
- package/dist/tools/format/elements-format.d.ts.map +1 -1
- package/dist/tools/format/elements-format.js +134 -12
- package/dist/tools/format/elements-format.js.map +1 -1
- package/dist/tools/format/inspection-format.d.ts +29 -0
- package/dist/tools/format/inspection-format.d.ts.map +1 -1
- package/dist/tools/format/inspection-format.js +99 -22
- package/dist/tools/format/inspection-format.js.map +1 -1
- package/dist/tools/format/pages-format.d.ts.map +1 -1
- package/dist/tools/format/pages-format.js +7 -0
- package/dist/tools/format/pages-format.js.map +1 -1
- package/dist/tools/format/sources-format.d.ts +8 -0
- package/dist/tools/format/sources-format.d.ts.map +1 -1
- package/dist/tools/format/sources-format.js +10 -0
- package/dist/tools/format/sources-format.js.map +1 -1
- package/dist/tools/health.d.ts.map +1 -1
- package/dist/tools/health.js +24 -0
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/inspection.d.ts +24 -0
- package/dist/tools/inspection.d.ts.map +1 -1
- package/dist/tools/inspection.js +297 -5
- package/dist/tools/inspection.js.map +1 -1
- package/dist/tools/layout-flatten.d.ts +11 -8
- package/dist/tools/layout-flatten.d.ts.map +1 -1
- package/dist/tools/layout-flatten.js +17 -6
- package/dist/tools/layout-flatten.js.map +1 -1
- package/dist/tools/multi-items/builders.d.ts.map +1 -1
- package/dist/tools/multi-items/builders.js +18 -3
- package/dist/tools/multi-items/builders.js.map +1 -1
- package/dist/tools/multi-items/clean-implode-handler.d.ts.map +1 -1
- package/dist/tools/multi-items/clean-implode-handler.js +2 -2
- package/dist/tools/multi-items/clean-implode-handler.js.map +1 -1
- package/dist/tools/multi-items/format/inspection-format.d.ts +41 -0
- package/dist/tools/multi-items/format/inspection-format.d.ts.map +1 -0
- package/dist/tools/multi-items/format/inspection-format.js +64 -0
- package/dist/tools/multi-items/format/inspection-format.js.map +1 -0
- package/dist/tools/multi-items/inspect-handler.d.ts +50 -2
- package/dist/tools/multi-items/inspect-handler.d.ts.map +1 -1
- package/dist/tools/multi-items/inspect-handler.js +237 -10
- package/dist/tools/multi-items/inspect-handler.js.map +1 -1
- package/dist/tools/multi-items/inspection-cache.d.ts +85 -0
- package/dist/tools/multi-items/inspection-cache.d.ts.map +1 -0
- package/dist/tools/multi-items/inspection-cache.js +126 -0
- package/dist/tools/multi-items/inspection-cache.js.map +1 -0
- package/dist/tools/pages/builders.d.ts +31 -2
- package/dist/tools/pages/builders.d.ts.map +1 -1
- package/dist/tools/pages/builders.js +173 -17
- package/dist/tools/pages/builders.js.map +1 -1
- package/dist/tools/pages/handlers-read.d.ts +6 -2
- package/dist/tools/pages/handlers-read.d.ts.map +1 -1
- package/dist/tools/pages/handlers-read.js +228 -26
- package/dist/tools/pages/handlers-read.js.map +1 -1
- package/dist/tools/pages/handlers-write.d.ts +143 -7
- package/dist/tools/pages/handlers-write.d.ts.map +1 -1
- package/dist/tools/pages/handlers-write.js +215 -11
- package/dist/tools/pages/handlers-write.js.map +1 -1
- package/dist/tools/pages/index.d.ts +1 -1
- package/dist/tools/pages/index.d.ts.map +1 -1
- package/dist/tools/pages/index.js +1 -1
- package/dist/tools/pages/index.js.map +1 -1
- package/dist/tools/pages/schemas.d.ts +166 -0
- package/dist/tools/pages/schemas.d.ts.map +1 -1
- package/dist/tools/pages/schemas.js +347 -0
- package/dist/tools/pages/schemas.js.map +1 -1
- package/dist/tools/shared-schemas.d.ts.map +1 -1
- package/dist/tools/shared-schemas.js +26 -11
- package/dist/tools/shared-schemas.js.map +1 -1
- package/dist/tools/sources/builders.d.ts.map +1 -1
- package/dist/tools/sources/builders.js +64 -6
- package/dist/tools/sources/builders.js.map +1 -1
- package/dist/tools/sources/handlers-bind.d.ts +13 -1
- package/dist/tools/sources/handlers-bind.d.ts.map +1 -1
- package/dist/tools/sources/handlers-bind.js +219 -5
- package/dist/tools/sources/handlers-bind.js.map +1 -1
- package/dist/tools/sources/handlers.d.ts +3 -0
- package/dist/tools/sources/handlers.d.ts.map +1 -1
- package/dist/tools/sources/handlers.js +45 -8
- package/dist/tools/sources/handlers.js.map +1 -1
- package/dist/tools/sparse-fields.d.ts +23 -0
- package/dist/tools/sparse-fields.d.ts.map +1 -1
- package/dist/tools/sparse-fields.js +29 -0
- package/dist/tools/sparse-fields.js.map +1 -1
- package/dist/tools/sublayout/builders.d.ts +23 -0
- package/dist/tools/sublayout/builders.d.ts.map +1 -0
- package/dist/tools/sublayout/builders.js +54 -0
- package/dist/tools/sublayout/builders.js.map +1 -0
- package/dist/tools/sublayout/index.d.ts +13 -0
- package/dist/tools/sublayout/index.d.ts.map +1 -0
- package/dist/tools/sublayout/index.js +13 -0
- package/dist/tools/sublayout/index.js.map +1 -0
- package/dist/tools/sublayout/inspect-sublayout-handler.d.ts +95 -0
- package/dist/tools/sublayout/inspect-sublayout-handler.d.ts.map +1 -0
- package/dist/tools/sublayout/inspect-sublayout-handler.js +181 -0
- package/dist/tools/sublayout/inspect-sublayout-handler.js.map +1 -0
- package/dist/tools/tool-builder/results.d.ts +31 -0
- package/dist/tools/tool-builder/results.d.ts.map +1 -1
- package/dist/tools/tool-builder/results.js +95 -4
- package/dist/tools/tool-builder/results.js.map +1 -1
- package/dist/uninstall-skill.d.ts +52 -0
- package/dist/uninstall-skill.d.ts.map +1 -0
- package/dist/uninstall-skill.js +146 -0
- package/dist/uninstall-skill.js.map +1 -0
- package/dist/uninstall.d.ts +73 -0
- package/dist/uninstall.d.ts.map +1 -0
- package/dist/uninstall.js +82 -0
- package/dist/uninstall.js.map +1 -0
- package/icon.png +0 -0
- package/manifest.json +10 -10
- package/package.json +7 -3
- package/skills/yt-builder-mcp/SKILL.md +157 -88
|
@@ -12,12 +12,17 @@ description: Drive the YOOtheme Pro Page Builder on WordPress or Joomla 5/6. Dis
|
|
|
12
12
|
> WordPress and Joomla 5/6.
|
|
13
13
|
|
|
14
14
|
This skill helps AI assistants drive the YOOtheme Pro Page Builder through the
|
|
15
|
-
`@wootsup/yt-builder-mcp` server. The server
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
`@wootsup/yt-builder-mcp` server. The server catalogues 32 typed, scoped,
|
|
16
|
+
idempotent tools (34 callable end-to-end with the two gateways). 29 of them
|
|
17
|
+
advertised as first-class entries in `tools/list`
|
|
18
|
+
(25 essential L1 forwards + 2 direct L3 entries + 2 gateways), and 5 advanced
|
|
19
|
+
tools reachable through the gateways. The write-capable
|
|
20
|
+
`yootheme_builder_advanced` gateway routes all 5; the read-only
|
|
21
|
+
`yootheme_builder_advanced_read` gateway routes only the read-only subset
|
|
22
|
+
(page_get_schema, element_get_binding, inspect_sublayout) and is itself
|
|
23
|
+
read-only-annotated, so MCP hosts can auto-allow pure inspection without a
|
|
24
|
+
per-call write-approval prompt. This 3-lane split keeps `tools/list` well below
|
|
25
|
+
the ~40-tool Cursor cap while every catalogued tool stays fully reachable.
|
|
21
26
|
|
|
22
27
|
## How to use this MCP server
|
|
23
28
|
|
|
@@ -48,8 +53,10 @@ Some clients (notably Claude Desktop with the `.dxt` bundle) expose **two**
|
|
|
48
53
|
entries when the user types "YT Builder MCP" into the picker:
|
|
49
54
|
|
|
50
55
|
- **`YT Builder MCP for YOOtheme Pro (unofficial)`**: the MCP **server**.
|
|
51
|
-
Provides the
|
|
52
|
-
The `yootheme_builder_advanced` gateway routes
|
|
56
|
+
Provides the 28 first-class tools (24 essential, 2 direct, 2 gateways).
|
|
57
|
+
The `yootheme_builder_advanced` gateway routes all 5 advanced tools; the
|
|
58
|
+
read-only `yootheme_builder_advanced_read` gateway routes the read-only
|
|
59
|
+
subset without a write-approval prompt.
|
|
53
60
|
- **`Von YT Builder MCP for YOOtheme Pro`**: the bundled **skill** (this
|
|
54
61
|
document). Gives the agent the workflow knowledge needed to drive those
|
|
55
62
|
tools correctly on first try.
|
|
@@ -74,24 +81,37 @@ The server exposes:
|
|
|
74
81
|
- **2 direct top-level tools**, always callable, always in `tools/list`:
|
|
75
82
|
`yootheme_builder_health` and `yootheme_builder_diagnose`. These are
|
|
76
83
|
the "the gateway itself might be broken" escape hatch.
|
|
77
|
-
- **
|
|
78
|
-
(pages_list,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
sites_list, sites_test
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
(
|
|
84
|
+
- **25 essential forwarded tools**: common reads + the most-used writes
|
|
85
|
+
(pages_list, pages_create, pages_delete, page_dynamize, scaffold_section,
|
|
86
|
+
get_etag, element_list / add / update_settings / get / move / clone / delete,
|
|
87
|
+
page_get_layout, sources_list, element_types_list, element_type_get_schema,
|
|
88
|
+
template_summary, inspect_multi_items_binding, sites_list, sites_test,
|
|
89
|
+
use_site, and the bind→save→publish chain element_bind_source /
|
|
90
|
+
page_save / page_publish). Always advertised in `tools/list` so AI
|
|
91
|
+
clients see them first-class. `scaffold_section` creates a valid
|
|
92
|
+
section → row → column hull in one call — the easiest correct way to
|
|
93
|
+
start a layout block (content placed anywhere else is rejected by the
|
|
94
|
+
structural-hierarchy guard).
|
|
95
|
+
- **5 advanced captured tools**: everything else (page_get_schema,
|
|
96
|
+
element_get_binding, element_unbind_source, clean_implode_directives,
|
|
97
|
+
and `inspect_sublayout`). Reachable through one gateway tool:
|
|
98
|
+
`yootheme_builder_advanced({ tool: "<name>", arguments: { ... } })`. For
|
|
99
|
+
example, to inspect a panel/grid_item `< SUBLAYOUT`:
|
|
100
|
+
`yootheme_builder_advanced({ tool: "yootheme_builder_inspect_sublayout", arguments: { template_id, element_path } })`.
|
|
101
|
+
- **2 gateway tools**: `yootheme_builder_advanced` (write-capable; can route
|
|
102
|
+
into delete/unbind, so hosts gate it) and `yootheme_builder_advanced_read`
|
|
103
|
+
(read-only; routes ONLY the read-only advanced subset — page_get_schema,
|
|
104
|
+
element_get_binding, inspect_sublayout — and is read-only-annotated so hosts
|
|
105
|
+
auto-allow it). Prefer the read gateway for pure inspection:
|
|
106
|
+
`yootheme_builder_advanced_read({ tool: "yootheme_builder_page_get_schema", arguments: { template_id } })`.
|
|
107
|
+
|
|
108
|
+
`tools/list` therefore advertises 29 names (25 + 2 + 2). That's 25 L1
|
|
109
|
+
essentials + 2 L3 direct + 2 gateways. The total callable surface is 34
|
|
110
|
+
(29 advertised + 5 advanced reachable through the gateways). If the AI
|
|
92
111
|
client reports "tool not found", you are almost certainly calling an
|
|
93
112
|
advanced tool by its raw name. Wrap it in
|
|
94
|
-
`yootheme_builder_advanced({ tool,
|
|
113
|
+
`yootheme_builder_advanced({ tool, arguments })` (or the read gateway for
|
|
114
|
+
read-only tools) instead.
|
|
95
115
|
|
|
96
116
|
## Site and frontend URLs (for deep-linking and verification)
|
|
97
117
|
|
|
@@ -137,7 +157,7 @@ Do not loop on auth errors.
|
|
|
137
157
|
> REST endpoints for per-article custom layouts, but they are NOT exposed
|
|
138
158
|
> via MCP tools in v1.x. To use that surface, call the REST endpoints
|
|
139
159
|
> directly with the Bearer key. MCP tool coverage for L2 articles is
|
|
140
|
-
> planned for
|
|
160
|
+
> planned for a future release.
|
|
141
161
|
|
|
142
162
|
---
|
|
143
163
|
|
|
@@ -281,8 +301,8 @@ one conversation.
|
|
|
281
301
|
- `yootheme_builder_pages_list({ site_id: "wp-acme", fields: ["id", "label"] })`
|
|
282
302
|
- `yootheme_builder_get_etag({ site_id: "wp-acme" })`
|
|
283
303
|
- `yootheme_builder_element_update_settings({ site_id: "wp-acme", template_id: "home", element_path: "/0/children/0/children/0/children/0", props: { content: "New headline" }, merge: true, etag: "<etag>" })`
|
|
284
|
-
- `
|
|
285
|
-
- `
|
|
304
|
+
- `yootheme_builder_page_save({ site_id: "wp-acme", template_id: "home", etag: "<fresh>" })`
|
|
305
|
+
- `yootheme_builder_page_publish({ site_id: "wp-acme", template_id: "home", etag: "<fresh>" })`
|
|
286
306
|
3. The customer sees a stream of replies, each prefixed with the matching
|
|
287
307
|
`[label @ host]`, so it is obvious which site is at which step.
|
|
288
308
|
|
|
@@ -320,11 +340,11 @@ to an existing page.
|
|
|
320
340
|
add a text element.
|
|
321
341
|
8. `yootheme_builder_element_add({ template_id, parent_path: "<row-path>", element_type: "button", props: { content: "<cta>", link: "<url>" }, etag })`:
|
|
322
342
|
add the CTA button.
|
|
323
|
-
9. `
|
|
343
|
+
9. `yootheme_builder_page_save({ template_id, etag })`:
|
|
324
344
|
persist the working copy (visible in YOOtheme Customizer preview).
|
|
325
|
-
`page_save` is
|
|
326
|
-
10. `
|
|
327
|
-
make the changes live on the front-end. Also
|
|
345
|
+
`page_save` is a first-class L1 tool; call it directly.
|
|
346
|
+
10. `yootheme_builder_page_publish({ template_id, etag })`:
|
|
347
|
+
make the changes live on the front-end. Also a first-class L1 tool.
|
|
328
348
|
|
|
329
349
|
**Common pitfalls:**
|
|
330
350
|
|
|
@@ -345,9 +365,11 @@ to an existing page.
|
|
|
345
365
|
- **Reusing a stale etag across many writes.** Every write returns a
|
|
346
366
|
fresh etag in the response. Pass THAT etag into the next write.
|
|
347
367
|
Don't hold the one from the original `get_etag` call.
|
|
348
|
-
- **
|
|
349
|
-
|
|
350
|
-
|
|
368
|
+
- **Forgetting to publish.** `page_save` and `page_publish` are both
|
|
369
|
+
first-class L1 tools (call them directly by name — they are advertised
|
|
370
|
+
in `tools/list`). Saving stages the change; only `page_publish` makes
|
|
371
|
+
it live. A saved-but-unpublished edit looks "done" in the Customizer
|
|
372
|
+
but visitors still see the old page.
|
|
351
373
|
|
|
352
374
|
**Worked example (tool-call snippet):**
|
|
353
375
|
|
|
@@ -363,11 +385,8 @@ yootheme_builder_element_add({
|
|
|
363
385
|
// Response: { path: "/0/children/3", etag: "def456" }
|
|
364
386
|
// → next call uses etag "def456"
|
|
365
387
|
|
|
366
|
-
// Step 9. page_save is
|
|
367
|
-
|
|
368
|
-
tool: "yootheme_builder_page_save",
|
|
369
|
-
input: { template_id: "home", etag: "<latest>" }
|
|
370
|
-
})
|
|
388
|
+
// Step 9. page_save is a first-class L1 tool; call it directly.
|
|
389
|
+
yootheme_builder_page_save({ template_id: "home", etag: "<latest>" })
|
|
371
390
|
```
|
|
372
391
|
|
|
373
392
|
**Edge case:** YOOtheme allows nested sections (rare). If the user
|
|
@@ -402,21 +421,21 @@ renders dynamic items.
|
|
|
402
421
|
4. `yootheme_builder_sources_list()`: enumerate available Sources.
|
|
403
422
|
Each returns `{ name, label, origin, kind }`. Pick the one the
|
|
404
423
|
user asked for.
|
|
405
|
-
5. `yootheme_builder_advanced({ tool: "yootheme_builder_element_get_binding",
|
|
424
|
+
5. `yootheme_builder_advanced({ tool: "yootheme_builder_element_get_binding", arguments: { template_id, element_path } })`
|
|
406
425
|
check whether the Grid is already bound (idempotency: skip step
|
|
407
426
|
7 if `source_name` already matches the user's intent).
|
|
408
427
|
`element_get_binding` is an advanced (L2) tool. Call via the gateway.
|
|
409
428
|
6. `yootheme_builder_get_etag()`: fetch the optimistic-lock etag for
|
|
410
429
|
the upcoming mutation.
|
|
411
|
-
7. `
|
|
430
|
+
7. `yootheme_builder_element_bind_source({ template_id, element_path, source_name: "<name>", etag: "<etag>" })`
|
|
412
431
|
applies the binding. Returns `{ path, etag, has_binding: true }`.
|
|
413
432
|
Pass `source_id: "<origin>:<name>"` as well **only** when two
|
|
414
433
|
plugins register a source with the same `source_name` (the server
|
|
415
434
|
surfaces the ambiguity as an elicitation prompt; if the host
|
|
416
435
|
doesn't support elicitation you'll see a structured error listing
|
|
417
|
-
the candidates).
|
|
418
|
-
8. `
|
|
419
|
-
then `
|
|
436
|
+
the candidates). This is a first-class L1 tool — call it directly.
|
|
437
|
+
8. `yootheme_builder_page_save({ template_id, etag: "<fresh>" })`
|
|
438
|
+
then `yootheme_builder_page_publish({ template_id, etag: "<fresh>" })`.
|
|
420
439
|
|
|
421
440
|
**Common pitfalls:**
|
|
422
441
|
|
|
@@ -439,29 +458,29 @@ renders dynamic items.
|
|
|
439
458
|
- **Forgetting `etag`.** Every write requires the optimistic-lock
|
|
440
459
|
etag. On `412 Precondition Failed` re-fetch via
|
|
441
460
|
`yootheme_builder_get_etag` and retry.
|
|
442
|
-
- **
|
|
443
|
-
|
|
444
|
-
`
|
|
461
|
+
- **Mis-routing bind vs the read helpers.** `element_bind_source` is
|
|
462
|
+
now a first-class L1 tool — call it directly by name. The binding
|
|
463
|
+
*read* helpers `element_get_binding` and `element_unbind_source` stay
|
|
464
|
+
L2 advanced; reach those through
|
|
465
|
+
`yootheme_builder_advanced({ tool, arguments })`.
|
|
445
466
|
|
|
446
467
|
**Worked example (tool-call snippet):**
|
|
447
468
|
|
|
448
469
|
```jsonc
|
|
449
|
-
// Step 7. Bind a Posts source onto a Grid element
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
// source_id: "wordpress:wp_posts" // pass ONLY when name collides
|
|
458
|
-
}
|
|
470
|
+
// Step 7. Bind a Posts source onto a Grid element. element_bind_source
|
|
471
|
+
// is a first-class L1 tool — call it directly.
|
|
472
|
+
yootheme_builder_element_bind_source({
|
|
473
|
+
template_id: "home",
|
|
474
|
+
element_path: "/0/children/2/children/0",
|
|
475
|
+
source_name: "wp_posts",
|
|
476
|
+
etag: "abc123"
|
|
477
|
+
// source_id: "wordpress:wp_posts" // pass ONLY when name collides
|
|
459
478
|
})
|
|
460
479
|
// Response: { path: "/0/children/2/children/0", etag: "def456", has_binding: true }
|
|
461
480
|
// Verify (via gateway):
|
|
462
481
|
yootheme_builder_advanced({
|
|
463
482
|
tool: "yootheme_builder_element_get_binding",
|
|
464
|
-
|
|
483
|
+
arguments: { template_id: "home", element_path: "/0/children/2/children/0" }
|
|
465
484
|
})
|
|
466
485
|
// → { source_name: "wp_posts", source_config: { ... }, ... }
|
|
467
486
|
```
|
|
@@ -477,6 +496,50 @@ items from the Source (verify by item count and at least one
|
|
|
477
496
|
field-value spot-check). `yootheme_builder_element_get_binding`
|
|
478
497
|
(via gateway) returns the new `source_name`.
|
|
479
498
|
|
|
499
|
+
### Multi-Items renderer truth table (read before binding rich cards)
|
|
500
|
+
|
|
501
|
+
The YT5 renderer (`SourceTransform`) follows ONE rule:
|
|
502
|
+
|
|
503
|
+
> A `…List` source renders nested children **only** when the element
|
|
504
|
+
> carrying it is a **CONTAINER** whose template renders its children
|
|
505
|
+
> (`column`, `fragment`, `row`, `section`, `grid`). `grid_item` and every
|
|
506
|
+
> `*_item` atom are **LEAF renderers**: the list iterates them per row, but
|
|
507
|
+
> their template paints **only their own slots** and **never** renders nested
|
|
508
|
+
> children — so any elements nested inside an iterating `grid_item` are
|
|
509
|
+
> dropped and you see placeholders.
|
|
510
|
+
|
|
511
|
+
What the renderer consumes from `item.source.props`: it maps each row field
|
|
512
|
+
onto the element's **own** display slots (`grid_item`:
|
|
513
|
+
title/meta/content/image/video/hover_image/hover_video/link/icon; `panel`:
|
|
514
|
+
title/meta/content/image). It is **last-write-wins** — two fields mapped to
|
|
515
|
+
the same slot silently lose one.
|
|
516
|
+
|
|
517
|
+
Two canonical forms (both live-verified):
|
|
518
|
+
|
|
519
|
+
- **(a) Simple card, N ≤ slots — iterate ON the `grid_item`:**
|
|
520
|
+
`grid_item{ source:{ query:{name:"…List"}, props:{ title:{name:F1}, meta:{name:F2}, image:{name:F3} } } }`.
|
|
521
|
+
No nested children. Renders because the data lands on the item's own slots.
|
|
522
|
+
|
|
523
|
+
- **(b) Rich / arbitrary card, any N — iterate ON a CONTAINER:**
|
|
524
|
+
`column{ source:{query:{name:"…List"}} > fragment{#parent} > leaves{ source:{query:{name:"#parent"}, props:{<slot>:{name:Fk}}} }`.
|
|
525
|
+
One leaf per field, **no leaf limit**. `<slot>` is `content` for
|
|
526
|
+
headline/text, or title/meta/image for panel. The `fragment` wrapper is
|
|
527
|
+
**optional** (it may carry `source.query.name="#parent"` or no source —
|
|
528
|
+
both work because a fragment renders its children either way).
|
|
529
|
+
|
|
530
|
+
**Guards (the tool enforces these):**
|
|
531
|
+
|
|
532
|
+
- Binding a leaf that is a **DIRECT child of an iterating `grid_item`** (no
|
|
533
|
+
`fragment` between) auto-**consolidates** the field onto the item's own
|
|
534
|
+
slots (form (a)) and leaves the leaf source-free (`consolidated_to_parent`).
|
|
535
|
+
- A consolidation that targets an **occupied slot** OR a key that is **not a
|
|
536
|
+
slot** of the item type is **rejected** with `slot_collision` (HTTP 409) —
|
|
537
|
+
give each field its own leaf / a distinct slot.
|
|
538
|
+
- Binding a `…List` source ONTO a `grid_item` that already has nested
|
|
539
|
+
children surfaces a blocking `iterator_is_leaf_renderer` warning (the
|
|
540
|
+
children are render-dead): map the fields onto the item's slots, or move
|
|
541
|
+
the List onto a container.
|
|
542
|
+
|
|
480
543
|
---
|
|
481
544
|
|
|
482
545
|
## Workflow 3: Clone & modify a section within a template
|
|
@@ -501,7 +564,7 @@ CMS-level template duplication (in wp-admin or Joomla administrator).
|
|
|
501
564
|
1. `yootheme_builder_health`: confirm host plugin reachable.
|
|
502
565
|
2. `yootheme_builder_pages_list({ fields: ["id", "label"] })`:
|
|
503
566
|
locate the template by `label`. Note its `id`.
|
|
504
|
-
3. `yootheme_builder_advanced({ tool: "yootheme_builder_page_get_schema",
|
|
567
|
+
3. `yootheme_builder_advanced({ tool: "yootheme_builder_page_get_schema", arguments: { template_id } })`
|
|
505
568
|
returns a flat schema view (lighter than `page_get_layout`) showing every
|
|
506
569
|
element path + type. Pick the JSON-Pointer path of the section
|
|
507
570
|
to clone. `page_get_schema` is L2; call via the gateway.
|
|
@@ -517,8 +580,8 @@ CMS-level template duplication (in wp-admin or Joomla administrator).
|
|
|
517
580
|
pass `merge: true` to apply a server-side deep-merge instead).
|
|
518
581
|
Read the current props first via `yootheme_builder_element_get`
|
|
519
582
|
if you only want to tweak a subset.
|
|
520
|
-
8. `
|
|
521
|
-
then `
|
|
583
|
+
8. `yootheme_builder_page_save({ template_id, etag })`
|
|
584
|
+
then `yootheme_builder_page_publish({ template_id, etag })`.
|
|
522
585
|
|
|
523
586
|
**Common pitfalls:**
|
|
524
587
|
|
|
@@ -536,7 +599,7 @@ CMS-level template duplication (in wp-admin or Joomla administrator).
|
|
|
536
599
|
- **Cloning a bound element keeps the binding.** `element_clone`
|
|
537
600
|
copies the entire element including `props.source`. If the user
|
|
538
601
|
wanted a "data-free" copy, call
|
|
539
|
-
`yootheme_builder_advanced({ tool: "yootheme_builder_element_unbind_source",
|
|
602
|
+
`yootheme_builder_advanced({ tool: "yootheme_builder_element_unbind_source", arguments: { ... } })`
|
|
540
603
|
on the new path afterwards.
|
|
541
604
|
- **Wrong parameter names.** Use `template_id`, `element_path`,
|
|
542
605
|
`etag` (NOT `pageId`, `srcPath`, `ifMatch`).
|
|
@@ -568,11 +631,11 @@ yootheme_builder_element_update_settings({
|
|
|
568
631
|
**Edge case:** When cloning a Grid with a source binding, the binding
|
|
569
632
|
is preserved (same `source_name`). If the user wants a "data-free"
|
|
570
633
|
copy, follow up with
|
|
571
|
-
`yootheme_builder_advanced({ tool: "yootheme_builder_element_unbind_source",
|
|
634
|
+
`yootheme_builder_advanced({ tool: "yootheme_builder_element_unbind_source", arguments: { ... } })`
|
|
572
635
|
on the new path. Verify with the gateway `element_get_binding` call.
|
|
573
636
|
|
|
574
637
|
**Success criterion:** After publish,
|
|
575
|
-
`yootheme_builder_advanced({ tool: "yootheme_builder_page_get_schema",
|
|
638
|
+
`yootheme_builder_advanced({ tool: "yootheme_builder_page_get_schema", arguments: { template_id } })`
|
|
576
639
|
shows the new section at the cloned path with the user's tweaks reflected in
|
|
577
640
|
`element_get` on that path.
|
|
578
641
|
|
|
@@ -650,7 +713,7 @@ yootheme_builder_diagnose({})
|
|
|
650
713
|
// Response shape:
|
|
651
714
|
// {
|
|
652
715
|
// plugin_reachable: true,
|
|
653
|
-
// plugin_version: "1.
|
|
716
|
+
// plugin_version: "1.2.0",
|
|
654
717
|
// yootheme_loaded: true,
|
|
655
718
|
// yootheme_version: "5.0.22",
|
|
656
719
|
// endpoint_count: 16,
|
|
@@ -707,8 +770,8 @@ an instance with a sensible default props payload.
|
|
|
707
770
|
iterates on the props. **Note: this REPLACES `props` entirely by
|
|
708
771
|
default; pass `merge: true` for a server-side deep-merge.** When
|
|
709
772
|
replacing, include every key you want to keep.
|
|
710
|
-
8. `
|
|
711
|
-
then `
|
|
773
|
+
8. `yootheme_builder_page_save({ template_id, etag })`
|
|
774
|
+
then `yootheme_builder_page_publish({ template_id, etag })`.
|
|
712
775
|
|
|
713
776
|
**Common pitfalls:**
|
|
714
777
|
|
|
@@ -788,11 +851,11 @@ and the props payload you passed.
|
|
|
788
851
|
elicitation, it returns a preview-with-confirm-required response;
|
|
789
852
|
call again with `confirm: true`.
|
|
790
853
|
- **Unbind a source**: call through the gateway:
|
|
791
|
-
`yootheme_builder_advanced({ tool: "yootheme_builder_element_unbind_source",
|
|
854
|
+
`yootheme_builder_advanced({ tool: "yootheme_builder_element_unbind_source", arguments: { template_id, element_path, etag, confirm: true } })`.
|
|
792
855
|
Same elicitation flow as delete.
|
|
793
856
|
- **Flat schema inspection** (e.g. enumerate every element path +
|
|
794
857
|
type without fetching the whole nested tree): call through the
|
|
795
|
-
gateway: `yootheme_builder_advanced({ tool: "yootheme_builder_page_get_schema",
|
|
858
|
+
gateway: `yootheme_builder_advanced({ tool: "yootheme_builder_page_get_schema", arguments: { template_id } })`.
|
|
796
859
|
- **Etag-only fetch** (e.g. polling for concurrent edits): use
|
|
797
860
|
`yootheme_builder_get_etag()` (takes no arguments) is cheaper than
|
|
798
861
|
fetching the full layout.
|
|
@@ -807,7 +870,7 @@ and the props payload you passed.
|
|
|
807
870
|
- **Strip legacy `implode` directives** from an element binding (audit-clean
|
|
808
871
|
source props that pre-date the wrapper-source refactor): call through the
|
|
809
872
|
gateway:
|
|
810
|
-
`yootheme_builder_advanced({ tool: "yootheme_builder_clean_implode_directives",
|
|
873
|
+
`yootheme_builder_advanced({ tool: "yootheme_builder_clean_implode_directives", arguments: { template_id, element_path, etag } })`.
|
|
811
874
|
Returns the audit log + a fresh ETag; idempotent (`cleaned_count: 0` when
|
|
812
875
|
there is nothing to remove).
|
|
813
876
|
|
|
@@ -821,35 +884,41 @@ Joomla administrator access." Don't fabricate tool calls.
|
|
|
821
884
|
|
|
822
885
|
<!-- TOOL-CATALOG:BEGIN -->
|
|
823
886
|
|
|
824
|
-
**
|
|
887
|
+
**32 catalogued tools** plus the `yootheme_builder_advanced` (write) + `yootheme_builder_advanced_read` (read-only) gateways = **34 reachable via `tools/list`** (25 L1 + 2 L3 + 2 gateways = 29 advertised; the gateways route to 5 additional advanced tools, bringing the total to 34 callable). Generated by `scripts/extract-tools.mjs` from the compiled `buildAllTools()` registry. Do not hand-edit this section; re-run `npm run build && node scripts/extract-tools.mjs` after changing tool definitions.
|
|
825
888
|
|
|
826
889
|
| Tool | Kind | Input keys | Description |
|
|
827
890
|
| --- | --- | --- | --- |
|
|
828
|
-
| `yootheme_builder_clean_implode_directives` |
|
|
891
|
+
| `yootheme_builder_clean_implode_directives` | destructive | `confirm`, `element_path`, `etag`, `site_id`, `template_id` | Strips `props.source.props.*.implode` directives from an element binding. Returns audit log + new ETag. Idempotent at the server (cleaned_count: 0 when nothing to remove) but classed as destructive because the affected binding cannot be restored without re-mapping. Always ask the user to confirm first, then call again with `confirm: true`. Requires ETag. Operates on the default site unless site_id is provided. |
|
|
829
892
|
| `yootheme_builder_diagnose` | read+idempotent | `site_id` | Full diagnostic: /health + authenticated /etag probe. Returns site_url, home_url, plugin reachability, Bearer validity in one call. First call when you need to know where the site lives. For per-template URLs see pages_list. Operates on the default site unless site_id is provided. |
|
|
830
|
-
| `yootheme_builder_element_add` | mutating | `children`, `element_type`, `etag`, `parent_path`, `props`, `site_id`, `template_id` | Add a new element to a template. Provide `parent_path` (or "" for root), `element_type` (e.g. "headline", "text", "grid"), and optional `props` / `children`. Returns the new element's JSON-Pointer path. Requires ETag. Operates on the default site unless site_id is provided. |
|
|
831
|
-
| `yootheme_builder_element_bind_source` | idempotent | `bindingLevel`, `element_path`, `etag`, `field_mappings`, `site_id`, `source_id`, `source_name`, `template_id` | Binds a Builder source to an element (
|
|
893
|
+
| `yootheme_builder_element_add` | mutating | `children`, `element_type`, `etag`, `index`, `parent_path`, `position`, `props`, `site_id`, `template_id`, `type_name` | Add a new element to a template. Provide `parent_path` (or "" for root), `element_type` (e.g. "headline", "text", "grid"), and optional `props` / `children`. Appends by default; pass `index` (0 = first) to insert before siblings. Returns the new element's JSON-Pointer path. Requires ETag. Operates on the default site unless site_id is provided. |
|
|
894
|
+
| `yootheme_builder_element_bind_source` | idempotent | `bindingLevel`, `element_path`, `etag`, `field_mappings`, `site_id`, `source_id`, `source_name`, `template_id` | Binds a Builder source to an element (canonical shape: `source` top-level). Pass `field_mappings` in the SAME call; bindingLevel "item" binds a container's first *_item child. Leaf under an iterating *_item → CONSOLIDATE onto item slots (409 slot_collision if taken/not a slot); leaf under a #parent fragment → INHERIT (`__node_item__`); standalone renders empty. List on a grid_item with children → iterator_is_leaf_renderer. Map: bind `map_item`, map `location` to a "lat,lng" field or no markers. Requires ETag. Call directly. Operates on the default site unless site_id is provided. |
|
|
832
895
|
| `yootheme_builder_element_clone` | mutating | `element_path`, `etag`, `site_id`, `template_id` | Clone an element as a sibling (same parent, immediately after the source). Returns the new element's path. Requires ETag. Operates on the default site unless site_id is provided. |
|
|
833
|
-
| `yootheme_builder_element_delete` | destructive | `confirm`, `element_path`, `etag`, `site_id`, `template_id` | PERMANENTLY delete an element
|
|
896
|
+
| `yootheme_builder_element_delete` | destructive | `confirm`, `element_path`, `etag`, `site_id`, `template_id` | PERMANENTLY delete an element + children. Cannot be undone. Pass `confirm: true` (boolean) AND a fresh ETag. If `preview:true` returns despite confirm, check `details.received_confirm` — strings/numbers accepted, but boolean is canonical. Operates on the default site unless site_id is provided. |
|
|
834
897
|
| `yootheme_builder_element_get` | read+idempotent | `element_path`, `site_id`, `template_id` | Get the full element object at a specific JSON-Pointer path, including props and children. Use yootheme_builder_element_list to discover paths. Operates on the default site unless site_id is provided. |
|
|
835
|
-
| `yootheme_builder_element_get_binding` | read+idempotent | `element_path`, `site_id`, `template_id` | Read the source binding attached to an element
|
|
898
|
+
| `yootheme_builder_element_get_binding` | read+idempotent | `element_path`, `site_id`, `template_id` | Read the source binding attached to an element — the bound source name, the field-mappings (which source field feeds which element prop) and the query arguments/directives. Returns the empty object if the element is not bound. Operates on the default site unless site_id is provided. |
|
|
836
899
|
| `yootheme_builder_element_list` | read+idempotent | `cursor`, `depth`, `fields`, `limit`, `root_path`, `site_id`, `template_id` | List elements in a template as a flat array with JSON-Pointer paths + types. Scope with `root_path`/`depth` for a subtree, paginate with `limit`/`cursor` for large templates. `fields[]` narrows each row. Operates on the default site unless site_id is provided. |
|
|
837
900
|
| `yootheme_builder_element_move` | idempotent | `element_path`, `etag`, `site_id`, `template_id`, `to_index`, `to_parent_path` | Move an element to a new parent + index in the tree. Useful for reordering or reparenting (e.g. moving a card from one grid column to another). Requires ETag. Operates on the default site unless site_id is provided. |
|
|
838
|
-
| `yootheme_builder_element_type_get_schema` | read+idempotent | `element_type`, `site_id`, `type_name` | **Call before every `element_add` / `_update_settings
|
|
839
|
-
| `yootheme_builder_element_types_list` | read+idempotent | `fields`, `site_id` | List element types registered on this site (built-ins + YOOessentials/uEssentials extras). Names feed `element_type` of element_add. Pass `fields[]` to narrow each row. Operates on the default site unless site_id is provided. |
|
|
840
|
-
| `yootheme_builder_element_unbind_source` | destructive | `confirm`, `element_path`, `etag`, `site_id`, `template_id` | Remove the source binding from an element. Clears `props.source`. Destructive in the sense that it may break dynamic-content rendering
|
|
841
|
-
| `yootheme_builder_element_update_settings` | idempotent | `element_path`, `etag`, `merge`, `props`, `site_id`, `template_id` | Update `props` on an element. Default replaces all props; pass `merge:true` for server-side deep-merge (only request keys overwritten, others survive
|
|
901
|
+
| `yootheme_builder_element_type_get_schema` | read+idempotent | `element_type`, `site_id`, `type_name` | **Call before every `element_add` / `_update_settings`** — unknown prop keys are silently dropped server-side, so guessing fails quietly. Returns `{name,type,label?}` field descriptors. Use `element_type`; `type_name` is DEPRECATED. Operates on the default site unless site_id is provided. |
|
|
902
|
+
| `yootheme_builder_element_types_list` | read+idempotent | `fields`, `site_id` | List element types registered on this site (built-ins + YOOessentials/uEssentials extras). Names feed `element_type` of element_add. Pass `fields[]` to narrow each row. Keywords: "slider"/"carousel" → `slideshow`/`panel-slider`/`overlay-slider`. Prop keys differ per element (grid_item `title` vs headline `content`) — use element_type_get_schema before element_add/bind. Operates on the default site unless site_id is provided. |
|
|
903
|
+
| `yootheme_builder_element_unbind_source` | destructive | `confirm`, `element_path`, `etag`, `site_id`, `template_id` | Remove the source binding from an element. Clears `props.source`. Destructive in the sense that it may break dynamic-content rendering — always ask the user to confirm. Requires ETag. Operates on the default site unless site_id is provided. |
|
|
904
|
+
| `yootheme_builder_element_update_settings` | idempotent | `element_path`, `etag`, `merge`, `props`, `site_id`, `template_id` | Update `props` on an element. Default replaces all props; pass `merge:true` for server-side deep-merge (only request keys overwritten, others survive — avoids read-modify-write races). Requires ETag. Operates on the default site unless site_id is provided. |
|
|
842
905
|
| `yootheme_builder_get_etag` | read+idempotent | `site_id` | Get the current ETag (state revision) for the YOOtheme builder. Returns sha256+revision string used for optimistic locking on writes. Pass the returned value back as `etag` on any write tool (page_save, page_publish, element_add, element_update_settings, element_clone, element_move, element_delete). The server returns HTTP 412 if the ETag has changed since you read it. Keywords: get etag, current etag, state revision, optimistic lock, version stamp. Operates on the default site unless site_id is provided. |
|
|
843
906
|
| `yootheme_builder_health` | read+idempotent | `site_id` | Check plugin installed/reachable. Returns plugin version, YT Pro version, REST endpoints. Authenticated payload adds site_url + home_url for deep-linking. See yootheme_builder_diagnose for Bearer-validity + connectivity summary. Operates on the default site unless site_id is provided. |
|
|
844
|
-
| `yootheme_builder_inspect_multi_items_binding` | read+idempotent | `element_path`, `site_id`, `template_id` | Reports Multi-Items binding state: container/item pair (grid↔grid_item, slideshow↔slideshow_item, …), current binding level (none\|container\|item), and a recommended_fix when the binding sits on the container instead of the child. Operates on the default site unless site_id is provided. |
|
|
845
|
-
| `
|
|
846
|
-
| `
|
|
847
|
-
| `
|
|
848
|
-
| `
|
|
849
|
-
| `
|
|
907
|
+
| `yootheme_builder_inspect_multi_items_binding` | read+idempotent | `element_path`, `site_id`, `template_id` | Reports Multi-Items binding state: container/item pair (grid↔grid_item, slideshow↔slideshow_item, map↔map_item, …), current binding level (none\|container\|item), and a recommended_fix when the binding sits on the container instead of the child. For map/map_item, a bound item without a `location` ("lat,lng") field is flagged as a blocking map_location_warning (renders 0 markers). A List on a grid_item with nested children → blocking iterator_is_leaf_renderer (children never render). Operates on the default site unless site_id is provided. |
|
|
908
|
+
| `yootheme_builder_inspect_sublayout` | read+idempotent | `element_path`, `site_id`, `template_id` | Inspects a panel/grid_item `< SUBLAYOUT`: lists the `fragment` subtree bindable leaves (with JSON-Pointer paths to bind on — NOT the container) and the render-time inner grid. Flags `ungated_grid_prop` (blocking): grid props set but the gate (title_align=left / image_align=left\|right) unsatisfied → silent no-op. For container↔item binding see inspect_multi_items_binding. Operates on the default site unless site_id is provided. |
|
|
909
|
+
| `yootheme_builder_page_dynamize` | mutating | `conditions`, `element_path`, `etag`, `leaf_map`, `list_source_name`, `page`, `remove_leaves`, `section_name`, `site_id`, `source_map`, `template_id` | One-call way to dynamize a designed section: copies the layout byte-identically and swaps only what you map. Use INSTEAD of hand-editing JSON. Give a REFERENCE (section_name from template_summary, or element_path) + list_source_name + a leaf_map (original leaf field-name → flat flow field; #parent + tuned props kept). A section with several source blocks (Played/Next/Later) dynamizes in ONE call via source_map ({match, source_name, leaf_map?}[]). Sub-query panels: key by "<subquery>.<leaf>". Returns page + `summary`. Requires page.title. Operates on the default site unless site_id is provided. |
|
|
910
|
+
| `yootheme_builder_page_get_layout` | read+idempotent | `fields`, `flat`, `force`, `mode`, `site_id`, `template_id` | Get the layout tree for one template. For dynamize/bind work prefer `mode:"bindings_only"` — just the binding skeleton (path, element_type, name, has_binding, source{query_name,props,has_condition}, children), no style props, typically <=15% of full size. Default `mode:"full"` returns nested `{layout, etag}`. `flat:true` gives a depth-first `{elements:[...], etag}` array (combine with `fields[]`). A repeated full read of an unchanged template auto-skips with `[unchanged]` — `force:true` re-fetches. Operates on the default site unless site_id is provided. |
|
|
911
|
+
| `yootheme_builder_page_get_schema` | read+idempotent | `site_id`, `template_id` | Get the flat schema for a template — a list of nodes with their JSON-Pointer paths and element types. Best entry-point for navigation: lighter than page_get_layout, sufficient to locate elements before editing. Operates on the default site unless site_id is provided. |
|
|
912
|
+
| `yootheme_builder_page_publish` | idempotent | `etag`, `site_id`, `template_id` | Publish a template — persist state, flush YT + WP caches, snapshot the published-state ETag. ETag optional — when provided, 412 on conflict; when omitted, last-write-wins. Recommended for collaborative edits. Operates on the default site unless site_id is provided. |
|
|
913
|
+
| `yootheme_builder_page_save` | idempotent | `etag`, `layout`, `site_id`, `template_id` | Re-run save-transforms + flush caches. Optionally pass a whole `layout` to REPLACE the template tree ATOMICALLY (F85) — ideal for wholesale dynamization (read layout → swap query → remap fields → write back). A supplied layout is validated + ETag-locked; on rejection nothing is persisted. Omit `layout` to just re-run transforms (no-op if byte-identical) — for incremental edits use element_add/update/bind/delete first. New pages: pages_create. Publish: page_publish. ETag optional (412 on conflict; else last-write-wins). Operates on the default site unless site_id is provided. |
|
|
914
|
+
| `yootheme_builder_pages_create` | idempotent | `dry_run`, `layout`, `menu_item`, `published`, `site_id`, `slug`, `status`, `title` | Create a page (WordPress) or article (Joomla 5/6) with a YOOtheme per-page layout. Required: title. Optional: slug, status (default draft), published (default false → live on true: WP publish / Joomla state 1), layout (JSON), menu_item (Joomla SEF route), dry_run (preflight, no persist). Returns page_id (WP) / article_id (Joomla), slug, template_id (page:{id} or article:{id}), etag, warnings. Joomla: a published article has NO SEF route until a menu item points at it — pass menu_item, else frontend_url may 404. Operates on the default site unless site_id is provided. |
|
|
915
|
+
| `yootheme_builder_pages_delete` | idempotent | `confirm`, `force`, `post_id`, `site_id` | Delete a page (WordPress) or article (Joomla 5/6) with its YOOtheme per-page layout. Requires confirm:true (gate against accidental deletion). Default: trash (recoverable). force:true: permanent delete. Refuses non-page/article types with 403 (Layer 9 defense). Returns deleted:true, page_id (WP) / article_id (Joomla), force_deleted, bumped etag. Operates on the default site unless site_id is provided. |
|
|
916
|
+
| `yootheme_builder_pages_list` | read+idempotent | `fields`, `site_id` | List all pages, templates, and layouts in the YOOtheme Pro builder. Returns template_id, label, type, element count, frontend_url, and builder_url (deep-link to open it in the builder) per row. CALL THIS FIRST to discover available template IDs before any tool that needs a template_id (page_get_layout, element_list, page_get_schema, etc.). Keywords: list pages, list templates, discover template_id. Pass `fields:["id","label"]` to slim. Returns ALL pages in one call (no pagination, typically <50 templates per site). Operates on the default site unless site_id is provided. |
|
|
917
|
+
| `yootheme_builder_scaffold_section` | mutating | `columns`, `etag`, `site_id`, `template_id` | Create a VALID section → row → column hull in ONE atomic call and return the column JSON-Pointer path(s) to drop content into. This is the EASIEST correct way to start a new layout block: YOOtheme content must live in section → row → column, and adding content anywhere else (root, bare section, bare row) is rejected. Pass `columns` (1-12, default 1) for a multi-column row. Requires ETag. Operates on the default site unless site_id is provided. |
|
|
850
918
|
| `yootheme_builder_sites_list` | read+idempotent | `site_id` | List all sites configured in this multi-site MCP installation. Returns site_id + URL + platform (wordpress\|joomla) + default flag per row. CALL THIS FIRST when working with a fresh MCP connection to discover available site_ids before targeting one with any other tool. Read-only, no REST calls. Keywords: list sites, list connections, list installations, discover site_id, available sites, configured sites, what sites exist, multi-site index. (site_id is accepted for schema-uniformity but ignored by this tool.) |
|
|
851
919
|
| `yootheme_builder_sites_test` | read+idempotent | `site_id` | Verify connectivity to ONE site: probes /health (no auth) + /etag (auth) in parallel; returns plugin_reachable + bearer_valid. `site_id` is REQUIRED. Use sites_list to find IDs. |
|
|
852
|
-
| `yootheme_builder_sources_list` | read+idempotent | `fields`, `site_id` | List all data sources, feeds, and dynamic content sources available in the YOOtheme Pro builder. Returns name + label + origin (apimapper / wordpress / joomla / essentials) per source. CALL THIS BEFORE binding any element to a data source.
|
|
853
|
-
| `yootheme_builder_template_summary` | read+idempotent | `site_id`, `template_id` | Token-efficient template overview: element counts by type, binding count, max nesting depth, and named landmark sections
|
|
920
|
+
| `yootheme_builder_sources_list` | read+idempotent | `fields`, `site_id` | List all data sources, feeds, and dynamic content sources available in the YOOtheme Pro builder. Returns name + label + origin (apimapper / wordpress / joomla / essentials) per source. CALL THIS BEFORE binding any element to a data source. Then bind directly with yootheme_builder_element_bind_source (a first-class tool in tools/list). Keywords: list sources, list data sources, list feeds, list bindings, dynamic content, available data, what sources exist. Pass `fields[]` to narrow each row. Operates on the default site unless site_id is provided. |
|
|
921
|
+
| `yootheme_builder_template_summary` | read+idempotent | `site_id`, `template_id` | Token-efficient template overview: element counts by type, binding count, max nesting depth, and named landmark sections — computed server-side in one call. Use this to grasp a large template before pulling element_list or page_get_layout. Example: yootheme_builder_template_summary({ template_id: "default" }). Operates on the default site unless site_id is provided. |
|
|
922
|
+
| `yootheme_builder_use_site` | idempotent | `probe`, `site_id` | Switch the ACTIVE site for this multi-site session. After this call, every tool that omits `site_id` targets the site you picked here. NOTE: this default is PROCESS-WIDE — concurrent clients sharing this MCP server inherit it; pass `site_id` per call for isolation between parallel agents. Runs a /health + /etag probe by default; pass `probe: false` to switch offline. A degraded site is a soft warning (the switch still happens). `site_id` is REQUIRED. Keywords: switch/change/set active/target site, select installation, use profile. Use yootheme_builder_sites_list first to find IDs. |
|
|
854
923
|
|
|
855
924
|
<!-- TOOL-CATALOG:END -->
|