@wootsup/yt-builder-mcp 1.3.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 +1 -1
- package/dist/cli/doctor-command.d.ts +21 -0
- package/dist/cli/doctor-command.d.ts.map +1 -0
- package/dist/cli/doctor-command.js +111 -0
- package/dist/cli/doctor-command.js.map +1 -0
- package/dist/cli/invocation-decision.d.ts.map +1 -1
- package/dist/cli/invocation-decision.js +2 -0
- package/dist/cli/invocation-decision.js.map +1 -1
- package/dist/client.d.ts +14 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -0
- package/dist/client.js.map +1 -1
- package/dist/diagnostics/ca-trust.d.ts +16 -0
- package/dist/diagnostics/ca-trust.d.ts.map +1 -0
- package/dist/diagnostics/ca-trust.js +54 -0
- package/dist/diagnostics/ca-trust.js.map +1 -0
- package/dist/diagnostics/diagnose-network-error.d.ts +37 -0
- package/dist/diagnostics/diagnose-network-error.d.ts.map +1 -0
- package/dist/diagnostics/diagnose-network-error.js +158 -0
- package/dist/diagnostics/diagnose-network-error.js.map +1 -0
- package/dist/diagnostics/doctor.d.ts +62 -0
- package/dist/diagnostics/doctor.d.ts.map +1 -0
- package/dist/diagnostics/doctor.js +165 -0
- package/dist/diagnostics/doctor.js.map +1 -0
- package/dist/gateway/essentials.d.ts +1 -1
- package/dist/gateway/essentials.d.ts.map +1 -1
- package/dist/gateway/essentials.js +5 -0
- package/dist/gateway/essentials.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -1
- package/dist/install-skill.d.ts +1 -1
- package/dist/install-skill.js +1 -1
- package/dist/net/extra-headers.d.ts +66 -0
- package/dist/net/extra-headers.d.ts.map +1 -0
- package/dist/net/extra-headers.js +164 -0
- package/dist/net/extra-headers.js.map +1 -0
- package/dist/net/internal-host.d.ts +45 -0
- package/dist/net/internal-host.d.ts.map +1 -0
- package/dist/net/internal-host.js +164 -0
- package/dist/net/internal-host.js.map +1 -0
- package/dist/net/proxy-dispatcher.d.ts +40 -0
- package/dist/net/proxy-dispatcher.d.ts.map +1 -0
- package/dist/net/proxy-dispatcher.js +65 -0
- package/dist/net/proxy-dispatcher.js.map +1 -0
- package/dist/proxy/bridge.d.ts +18 -11
- package/dist/proxy/bridge.d.ts.map +1 -1
- package/dist/proxy/bridge.js +30 -4
- package/dist/proxy/bridge.js.map +1 -1
- package/dist/setup-ca-env.d.ts +40 -0
- package/dist/setup-ca-env.d.ts.map +1 -0
- package/dist/setup-ca-env.js +58 -0
- package/dist/setup-ca-env.js.map +1 -0
- package/dist/setup-ca-reprobe.d.ts +38 -0
- package/dist/setup-ca-reprobe.d.ts.map +1 -0
- package/dist/setup-ca-reprobe.js +68 -0
- package/dist/setup-ca-reprobe.js.map +1 -0
- package/dist/setup-cli.d.ts +37 -2
- package/dist/setup-cli.d.ts.map +1 -1
- package/dist/setup-cli.js +178 -4
- package/dist/setup-cli.js.map +1 -1
- package/dist/setup-npx-spec.d.ts +44 -0
- package/dist/setup-npx-spec.d.ts.map +1 -0
- package/dist/setup-npx-spec.js +66 -0
- package/dist/setup-npx-spec.js.map +1 -0
- package/dist/setup-prompts.d.ts +14 -1
- package/dist/setup-prompts.d.ts.map +1 -1
- package/dist/setup-prompts.js +53 -1
- package/dist/setup-prompts.js.map +1 -1
- package/dist/setup-wizard-defaults.d.ts.map +1 -1
- package/dist/setup-wizard-defaults.js +29 -5
- package/dist/setup-wizard-defaults.js.map +1 -1
- package/dist/setup-wizard-handshake.d.ts +4 -4
- package/dist/setup-wizard-handshake.d.ts.map +1 -1
- package/dist/setup-wizard-handshake.js +46 -12
- package/dist/setup-wizard-handshake.js.map +1 -1
- package/dist/setup-wizard-types.d.ts +81 -0
- package/dist/setup-wizard-types.d.ts.map +1 -1
- package/dist/setup-wizard.d.ts +2 -2
- package/dist/setup-wizard.d.ts.map +1 -1
- package/dist/setup-wizard.js +133 -18
- package/dist/setup-wizard.js.map +1 -1
- package/dist/sites/client-pool.d.ts +8 -1
- package/dist/sites/client-pool.d.ts.map +1 -1
- package/dist/sites/client-pool.js +13 -1
- package/dist/sites/client-pool.js.map +1 -1
- package/dist/tools/elements/builders.d.ts.map +1 -1
- package/dist/tools/elements/builders.js +4 -2
- package/dist/tools/elements/builders.js.map +1 -1
- package/dist/tools/elements/handlers.d.ts +2 -1
- package/dist/tools/elements/handlers.d.ts.map +1 -1
- package/dist/tools/elements/handlers.js +3 -22
- package/dist/tools/elements/handlers.js.map +1 -1
- package/dist/tools/format/health-format.d.ts +3 -0
- package/dist/tools/format/health-format.d.ts.map +1 -1
- package/dist/tools/format/health-format.js +21 -4
- package/dist/tools/format/health-format.js.map +1 -1
- package/dist/tools/health.d.ts.map +1 -1
- package/dist/tools/health.js +32 -0
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/pages/builders.d.ts.map +1 -1
- package/dist/tools/pages/builders.js +78 -27
- package/dist/tools/pages/builders.js.map +1 -1
- package/dist/tools/pages/handlers-read.d.ts +36 -5
- package/dist/tools/pages/handlers-read.d.ts.map +1 -1
- package/dist/tools/pages/handlers-read.js +217 -34
- package/dist/tools/pages/handlers-read.js.map +1 -1
- package/dist/tools/pages/schemas.d.ts +20 -5
- package/dist/tools/pages/schemas.d.ts.map +1 -1
- package/dist/tools/pages/schemas.js +44 -6
- package/dist/tools/pages/schemas.js.map +1 -1
- package/dist/tools/shared-schemas.d.ts +3 -0
- package/dist/tools/shared-schemas.d.ts.map +1 -1
- package/dist/tools/shared-schemas.js +28 -0
- 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 +30 -5
- package/dist/tools/sources/builders.js.map +1 -1
- package/dist/tools/sources/handlers.d.ts +9 -1
- package/dist/tools/sources/handlers.d.ts.map +1 -1
- package/dist/tools/sources/handlers.js +62 -12
- package/dist/tools/sources/handlers.js.map +1 -1
- package/dist/tools/sparse-fields.d.ts +50 -0
- package/dist/tools/sparse-fields.d.ts.map +1 -1
- package/dist/tools/sparse-fields.js +107 -0
- package/dist/tools/sparse-fields.js.map +1 -1
- package/dist/update/update-check.d.ts +56 -0
- package/dist/update/update-check.d.ts.map +1 -0
- package/dist/update/update-check.js +155 -0
- package/dist/update/update-check.js.map +1 -0
- package/manifest.json +1 -1
- package/package.json +2 -1
- package/skills/yt-builder-mcp/SKILL.md +13 -12
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// packages/mcp/src/update/update-check.ts
|
|
2
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
const DEFAULT_TTL_MS = 24 * 60 * 60 * 1_000;
|
|
6
|
+
const DEFAULT_TIMEOUT_MS = 3_000;
|
|
7
|
+
/** Parse `x.y.z` (ignoring any `-prerelease`/`+build`) into a numeric triple. */
|
|
8
|
+
function parseCore(version) {
|
|
9
|
+
const m = /^\s*v?(\d+)\.(\d+)\.(\d+)/.exec(version);
|
|
10
|
+
if (m === null)
|
|
11
|
+
return null;
|
|
12
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
13
|
+
}
|
|
14
|
+
/** Is `latest` strictly newer than `current`? Fail-closed on unparseable input. */
|
|
15
|
+
export function isVersionNewer(latest, current) {
|
|
16
|
+
const a = parseCore(latest);
|
|
17
|
+
const b = parseCore(current);
|
|
18
|
+
if (a === null || b === null)
|
|
19
|
+
return false;
|
|
20
|
+
const [a0, a1, a2] = a;
|
|
21
|
+
const [b0, b1, b2] = b;
|
|
22
|
+
if (a0 !== b0)
|
|
23
|
+
return a0 > b0;
|
|
24
|
+
if (a1 !== b1)
|
|
25
|
+
return a1 > b1;
|
|
26
|
+
if (a2 !== b2)
|
|
27
|
+
return a2 > b2;
|
|
28
|
+
// Equal core → a release (latest, no prerelease) outranks a prerelease
|
|
29
|
+
// current (e.g. latest "1.3.0" vs current "1.3.0-beta.1").
|
|
30
|
+
const latestPre = latest.includes('-');
|
|
31
|
+
const currentPre = current.includes('-');
|
|
32
|
+
return currentPre && !latestPre;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Default registry fetch: the abbreviated packument's `dist-tags.latest`.
|
|
36
|
+
* (The `/latest` single-version endpoint behaves inconsistently under the
|
|
37
|
+
* abbreviated accept header for scoped packages; the packument + dist-tags is
|
|
38
|
+
* the robust path and the smaller abbreviated response.)
|
|
39
|
+
*/
|
|
40
|
+
export async function fetchLatestFromNpm(packageName, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
41
|
+
const url = `https://registry.npmjs.org/${packageName.replace('/', '%2F')}`;
|
|
42
|
+
try {
|
|
43
|
+
const res = await fetch(url, {
|
|
44
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
45
|
+
headers: { accept: 'application/vnd.npm.install-v1+json' },
|
|
46
|
+
});
|
|
47
|
+
if (!res.ok)
|
|
48
|
+
return null;
|
|
49
|
+
const body = await res.json();
|
|
50
|
+
if (body !== null && typeof body === 'object' && 'dist-tags' in body) {
|
|
51
|
+
const tags = body['dist-tags'];
|
|
52
|
+
if (tags !== null && typeof tags === 'object' && 'latest' in tags) {
|
|
53
|
+
const latest = tags.latest;
|
|
54
|
+
if (typeof latest === 'string' && latest !== '')
|
|
55
|
+
return latest;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Offline / proxy / TLS / timeout — fail silent. The notifier is a
|
|
62
|
+
// courtesy, never a hard dependency.
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Default cache: a JSON file under the user's home dir. Fail-silent on fs errors. */
|
|
67
|
+
export const fileUpdateCache = {
|
|
68
|
+
read() {
|
|
69
|
+
try {
|
|
70
|
+
const raw = readFileSync(updateCachePath(), 'utf8');
|
|
71
|
+
const parsed = JSON.parse(raw);
|
|
72
|
+
if (parsed !== null &&
|
|
73
|
+
typeof parsed === 'object' &&
|
|
74
|
+
typeof parsed.checkedAt === 'number' &&
|
|
75
|
+
typeof parsed.latest === 'string') {
|
|
76
|
+
return parsed;
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
write(entry) {
|
|
85
|
+
try {
|
|
86
|
+
const path = updateCachePath();
|
|
87
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
88
|
+
writeFileSync(path, JSON.stringify(entry), 'utf8');
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// A non-writable home dir must not break startup.
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
function updateCachePath() {
|
|
96
|
+
return join(homedir(), '.yt-builder-mcp', 'update-check.json');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve whether a newer version is available, throttled by a cache TTL and
|
|
100
|
+
* fail-silent on every network/fs error. Never throws.
|
|
101
|
+
*/
|
|
102
|
+
export async function checkForUpdate(options) {
|
|
103
|
+
const { currentVersion, packageName, fetchLatest = (pkg) => fetchLatestFromNpm(pkg, options.timeoutMs), cache = fileUpdateCache, now = Date.now(), ttlMs = DEFAULT_TTL_MS, } = options;
|
|
104
|
+
const cached = safeRead(cache);
|
|
105
|
+
if (cached !== null && now - cached.checkedAt < ttlMs) {
|
|
106
|
+
return verdict(currentVersion, cached.latest, true);
|
|
107
|
+
}
|
|
108
|
+
let latest = null;
|
|
109
|
+
let error;
|
|
110
|
+
try {
|
|
111
|
+
latest = await fetchLatest(packageName);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
error = err instanceof Error ? err.message : String(err);
|
|
115
|
+
}
|
|
116
|
+
if (latest === null) {
|
|
117
|
+
// Fall back to a (stale) cached value if we have one, else "unknown".
|
|
118
|
+
if (cached !== null)
|
|
119
|
+
return { ...verdict(currentVersion, cached.latest, true), error };
|
|
120
|
+
return { updateAvailable: false, current: currentVersion, latest: null, fromCache: false, error };
|
|
121
|
+
}
|
|
122
|
+
safeWrite(cache, { checkedAt: now, latest });
|
|
123
|
+
return verdict(currentVersion, latest, false);
|
|
124
|
+
}
|
|
125
|
+
function verdict(current, latest, fromCache) {
|
|
126
|
+
return { updateAvailable: isVersionNewer(latest, current), current, latest, fromCache };
|
|
127
|
+
}
|
|
128
|
+
function safeRead(cache) {
|
|
129
|
+
try {
|
|
130
|
+
return cache.read();
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function safeWrite(cache, entry) {
|
|
137
|
+
try {
|
|
138
|
+
cache.write(entry);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
/* ignore */
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* A one-line, actionable update notice for stderr / the diagnose tool, or null
|
|
146
|
+
* when no update is available.
|
|
147
|
+
*/
|
|
148
|
+
export function formatUpdateNotice(status) {
|
|
149
|
+
if (!status.updateAvailable || status.latest === null)
|
|
150
|
+
return null;
|
|
151
|
+
return (`[yt-builder-mcp] update available: ${status.current} → ${status.latest}. ` +
|
|
152
|
+
`Restart your AI client to pick it up (npx pulls @latest), or update a global install: ` +
|
|
153
|
+
`npm i -g @wootsup/yt-builder-mcp@latest.`);
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=update-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/update/update-check.ts"],"names":[],"mappings":"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"}
|
package/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"dxt_version": "0.1",
|
|
3
3
|
"name": "@wootsup/yt-builder-mcp",
|
|
4
4
|
"display_name": "YT Builder MCP for YOOtheme Pro (unofficial)",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.4.0",
|
|
6
6
|
"description": "Drive your YOOtheme Pro Page Builder programmatically from Claude, Cursor, Codex, Gemini and 5 other MCP-capable AI assistants — read layouts, edit settings, add elements, bind dynamic sources. Works on WordPress and Joomla 5/6. Built for YOOtheme Pro 4.0+. Independent third-party project, not affiliated with YOOtheme GmbH.",
|
|
7
7
|
"long_description": "YT Builder MCP gives AI assistants a typed, scoped, and idempotent surface for your YOOtheme Pro Page Builder, on either WordPress or Joomla 5/6. Tools cover page discovery, layout inspection, element CRUD, source binding, and diagnostics. Bearer auth, optimistic locking via ETag, scope hierarchy (read < write < admin), and structured-error responses keep the agent safe and the workflow correct on first try. Independent third-party project — YOOtheme® is a registered trademark of YOOtheme GmbH (yootheme.com); YT Builder MCP is built by WootsUp (getimo productions) and is not affiliated with, endorsed by, or sponsored by YOOtheme.",
|
|
8
8
|
"icon": "icon.png",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wootsup/yt-builder-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "YT Builder MCP — drive your page builder from Claude, Cursor, Codex, Gemini and 5 other MCP-capable AI assistants. Built for YOOtheme Pro 4.0+. Independent third-party project, not affiliated with YOOtheme GmbH.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"@clack/prompts": "^0.7.0",
|
|
72
72
|
"pino": "^10.3.1",
|
|
73
73
|
"proper-lockfile": "^4.1.2",
|
|
74
|
+
"undici": "^6.27.0",
|
|
74
75
|
"zod": "^4.3.6"
|
|
75
76
|
},
|
|
76
77
|
"devDependencies": {
|
|
@@ -12,10 +12,10 @@ 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 catalogues
|
|
16
|
-
idempotent tools (
|
|
15
|
+
`@wootsup/yt-builder-mcp` server. The server catalogues 33 typed, scoped,
|
|
16
|
+
idempotent tools (35 callable end-to-end with the two gateways). 30 of them
|
|
17
17
|
advertised as first-class entries in `tools/list`
|
|
18
|
-
(
|
|
18
|
+
(26 essential L1 forwards + 2 direct L3 entries + 2 gateways), and 5 advanced
|
|
19
19
|
tools reachable through the gateways. The write-capable
|
|
20
20
|
`yootheme_builder_advanced` gateway routes all 5; the read-only
|
|
21
21
|
`yootheme_builder_advanced_read` gateway routes only the read-only subset
|
|
@@ -81,8 +81,8 @@ The server exposes:
|
|
|
81
81
|
- **2 direct top-level tools**, always callable, always in `tools/list`:
|
|
82
82
|
`yootheme_builder_health` and `yootheme_builder_diagnose`. These are
|
|
83
83
|
the "the gateway itself might be broken" escape hatch.
|
|
84
|
-
- **
|
|
85
|
-
(pages_list, pages_create, pages_delete, page_dynamize, scaffold_section,
|
|
84
|
+
- **26 essential forwarded tools**: common reads + the most-used writes
|
|
85
|
+
(pages_list, pages_resolve, pages_create, pages_delete, page_dynamize, scaffold_section,
|
|
86
86
|
get_etag, element_list / add / update_settings / get / move / clone / delete,
|
|
87
87
|
page_get_layout, sources_list, element_types_list, element_type_get_schema,
|
|
88
88
|
template_summary, inspect_multi_items_binding, sites_list, sites_test,
|
|
@@ -105,9 +105,9 @@ The server exposes:
|
|
|
105
105
|
auto-allow it). Prefer the read gateway for pure inspection:
|
|
106
106
|
`yootheme_builder_advanced_read({ tool: "yootheme_builder_page_get_schema", arguments: { template_id } })`.
|
|
107
107
|
|
|
108
|
-
`tools/list` therefore advertises
|
|
109
|
-
essentials + 2 L3 direct + 2 gateways. The total callable surface is
|
|
110
|
-
(
|
|
108
|
+
`tools/list` therefore advertises 30 names (26 + 2 + 2). That's 26 L1
|
|
109
|
+
essentials + 2 L3 direct + 2 gateways. The total callable surface is 35
|
|
110
|
+
(30 advertised + 5 advanced reachable through the gateways). If the AI
|
|
111
111
|
client reports "tool not found", you are almost certainly calling an
|
|
112
112
|
advanced tool by its raw name. Wrap it in
|
|
113
113
|
`yootheme_builder_advanced({ tool, arguments })` (or the read gateway for
|
|
@@ -884,7 +884,7 @@ Joomla administrator access." Don't fabricate tool calls.
|
|
|
884
884
|
|
|
885
885
|
<!-- TOOL-CATALOG:BEGIN -->
|
|
886
886
|
|
|
887
|
-
**
|
|
887
|
+
**33 catalogued tools** plus the `yootheme_builder_advanced` (write) + `yootheme_builder_advanced_read` (read-only) gateways = **35 reachable via `tools/list`** (26 L1 + 2 L3 + 2 gateways = 30 advertised; the gateways route to 5 additional advanced tools, bringing the total to 35 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.
|
|
888
888
|
|
|
889
889
|
| Tool | Kind | Input keys | Description |
|
|
890
890
|
| --- | --- | --- | --- |
|
|
@@ -907,13 +907,14 @@ Joomla administrator access." Don't fabricate tool calls.
|
|
|
907
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
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
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"` —
|
|
911
|
-
| `yootheme_builder_page_get_schema` | read+idempotent | `site_id`, `template_id` | Get the flat schema for a template —
|
|
910
|
+
| `yootheme_builder_page_get_layout` | read+idempotent | `fields`, `flat`, `force`, `mode`, `post_id`, `site_id`, `template_id`, `url` | Get the layout tree for one template — address it by `template_id` (from pages_list), `post_id` (numeric post/article id), or `url` (public page URL, resolved in one call). For dynamize/bind work prefer `mode:"bindings_only"` — the binding skeleton only (no style props). Default `mode:"full"` returns nested `{layout, etag}`. `flat:true` gives a depth-first `{elements:[...], etag}` array (with `fields[]`). A repeated unchanged read auto-skips `[unchanged]`; `force:true` re-fetches. |
|
|
911
|
+
| `yootheme_builder_page_get_schema` | read+idempotent | `post_id`, `site_id`, `template_id`, `url` | Get the flat schema for a template — nodes with their JSON-Pointer paths and element types. Lighter than page_get_layout, enough to locate elements before editing. Address it by `template_id` (from pages_list), `post_id` (numeric post/article id), or `url` (public page URL, resolved in one call). Default site unless site_id is provided. |
|
|
912
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
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
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
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
|
|
916
|
+
| `yootheme_builder_pages_list` | read+idempotent | `cursor`, `fields`, `label_contains`, `limit`, `site_id` | List pages, templates, and layouts in the YOOtheme Pro builder (template_id, label, type, element count, frontend_url, builder_url per row). CALL THIS FIRST to discover template IDs before page_get_layout / element_list / page_get_schema. Paginates: up to `limit` rows (default 50) plus `total` and a `next_cursor` (pass it back as `cursor`) when more remain. Filter with `label_contains`. Slim rows with `fields:["id","label"]`. Operates on the default site unless site_id is provided. |
|
|
917
|
+
| `yootheme_builder_pages_resolve` | read+idempotent | `site_id`, `url` | Resolve a public page/article URL to the template_id that renders it — paste a URL, get a layout-addressable id in one call. Returns {template_id (page:{id}/article:{id}), post_id, type, frontend_url}. 404s with a hint for THEME-template URLs (use pages_list instead). page_get_layout / page_get_schema also accept a `url` param directly. Default site unless site_id given. |
|
|
917
918
|
| `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. |
|
|
918
919
|
| `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.) |
|
|
919
920
|
| `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. |
|