@wootsup/yt-builder-mcp 1.0.0 → 1.1.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.
Files changed (187) hide show
  1. package/README.md +18 -6
  2. package/bin/yt-builder-mcp.js +6 -0
  3. package/dist/auth.d.ts +86 -6
  4. package/dist/auth.d.ts.map +1 -1
  5. package/dist/auth.js +141 -8
  6. package/dist/auth.js.map +1 -1
  7. package/dist/errors/sanitize.d.ts.map +1 -1
  8. package/dist/errors/sanitize.js +10 -0
  9. package/dist/errors/sanitize.js.map +1 -1
  10. package/dist/gateway/essentials.d.ts +1 -1
  11. package/dist/gateway/essentials.d.ts.map +1 -1
  12. package/dist/gateway/essentials.js +15 -2
  13. package/dist/gateway/essentials.js.map +1 -1
  14. package/dist/index.d.ts +5 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +52 -16
  17. package/dist/index.js.map +1 -1
  18. package/dist/install-skill.d.ts +10 -2
  19. package/dist/install-skill.d.ts.map +1 -1
  20. package/dist/install-skill.js +18 -7
  21. package/dist/install-skill.js.map +1 -1
  22. package/dist/platform/detect.d.ts +64 -0
  23. package/dist/platform/detect.d.ts.map +1 -0
  24. package/dist/platform/detect.js +98 -0
  25. package/dist/platform/detect.js.map +1 -0
  26. package/dist/platform/index.d.ts +72 -0
  27. package/dist/platform/index.d.ts.map +1 -1
  28. package/dist/platform/index.js +138 -0
  29. package/dist/platform/index.js.map +1 -1
  30. package/dist/platform/joomla.d.ts +44 -0
  31. package/dist/platform/joomla.d.ts.map +1 -0
  32. package/dist/platform/joomla.js +46 -0
  33. package/dist/platform/joomla.js.map +1 -0
  34. package/dist/server.d.ts +61 -2
  35. package/dist/server.d.ts.map +1 -1
  36. package/dist/server.js +86 -2
  37. package/dist/server.js.map +1 -1
  38. package/dist/setup-cli-confirm.d.ts +36 -0
  39. package/dist/setup-cli-confirm.d.ts.map +1 -0
  40. package/dist/setup-cli-confirm.js +59 -0
  41. package/dist/setup-cli-confirm.js.map +1 -0
  42. package/dist/setup-cli.d.ts +53 -1
  43. package/dist/setup-cli.d.ts.map +1 -1
  44. package/dist/setup-cli.js +525 -10
  45. package/dist/setup-cli.js.map +1 -1
  46. package/dist/setup-prompts.d.ts.map +1 -1
  47. package/dist/setup-prompts.js +12 -8
  48. package/dist/setup-prompts.js.map +1 -1
  49. package/dist/setup-wizard-types.d.ts +19 -3
  50. package/dist/setup-wizard-types.d.ts.map +1 -1
  51. package/dist/setup-wizard.d.ts.map +1 -1
  52. package/dist/setup-wizard.js +34 -1
  53. package/dist/setup-wizard.js.map +1 -1
  54. package/dist/sites/cli/add-site.d.ts +106 -0
  55. package/dist/sites/cli/add-site.d.ts.map +1 -0
  56. package/dist/sites/cli/add-site.js +185 -0
  57. package/dist/sites/cli/add-site.js.map +1 -0
  58. package/dist/sites/cli/list-sites.d.ts +40 -0
  59. package/dist/sites/cli/list-sites.d.ts.map +1 -0
  60. package/dist/sites/cli/list-sites.js +117 -0
  61. package/dist/sites/cli/list-sites.js.map +1 -0
  62. package/dist/sites/cli/remove-site.d.ts +60 -0
  63. package/dist/sites/cli/remove-site.d.ts.map +1 -0
  64. package/dist/sites/cli/remove-site.js +120 -0
  65. package/dist/sites/cli/remove-site.js.map +1 -0
  66. package/dist/sites/cli/set-default.d.ts +47 -0
  67. package/dist/sites/cli/set-default.d.ts.map +1 -0
  68. package/dist/sites/cli/set-default.js +69 -0
  69. package/dist/sites/cli/set-default.js.map +1 -0
  70. package/dist/sites/cli/test-site.d.ts +77 -0
  71. package/dist/sites/cli/test-site.d.ts.map +1 -0
  72. package/dist/sites/cli/test-site.js +146 -0
  73. package/dist/sites/cli/test-site.js.map +1 -0
  74. package/dist/sites/client-pool.d.ts +124 -0
  75. package/dist/sites/client-pool.d.ts.map +1 -0
  76. package/dist/sites/client-pool.js +172 -0
  77. package/dist/sites/client-pool.js.map +1 -0
  78. package/dist/sites/env-bridge.d.ts +55 -0
  79. package/dist/sites/env-bridge.d.ts.map +1 -0
  80. package/dist/sites/env-bridge.js +94 -0
  81. package/dist/sites/env-bridge.js.map +1 -0
  82. package/dist/sites/paths.d.ts +21 -0
  83. package/dist/sites/paths.d.ts.map +1 -0
  84. package/dist/sites/paths.js +37 -0
  85. package/dist/sites/paths.js.map +1 -0
  86. package/dist/sites/probe.d.ts +60 -0
  87. package/dist/sites/probe.d.ts.map +1 -0
  88. package/dist/sites/probe.js +112 -0
  89. package/dist/sites/probe.js.map +1 -0
  90. package/dist/sites/registry.d.ts +142 -0
  91. package/dist/sites/registry.d.ts.map +1 -0
  92. package/dist/sites/registry.js +163 -0
  93. package/dist/sites/registry.js.map +1 -0
  94. package/dist/sites/schema.d.ts +90 -0
  95. package/dist/sites/schema.d.ts.map +1 -0
  96. package/dist/sites/schema.js +71 -0
  97. package/dist/sites/schema.js.map +1 -0
  98. package/dist/sites/secret-resolver.d.ts +109 -0
  99. package/dist/sites/secret-resolver.d.ts.map +1 -0
  100. package/dist/sites/secret-resolver.js +189 -0
  101. package/dist/sites/secret-resolver.js.map +1 -0
  102. package/dist/sites/store.d.ts +82 -0
  103. package/dist/sites/store.d.ts.map +1 -0
  104. package/dist/sites/store.js +198 -0
  105. package/dist/sites/store.js.map +1 -0
  106. package/dist/sites/tools/index.d.ts +28 -0
  107. package/dist/sites/tools/index.d.ts.map +1 -0
  108. package/dist/sites/tools/index.js +30 -0
  109. package/dist/sites/tools/index.js.map +1 -0
  110. package/dist/sites/tools/sites-list.d.ts +48 -0
  111. package/dist/sites/tools/sites-list.d.ts.map +1 -0
  112. package/dist/sites/tools/sites-list.js +135 -0
  113. package/dist/sites/tools/sites-list.js.map +1 -0
  114. package/dist/sites/tools/sites-test.d.ts +47 -0
  115. package/dist/sites/tools/sites-test.d.ts.map +1 -0
  116. package/dist/sites/tools/sites-test.js +148 -0
  117. package/dist/sites/tools/sites-test.js.map +1 -0
  118. package/dist/skill-loader.d.ts +63 -3
  119. package/dist/skill-loader.d.ts.map +1 -1
  120. package/dist/skill-loader.js +123 -10
  121. package/dist/skill-loader.js.map +1 -1
  122. package/dist/tools/elements/builders.d.ts +2 -2
  123. package/dist/tools/elements/builders.d.ts.map +1 -1
  124. package/dist/tools/elements/builders.js +45 -23
  125. package/dist/tools/elements/builders.js.map +1 -1
  126. package/dist/tools/elements/handlers.d.ts +8 -1
  127. package/dist/tools/elements/handlers.d.ts.map +1 -1
  128. package/dist/tools/elements/handlers.js +37 -1
  129. package/dist/tools/elements/handlers.js.map +1 -1
  130. package/dist/tools/format/health-format.d.ts +12 -6
  131. package/dist/tools/format/health-format.d.ts.map +1 -1
  132. package/dist/tools/format/health-format.js +14 -11
  133. package/dist/tools/format/health-format.js.map +1 -1
  134. package/dist/tools/format/pages-format.d.ts +7 -1
  135. package/dist/tools/format/pages-format.d.ts.map +1 -1
  136. package/dist/tools/format/pages-format.js +25 -1
  137. package/dist/tools/format/pages-format.js.map +1 -1
  138. package/dist/tools/health.d.ts +2 -2
  139. package/dist/tools/health.d.ts.map +1 -1
  140. package/dist/tools/health.js +120 -47
  141. package/dist/tools/health.js.map +1 -1
  142. package/dist/tools/index.d.ts +9 -2
  143. package/dist/tools/index.d.ts.map +1 -1
  144. package/dist/tools/index.js +21 -7
  145. package/dist/tools/index.js.map +1 -1
  146. package/dist/tools/inspection.d.ts +2 -2
  147. package/dist/tools/inspection.d.ts.map +1 -1
  148. package/dist/tools/inspection.js +67 -22
  149. package/dist/tools/inspection.js.map +1 -1
  150. package/dist/tools/multi-items/builders.d.ts +2 -2
  151. package/dist/tools/multi-items/builders.d.ts.map +1 -1
  152. package/dist/tools/multi-items/builders.js +21 -8
  153. package/dist/tools/multi-items/builders.js.map +1 -1
  154. package/dist/tools/pages/builders.d.ts +2 -2
  155. package/dist/tools/pages/builders.d.ts.map +1 -1
  156. package/dist/tools/pages/builders.js +36 -24
  157. package/dist/tools/pages/builders.js.map +1 -1
  158. package/dist/tools/pages/handlers-read.d.ts.map +1 -1
  159. package/dist/tools/pages/handlers-read.js +10 -0
  160. package/dist/tools/pages/handlers-read.js.map +1 -1
  161. package/dist/tools/pages/schemas.d.ts.map +1 -1
  162. package/dist/tools/pages/schemas.js +18 -0
  163. package/dist/tools/pages/schemas.js.map +1 -1
  164. package/dist/tools/pool-resolve-helper.d.ts +83 -0
  165. package/dist/tools/pool-resolve-helper.d.ts.map +1 -0
  166. package/dist/tools/pool-resolve-helper.js +148 -0
  167. package/dist/tools/pool-resolve-helper.js.map +1 -0
  168. package/dist/tools/shared-schemas.d.ts +10 -0
  169. package/dist/tools/shared-schemas.d.ts.map +1 -1
  170. package/dist/tools/shared-schemas.js +20 -2
  171. package/dist/tools/shared-schemas.js.map +1 -1
  172. package/dist/tools/sources/builders.d.ts +2 -2
  173. package/dist/tools/sources/builders.d.ts.map +1 -1
  174. package/dist/tools/sources/builders.js +27 -15
  175. package/dist/tools/sources/builders.js.map +1 -1
  176. package/dist/tools/tool-builder/index.d.ts +1 -1
  177. package/dist/tools/tool-builder/index.d.ts.map +1 -1
  178. package/dist/tools/tool-builder/index.js +1 -1
  179. package/dist/tools/tool-builder/index.js.map +1 -1
  180. package/dist/tools/tool-builder/results.d.ts +34 -0
  181. package/dist/tools/tool-builder/results.d.ts.map +1 -1
  182. package/dist/tools/tool-builder/results.js +86 -0
  183. package/dist/tools/tool-builder/results.js.map +1 -1
  184. package/manifest.json +27 -10
  185. package/package.json +3 -1
  186. package/skills/yt-builder-mcp/SKILL.md +846 -0
  187. package/skills/yootheme-builder/SKILL.md +0 -587
