@wix/mcp 1.0.83 → 1.0.85

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.
@@ -19494,7 +19494,16 @@ ${skillsContent}`
19494
19494
  ] : await Promise.all(
19495
19495
  baseDocs.filter((doc) => doc.url === RECIPES_INDEX_URL).map(fetchDoc)
19496
19496
  );
19497
- const contents = [...baseContents, ...recipesContents];
19497
+ const recipeNotes = !skillsContent?.includes("Dashboard Navigation") ? [] : [
19498
+ await fetchDoc({
19499
+ action: "text",
19500
+ title: "Recipe Notes",
19501
+ content: dedent_default`
19502
+ - **Navigation recipes** (the *Dashboard Navigation* family) build direct manage.wix.com URLs. If your environment provides dedicated navigation tools, use those to perform the actual navigation — opening a recipe-built URL forces a full page refresh. Use the recipe URLs for composing a link to hand the user, or for navigating when no dedicated tool exists.
19503
+ `
19504
+ })
19505
+ ];
19506
+ const contents = [...baseContents, ...recipesContents, ...recipeNotes];
19498
19507
  const dynamicContext = await dynamicContextPromise;
19499
19508
  const parts = [
19500
19509
  ...contents.filter(
@@ -22019,11 +22028,13 @@ function validateExecuteCode(code) {
22019
22028
  }
22020
22029
 
22021
22030
  // src/code-mode/index.ts
22031
+ var defaultCodeModeFetch = (url, init) => fetch(url, init);
22022
22032
  var SEARCH_TOOL_NAME = "SearchWixAPISpec";
22023
22033
  var EXECUTE_TOOL_NAME = "ExecuteWixAPI";
22024
22034
  function addSearchCodeModeTool(server, options) {
22025
22035
  const {
22026
22036
  codeModeBaseUrl,
22037
+ codeModeFetch,
22027
22038
  authStrategy,
22028
22039
  disableTools = [],
22029
22040
  toolDescriptions,
@@ -22038,12 +22049,14 @@ function addSearchCodeModeTool(server, options) {
22038
22049
  codeModeBaseUrl,
22039
22050
  description,
22040
22051
  maxResponseSize,
22041
- authStrategy
22052
+ authStrategy,
22053
+ codeModeFetch
22042
22054
  );
22043
22055
  }
22044
22056
  function addExecuteCodeModeTool(server, options) {
22045
22057
  const {
22046
22058
  codeModeBaseUrl,
22059
+ codeModeFetch,
22047
22060
  authStrategy,
22048
22061
  visitor,
22049
22062
  disableTools = [],
@@ -22055,6 +22068,7 @@ function addExecuteCodeModeTool(server, options) {
22055
22068
  }
22056
22069
  addExecuteTool(server, {
22057
22070
  codeModeBaseUrl,
22071
+ codeModeFetch,
22058
22072
  authStrategy,
22059
22073
  visitor,
22060
22074
  toolDescriptions,
@@ -22069,7 +22083,7 @@ async function resolveLoopbackAuthorization(authStrategy) {
22069
22083
  return void 0;
22070
22084
  }
22071
22085
  }
22072
- function registerSearchTool(server, codeModeBaseUrl, description, maxResponseSize, authStrategy) {
22086
+ function registerSearchTool(server, codeModeBaseUrl, description, maxResponseSize, authStrategy, codeModeFetch = defaultCodeModeFetch) {
22073
22087
  const searchUrl = `${codeModeBaseUrl}/api/code-mode/search`;
22074
22088
  server.tool(
22075
22089
  SEARCH_TOOL_NAME,
@@ -22089,7 +22103,7 @@ function registerSearchTool(server, codeModeBaseUrl, description, maxResponseSiz
22089
22103
  );
22090
22104
  try {
22091
22105
  const authorization = await resolveLoopbackAuthorization(authStrategy);
22092
- const resp = await fetch(searchUrl, {
22106
+ const resp = await codeModeFetch(searchUrl, {
22093
22107
  method: "POST",
22094
22108
  headers: {
22095
22109
  "Content-Type": "application/json",
@@ -22140,8 +22154,8 @@ function registerSearchTool(server, codeModeBaseUrl, description, maxResponseSiz
22140
22154
  }
22141
22155
  );
22142
22156
  }
22143
- async function postExecute(executeUrl, body, authorization) {
22144
- const resp = await fetch(executeUrl, {
22157
+ async function postExecute(executeUrl, body, authorization, codeModeFetch = defaultCodeModeFetch) {
22158
+ const resp = await codeModeFetch(executeUrl, {
22145
22159
  method: "POST",
22146
22160
  headers: {
22147
22161
  "Content-Type": "application/json",
@@ -22183,6 +22197,7 @@ function formatExecuteResult(data, maxResponseSize, reportBi) {
22183
22197
  function addExecuteTool(server, options) {
22184
22198
  const {
22185
22199
  codeModeBaseUrl,
22200
+ codeModeFetch,
22186
22201
  authStrategy,
22187
22202
  visitor,
22188
22203
  toolDescriptions,
@@ -22271,7 +22286,8 @@ function addExecuteTool(server, options) {
22271
22286
  accountId: accountHeaders?.["wix-account-id"],
22272
22287
  siteAuthContext
22273
22288
  },
22274
- visitor ? visitorToken : accountHeaders?.Authorization ?? siteHeaders?.Authorization
22289
+ visitor ? visitorToken : accountHeaders?.Authorization ?? siteHeaders?.Authorization,
22290
+ codeModeFetch
22275
22291
  );
22276
22292
  if (data.authErrorStatus && visitor) {
22277
22293
  return executeErrorResult(
@@ -22533,7 +22549,8 @@ function createWixToolkit(options) {
22533
22549
  toolDescriptions,
22534
22550
  toolHints,
22535
22551
  maxResponseSize,
22536
- codeModeBaseUrl = "https://mcp.wix.com"
22552
+ codeModeBaseUrl = "https://mcp.wix.com",
22553
+ codeModeFetch
22537
22554
  } = api;
22538
22555
  const effectiveToolDescriptions = {
22539
22556
  ...descriptionsWithoutReadme,
@@ -22557,6 +22574,7 @@ function createWixToolkit(options) {
22557
22574
  if (requestedTools.has("SearchWixAPISpec") && !disableTools?.includes("SearchWixAPISpec")) {
22558
22575
  addSearchCodeModeTool(server, {
22559
22576
  codeModeBaseUrl,
22577
+ codeModeFetch,
22560
22578
  authStrategy,
22561
22579
  disableTools,
22562
22580
  toolDescriptions: effectiveToolDescriptions,
@@ -22566,6 +22584,7 @@ function createWixToolkit(options) {
22566
22584
  if (requestedTools.has("ExecuteWixAPI") && !disableTools?.includes("ExecuteWixAPI")) {
22567
22585
  addExecuteCodeModeTool(server, {
22568
22586
  codeModeBaseUrl,
22587
+ codeModeFetch,
22569
22588
  authStrategy,
22570
22589
  disableTools,
22571
22590
  toolDescriptions: effectiveToolDescriptions,
@@ -1,7 +1,14 @@
1
1
  import { WixMcpServer } from '../wix-mcp-server.js';
2
2
  import { type McpAuthenticationStrategy } from '../auth/index.js';
3
+ /**
4
+ * Transport for the code-mode endpoints (`/api/code-mode/search|execute`).
5
+ * Defaults to the global `fetch`; a host that serves those endpoints itself
6
+ * can pass an in-runtime loopback instead.
7
+ */
8
+ export type CodeModeFetch = (url: string, init: RequestInit) => Promise<Response>;
3
9
  export interface CodeModeOptions {
4
10
  codeModeBaseUrl: string;
11
+ codeModeFetch?: CodeModeFetch;
5
12
  authStrategy?: McpAuthenticationStrategy;
6
13
  /**
7
14
  * Visitor mode: pin ExecuteWixAPI to one site and take an agent-supplied
@@ -6,14 +6,17 @@ import { validateExecuteCode } from './validation.js';
6
6
  import { desc } from '../config/param-descriptions.js';
7
7
  import { rethrowIfUnauthorized } from '../auth/index.js';
8
8
  import { WixFetchError } from '../wix-fetch-error.js';
9
+ // Looks `fetch` up per call so a host or test that swaps the global is honored.
10
+ const defaultCodeModeFetch = (url, init) => fetch(url, init);
9
11
  const SEARCH_TOOL_NAME = 'SearchWixAPISpec';
10
12
  export const EXECUTE_TOOL_NAME = 'ExecuteWixAPI';
11
13
  export async function addCodeModeTools(server, options) {
12
- const { codeModeBaseUrl, authStrategy, disableTools = [], toolDescriptions, maxResponseSize } = options;
14
+ const { codeModeBaseUrl, codeModeFetch, authStrategy, disableTools = [], toolDescriptions, maxResponseSize } = options;
13
15
  addSearchCodeModeTool(server, options);
14
16
  if (!disableTools.includes(EXECUTE_TOOL_NAME) && authStrategy) {
15
17
  addExecuteCodeModeTool(server, {
16
18
  codeModeBaseUrl,
19
+ codeModeFetch,
17
20
  authStrategy,
18
21
  disableTools,
19
22
  toolDescriptions,
@@ -29,21 +32,22 @@ export async function addCodeModeTools(server, options) {
29
32
  * lightIndex.
30
33
  */
31
34
  export function addSearchCodeModeTool(server, options) {
32
- const { codeModeBaseUrl, authStrategy, disableTools = [], toolDescriptions, maxResponseSize } = options;
35
+ const { codeModeBaseUrl, codeModeFetch, authStrategy, disableTools = [], toolDescriptions, maxResponseSize } = options;
33
36
  if (disableTools.includes(SEARCH_TOOL_NAME)) {
34
37
  return;
35
38
  }
36
39
  const description = toolDescriptions?.[SEARCH_TOOL_NAME] ??
37
40
  defaultToolDescriptions.SearchWixAPISpec;
38
- registerSearchTool(server, codeModeBaseUrl, description, maxResponseSize, authStrategy);
41
+ registerSearchTool(server, codeModeBaseUrl, description, maxResponseSize, authStrategy, codeModeFetch);
39
42
  }
40
43
  export function addExecuteCodeModeTool(server, options) {
41
- const { codeModeBaseUrl, authStrategy, visitor, disableTools = [], toolDescriptions, maxResponseSize } = options;
44
+ const { codeModeBaseUrl, codeModeFetch, authStrategy, visitor, disableTools = [], toolDescriptions, maxResponseSize } = options;
42
45
  if ((!authStrategy && !visitor) || disableTools.includes(EXECUTE_TOOL_NAME)) {
43
46
  return;
44
47
  }
45
48
  addExecuteTool(server, {
46
49
  codeModeBaseUrl,
50
+ codeModeFetch,
47
51
  authStrategy,
48
52
  visitor,
49
53
  toolDescriptions,
@@ -64,7 +68,7 @@ async function resolveLoopbackAuthorization(authStrategy) {
64
68
  return undefined;
65
69
  }
66
70
  }
67
- function registerSearchTool(server, codeModeBaseUrl, description, maxResponseSize, authStrategy) {
71
+ function registerSearchTool(server, codeModeBaseUrl, description, maxResponseSize, authStrategy, codeModeFetch = defaultCodeModeFetch) {
68
72
  const searchUrl = `${codeModeBaseUrl}/api/code-mode/search`;
69
73
  server.tool(SEARCH_TOOL_NAME, description, {
70
74
  code: z
@@ -77,7 +81,7 @@ function registerSearchTool(server, codeModeBaseUrl, description, maxResponseSiz
77
81
  logger.log(`[SearchWixAPISpec] Executing search (${code.length} chars), reason="${reason}"`);
78
82
  try {
79
83
  const authorization = await resolveLoopbackAuthorization(authStrategy);
80
- const resp = await fetch(searchUrl, {
84
+ const resp = await codeModeFetch(searchUrl, {
81
85
  method: 'POST',
82
86
  headers: {
83
87
  'Content-Type': 'application/json',
@@ -135,8 +139,8 @@ function registerSearchTool(server, codeModeBaseUrl, description, maxResponseSiz
135
139
  * the call looked anonymous to `rateLimiterMiddleware` and shared its IP-keyed
136
140
  * bucket — it comes from the Durable Object, not the client.
137
141
  */
138
- async function postExecute(executeUrl, body, authorization) {
139
- const resp = await fetch(executeUrl, {
142
+ async function postExecute(executeUrl, body, authorization, codeModeFetch = defaultCodeModeFetch) {
143
+ const resp = await codeModeFetch(executeUrl, {
140
144
  method: 'POST',
141
145
  headers: {
142
146
  'Content-Type': 'application/json',
@@ -179,7 +183,7 @@ function formatExecuteResult(data, maxResponseSize, reportBi) {
179
183
  };
180
184
  }
181
185
  function addExecuteTool(server, options) {
182
- const { codeModeBaseUrl, authStrategy, visitor, toolDescriptions, maxResponseSize } = options;
186
+ const { codeModeBaseUrl, codeModeFetch, authStrategy, visitor, toolDescriptions, maxResponseSize } = options;
183
187
  const executeUrl = `${codeModeBaseUrl}/api/code-mode/execute`;
184
188
  const d = desc('ExecuteWixAPI');
185
189
  server.tool(EXECUTE_TOOL_NAME, toolDescriptions?.[EXECUTE_TOOL_NAME] ??
@@ -289,7 +293,7 @@ function addExecuteTool(server, options) {
289
293
  siteAuthContext
290
294
  }, visitor
291
295
  ? visitorToken
292
- : (accountHeaders?.Authorization ?? siteHeaders?.Authorization));
296
+ : (accountHeaders?.Authorization ?? siteHeaders?.Authorization), codeModeFetch);
293
297
  // Visitor mode can't refresh server-side, so steer the agent to regenerate.
294
298
  if (data.authErrorStatus && visitor) {
295
299
  return executeErrorResult(`Visitor token rejected (HTTP ${data.authErrorStatus}). Call GenerateVisitorToken to obtain a fresh token, then retry.`);
@@ -217,7 +217,23 @@ export async function addGetToKnowTools({ server, disableTools = [], toolDescrip
217
217
  : await Promise.all(baseDocs
218
218
  .filter((doc) => doc.url === RECIPES_INDEX_URL)
219
219
  .map(fetchDoc));
220
- const contents = [...baseContents, ...recipesContents];
220
+ // Cross-recipe steering that applies to a family of recipes rather than
221
+ // any single article; rendered right after the index. Gated on the note's
222
+ // target family actually appearing in the rendered index — this also
223
+ // covers a failed/custom index (no recipes → no notes) and tag-filtered
224
+ // visitor indexes, which carry no Dashboard Navigation recipes.
225
+ const recipeNotes = !skillsContent?.includes('Dashboard Navigation')
226
+ ? []
227
+ : [
228
+ await fetchDoc({
229
+ action: 'text',
230
+ title: 'Recipe Notes',
231
+ content: dedent `
232
+ - **Navigation recipes** (the *Dashboard Navigation* family) build direct manage.wix.com URLs. If your environment provides dedicated navigation tools, use those to perform the actual navigation — opening a recipe-built URL forces a full page refresh. Use the recipe URLs for composing a link to hand the user, or for navigating when no dedicated tool exists.
233
+ `
234
+ })
235
+ ];
236
+ const contents = [...baseContents, ...recipesContents, ...recipeNotes];
221
237
  const dynamicContext = await dynamicContextPromise;
222
238
  const parts = [
223
239
  ...contents
@@ -21,7 +21,7 @@ export type { WixToolCallResult, WixToolContentBlock, WixToolAnnotations } from
21
21
  export { createWixToolkit, extractText, type WixTool, type WixToolkit, type WixToolkitOptions, type WixToolkitHooks, type WixToolkitAuth, type WixToolkitDocsConfig, type WixToolkitApiConfig } from './toolkit.js';
22
22
  export { fetchRecipesIndex, fetchArticle, RECIPES_INDEX_URL } from './docs/fetch-article.js';
23
23
  export { generateDocsNavigationTree, fetchMenuContent, MENU_CONTENT_THRESHOLD, normalizeMenuContent, summarizeLargeMenu, parseDirectChildren } from './docs/normalize-menu-content.js';
24
- export { addCodeModeTools, addExecuteCodeModeTool, addSearchCodeModeTool, type CodeModeOptions } from './code-mode/index.js';
24
+ export { addCodeModeTools, addExecuteCodeModeTool, addSearchCodeModeTool, type CodeModeFetch, type CodeModeOptions } from './code-mode/index.js';
25
25
  export { validateExecuteCode, EXECUTE_FUNCTION_EXPRESSION_HINT, type CodeValidationResult } from './code-mode/validation.js';
26
26
  export { addGraphqlTools, resetGraphqlSchemaCache, GRAPHQL_TOOL_NAMES, SEARCH_GRAPHQL_TOOL_NAME, INSPECT_GRAPHQL_TOOL_NAME, EXECUTE_GRAPHQL_TOOL_NAME, WIX_GRAPHQL_ENDPOINT, type GraphqlToolsOptions, type GraphqlToolName } from './graphql/index.js';
27
27
  export { defaultConfig, defaultToolDescriptions, defaultReadmeDocs, widgetSiteCreationConfig, SITE_CREATION_COPY, toWidget, executeCodeModeToolDescriptions, SYSTEM_REMINDER_GUIDELINES, SYSTEM_REMINDER, mergeConfig, type ModeDefaultConfig } from './config/default-config.js';
@@ -11,6 +11,8 @@ const NON_LATIN_LETTER = /(?![\p{Script=Latin}])\p{L}/u;
11
11
  function isSearchableSiteName(siteName) {
12
12
  return (!DEFAULT_SITE_NAME.test(siteName.trim()) && !NON_LATIN_LETTER.test(siteName));
13
13
  }
14
+ // Domain search rejects longer queries.
15
+ const MAX_QUERY_LENGTH = 100;
14
16
  async function fetchSiteDisplayName(siteAuthorization, siteId) {
15
17
  const response = await fetch(`${WIX_APIS_BASE_URL}/site-properties/v4/properties`, {
16
18
  headers: {
@@ -41,7 +43,7 @@ export function addSuggestedDomainTool(server, authStrategy) {
41
43
  query: z
42
44
  .string()
43
45
  .optional()
44
- .describe("Free-text keywords, business idea, or brand concept to base suggestions on. Use the user's own words."),
46
+ .describe("A few keywords, a business idea, or a brand name to base suggestions on, up to 100 characters. Use the user's own words."),
45
47
  siteId: z
46
48
  .string()
47
49
  .optional()
@@ -49,7 +51,7 @@ export function addSuggestedDomainTool(server, authStrategy) {
49
51
  tlds: z
50
52
  .array(z.string())
51
53
  .optional()
52
- .describe('Filter by specific TLDs (e.g. ["com", "net"]). Do not include the dot.'),
54
+ .describe('Optional. Include only when the user asks for specific TLDs. Filter by specific TLDs (e.g. ["com", "net"]). Do not include the dot.'),
53
55
  limit: z
54
56
  .number()
55
57
  .optional()
@@ -128,7 +130,9 @@ export function addSuggestedDomainTool(server, authStrategy) {
128
130
  }
129
131
  }
130
132
  }
131
- const params = new URLSearchParams({ query: resolvedQuery });
133
+ const params = new URLSearchParams({
134
+ query: resolvedQuery.slice(0, MAX_QUERY_LENGTH)
135
+ });
132
136
  if (limit) {
133
137
  params.set('paging.limit', String(limit));
134
138
  }
@@ -137,14 +141,21 @@ export function addSuggestedDomainTool(server, authStrategy) {
137
141
  params.append('tlds', tld);
138
142
  }
139
143
  }
140
- const response = await fetch(`${WIX_APIS_BASE_URL}/domain-search/v2/suggest-domains?${params}`, {
144
+ const suggestDomains = () => fetch(`${WIX_APIS_BASE_URL}/domain-search/v2/suggest-domains?${params}`, {
141
145
  method: 'GET',
142
146
  headers: {
143
147
  Accept: 'application/json'
144
148
  }
145
149
  });
150
+ let response = await suggestDomains();
151
+ let errorText = response.ok ? '' : await response.text();
152
+ // Domain search sells only some TLDs and rejects the whole request for one it doesn't.
153
+ if (errorText.includes('TLD_NOT_SUPPORTED') && params.has('tlds')) {
154
+ params.delete('tlds');
155
+ response = await suggestDomains();
156
+ errorText = response.ok ? '' : await response.text();
157
+ }
146
158
  if (!response.ok) {
147
- const errorText = await response.text();
148
159
  throw new Error(`Domain suggestions API returned ${response.status}: ${errorText}`);
149
160
  }
150
161
  const data = (await response.json());
@@ -163,6 +163,12 @@ export interface ToolHintsConfig {
163
163
  destructiveHint?: boolean;
164
164
  openWorldHint?: boolean;
165
165
  }
166
+ /**
167
+ * Transport for the code-mode endpoints (`/api/code-mode/search|execute`).
168
+ * Defaults to the global `fetch`; a host that serves those endpoints itself
169
+ * can pass an in-runtime loopback instead.
170
+ */
171
+ export type CodeModeFetch = (url: string, init: RequestInit) => Promise<Response>;
166
172
  /**
167
173
  * Safely extract all text content from a WixToolCallResult.
168
174
  * Filters out non-text content blocks (images, audio, resources)
@@ -251,6 +257,8 @@ export interface WixToolkitApiConfig {
251
257
  maxResponseSize?: number;
252
258
  /** Base URL for code-mode tools such as ExecuteWixAPI */
253
259
  codeModeBaseUrl?: string;
260
+ /** Transport for the code-mode endpoints; defaults to the global `fetch`. */
261
+ codeModeFetch?: CodeModeFetch;
254
262
  }
255
263
  /** Options for createWixToolkit. */
256
264
  export interface WixToolkitOptions {
@@ -163,6 +163,12 @@ export interface ToolHintsConfig {
163
163
  destructiveHint?: boolean;
164
164
  openWorldHint?: boolean;
165
165
  }
166
+ /**
167
+ * Transport for the code-mode endpoints (`/api/code-mode/search|execute`).
168
+ * Defaults to the global `fetch`; a host that serves those endpoints itself
169
+ * can pass an in-runtime loopback instead.
170
+ */
171
+ export type CodeModeFetch = (url: string, init: RequestInit) => Promise<Response>;
166
172
  /**
167
173
  * Safely extract all text content from a WixToolCallResult.
168
174
  * Filters out non-text content blocks (images, audio, resources)
@@ -251,6 +257,8 @@ export interface WixToolkitApiConfig {
251
257
  maxResponseSize?: number;
252
258
  /** Base URL for code-mode tools such as ExecuteWixAPI */
253
259
  codeModeBaseUrl?: string;
260
+ /** Transport for the code-mode endpoints; defaults to the global `fetch`. */
261
+ codeModeFetch?: CodeModeFetch;
254
262
  }
255
263
  /** Options for createWixToolkit. */
256
264
  export interface WixToolkitOptions {
@@ -30,6 +30,7 @@ import type { WixToolCallResult, WixToolAnnotations } from './toolkit-types.js';
30
30
  import { z } from 'zod';
31
31
  import { type DocsToolsOptions, type DocsTool } from './docs/docs.js';
32
32
  import { type ToolHintsConfig } from './api-call/index.js';
33
+ import { type CodeModeFetch } from './code-mode/index.js';
33
34
  import type { McpAuthenticationStrategy, McpHeaders } from './auth/index.js';
34
35
  import { extractText, formatToolResultAdditionalFields } from './infra/tool-bi.js';
35
36
  /** A single tool extracted from @wix/mcp, ready to execute. */
@@ -113,6 +114,8 @@ export interface WixToolkitApiConfig {
113
114
  maxResponseSize?: number;
114
115
  /** Base URL for code-mode tools such as ExecuteWixAPI */
115
116
  codeModeBaseUrl?: string;
117
+ /** Transport for the code-mode endpoints; defaults to the global `fetch`. */
118
+ codeModeFetch?: CodeModeFetch;
116
119
  }
117
120
  /** Options for createWixToolkit. */
118
121
  export interface WixToolkitOptions {
@@ -193,7 +193,7 @@ export function createWixToolkit(options) {
193
193
  }
194
194
  // Register API tools
195
195
  if (api) {
196
- const { tools: apiTools, disableTools, enableTools, toolDescriptions, toolHints, maxResponseSize, codeModeBaseUrl = 'https://mcp.wix.com' } = api;
196
+ const { tools: apiTools, disableTools, enableTools, toolDescriptions, toolHints, maxResponseSize, codeModeBaseUrl = 'https://mcp.wix.com', codeModeFetch } = api;
197
197
  // Precedence (low → high): README-free defaults, code-mode variant, consumer overrides.
198
198
  const effectiveToolDescriptions = {
199
199
  ...descriptionsWithoutReadme,
@@ -209,6 +209,7 @@ export function createWixToolkit(options) {
209
209
  !disableTools?.includes('SearchWixAPISpec')) {
210
210
  addSearchCodeModeTool(server, {
211
211
  codeModeBaseUrl,
212
+ codeModeFetch,
212
213
  authStrategy,
213
214
  disableTools,
214
215
  toolDescriptions: effectiveToolDescriptions,
@@ -219,6 +220,7 @@ export function createWixToolkit(options) {
219
220
  !disableTools?.includes('ExecuteWixAPI')) {
220
221
  addExecuteCodeModeTool(server, {
221
222
  codeModeBaseUrl,
223
+ codeModeFetch,
222
224
  authStrategy,
223
225
  disableTools,
224
226
  toolDescriptions: effectiveToolDescriptions,
@@ -3,6 +3,8 @@ import { WixMcpServer } from '../wix-mcp-server.js';
3
3
  export interface WixelSessionToolOptions {
4
4
  conductorOverride?: string;
5
5
  supportsWidgets?: () => boolean;
6
+ /** Shared by the session tools of one server; created by addWixelSessionTools. */
7
+ liveCards?: LiveCardRegistry;
6
8
  }
7
9
  type WixelAssetEntity = {
8
10
  id?: string;
@@ -30,11 +32,52 @@ export type WixelDeck = {
30
32
  };
31
33
  export declare function collectDecks(projectAssets: WixelAssetEntity[], deckIds: Set<string>): Map<string, WixelDeck>;
32
34
  export declare function extractAssetIds(text: string): string[];
35
+ /**
36
+ * Live result cards, per Wixel session handle: the turns a card was rendered
37
+ * for (and when), the asset ids / media URLs those cards display, and the
38
+ * last turn send_wixel_message opened. The model does not reliably obey "do
39
+ * not poll" once a live card is up, so the tools enforce it: list_wixel_events
40
+ * refuses while a card is active, get_wixel_asset_result refuses to render
41
+ * the same result a second time, and get_wixel_pending_question stays quiet
42
+ * for a question the card already shows.
43
+ *
44
+ * One registry per server instance (like list_wixel_events' cursor memory),
45
+ * so sessions never see each other's records. In-memory like that memory
46
+ * too: a Durable Object wake-up starts empty, and the intercepts simply
47
+ * don't apply until the next send.
48
+ */
49
+ type LiveCardRecord = {
50
+ /** Turn id → when its live card was rendered. */
51
+ turns: Map<string, number>;
52
+ /** Turns whose card reached done/failed — the agent may poll again. */
53
+ finishedTurns: Set<string>;
54
+ shownAssets: Set<string>;
55
+ lastSentTurn: string | null;
56
+ };
57
+ export type LiveCardRegistry = ReturnType<typeof createLiveCardRegistry>;
58
+ export declare function createLiveCardRegistry(): {
59
+ get: (handle: string) => LiveCardRecord | undefined;
60
+ forHandle: (handle: string) => LiveCardRecord;
61
+ isActive: (handle: string, params: {
62
+ authHeaders: Record<string, string>;
63
+ conductorOverride?: string;
64
+ metaSiteId: string;
65
+ }) => Promise<boolean>;
66
+ };
33
67
  export declare function addGetWixelPendingQuestionTool(server: WixMcpServer, authStrategy: McpAuthenticationStrategy, options?: WixelSessionToolOptions): void;
34
68
  export declare function addStartWixelSessionTool(server: WixMcpServer, authStrategy: McpAuthenticationStrategy, options?: WixelSessionToolOptions): void;
35
69
  export declare function addSendWixelMessageTool(server: WixMcpServer, authStrategy: McpAuthenticationStrategy, options?: WixelSessionToolOptions): void;
36
70
  export declare function addListWixelEventsTool(server: WixMcpServer, authStrategy: McpAuthenticationStrategy, options?: WixelSessionToolOptions): void;
37
71
  export declare function addGetWixelStylePresetsTool(server: WixMcpServer, authStrategy: McpAuthenticationStrategy, options?: WixelSessionToolOptions): void;
72
+ export type WixelTurnStatus = 'generating' | 'question' | 'done' | 'failed';
73
+ export declare function addGetWixelTurnResultTool(server: WixMcpServer, authStrategy: McpAuthenticationStrategy, options?: WixelSessionToolOptions): void;
74
+ export type WixelResultAssetEntry = {
75
+ id: string;
76
+ kind: 'image' | 'video' | 'slides' | 'document';
77
+ name: string | null;
78
+ url: string;
79
+ slideUrls?: string[];
80
+ };
38
81
  export declare function addGetWixelAssetResultTool(server: WixMcpServer, authStrategy: McpAuthenticationStrategy, options?: WixelSessionToolOptions): void;
39
82
  export declare function addWixelSessionTools(server: WixMcpServer, authStrategy: McpAuthenticationStrategy, options?: WixelSessionToolOptions): void;
40
83
  export {};