package/README.md CHANGED
@@ -79,7 +79,7 @@ in `tools/list`** (well under Cursor's ~40-tool cap):
79
79
  clean_implode_directives, element_type_get_schema).
80
80
 
81
81
  Total: **23 domain tools + 1 gateway = 24**. Surface: **11 entries
82
- in tools/list**. See `skills/yootheme-builder/SKILL.md` for the
82
+ in tools/list**. See `skills/yt-builder-mcp/SKILL.md` for the
83
83
  full catalog and the 5 canonical workflows.
84
84
 
85
85
  ## Tool catalogue — 23 domain tools
@@ -144,8 +144,10 @@ When launched by an AI client (or directly):
144
144
 
145
145
  | Variable | Required? | Purpose |
146
146
  |----------|-----------|---------|
147
- | `YTB_MCP_WP_URL` | Yes | WordPress base URL (e.g. `https://example.com`). Trailing slash is stripped. |
148
- | `YTB_MCP_BEARER_TOKEN` | Yes | Bearer key from wp-admin. Format-checked client-side: must match `ytb_(live\|test)_<payload>.<sig>`. Do **not** prepend `Bearer ` the MCP server adds it. |
147
+ | `YTB_MCP_SITE_URL` | Yes | Host CMS base URL (e.g. `https://example.com`). Works for BOTH WordPress and Joomla. Trailing slash is stripped. |
148
+ | `YTB_MCP_WP_URL` | No (deprecated) | Legacy alias for `YTB_MCP_SITE_URL`; still honoured for pre-Wave-7 configurations. A non-fatal deprecation notice is written to stderr when this is used without `YTB_MCP_SITE_URL`. |
149
+ | `YTB_MCP_BEARER_TOKEN` | Yes | Bearer key from wp-admin (WordPress: Tools → "YT Builder MCP") or Administrator → Components → "YT Builder MCP" (Joomla). Format-checked client-side: must match `ytb_(live\|test)_<payload>.<sig>`. Do **not** prepend `Bearer ` — the MCP server adds it. |
150
+ | `YTB_MCP_PLATFORM` | No | Explicit platform hint: `wordpress` or `joomla`. Set to `joomla` when `YTB_MCP_SITE_URL` is an origin-only Joomla URL (no `/api/index.php/` in the path). Defaults to URL-shape auto-detection. |
149
151
  | `YTB_MCP_TIMEOUT_MS` | No | REST timeout (default 15000). |
150
152
  | `YTB_MCP_TEST_MODE` | No | `1` skips the stdio loop (smoke tests). |
151
153
 
@@ -157,11 +159,11 @@ client's MCP config file:
157
159
  ```json
158
160
  {
159
161
  "mcpServers": {
160
- "yootheme-builder": {
162
+ "yt-builder-mcp": {
161
163
  "command": "npx",
162
164
  "args": ["-y", "@wootsup/yt-builder-mcp"],
163
165
  "env": {
164
- "YTB_MCP_WP_URL": "https://example.com",
166
+ "YTB_MCP_SITE_URL": "https://example.com",
165
167
  "YTB_MCP_BEARER_TOKEN": "ytb_live_…"
166
168
  }
167
169
  }
@@ -169,6 +171,16 @@ client's MCP config file:
169
171
  }
170
172
  ```
171
173
 
174
+ For a Joomla install at an origin-only URL, also set the platform hint:
175
+
176
+ ```json
177
+ "env": {
178
+ "YTB_MCP_SITE_URL": "https://example.com/joomla",
179
+ "YTB_MCP_BEARER_TOKEN": "ytb_live_…",
180
+ "YTB_MCP_PLATFORM": "joomla"
181
+ }
182
+ ```
183
+
172
184
  ## Non-interactive CI usage
173
185
 
174
186
  For scripted / CI installs, pass the answers as flags and add
@@ -213,7 +225,7 @@ The CLI returns POSIX-style exit codes for scripting / CI:
213
225
 
214
226
  ## Documentation
215
227
 
216
- - [SKILL.md (bundled agent skill)](./skills/yootheme-builder/SKILL.md) — 5 canonical workflows, gateway model, tool catalog
228
+ - [SKILL.md (bundled agent skill)](./skills/yt-builder-mcp/SKILL.md) — 5 canonical workflows, gateway model, tool catalog
217
229
  - [REST API Reference](https://github.com/wootsup/yt-builder-mcp/blob/main/docs/rest-api-reference.md)
218
230
  - [MCP Tool Reference](https://github.com/wootsup/yt-builder-mcp/blob/main/docs/mcp-tool-reference.md)
219
231
 
@@ -25,6 +25,12 @@ const CLI_SUBCOMMANDS = new Set([
25
25
  'setup',
26
26
  'install-skill',
27
27
  'install',
28
+ // W9 multi-site CLI subcommands.
29
+ 'add-site',
30
+ 'list-sites',
31
+ 'remove-site',
32
+ 'set-default',
33
+ 'test-site',
28
34
  'help',
29
35
  '--help',
30
36
  '-h',
package/dist/auth.d.ts CHANGED
@@ -3,12 +3,22 @@
3
3
  *
4
4
  * The MCP server reads two environment variables on startup:
5
5
  *
6
- * YTB_MCP_WP_URL — base URL of the WordPress install, e.g.
7
- * `https://example.com`. The REST namespace
8
- * `/wp-json/yt-builder-mcp/v1` is
9
- * appended internally.
6
+ * YTB_MCP_SITE_URL — base URL of the host CMS install (WordPress
7
+ * OR Joomla), e.g. `https://example.com`.
8
+ * The per-platform REST namespace
9
+ * (`/wp-json/yt-builder-mcp/v1` for WP,
10
+ * `/api/index.php/v1/yt-builder-mcp` for
11
+ * Joomla) is appended internally based on
12
+ * runtime platform detection.
13
+ * YTB_MCP_WP_URL — DEPRECATED alias for YTB_MCP_SITE_URL,
14
+ * kept for back-compat with pre-Wave 7
15
+ * configurations. A non-fatal deprecation
16
+ * notice is written to stderr when the
17
+ * legacy var is used in non-test mode.
10
18
  * YTB_MCP_BEARER_TOKEN — the Bearer key generated by the plugin
11
- * Settings page (`wp-admin → YT Builder MCP`).
19
+ * Settings page (`wp-admin → YT Builder MCP`
20
+ * on WordPress, `Components → YT Builder MCP`
21
+ * on Joomla).
12
22
  *
13
23
  * `loadConfig()` throws `ConfigError` if either is missing, so the
14
24
  * server fails fast with a useful message rather than emitting cryptic
@@ -16,13 +26,19 @@
16
26
  *
17
27
  * @license MIT
18
28
  */
29
+ import { SiteRegistry } from './sites/registry.js';
19
30
  export interface ServerConfig {
20
- /** Base URL of the WordPress install (no trailing slash). */
31
+ /** Base URL of the host-CMS install (no trailing slash). */
21
32
  readonly baseUrl: string;
22
33
  /** Bearer key. */
23
34
  readonly bearerToken: string;
24
35
  /** Network timeout (ms) for REST calls. */
25
36
  readonly timeoutMs: number;
37
+ /**
38
+ * Optional explicit platform hint from {@link ENV_PLATFORM}.
39
+ * `undefined` lets the consumer rely on URL-shape detection.
40
+ */
41
+ readonly platformHint?: 'wordpress' | 'joomla';
26
42
  }
27
43
  export interface LoadConfigOptions {
28
44
  /** Allow the bearer-token to be empty (for health-only smoke tests). */
@@ -30,10 +46,74 @@ export interface LoadConfigOptions {
30
46
  /** Source of env vars (defaults to process.env). */
31
47
  readonly env?: NodeJS.ProcessEnv;
32
48
  }
49
+ /**
50
+ * Canonical env-var name for the host-CMS base URL (Wave 7+: covers
51
+ * both WordPress and Joomla). Prefer this for all new configurations.
52
+ */
53
+ export declare const ENV_SITE_URL = "YTB_MCP_SITE_URL";
54
+ /**
55
+ * Legacy env-var name kept for back-compat. Pre-Wave-7 configurations
56
+ * (every release through v1.0.x) used `YTB_MCP_WP_URL`. New code should
57
+ * use {@link ENV_SITE_URL}; this constant is retained so the wizard,
58
+ * tests, and error hints can still reference the legacy name.
59
+ */
33
60
  export declare const ENV_WP_URL = "YTB_MCP_WP_URL";
34
61
  export declare const ENV_BEARER = "YTB_MCP_BEARER_TOKEN";
35
62
  export declare const ENV_TIMEOUT = "YTB_MCP_TIMEOUT_MS";
36
63
  export declare const ENV_TEST_MODE = "YTB_MCP_TEST_MODE";
64
+ /**
65
+ * Optional platform hint env var — `'wordpress'` or `'joomla'`. When
66
+ * unset, the server auto-detects from the URL shape (cookbook §3.7.1):
67
+ * - URL contains `/wp-json/` → wordpress
68
+ * - URL contains `/api/index.php/` → joomla
69
+ * - origin-only URL → defaults to wordpress (back-compat)
70
+ *
71
+ * Set this to `'joomla'` when your YTB_MCP_SITE_URL is an origin-only
72
+ * Joomla URL like `https://example.com/joomla`.
73
+ */
74
+ export declare const ENV_PLATFORM = "YTB_MCP_PLATFORM";
75
+ /**
76
+ * W10 — canonical env-var name for the multi-site registry file. When
77
+ * set, {@link loadRegistry} loads + validates the JSON at this path and
78
+ * the legacy {@link ENV_SITE_URL} / {@link ENV_BEARER} pair is ignored.
79
+ * When unset, the env-bridge falls back to building a one-site registry
80
+ * from the legacy single-site pair.
81
+ */
82
+ export declare const ENV_SITES_FILE = "YTB_MCP_SITES_FILE";
37
83
  export declare function loadConfig(options?: LoadConfigOptions): ServerConfig;
38
84
  export declare function isTestMode(env?: NodeJS.ProcessEnv): boolean;
85
+ /**
86
+ * Options accepted by {@link loadRegistry}.
87
+ */
88
+ export interface LoadRegistryOptions {
89
+ /** Source of env vars (defaults to process.env). */
90
+ readonly env?: NodeJS.ProcessEnv;
91
+ }
92
+ /**
93
+ * W10 — canonical boot-time registry loader.
94
+ *
95
+ * Resolution order:
96
+ * 1. **Sites file** — if {@link ENV_SITES_FILE} is set to a non-empty
97
+ * string, parse + validate the JSON at that path and wrap it in a
98
+ * {@link SiteRegistry}. Schema failures bubble up as
99
+ * `SitesFileError` (the store does not swallow them); the caller
100
+ * decides whether to fail-fast or fall back. Wave 10 chooses
101
+ * fail-fast — explicit file = explicit intent.
102
+ *
103
+ * 2. **Legacy env-bridge** — synthesise a one-site registry from the
104
+ * pre-W10 single-site env-vars ({@link ENV_SITE_URL} +
105
+ * {@link ENV_BEARER}, with {@link ENV_PLATFORM} as optional hint).
106
+ * Preserves the single-site UX for every customer who has not
107
+ * migrated to a sites.json yet.
108
+ *
109
+ * 3. **Hard fail** — neither configured. Surface a {@link ConfigError}
110
+ * with the three setup options so the operator knows exactly which
111
+ * knob to turn.
112
+ *
113
+ * This function replaces {@link loadConfig} on the main boot path.
114
+ * `loadConfig` is intentionally retained for the test-mode fallback in
115
+ * `index.ts` (`--test-mode` smoke probes) and for any embedded consumer
116
+ * that still wants a flat `ServerConfig`.
117
+ */
118
+ export declare function loadRegistry(opts?: LoadRegistryOptions): Promise<SiteRegistry>;
39
119
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,MAAM,WAAW,YAAY;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,kBAAkB;IAClB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2CAA2C;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC,oDAAoD;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACpC;AAED,eAAO,MAAM,UAAU,mBAAmB,CAAC;AAC3C,eAAO,MAAM,UAAU,yBAAyB,CAAC;AACjD,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAChD,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAkCjD,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,YAAY,CAiDxE;AAED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAExE"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAInD,MAAM,WAAW,YAAY;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,kBAAkB;IAClB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2CAA2C;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;CAClD;AAED,MAAM,WAAW,iBAAiB;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC,oDAAoD;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAC/C;;;;;GAKG;AACH,eAAO,MAAM,UAAU,mBAAmB,CAAC;AAC3C,eAAO,MAAM,UAAU,yBAAyB,CAAC;AACjD,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAChD,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAC/C;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAkCnD,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,YAAY,CA8ExE;AAED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAExE;AAMD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,oDAAoD;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,YAAY,CAC9B,IAAI,GAAE,mBAAwB,GAC/B,OAAO,CAAC,YAAY,CAAC,CA8CvB"}
package/dist/auth.js CHANGED
@@ -3,12 +3,22 @@
3
3
  *
4
4
  * The MCP server reads two environment variables on startup:
5
5
  *
6
- * YTB_MCP_WP_URL — base URL of the WordPress install, e.g.
7
- * `https://example.com`. The REST namespace
8
- * `/wp-json/yt-builder-mcp/v1` is
9
- * appended internally.
6
+ * YTB_MCP_SITE_URL — base URL of the host CMS install (WordPress
7
+ * OR Joomla), e.g. `https://example.com`.
8
+ * The per-platform REST namespace
9
+ * (`/wp-json/yt-builder-mcp/v1` for WP,
10
+ * `/api/index.php/v1/yt-builder-mcp` for
11
+ * Joomla) is appended internally based on
12
+ * runtime platform detection.
13
+ * YTB_MCP_WP_URL — DEPRECATED alias for YTB_MCP_SITE_URL,
14
+ * kept for back-compat with pre-Wave 7
15
+ * configurations. A non-fatal deprecation
16
+ * notice is written to stderr when the
17
+ * legacy var is used in non-test mode.
10
18
  * YTB_MCP_BEARER_TOKEN — the Bearer key generated by the plugin
11
- * Settings page (`wp-admin → YT Builder MCP`).
19
+ * Settings page (`wp-admin → YT Builder MCP`
20
+ * on WordPress, `Components → YT Builder MCP`
21
+ * on Joomla).
12
22
  *
13
23
  * `loadConfig()` throws `ConfigError` if either is missing, so the
14
24
  * server fails fast with a useful message rather than emitting cryptic
@@ -18,10 +28,44 @@
18
28
  */
19
29
  import { z } from 'zod';
20
30
  import { ConfigError } from './errors.js';
31
+ import { synthesiseFromEnv } from './sites/env-bridge.js';
32
+ import { SiteRegistry } from './sites/registry.js';
33
+ import { SitesFile } from './sites/schema.js';
34
+ import { loadSitesFile } from './sites/store.js';
35
+ /**
36
+ * Canonical env-var name for the host-CMS base URL (Wave 7+: covers
37
+ * both WordPress and Joomla). Prefer this for all new configurations.
38
+ */
39
+ export const ENV_SITE_URL = 'YTB_MCP_SITE_URL';
40
+ /**
41
+ * Legacy env-var name kept for back-compat. Pre-Wave-7 configurations
42
+ * (every release through v1.0.x) used `YTB_MCP_WP_URL`. New code should
43
+ * use {@link ENV_SITE_URL}; this constant is retained so the wizard,
44
+ * tests, and error hints can still reference the legacy name.
45
+ */
21
46
  export const ENV_WP_URL = 'YTB_MCP_WP_URL';
22
47
  export const ENV_BEARER = 'YTB_MCP_BEARER_TOKEN';
23
48
  export const ENV_TIMEOUT = 'YTB_MCP_TIMEOUT_MS';
24
49
  export const ENV_TEST_MODE = 'YTB_MCP_TEST_MODE';
50
+ /**
51
+ * Optional platform hint env var — `'wordpress'` or `'joomla'`. When
52
+ * unset, the server auto-detects from the URL shape (cookbook §3.7.1):
53
+ * - URL contains `/wp-json/` → wordpress
54
+ * - URL contains `/api/index.php/` → joomla
55
+ * - origin-only URL → defaults to wordpress (back-compat)
56
+ *
57
+ * Set this to `'joomla'` when your YTB_MCP_SITE_URL is an origin-only
58
+ * Joomla URL like `https://example.com/joomla`.
59
+ */
60
+ export const ENV_PLATFORM = 'YTB_MCP_PLATFORM';
61
+ /**
62
+ * W10 — canonical env-var name for the multi-site registry file. When
63
+ * set, {@link loadRegistry} loads + validates the JSON at this path and
64
+ * the legacy {@link ENV_SITE_URL} / {@link ENV_BEARER} pair is ignored.
65
+ * When unset, the env-bridge falls back to building a one-site registry
66
+ * from the legacy single-site pair.
67
+ */
68
+ export const ENV_SITES_FILE = 'YTB_MCP_SITES_FILE';
25
69
  const DEFAULT_TIMEOUT_MS = 15_000;
26
70
  /**
27
71
  * Maximum accepted length for a Bearer token (defense-in-depth bound;
@@ -47,12 +91,30 @@ const BEARER_FORMAT_SCHEMA = z
47
91
  .regex(/^ytb_(live|test)_[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/, 'Bearer must match ytb_(live|test)_<payloadB64Url>.<sigB64Url> format (copy the key as shown in wp-admin → "YT Builder MCP" → Settings; do NOT prepend "Bearer ").');
48
92
  export function loadConfig(options = {}) {
49
93
  const env = options.env ?? process.env;
50
- const rawUrl = (env[ENV_WP_URL] ?? '').trim();
94
+ // Wave 7: YTB_MCP_SITE_URL is canonical (covers both WP + Joomla);
95
+ // YTB_MCP_WP_URL is retained as a deprecated back-compat alias.
96
+ // Resolution order: SITE_URL wins; legacy WP_URL fallback emits a
97
+ // soft deprecation note in non-test mode.
98
+ const rawSiteUrl = (env[ENV_SITE_URL] ?? '').trim();
99
+ const rawLegacyUrl = (env[ENV_WP_URL] ?? '').trim();
100
+ const rawUrl = rawSiteUrl !== '' ? rawSiteUrl : rawLegacyUrl;
101
+ // Soft deprecation notice — only when the loader is being used in
102
+ // its real-server role (env defaulted to process.env). Programmatic
103
+ // callers (tests, embedded uses) pass `options.env` explicitly and
104
+ // are silently treated as opt-in to the legacy var.
105
+ if (rawSiteUrl === ''
106
+ && rawLegacyUrl !== ''
107
+ && options.env === undefined
108
+ && !isTestMode(env)) {
109
+ process.stderr.write(`[yt-builder-mcp] notice: ${ENV_WP_URL} is deprecated — ` +
110
+ `set ${ENV_SITE_URL} instead (same value; covers WordPress + Joomla).\n`);
111
+ }
51
112
  const rawToken = (env[ENV_BEARER] ?? '').trim();
52
113
  const rawTimeout = (env[ENV_TIMEOUT] ?? '').trim();
53
114
  if (rawUrl === '') {
54
- throw new ConfigError(`Missing ${ENV_WP_URL}. Set it to your WordPress base URL ` +
55
- '(e.g. https://example.com). Run `yt-builder-mcp setup` to configure.');
115
+ throw new ConfigError(`Missing ${ENV_SITE_URL}. Set it to your CMS base URL ` +
116
+ '(e.g. https://example.com WordPress or Joomla). ' +
117
+ 'Run `yt-builder-mcp setup` to configure.');
56
118
  }
57
119
  if (!options.allowMissingToken && rawToken === '') {
58
120
  throw new ConfigError(`Missing ${ENV_BEARER}. Generate a Bearer key in wp-admin → "YT Builder MCP" → ` +
@@ -78,10 +140,15 @@ export function loadConfig(options = {}) {
78
140
  timeoutMs = parsed;
79
141
  }
80
142
  }
143
+ const rawPlatform = (env[ENV_PLATFORM] ?? '').trim().toLowerCase();
144
+ const platformHint = rawPlatform === 'wordpress' || rawPlatform === 'joomla'
145
+ ? rawPlatform
146
+ : undefined;
81
147
  return {
82
148
  baseUrl: stripTrailingSlash(rawUrl),
83
149
  bearerToken: rawToken,
84
150
  timeoutMs,
151
+ ...(platformHint !== undefined ? { platformHint } : {}),
85
152
  };
86
153
  }
87
154
  export function isTestMode(env = process.env) {
@@ -90,4 +157,70 @@ export function isTestMode(env = process.env) {
90
157
  function stripTrailingSlash(url) {
91
158
  return url.replace(/\/+$/, '');
92
159
  }
160
+ /**
161
+ * W10 — canonical boot-time registry loader.
162
+ *
163
+ * Resolution order:
164
+ * 1. **Sites file** — if {@link ENV_SITES_FILE} is set to a non-empty
165
+ * string, parse + validate the JSON at that path and wrap it in a
166
+ * {@link SiteRegistry}. Schema failures bubble up as
167
+ * `SitesFileError` (the store does not swallow them); the caller
168
+ * decides whether to fail-fast or fall back. Wave 10 chooses
169
+ * fail-fast — explicit file = explicit intent.
170
+ *
171
+ * 2. **Legacy env-bridge** — synthesise a one-site registry from the
172
+ * pre-W10 single-site env-vars ({@link ENV_SITE_URL} +
173
+ * {@link ENV_BEARER}, with {@link ENV_PLATFORM} as optional hint).
174
+ * Preserves the single-site UX for every customer who has not
175
+ * migrated to a sites.json yet.
176
+ *
177
+ * 3. **Hard fail** — neither configured. Surface a {@link ConfigError}
178
+ * with the three setup options so the operator knows exactly which
179
+ * knob to turn.
180
+ *
181
+ * This function replaces {@link loadConfig} on the main boot path.
182
+ * `loadConfig` is intentionally retained for the test-mode fallback in
183
+ * `index.ts` (`--test-mode` smoke probes) and for any embedded consumer
184
+ * that still wants a flat `ServerConfig`.
185
+ */
186
+ export async function loadRegistry(opts = {}) {
187
+ const env = opts.env ?? process.env;
188
+ // (1) sites file (preferred).
189
+ const sitesFilePath = (env[ENV_SITES_FILE] ?? '').trim();
190
+ if (sitesFilePath !== '') {
191
+ // loadSitesFile handles both "file present" and "file absent"
192
+ // (the latter returns an emptySitesFile). When the file is
193
+ // empty (no sites), fall through to env-bridge instead of
194
+ // booting with an empty registry — operators who set
195
+ // SITES_FILE to a not-yet-populated path should still get the
196
+ // legacy env-var ramp until they run `add-site`.
197
+ const file = await loadSitesFile(sitesFilePath);
198
+ if (file.sites.length > 0) {
199
+ return new SiteRegistry(file);
200
+ }
201
+ }
202
+ // (2) legacy env-bridge. The bridge already enforces URL/bearer
203
+ // non-emptiness and platform-hint validity, but we re-validate the
204
+ // full file shape through the W1 Zod schema before handing it to
205
+ // the registry. Defense-in-depth: a future env-bridge change cannot
206
+ // introduce a SitesFileT-shape regression that lands on the
207
+ // registry path without first failing this gate.
208
+ const synth = synthesiseFromEnv(env);
209
+ if (synth !== null) {
210
+ const parsed = SitesFile.safeParse(synth);
211
+ if (!parsed.success) {
212
+ const issues = parsed.error.issues
213
+ .map((i) => `${i.path.join('.')}: ${i.message}`)
214
+ .join('; ');
215
+ throw new ConfigError(`Env-bridge synthesised an invalid sites file: ${issues}`);
216
+ }
217
+ return new SiteRegistry(parsed.data);
218
+ }
219
+ // (3) fail-fast.
220
+ throw new ConfigError('No sites configured. Either: '
221
+ + '(a) set YTB_MCP_SITES_FILE to your sites.json path, or '
222
+ + '(b) set YTB_MCP_SITE_URL + YTB_MCP_BEARER_TOKEN for '
223
+ + 'single-site mode, or '
224
+ + '(c) run `npx -y @wootsup/yt-builder-mcp setup` interactively.');
225
+ }
93
226
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/errors/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA6CH;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAgB9C"}
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/errors/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAuDH;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAgB9C"}
@@ -59,6 +59,16 @@ const SECRET_KEYS = new Set([
59
59
  'sessionToken',
60
60
  'id_token',
61
61
  'idToken',
62
+ // W12-R1.3 (A2-M2) — 1Password Secret References are not secrets
63
+ // per se (the ref string itself is safe to log), BUT they identify
64
+ // the vault path + item + field of a real bearer. Surfacing them
65
+ // verbatim in an error payload that ends up in a Discord paste, a
66
+ // GitHub issue, or an LLM-shared transcript leaks the production
67
+ // 1Password layout to anyone reading. Treat as secret to be safe.
68
+ 'bearer_ref',
69
+ 'bearerRef',
70
+ 'token_ref',
71
+ 'tokenRef',
62
72
  ]);
63
73
  /**
64
74
  * Recursively walk any JSON-serialisable value and redact any nested
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/errors/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS;IAChC,sBAAsB;IACtB,OAAO;IACP,QAAQ;IACR,cAAc;IACd,aAAa;IACb,4BAA4B;IAC5B,WAAW;IACX,UAAU;IACV,cAAc;IACd,qBAAqB;IACrB,mBAAmB;IACnB,eAAe;IACf,cAAc;IACd,cAAc;IACd,aAAa;IACb,mBAAmB;IACnB,eAAe;IACf,cAAc;IACd,SAAS;IACT,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,WAAW;IACX,8DAA8D;IAC9D,aAAa;IACb,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,cAAc;IACd,aAAa;IACb,eAAe;IACf,cAAc;IACd,UAAU;IACV,SAAS;CACZ,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAI,KAAQ;IACvC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAiB,CAAC;IACtE,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;YACpE,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrB,GAAG,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACJ,GAAG,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;YAChC,CAAC;QACL,CAAC;QACD,OAAO,GAAmB,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/errors/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS;IAChC,sBAAsB;IACtB,OAAO;IACP,QAAQ;IACR,cAAc;IACd,aAAa;IACb,4BAA4B;IAC5B,WAAW;IACX,UAAU;IACV,cAAc;IACd,qBAAqB;IACrB,mBAAmB;IACnB,eAAe;IACf,cAAc;IACd,cAAc;IACd,aAAa;IACb,mBAAmB;IACnB,eAAe;IACf,cAAc;IACd,SAAS;IACT,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,WAAW;IACX,8DAA8D;IAC9D,aAAa;IACb,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,cAAc;IACd,aAAa;IACb,eAAe;IACf,cAAc;IACd,UAAU;IACV,SAAS;IACT,iEAAiE;IACjE,mEAAmE;IACnE,iEAAiE;IACjE,kEAAkE;IAClE,iEAAiE;IACjE,kEAAkE;IAClE,YAAY;IACZ,WAAW;IACX,WAAW;IACX,UAAU;CACb,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAI,KAAQ;IACvC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAiB,CAAC;IACtE,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;YACpE,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrB,GAAG,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACJ,GAAG,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;YAChC,CAAC;QACL,CAAC;QACD,OAAO,GAAmB,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}
@@ -31,7 +31,7 @@
31
31
  * L1 — Tools kept as first-class entries in `tools/list`.
32
32
  * Forwarded by the CapturingServer to the real McpServer.
33
33
  */
34
- export declare const ESSENTIAL_TOOLS: readonly ["yootheme_builder_pages_list", "yootheme_builder_get_etag", "yootheme_builder_element_list", "yootheme_builder_element_add", "yootheme_builder_element_update_settings", "yootheme_builder_sources_list", "yootheme_builder_element_types_list", "yootheme_builder_inspect_multi_items_binding", "yootheme_builder_element_get", "yootheme_builder_element_delete", "yootheme_builder_element_clone", "yootheme_builder_element_move", "yootheme_builder_page_get_layout", "yootheme_builder_template_summary"];
34
+ export declare const ESSENTIAL_TOOLS: readonly ["yootheme_builder_pages_list", "yootheme_builder_get_etag", "yootheme_builder_element_list", "yootheme_builder_element_add", "yootheme_builder_element_update_settings", "yootheme_builder_sources_list", "yootheme_builder_element_types_list", "yootheme_builder_inspect_multi_items_binding", "yootheme_builder_element_get", "yootheme_builder_element_delete", "yootheme_builder_element_clone", "yootheme_builder_element_move", "yootheme_builder_page_get_layout", "yootheme_builder_template_summary", "yootheme_builder_element_type_get_schema", "yootheme_builder_sites_list", "yootheme_builder_sites_test"];
35
35
  /**
36
36
  * L3 — Tools registered DIRECTLY on the real McpServer, BEFORE the
37
37
  * CapturingServer wraps it. The CapturingServer treats these names as a
@@ -1 +1 @@
1
- {"version":3,"file":"essentials.d.ts","sourceRoot":"","sources":["../../src/gateway/essentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,2fAyBlB,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,mEAGzB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7D,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,gEAAgE;AAChE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD"}
1
+ {"version":3,"file":"essentials.d.ts","sourceRoot":"","sources":["../../src/gateway/essentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,qmBAsClB,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,mEAGzB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7D,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,gEAAgE;AAChE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD"}
@@ -46,8 +46,8 @@ export const ESSENTIAL_TOOLS = [
46
46
  'yootheme_builder_inspect_multi_items_binding',
47
47
  // F-16 hot-path promotions (Maria-Audit v2 re-confirmed) — the 5
48
48
  // most-used read/mutate operations skip the advanced-router
49
- // discovery roundtrip. Cursor cap is ~40; we sit at 13 L1 + 2 L3 +
50
- // 1 gateway = 16, comfortable below the limit.
49
+ // discovery roundtrip. Cursor cap is ~40; we sit at 15 L1 + 2 L3 +
50
+ // 1 gateway = 18, comfortable below the limit.
51
51
  'yootheme_builder_element_get',
52
52
  'yootheme_builder_element_delete',
53
53
  'yootheme_builder_element_clone',
@@ -56,6 +56,19 @@ export const ESSENTIAL_TOOLS = [
56
56
  // T9 (Audit-v3 B.5) — token-efficient template overview. L1 because
57
57
  // it's the recommended first call when orienting in a large template.
58
58
  'yootheme_builder_template_summary',
59
+ // 1.0.1 — element_type_get_schema promoted L2 → L1. Live-testing
60
+ // 1.0.0 in Claude Desktop showed tool_search couldn't surface it
61
+ // through the advanced gateway, yet it is the canonical prop-key
62
+ // discovery tool an agent needs BEFORE every element_add or
63
+ // element_update_settings. Hot-path for any write workflow.
64
+ 'yootheme_builder_element_type_get_schema',
65
+ // W7 (Multi-Site) — sites_list + sites_test must be L1 so an agent
66
+ // that just connected to a fresh MCP server can answer "which sites
67
+ // am I configured against?" without first discovering the gateway.
68
+ // Both are platform-agnostic (sites_list reads the registry only,
69
+ // sites_test probes /health + /etag for ONE site). L1 surface 15 → 17.
70
+ 'yootheme_builder_sites_list',
71
+ 'yootheme_builder_sites_test',
59
72
  ];
60
73
  /**
61
74
  * L3 — Tools registered DIRECTLY on the real McpServer, BEFORE the
@@ -1 +1 @@
1
- {"version":3,"file":"essentials.js","sourceRoot":"","sources":["../../src/gateway/essentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC3B,6BAA6B;IAC7B,2BAA2B;IAC3B,+BAA+B;IAC/B,8BAA8B;IAC9B,0CAA0C;IAC1C,+BAA+B;IAC/B,qCAAqC;IACrC,6DAA6D;IAC7D,kEAAkE;IAClE,6DAA6D;IAC7D,yCAAyC;IACzC,8CAA8C;IAC9C,iEAAiE;IACjE,4DAA4D;IAC5D,mEAAmE;IACnE,+CAA+C;IAC/C,8BAA8B;IAC9B,iCAAiC;IACjC,gCAAgC;IAChC,+BAA+B;IAC/B,kCAAkC;IAClC,oEAAoE;IACpE,sEAAsE;IACtE,mCAAmC;CAC7B,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IAClC,yBAAyB;IACzB,2BAA2B;CACrB,CAAC;AAKX,gEAAgE;AAChE,MAAM,UAAU,WAAW,CAAC,IAAY;IACpC,OAAQ,eAAqC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAAC,IAAY;IACzC,OAAQ,sBAA4C,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC"}
1
+ {"version":3,"file":"essentials.js","sourceRoot":"","sources":["../../src/gateway/essentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC3B,6BAA6B;IAC7B,2BAA2B;IAC3B,+BAA+B;IAC/B,8BAA8B;IAC9B,0CAA0C;IAC1C,+BAA+B;IAC/B,qCAAqC;IACrC,6DAA6D;IAC7D,kEAAkE;IAClE,6DAA6D;IAC7D,yCAAyC;IACzC,8CAA8C;IAC9C,iEAAiE;IACjE,4DAA4D;IAC5D,mEAAmE;IACnE,+CAA+C;IAC/C,8BAA8B;IAC9B,iCAAiC;IACjC,gCAAgC;IAChC,+BAA+B;IAC/B,kCAAkC;IAClC,oEAAoE;IACpE,sEAAsE;IACtE,mCAAmC;IACnC,iEAAiE;IACjE,iEAAiE;IACjE,iEAAiE;IACjE,4DAA4D;IAC5D,4DAA4D;IAC5D,0CAA0C;IAC1C,mEAAmE;IACnE,oEAAoE;IACpE,mEAAmE;IACnE,kEAAkE;IAClE,uEAAuE;IACvE,6BAA6B;IAC7B,6BAA6B;CACvB,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IAClC,yBAAyB;IACzB,2BAA2B;CACrB,CAAC;AAKX,gEAAgE;AAChE,MAAM,UAAU,WAAW,CAAC,IAAY;IACpC,OAAQ,eAAqC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAAC,IAAY;IACzC,OAAQ,sBAA4C,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -13,9 +13,13 @@
13
13
  */
14
14
  export { createServer, SERVER_NAME, SERVER_VERSION } from './server.js';
15
15
  export { RestClient, REST_NAMESPACE_PATH, encodeElementPath } from './client.js';
16
- export { loadConfig, isTestMode, ENV_WP_URL, ENV_BEARER, ENV_TEST_MODE } from './auth.js';
16
+ export { loadConfig, loadRegistry, isTestMode, ENV_SITE_URL, ENV_WP_URL, ENV_BEARER, ENV_SITES_FILE, ENV_TEST_MODE, } from './auth.js';
17
17
  export { ConfigError, RestError, NetworkError } from './errors.js';
18
18
  export { buildAllTools } from './tools/index.js';
19
+ export { ClientPool, NoDefaultSiteError, UnknownSiteError } from './sites/client-pool.js';
20
+ export { SiteRegistry } from './sites/registry.js';
21
+ export { synthesiseFromEnv } from './sites/env-bridge.js';
22
+ export { defaultSecretResolver, PlainSecretResolver } from './sites/secret-resolver.js';
19
23
  export { ESSENTIAL_TOOLS, DIRECT_TOP_LEVEL_TOOLS, isEssential, isDirectTopLevel, } from './gateway/essentials.js';
20
24
  export { CapturingServer, type AdvancedToolEntry, type CapturedToolHandler, type ToolRegistrar, } from './gateway/capturing-server.js';
21
25
  export { registerAdvancedTool } from './gateway/advanced-tool.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACH,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,gBAAgB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,aAAa,GACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EACH,yBAAyB,EACzB,QAAQ,EACR,KAAK,aAAa,GACrB,MAAM,2BAA2B,CAAC;AAEnC,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAsCnC;AAkBD,OAAO,EAAE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EACH,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,cAAc,EACd,aAAa,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACxF,OAAO,EACH,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,gBAAgB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,aAAa,GACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EACH,yBAAyB,EACzB,QAAQ,EACR,KAAK,aAAa,GACrB,MAAM,2BAA2B,CAAC;AAEnC,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAkEnC;AAkBD,OAAO,EAAE,IAAI,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -12,40 +12,76 @@
12
12
  * @license MIT
13
13
  */
14
14
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
15
- import { isTestMode, loadConfig } from './auth.js';
16
- import { RestClient } from './client.js';
15
+ import { isTestMode, loadConfig, loadRegistry } from './auth.js';
17
16
  import { ConfigError } from './errors.js';
17
+ import { ClientPool } from './sites/client-pool.js';
18
+ import { SiteRegistry } from './sites/registry.js';
19
+ import { defaultSecretResolver } from './sites/secret-resolver.js';
18
20
  import { createServer } from './server.js';
19
21
  export { createServer, SERVER_NAME, SERVER_VERSION } from './server.js';
20
22
  export { RestClient, REST_NAMESPACE_PATH, encodeElementPath } from './client.js';
21
- export { loadConfig, isTestMode, ENV_WP_URL, ENV_BEARER, ENV_TEST_MODE } from './auth.js';
23
+ export { loadConfig, loadRegistry, isTestMode, ENV_SITE_URL, ENV_WP_URL, ENV_BEARER, ENV_SITES_FILE, ENV_TEST_MODE, } from './auth.js';
22
24
  export { ConfigError, RestError, NetworkError } from './errors.js';
23
25
  export { buildAllTools } from './tools/index.js';
26
+ // W6 — multi-site primitives exported for dist consumers (scripts,
27
+ // embedded uses). The `ClientPool` is the new wiring contract.
28
+ export { ClientPool, NoDefaultSiteError, UnknownSiteError } from './sites/client-pool.js';
29
+ export { SiteRegistry } from './sites/registry.js';
30
+ export { synthesiseFromEnv } from './sites/env-bridge.js';
31
+ export { defaultSecretResolver, PlainSecretResolver } from './sites/secret-resolver.js';
24
32
  export { ESSENTIAL_TOOLS, DIRECT_TOP_LEVEL_TOOLS, isEssential, isDirectTopLevel, } from './gateway/essentials.js';
25
33
  export { CapturingServer, } from './gateway/capturing-server.js';
26
34
  export { registerAdvancedTool } from './gateway/advanced-tool.js';
27
35
  export { collectAllRegisteredTools, findTool, } from './gateway/test-support.js';
28
36
  async function main() {
29
37
  const testMode = isTestMode();
30
- let config;
38
+ // W10 — multi-site bootstrap is now centralised in
39
+ // `auth.loadRegistry()`. The canonical resolution order is:
40
+ // 1. YTB_MCP_SITES_FILE → loadSitesFile + SiteRegistry
41
+ // 2. env-bridge (YTB_MCP_SITE_URL + YTB_MCP_BEARER_TOKEN)
42
+ // 3. ConfigError("No sites configured.")
43
+ //
44
+ // The single exception lives here: `--test-mode` smoke probes
45
+ // (release.php, CI tool-list dumps) must boot even when neither
46
+ // path is configured. We honor loadRegistry first, then trap the
47
+ // ConfigError in test-mode and synthesise an empty registry so the
48
+ // tool list still prints. Tools will refuse to run, which is
49
+ // expected — `--test-mode` never invokes them.
50
+ let registry;
31
51
  try {
32
- // In test mode, allow the bearer token to be missing — we exit before
33
- // anyone calls a tool.
34
- config = loadConfig({ allowMissingToken: testMode });
52
+ registry = await loadRegistry();
35
53
  }
36
54
  catch (e) {
37
- if (e instanceof ConfigError) {
38
- process.stderr.write(`[yt-builder-mcp] ${e.message}\n`);
55
+ if (testMode && e instanceof ConfigError) {
56
+ // Mirror legacy test-mode behaviour: try loadConfig with
57
+ // the back-compat permissive flag so the print-tools probe
58
+ // still boots even with no sites at all. If loadConfig
59
+ // *also* throws, surface the more specific message.
60
+ try {
61
+ loadConfig({ allowMissingToken: true });
62
+ }
63
+ catch (cfgErr) {
64
+ if (cfgErr instanceof ConfigError) {
65
+ process.stderr.write(`[yt-builder-mcp] ${cfgErr.message}\n`);
66
+ process.exit(1);
67
+ }
68
+ throw cfgErr;
69
+ }
70
+ registry = new SiteRegistry({
71
+ schema_version: 1,
72
+ default_site_id: null,
73
+ sites: [],
74
+ });
75
+ }
76
+ else {
77
+ const msg = e instanceof Error ? e.message : String(e);
78
+ process.stderr.write(`[yt-builder-mcp] ${msg}\n`);
39
79
  process.exit(1);
40
80
  }
41
- throw e;
42
81
  }
43
- const client = new RestClient({
44
- baseUrl: config.baseUrl,
45
- bearerToken: config.bearerToken,
46
- timeoutMs: config.timeoutMs,
47
- });
48
- const { mcp, tools } = createServer({ client });
82
+ const secretResolver = defaultSecretResolver();
83
+ const pool = new ClientPool(registry, secretResolver);
84
+ const { mcp, tools } = createServer({ pool });
49
85
  if (testMode) {
50
86
  // Print a one-line per tool summary to stderr (stdout is reserved
51
87
  // for the JSON-RPC frame in real runs) and exit cleanly.