@wix/mcp 1.0.81 → 1.0.82

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.
@@ -71652,6 +71652,8 @@ var SITE_CREATION_COPY = {
71652
71652
  var SITE_GUIDANCE = dedent_default`
71653
71653
  A new-site request has two things to settle: what the site is for, and how to build it. The how is AI generation vs. starting from a template, so naming templates, a template id or Wix Studio (Wix Studio is also the template side) already settles it.
71654
71654
 
71655
+ One case skips all of this: the user ALREADY HAS the finished site as files — hand-written HTML/CSS/JS, a zip, or the export of an AI builder. There is nothing to build, so don't offer AI or templates and don't call any site-creation tool. Send them to https://www.wix.com/headless/drop?utm_campaign=mcp — they drag the files in and get a live Wix-hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
71656
+
71655
71657
  Settle what the site is for first: its purpose, topic, business type, audience, or main visitor action. Naming a method is not a description of the site, and neither is the business or industry on its own.
71656
71658
  If you can't tell yet, ask the preferred question below and nothing else — one question, no creation-method question in the same reply, and no internal tool names.
71657
71659
  Once the purpose is clear, unless the user already named a method, ${SITE_CREATION_COPY.unstatedMethod.nonWidget}. A method they named is settled — never re-open it. Never default to AI or to templates, and never ask the user to choose between Harmony and Wix Studio; infer that from their words.
@@ -71984,7 +71986,8 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
71984
71986
  After calling, you MUST speak the message provided in the tool result to the user as your reply — do not stay silent and do not replace it with a one-line pointer to the widget. Write out ALL of it, word for word: its opening line (the "Ready to set up your … site?" question INCLUDING "Choose your path in the widget above:"), BOTH of its option bullets, and its "Next up:" line, each on its own line and in that order. Do not summarize, shorten, drop any line, invent your own opener, rename the options, or add an intro or outro.
71985
71987
  `,
71986
71988
  "import-claude-design-from-url": dedent_default`
71987
- Import a design into Wix from a publicly fetchable URL. The file is a self-contained HTML bundle with all images, fonts, and styles inlined. Creates a live Wix-hosted site and returns its URL.
71989
+ Import a design created in Claude's design tool into Wix. Takes the signed claudeusercontent.com URL Claude Design produces for its self-contained HTML bundle (all images, fonts, and styles inlined); any other host is rejected. Creates a live Wix-hosted site and returns its URL.
71990
+ NOT for site files the user provides themselves (their own HTML/CSS/JS, a zip, another builder's export) — for those, don't call this tool: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp, where they upload the files and get a live hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
71988
71991
  `,
71989
71992
  RunWixCliCommand: dedent_default`
71990
71993
  Executes Wix CLI commands for Wix app development and management.
@@ -72385,6 +72388,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
72385
72388
  CreateWixBusinessGuide: dedent_default`
72386
72389
  Provides comprehensive documentation for creating a new Wix business (site, app, etc.).
72387
72390
  Call this ONLY when the user explicitly asks for a headless site, a Wix Classic Editor site, or manual/advanced account/API-based site creation — these don't need the site's purpose first. For normal site-creation ${SITE_CREATION_COPY.normalCreationRoute.nonWidget}; for a specific template id, call \`CreateSiteFromTemplate\`.
72391
+ Exception, even when the user says "headless": if they ALREADY HAVE the finished site as files (their own HTML/CSS/JS, a zip, an AI-builder export) and want those files hosted, don't call this tool — send them to https://www.wix.com/headless/drop?utm_campaign=mcp to upload the files and get a live hosted site (give that URL exactly, keeping the utm_campaign=mcp parameter). This guide's CLI flow is for BUILDING a headless frontend, not for hosting ready-made files.
72388
72392
 
72389
72393
  ## What This Tool Contains
72390
72394
 
@@ -72813,7 +72817,16 @@ var known_apps_default = {
72813
72817
  "1480c568-5cbd-9392-5604-1148f5faffa0": "Promote SEO",
72814
72818
  "ff5d6eb1-65e4-4f9a-8b14-64d34c12cc2e": "Wix Rentals"
72815
72819
  };
72816
- var DYNAMIC_CONTEXT_URL = "https://dev.wix.com/_api/dynamic-context/v1/dynamic-context";
72820
+ var DYNAMIC_CONTEXT_PATH = "/_api/dynamic-context/v1/dynamic-context";
72821
+ var DYNAMIC_CONTEXT_URL = `https://dev.wix.com${DYNAMIC_CONTEXT_PATH}`;
72822
+ var isWixHost = (hostname3) => hostname3 === "wix.com" || hostname3.endsWith(".wix.com");
72823
+ var dynamicContextUrl = () => {
72824
+ if (typeof window === "undefined") {
72825
+ return DYNAMIC_CONTEXT_URL;
72826
+ }
72827
+ const hostname3 = window.location?.hostname;
72828
+ return typeof hostname3 === "string" && isWixHost(hostname3) ? DYNAMIC_CONTEXT_PATH : DYNAMIC_CONTEXT_URL;
72829
+ };
72817
72830
  var COUNT_SITES_URL = "https://www.wixapis.com/site-list/v2/sites/count";
72818
72831
  var MAX_SITES_FOR_DYNAMIC_CONTEXT = 10;
72819
72832
  var DYNAMIC_CONTEXT_PETRI_OVERRIDE = "shouldReturnDynamicContextInMCP#B";
@@ -72865,7 +72878,7 @@ async function getDynamicContext(auth, httpClient, filter, options) {
72865
72878
  if (filter?.siteId) body.site_id = filter.siteId;
72866
72879
  else if (filter?.siteName) body.site_name = filter.siteName;
72867
72880
  const dynamicContextPromise = httpClient.request({
72868
- url: DYNAMIC_CONTEXT_URL,
72881
+ url: dynamicContextUrl(),
72869
72882
  method: "POST",
72870
72883
  headers: {
72871
72884
  ...accountHeaders,
@@ -85356,6 +85369,11 @@ var WixMcpServer = class extends McpServer {
85356
85369
  isMcpAppsInMcpEnabled() {
85357
85370
  return this.mcpAppsInMcpEnabled;
85358
85371
  }
85372
+ /** Microsoft 365 Copilot ("sydney" at runtime) or Copilot Cowork ("copilot"). */
85373
+ isMicrosoftCopilotClient() {
85374
+ const clientName = this.getClientName?.()?.toLowerCase() ?? "";
85375
+ return clientName.includes("sydney") || clientName.includes("copilot");
85376
+ }
85359
85377
  shouldRenderMcpApps() {
85360
85378
  const clientName = this.getClientName?.()?.toLowerCase();
85361
85379
  const isOpenAi = clientName?.includes("openai") ?? false;
@@ -36094,6 +36094,11 @@ var WixMcpServer = class extends McpServer {
36094
36094
  isMcpAppsInMcpEnabled() {
36095
36095
  return this.mcpAppsInMcpEnabled;
36096
36096
  }
36097
+ /** Microsoft 365 Copilot ("sydney" at runtime) or Copilot Cowork ("copilot"). */
36098
+ isMicrosoftCopilotClient() {
36099
+ const clientName = this.getClientName?.()?.toLowerCase() ?? "";
36100
+ return clientName.includes("sydney") || clientName.includes("copilot");
36101
+ }
36097
36102
  shouldRenderMcpApps() {
36098
36103
  const clientName = this.getClientName?.()?.toLowerCase();
36099
36104
  const isOpenAi = clientName?.includes("openai") ?? false;
@@ -37221,6 +37226,8 @@ var SITE_CREATION_COPY = {
37221
37226
  var SITE_GUIDANCE = dedent_default`
37222
37227
  A new-site request has two things to settle: what the site is for, and how to build it. The how is AI generation vs. starting from a template, so naming templates, a template id or Wix Studio (Wix Studio is also the template side) already settles it.
37223
37228
 
37229
+ One case skips all of this: the user ALREADY HAS the finished site as files — hand-written HTML/CSS/JS, a zip, or the export of an AI builder. There is nothing to build, so don't offer AI or templates and don't call any site-creation tool. Send them to https://www.wix.com/headless/drop?utm_campaign=mcp — they drag the files in and get a live Wix-hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
37230
+
37224
37231
  Settle what the site is for first: its purpose, topic, business type, audience, or main visitor action. Naming a method is not a description of the site, and neither is the business or industry on its own.
37225
37232
  If you can't tell yet, ask the preferred question below and nothing else — one question, no creation-method question in the same reply, and no internal tool names.
37226
37233
  Once the purpose is clear, unless the user already named a method, ${SITE_CREATION_COPY.unstatedMethod.nonWidget}. A method they named is settled — never re-open it. Never default to AI or to templates, and never ask the user to choose between Harmony and Wix Studio; infer that from their words.
@@ -37553,7 +37560,8 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
37553
37560
  After calling, you MUST speak the message provided in the tool result to the user as your reply — do not stay silent and do not replace it with a one-line pointer to the widget. Write out ALL of it, word for word: its opening line (the "Ready to set up your … site?" question INCLUDING "Choose your path in the widget above:"), BOTH of its option bullets, and its "Next up:" line, each on its own line and in that order. Do not summarize, shorten, drop any line, invent your own opener, rename the options, or add an intro or outro.
37554
37561
  `,
37555
37562
  "import-claude-design-from-url": dedent_default`
37556
- Import a design into Wix from a publicly fetchable URL. The file is a self-contained HTML bundle with all images, fonts, and styles inlined. Creates a live Wix-hosted site and returns its URL.
37563
+ Import a design created in Claude's design tool into Wix. Takes the signed claudeusercontent.com URL Claude Design produces for its self-contained HTML bundle (all images, fonts, and styles inlined); any other host is rejected. Creates a live Wix-hosted site and returns its URL.
37564
+ NOT for site files the user provides themselves (their own HTML/CSS/JS, a zip, another builder's export) — for those, don't call this tool: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp, where they upload the files and get a live hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
37557
37565
  `,
37558
37566
  RunWixCliCommand: dedent_default`
37559
37567
  Executes Wix CLI commands for Wix app development and management.
@@ -37954,6 +37962,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
37954
37962
  CreateWixBusinessGuide: dedent_default`
37955
37963
  Provides comprehensive documentation for creating a new Wix business (site, app, etc.).
37956
37964
  Call this ONLY when the user explicitly asks for a headless site, a Wix Classic Editor site, or manual/advanced account/API-based site creation — these don't need the site's purpose first. For normal site-creation ${SITE_CREATION_COPY.normalCreationRoute.nonWidget}; for a specific template id, call \`CreateSiteFromTemplate\`.
37965
+ Exception, even when the user says "headless": if they ALREADY HAVE the finished site as files (their own HTML/CSS/JS, a zip, an AI-builder export) and want those files hosted, don't call this tool — send them to https://www.wix.com/headless/drop?utm_campaign=mcp to upload the files and get a live hosted site (give that URL exactly, keeping the utm_campaign=mcp parameter). This guide's CLI flow is for BUILDING a headless frontend, not for hosting ready-made files.
37957
37966
 
37958
37967
  ## What This Tool Contains
37959
37968
 
@@ -38419,7 +38428,16 @@ var known_apps_default = {
38419
38428
  "1480c568-5cbd-9392-5604-1148f5faffa0": "Promote SEO",
38420
38429
  "ff5d6eb1-65e4-4f9a-8b14-64d34c12cc2e": "Wix Rentals"
38421
38430
  };
38422
- var DYNAMIC_CONTEXT_URL = "https://dev.wix.com/_api/dynamic-context/v1/dynamic-context";
38431
+ var DYNAMIC_CONTEXT_PATH = "/_api/dynamic-context/v1/dynamic-context";
38432
+ var DYNAMIC_CONTEXT_URL = `https://dev.wix.com${DYNAMIC_CONTEXT_PATH}`;
38433
+ var isWixHost = (hostname2) => hostname2 === "wix.com" || hostname2.endsWith(".wix.com");
38434
+ var dynamicContextUrl = () => {
38435
+ if (typeof window === "undefined") {
38436
+ return DYNAMIC_CONTEXT_URL;
38437
+ }
38438
+ const hostname2 = window.location?.hostname;
38439
+ return typeof hostname2 === "string" && isWixHost(hostname2) ? DYNAMIC_CONTEXT_PATH : DYNAMIC_CONTEXT_URL;
38440
+ };
38423
38441
  var COUNT_SITES_URL = "https://www.wixapis.com/site-list/v2/sites/count";
38424
38442
  var MAX_SITES_FOR_DYNAMIC_CONTEXT = 10;
38425
38443
  var DYNAMIC_CONTEXT_PETRI_OVERRIDE = "shouldReturnDynamicContextInMCP#B";
@@ -38471,7 +38489,7 @@ async function getDynamicContext(auth, httpClient6, filter, options) {
38471
38489
  if (filter?.siteId) body.site_id = filter.siteId;
38472
38490
  else if (filter?.siteName) body.site_name = filter.siteName;
38473
38491
  const dynamicContextPromise = httpClient6.request({
38474
- url: DYNAMIC_CONTEXT_URL,
38492
+ url: dynamicContextUrl(),
38475
38493
  method: "POST",
38476
38494
  headers: {
38477
38495
  ...accountHeaders,
@@ -40932,9 +40950,18 @@ var SITE_CREATION_CUSTOM_ACTIONS_GUIDANCE = `2\u20133 specific, high-value setup
40932
40950
  * Events / Weddings / Real Estate: "add event schedules, display listings, and manage RSVP forms"
40933
40951
  * General / Unspecified: "${SITE_CREATION_DEFAULT_ACTIONS}"
40934
40952
  If none of these patterns fit the site, infer 2\u20133 actions that suit what that kind of business would manage on its site.`;
40935
- function buildSiteCreationSelectorMessage(siteType, customActions) {
40953
+ function buildSiteCreationSelectorMessage(siteType, customActions, { plain = false } = {}) {
40936
40954
  const type = (siteType ?? "").trim() || "new";
40937
40955
  const actions = (customActions ?? "").trim() || SITE_CREATION_DEFAULT_ACTIONS;
40956
+ const body = `Ready to set up your ${type} site? Choose your path in the widget above:
40957
+
40958
+ * **Build with AI** for a custom, tailor-made layout
40959
+ * **Pick a template** to start with a pre-designed layout
40960
+
40961
+ **Next up:** Once your site is created, you can customize it in Wix or ask me to ${actions}\u2014right here in the chat!`;
40962
+ if (plain) {
40963
+ return body;
40964
+ }
40938
40965
  return `You are the assistant replying to the user \u2014 say this message out loud in chat (do NOT stay silent, and do NOT just point at the widget). Your reply is only complete if it includes ALL of the following, word for word, each on its own line and in this order:
40939
40966
  1. "Ready to set up your ${type} site? Choose your path in the widget above:" \u2014 keep the "Choose your path in the widget above:" part.
40940
40967
  2. "* **Build with AI** for a custom, tailor-made layout"
@@ -40943,12 +40970,7 @@ function buildSiteCreationSelectorMessage(siteType, customActions) {
40943
40970
 
40944
40971
  Copy those four lines as written; do not summarize, shorten, reorder, or reword any of them. Here is the full message to send:
40945
40972
 
40946
- Ready to set up your ${type} site? Choose your path in the widget above:
40947
-
40948
- * **Build with AI** for a custom, tailor-made layout
40949
- * **Pick a template** to start with a pre-designed layout
40950
-
40951
- **Next up:** Once your site is created, you can customize it in Wix or ask me to ${actions}\u2014right here in the chat!`;
40973
+ ${body}`;
40952
40974
  }
40953
40975
  var OPENAI_WIDGET_MIME_TYPE = "text/html+skybridge";
40954
40976
  var SITE_WIDGET_MCP_CSP = {
@@ -47909,7 +47931,7 @@ function addCreateSiteWidgetTool(server, authStrategy, options) {
47909
47931
  `The prompt to build the site. If not provided, the user will be asked to provide a prompt.`
47910
47932
  ),
47911
47933
  suggestedSiteName: external_exports.string().optional().describe(
47912
- "Suggested site name to use for the site based on the site prompt."
47934
+ "You must provide this on every call, including updates to an existing job, in English. A short name for the site: the business name the user gave, or one you derive from the site prompt."
47913
47935
  )
47914
47936
  },
47915
47937
  _meta: toolDefinitionMeta,
@@ -48066,6 +48088,10 @@ async function buildHarmonySite({
48066
48088
 
48067
48089
  // src/site-widget-tools/suggested-domain-tool/index.ts
48068
48090
  var WIX_APIS_BASE_URL3 = "https://www.wixapis.com";
48091
+ var DEFAULT_SITE_NAME = /^my site(\s+\d+)?$/i;
48092
+ function isDefaultSiteName(siteName) {
48093
+ return DEFAULT_SITE_NAME.test(siteName.trim());
48094
+ }
48069
48095
  async function fetchSiteDisplayName(siteAuthorization, siteId) {
48070
48096
  const response = await fetch(
48071
48097
  `${WIX_APIS_BASE_URL3}/site-properties/v4/properties`,
@@ -48090,7 +48116,15 @@ function addSuggestedDomainTool(server, authStrategy) {
48090
48116
  GET_SUGGESTED_DOMAINS_TOOL_NAME,
48091
48117
  {
48092
48118
  title: "Get Suggested Domains",
48093
- description: 'Suggest available domain names. Provide either a free-text query (e.g. "pancakes business", "modern yoga studio") OR a siteId to auto-suggest based on the site name. At least one of query or siteId is required.',
48119
+ description: dedent_default`
48120
+ Suggests available domain names for a business, brand, or Wix site.
48121
+
48122
+ Call this when the user asks for domain name ideas, wants to know which domains are available, or wants a domain for a new or existing site.
48123
+
48124
+ Provide either a free-text \`query\` (the user's own words, e.g. "pancakes business", "modern yoga studio") OR a \`siteId\` to base the suggestions on that site's name. At least one of them is required.
48125
+
48126
+ Present the returned domains to the user as a short list. This tool only suggests domains — it does not purchase or connect them.
48127
+ `,
48094
48128
  inputSchema: {
48095
48129
  query: zod_default.string().optional().describe(
48096
48130
  "Free-text keywords, business idea, or brand concept to base suggestions on. Use the user's own words."
@@ -48110,10 +48144,11 @@ function addSuggestedDomainTool(server, authStrategy) {
48110
48144
  },
48111
48145
  _meta: {
48112
48146
  securitySchemes: [{ type: "oauth2", scopes: ["offline_access"] }],
48113
- ui: { visibility: ["app"] },
48147
+ // Model-visible so hosts (e.g. Microsoft 365 Copilot) can call it directly and show it
48148
+ // in their debug info; 'app' keeps it callable from the site-builder widget.
48149
+ ui: { visibility: ["app", "model"] },
48114
48150
  "openai/toolInvocation/invoking": "Fetching suggested domains",
48115
- "openai/toolInvocation/invoked": "Suggested domains retrieved",
48116
- "openai/visibility": "private"
48151
+ "openai/toolInvocation/invoked": "Suggested domains retrieved"
48117
48152
  }
48118
48153
  },
48119
48154
  async (args, { panorama }) => {
@@ -48161,7 +48196,9 @@ function addSuggestedDomainTool(server, authStrategy) {
48161
48196
  structuredContent: { domains: [] }
48162
48197
  };
48163
48198
  }
48164
- resolvedQuery = siteName;
48199
+ if (!isDefaultSiteName(siteName) || !resolvedQuery) {
48200
+ resolvedQuery = siteName;
48201
+ }
48165
48202
  } catch (error2) {
48166
48203
  panorama.logger().error(
48167
48204
  `[getSuggestedDomains] Error fetching site name for siteId: ${siteId}`,
@@ -48619,7 +48656,8 @@ function addWixSiteCreationTool(server, _authStrategy, options) {
48619
48656
  };
48620
48657
  const message = buildSiteCreationSelectorMessage(
48621
48658
  args.query,
48622
- args.customActions
48659
+ args.customActions,
48660
+ { plain: server.isMicrosoftCopilotClient() }
48623
48661
  );
48624
48662
  return withJsonContent({
48625
48663
  content: [
@@ -51403,10 +51441,14 @@ function addImportClaudeDesignTool(server, authStrategy, options) {
51403
51441
  try {
51404
51442
  designUrl = new URL(args.url);
51405
51443
  } catch {
51406
- return errorResult("Invalid design URL.");
51444
+ return errorResult(
51445
+ "Invalid design URL \u2014 this tool only accepts the claudeusercontent.com URL produced by Claude Design. For site files the user provided themselves, do not retry: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp to upload them and get a live hosted site."
51446
+ );
51407
51447
  }
51408
51448
  if (designUrl.protocol !== "https:" || !designUrl.hostname.endsWith(CLAUDE_USER_CONTENT_HOST_SUFFIX)) {
51409
- return errorResult("Invalid design URL.");
51449
+ return errorResult(
51450
+ "Invalid design URL \u2014 this tool only accepts the claudeusercontent.com URL produced by Claude Design. For site files the user provided themselves, do not retry: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp to upload them and get a live hosted site."
51451
+ );
51410
51452
  }
51411
51453
  const accountHeaders = await authStrategy.getAccountAuthHeaders();
51412
51454
  const wixstroOptions = { baseUrl: wixstroBaseUrl, accountHeaders };
@@ -17750,6 +17750,8 @@ var SITE_CREATION_COPY = {
17750
17750
  var SITE_GUIDANCE = dedent_default`
17751
17751
  A new-site request has two things to settle: what the site is for, and how to build it. The how is AI generation vs. starting from a template, so naming templates, a template id or Wix Studio (Wix Studio is also the template side) already settles it.
17752
17752
 
17753
+ One case skips all of this: the user ALREADY HAS the finished site as files — hand-written HTML/CSS/JS, a zip, or the export of an AI builder. There is nothing to build, so don't offer AI or templates and don't call any site-creation tool. Send them to https://www.wix.com/headless/drop?utm_campaign=mcp — they drag the files in and get a live Wix-hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
17754
+
17753
17755
  Settle what the site is for first: its purpose, topic, business type, audience, or main visitor action. Naming a method is not a description of the site, and neither is the business or industry on its own.
17754
17756
  If you can't tell yet, ask the preferred question below and nothing else — one question, no creation-method question in the same reply, and no internal tool names.
17755
17757
  Once the purpose is clear, unless the user already named a method, ${SITE_CREATION_COPY.unstatedMethod.nonWidget}. A method they named is settled — never re-open it. Never default to AI or to templates, and never ask the user to choose between Harmony and Wix Studio; infer that from their words.
@@ -18082,7 +18084,8 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
18082
18084
  After calling, you MUST speak the message provided in the tool result to the user as your reply — do not stay silent and do not replace it with a one-line pointer to the widget. Write out ALL of it, word for word: its opening line (the "Ready to set up your … site?" question INCLUDING "Choose your path in the widget above:"), BOTH of its option bullets, and its "Next up:" line, each on its own line and in that order. Do not summarize, shorten, drop any line, invent your own opener, rename the options, or add an intro or outro.
18083
18085
  `,
18084
18086
  "import-claude-design-from-url": dedent_default`
18085
- Import a design into Wix from a publicly fetchable URL. The file is a self-contained HTML bundle with all images, fonts, and styles inlined. Creates a live Wix-hosted site and returns its URL.
18087
+ Import a design created in Claude's design tool into Wix. Takes the signed claudeusercontent.com URL Claude Design produces for its self-contained HTML bundle (all images, fonts, and styles inlined); any other host is rejected. Creates a live Wix-hosted site and returns its URL.
18088
+ NOT for site files the user provides themselves (their own HTML/CSS/JS, a zip, another builder's export) — for those, don't call this tool: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp, where they upload the files and get a live hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
18086
18089
  `,
18087
18090
  RunWixCliCommand: dedent_default`
18088
18091
  Executes Wix CLI commands for Wix app development and management.
@@ -18483,6 +18486,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
18483
18486
  CreateWixBusinessGuide: dedent_default`
18484
18487
  Provides comprehensive documentation for creating a new Wix business (site, app, etc.).
18485
18488
  Call this ONLY when the user explicitly asks for a headless site, a Wix Classic Editor site, or manual/advanced account/API-based site creation — these don't need the site's purpose first. For normal site-creation ${SITE_CREATION_COPY.normalCreationRoute.nonWidget}; for a specific template id, call \`CreateSiteFromTemplate\`.
18489
+ Exception, even when the user says "headless": if they ALREADY HAVE the finished site as files (their own HTML/CSS/JS, a zip, an AI-builder export) and want those files hosted, don't call this tool — send them to https://www.wix.com/headless/drop?utm_campaign=mcp to upload the files and get a live hosted site (give that URL exactly, keeping the utm_campaign=mcp parameter). This guide's CLI flow is for BUILDING a headless frontend, not for hosting ready-made files.
18486
18490
 
18487
18491
  ## What This Tool Contains
18488
18492
 
@@ -18948,7 +18952,16 @@ var known_apps_default = {
18948
18952
  "1480c568-5cbd-9392-5604-1148f5faffa0": "Promote SEO",
18949
18953
  "ff5d6eb1-65e4-4f9a-8b14-64d34c12cc2e": "Wix Rentals"
18950
18954
  };
18951
- var DYNAMIC_CONTEXT_URL = "https://dev.wix.com/_api/dynamic-context/v1/dynamic-context";
18955
+ var DYNAMIC_CONTEXT_PATH = "/_api/dynamic-context/v1/dynamic-context";
18956
+ var DYNAMIC_CONTEXT_URL = `https://dev.wix.com${DYNAMIC_CONTEXT_PATH}`;
18957
+ var isWixHost = (hostname) => hostname === "wix.com" || hostname.endsWith(".wix.com");
18958
+ var dynamicContextUrl = () => {
18959
+ if (typeof window === "undefined") {
18960
+ return DYNAMIC_CONTEXT_URL;
18961
+ }
18962
+ const hostname = window.location?.hostname;
18963
+ return typeof hostname === "string" && isWixHost(hostname) ? DYNAMIC_CONTEXT_PATH : DYNAMIC_CONTEXT_URL;
18964
+ };
18952
18965
  var COUNT_SITES_URL = "https://www.wixapis.com/site-list/v2/sites/count";
18953
18966
  var MAX_SITES_FOR_DYNAMIC_CONTEXT = 10;
18954
18967
  var DYNAMIC_CONTEXT_PETRI_OVERRIDE = "shouldReturnDynamicContextInMCP#B";
@@ -19000,7 +19013,7 @@ async function getDynamicContext(auth, httpClient, filter, options) {
19000
19013
  if (filter?.siteId) body.site_id = filter.siteId;
19001
19014
  else if (filter?.siteName) body.site_name = filter.siteName;
19002
19015
  const dynamicContextPromise = httpClient.request({
19003
- url: DYNAMIC_CONTEXT_URL,
19016
+ url: dynamicContextUrl(),
19004
19017
  method: "POST",
19005
19018
  headers: {
19006
19019
  ...accountHeaders,
@@ -80,6 +80,8 @@ export const SITE_CREATION_COPY = {
80
80
  const SITE_GUIDANCE = dedent `
81
81
  A new-site request has two things to settle: what the site is for, and how to build it. The how is AI generation vs. starting from a template, so naming templates, a template id or Wix Studio (Wix Studio is also the template side) already settles it.
82
82
 
83
+ One case skips all of this: the user ALREADY HAS the finished site as files — hand-written HTML/CSS/JS, a zip, or the export of an AI builder. There is nothing to build, so don't offer AI or templates and don't call any site-creation tool. Send them to https://www.wix.com/headless/drop?utm_campaign=mcp — they drag the files in and get a live Wix-hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
84
+
83
85
  Settle what the site is for first: its purpose, topic, business type, audience, or main visitor action. Naming a method is not a description of the site, and neither is the business or industry on its own.
84
86
  If you can't tell yet, ask the preferred question below and nothing else — one question, no creation-method question in the same reply, and no internal tool names.
85
87
  Once the purpose is clear, unless the user already named a method, ${SITE_CREATION_COPY.unstatedMethod.nonWidget}. A method they named is settled — never re-open it. Never default to AI or to templates, and never ask the user to choose between Harmony and Wix Studio; infer that from their words.
@@ -412,7 +414,8 @@ export function buildToolDescriptions(includeReadme, includeImageUploadGuidance
412
414
  After calling, you MUST speak the message provided in the tool result to the user as your reply — do not stay silent and do not replace it with a one-line pointer to the widget. Write out ALL of it, word for word: its opening line (the "Ready to set up your … site?" question INCLUDING "Choose your path in the widget above:"), BOTH of its option bullets, and its "Next up:" line, each on its own line and in that order. Do not summarize, shorten, drop any line, invent your own opener, rename the options, or add an intro or outro.
413
415
  `,
414
416
  'import-claude-design-from-url': dedent `
415
- Import a design into Wix from a publicly fetchable URL. The file is a self-contained HTML bundle with all images, fonts, and styles inlined. Creates a live Wix-hosted site and returns its URL.
417
+ Import a design created in Claude's design tool into Wix. Takes the signed claudeusercontent.com URL Claude Design produces for its self-contained HTML bundle (all images, fonts, and styles inlined); any other host is rejected. Creates a live Wix-hosted site and returns its URL.
418
+ NOT for site files the user provides themselves (their own HTML/CSS/JS, a zip, another builder's export) — for those, don't call this tool: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp, where they upload the files and get a live hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
416
419
  `,
417
420
  RunWixCliCommand: dedent `
418
421
  Executes Wix CLI commands for Wix app development and management.
@@ -813,6 +816,7 @@ export function buildToolDescriptions(includeReadme, includeImageUploadGuidance
813
816
  CreateWixBusinessGuide: dedent `
814
817
  Provides comprehensive documentation for creating a new Wix business (site, app, etc.).
815
818
  Call this ONLY when the user explicitly asks for a headless site, a Wix Classic Editor site, or manual/advanced account/API-based site creation — these don't need the site's purpose first. For normal site-creation ${SITE_CREATION_COPY.normalCreationRoute.nonWidget}; for a specific template id, call \`CreateSiteFromTemplate\`.
819
+ Exception, even when the user says "headless": if they ALREADY HAVE the finished site as files (their own HTML/CSS/JS, a zip, an AI-builder export) and want those files hosted, don't call this tool — send them to https://www.wix.com/headless/drop?utm_campaign=mcp to upload the files and get a live hosted site (give that URL exactly, keeping the utm_campaign=mcp parameter). This guide's CLI flow is for BUILDING a headless frontend, not for hosting ready-made files.
816
820
 
817
821
  ## What This Tool Contains
818
822
 
@@ -86,11 +86,11 @@ export function addImportClaudeDesignTool(server, authStrategy, options) {
86
86
  designUrl = new URL(args.url);
87
87
  }
88
88
  catch {
89
- return errorResult('Invalid design URL.');
89
+ return errorResult('Invalid design URL — this tool only accepts the claudeusercontent.com URL produced by Claude Design. For site files the user provided themselves, do not retry: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp to upload them and get a live hosted site.');
90
90
  }
91
91
  if (designUrl.protocol !== 'https:' ||
92
92
  !designUrl.hostname.endsWith(CLAUDE_USER_CONTENT_HOST_SUFFIX)) {
93
- return errorResult('Invalid design URL.');
93
+ return errorResult('Invalid design URL — this tool only accepts the claudeusercontent.com URL produced by Claude Design. For site files the user provided themselves, do not retry: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp to upload them and get a live hosted site.');
94
94
  }
95
95
  // Resolve the caller's account identity BEFORE the design fetch — the
96
96
  // design URL is single-use, so an unauthenticated caller must fail
@@ -14,12 +14,19 @@ export declare const SITE_CREATION_DEFAULT_ACTIONS = "add products, set up booki
14
14
  */
15
15
  export declare const SITE_CREATION_CUSTOM_ACTIONS_GUIDANCE = "2\u20133 specific, high-value setup actions for the site's industry, written as a comma-separated phrase (it slots into \"\u2026ask me to ___ right here in the chat\"). Use the following domain patterns as guidance:\n* E-commerce / Retail: \"add products, set up payment methods, and organize collections\"\n* Restaurants / Food / Bakeries: \"add menu items, set up online ordering, and collect table reservations\"\n* Services / Fitness / Salons / Consultants: \"set up booking slots, add service pricing, and manage appointments\"\n* Creative / Portfolios / Photographers: \"upload project galleries, feature client reviews, and customize contact forms\"\n* Events / Weddings / Real Estate: \"add event schedules, display listings, and manage RSVP forms\"\n* General / Unspecified: \"add products, set up bookings, and adjust your content\"\nIf none of these patterns fit the site, infer 2\u20133 actions that suit what that kind of business would manage on its site.";
16
16
  /**
17
- * Builds the WixSiteCreation chooser reply. The message is fully composed here and wrapped in an
18
- * `<instructions>` preamble that tells the host model to display the body verbatim (keeping the
19
- * bullets and line breaks). The site type comes from `query`; the "Next up:" actions come from the
20
- * inferred `customActions`.
17
+ * Builds the WixSiteCreation chooser reply. The message is fully composed here and wrapped in a
18
+ * preamble that tells the host model to display the body verbatim (keeping the bullets and line
19
+ * breaks). The site type comes from `query`; the "Next up:" actions come from the inferred
20
+ * `customActions`.
21
+ *
22
+ * With `plain`, only the message itself is returned. Microsoft 365 Copilot's safety filter reads
23
+ * instructions inside a tool result ("you are the assistant…", "word for word…") as prompt
24
+ * injection and blocks the whole reply ("Sorry, it looks like I can't chat about this"); there the
25
+ * verbatim-reply instruction lives only in the tool description.
21
26
  */
22
- export declare function buildSiteCreationSelectorMessage(siteType?: string, customActions?: string): string;
27
+ export declare function buildSiteCreationSelectorMessage(siteType?: string, customActions?: string, { plain }?: {
28
+ plain?: boolean;
29
+ }): string;
23
30
  /** OpenAI/ChatGPT widget MIME type for Skybridge rendering */
24
31
  export declare const OPENAI_WIDGET_MIME_TYPE = "text/html+skybridge";
25
32
  /**
@@ -23,14 +23,28 @@ export const SITE_CREATION_CUSTOM_ACTIONS_GUIDANCE = `2–3 specific, high-value
23
23
  * General / Unspecified: "${SITE_CREATION_DEFAULT_ACTIONS}"
24
24
  If none of these patterns fit the site, infer 2–3 actions that suit what that kind of business would manage on its site.`;
25
25
  /**
26
- * Builds the WixSiteCreation chooser reply. The message is fully composed here and wrapped in an
27
- * `<instructions>` preamble that tells the host model to display the body verbatim (keeping the
28
- * bullets and line breaks). The site type comes from `query`; the "Next up:" actions come from the
29
- * inferred `customActions`.
26
+ * Builds the WixSiteCreation chooser reply. The message is fully composed here and wrapped in a
27
+ * preamble that tells the host model to display the body verbatim (keeping the bullets and line
28
+ * breaks). The site type comes from `query`; the "Next up:" actions come from the inferred
29
+ * `customActions`.
30
+ *
31
+ * With `plain`, only the message itself is returned. Microsoft 365 Copilot's safety filter reads
32
+ * instructions inside a tool result ("you are the assistant…", "word for word…") as prompt
33
+ * injection and blocks the whole reply ("Sorry, it looks like I can't chat about this"); there the
34
+ * verbatim-reply instruction lives only in the tool description.
30
35
  */
31
- export function buildSiteCreationSelectorMessage(siteType, customActions) {
36
+ export function buildSiteCreationSelectorMessage(siteType, customActions, { plain = false } = {}) {
32
37
  const type = (siteType ?? '').trim() || 'new';
33
38
  const actions = (customActions ?? '').trim() || SITE_CREATION_DEFAULT_ACTIONS;
39
+ const body = `Ready to set up your ${type} site? Choose your path in the widget above:
40
+
41
+ * **Build with AI** for a custom, tailor-made layout
42
+ * **Pick a template** to start with a pre-designed layout
43
+
44
+ **Next up:** Once your site is created, you can customize it in Wix or ask me to ${actions}—right here in the chat!`;
45
+ if (plain) {
46
+ return body;
47
+ }
34
48
  return `You are the assistant replying to the user — say this message out loud in chat (do NOT stay silent, and do NOT just point at the widget). Your reply is only complete if it includes ALL of the following, word for word, each on its own line and in this order:
35
49
  1. "Ready to set up your ${type} site? Choose your path in the widget above:" — keep the "Choose your path in the widget above:" part.
36
50
  2. "* **Build with AI** for a custom, tailor-made layout"
@@ -39,12 +53,7 @@ export function buildSiteCreationSelectorMessage(siteType, customActions) {
39
53
 
40
54
  Copy those four lines as written; do not summarize, shorten, reorder, or reword any of them. Here is the full message to send:
41
55
 
42
- Ready to set up your ${type} site? Choose your path in the widget above:
43
-
44
- * **Build with AI** for a custom, tailor-made layout
45
- * **Pick a template** to start with a pre-designed layout
46
-
47
- **Next up:** Once your site is created, you can customize it in Wix or ask me to ${actions}—right here in the chat!`;
56
+ ${body}`;
48
57
  }
49
58
  /** OpenAI/ChatGPT widget MIME type for Skybridge rendering */
50
59
  export const OPENAI_WIDGET_MIME_TYPE = 'text/html+skybridge';
@@ -67,7 +67,7 @@ export function addCreateSiteWidgetTool(server, authStrategy, options) {
67
67
  suggestedSiteName: z
68
68
  .string()
69
69
  .optional()
70
- .describe('Suggested site name to use for the site based on the site prompt.')
70
+ .describe('You must provide this on every call, including updates to an existing job, in English. A short name for the site: the business name the user gave, or one you derive from the site prompt.')
71
71
  },
72
72
  _meta: toolDefinitionMeta,
73
73
  annotations: {
@@ -85,8 +85,9 @@ export function addWixSiteCreationTool(server, _authStrategy, options) {
85
85
  // Reply instruction: a fixed SHAPE (question + the two options + a "Next up:" line) built
86
86
  // from the query (site type) and the inferred customActions, with the two option lines left
87
87
  // for the model to tailor to the industry. Returned as-is; the tool description also
88
- // instructs the model to write it out (both are load-bearing).
89
- const message = buildSiteCreationSelectorMessage(args.query, args.customActions);
88
+ // instructs the model to write it out (both are load-bearing). Microsoft Copilot gets the
89
+ // message without the preamble: its safety filter blocks the reply otherwise.
90
+ const message = buildSiteCreationSelectorMessage(args.query, args.customActions, { plain: server.isMicrosoftCopilotClient() });
90
91
  return withJsonContent({
91
92
  content: [
92
93
  {
@@ -1,7 +1,14 @@
1
1
  import { rethrowIfUnauthorized } from '../../auth/index.js';
2
2
  import z from 'zod';
3
+ import dedent from 'dedent';
3
4
  import { GET_SUGGESTED_DOMAINS_TOOL_NAME } from '../constants.js';
4
5
  const WIX_APIS_BASE_URL = 'https://www.wixapis.com';
6
+ // Sites keep this placeholder until the owner renames them, and domain search
7
+ // rejects it as a blacklisted term.
8
+ const DEFAULT_SITE_NAME = /^my site(\s+\d+)?$/i;
9
+ function isDefaultSiteName(siteName) {
10
+ return DEFAULT_SITE_NAME.test(siteName.trim());
11
+ }
5
12
  async function fetchSiteDisplayName(siteAuthorization, siteId) {
6
13
  const response = await fetch(`${WIX_APIS_BASE_URL}/site-properties/v4/properties`, {
7
14
  headers: {
@@ -19,7 +26,15 @@ export function addSuggestedDomainTool(server, authStrategy) {
19
26
  const { getSiteAuthHeaders, isAnonymous } = authStrategy;
20
27
  server.registerTool(GET_SUGGESTED_DOMAINS_TOOL_NAME, {
21
28
  title: 'Get Suggested Domains',
22
- description: 'Suggest available domain names. Provide either a free-text query (e.g. "pancakes business", "modern yoga studio") OR a siteId to auto-suggest based on the site name. At least one of query or siteId is required.',
29
+ description: dedent `
30
+ Suggests available domain names for a business, brand, or Wix site.
31
+
32
+ Call this when the user asks for domain name ideas, wants to know which domains are available, or wants a domain for a new or existing site.
33
+
34
+ Provide either a free-text \`query\` (the user's own words, e.g. "pancakes business", "modern yoga studio") OR a \`siteId\` to base the suggestions on that site's name. At least one of them is required.
35
+
36
+ Present the returned domains to the user as a short list. This tool only suggests domains — it does not purchase or connect them.
37
+ `,
23
38
  inputSchema: {
24
39
  query: z
25
40
  .string()
@@ -45,10 +60,11 @@ export function addSuggestedDomainTool(server, authStrategy) {
45
60
  },
46
61
  _meta: {
47
62
  securitySchemes: [{ type: 'oauth2', scopes: ['offline_access'] }],
48
- ui: { visibility: ['app'] },
63
+ // Model-visible so hosts (e.g. Microsoft 365 Copilot) can call it directly and show it
64
+ // in their debug info; 'app' keeps it callable from the site-builder widget.
65
+ ui: { visibility: ['app', 'model'] },
49
66
  'openai/toolInvocation/invoking': 'Fetching suggested domains',
50
- 'openai/toolInvocation/invoked': 'Suggested domains retrieved',
51
- 'openai/visibility': 'private'
67
+ 'openai/toolInvocation/invoked': 'Suggested domains retrieved'
52
68
  }
53
69
  }, async (args, { panorama }) => {
54
70
  console.log('[getSuggestedDomains] Invoked with args:', args);
@@ -90,7 +106,9 @@ export function addSuggestedDomainTool(server, authStrategy) {
90
106
  structuredContent: { domains: [] }
91
107
  };
92
108
  }
93
- resolvedQuery = siteName;
109
+ if (!isDefaultSiteName(siteName) || !resolvedQuery) {
110
+ resolvedQuery = siteName;
111
+ }
94
112
  }
95
113
  catch (error) {
96
114
  panorama
@@ -58,6 +58,8 @@ export declare class WixMcpServer extends McpServer {
58
58
  setOpenAiMcpAppsEnabled(enabled: boolean): void;
59
59
  setMcpAppsInMcpEnabled(enabled: boolean): void;
60
60
  isMcpAppsInMcpEnabled(): boolean;
61
+ /** Microsoft 365 Copilot ("sydney" at runtime) or Copilot Cowork ("copilot"). */
62
+ isMicrosoftCopilotClient(): boolean;
61
63
  shouldRenderMcpApps(): boolean;
62
64
  getWidgetExtras(): WidgetExtras;
63
65
  tool(name: string, cb: WixToolCallback): RegisteredTool;
@@ -60,6 +60,11 @@ export class WixMcpServer extends McpServer {
60
60
  isMcpAppsInMcpEnabled() {
61
61
  return this.mcpAppsInMcpEnabled;
62
62
  }
63
+ /** Microsoft 365 Copilot ("sydney" at runtime) or Copilot Cowork ("copilot"). */
64
+ isMicrosoftCopilotClient() {
65
+ const clientName = this.getClientName?.()?.toLowerCase() ?? '';
66
+ return clientName.includes('sydney') || clientName.includes('copilot');
67
+ }
63
68
  shouldRenderMcpApps() {
64
69
  const clientName = this.getClientName?.()?.toLowerCase();
65
70
  const isOpenAi = clientName?.includes('openai') ?? false;
@@ -29818,6 +29818,11 @@ var WixMcpServer = class extends McpServer {
29818
29818
  isMcpAppsInMcpEnabled() {
29819
29819
  return this.mcpAppsInMcpEnabled;
29820
29820
  }
29821
+ /** Microsoft 365 Copilot ("sydney" at runtime) or Copilot Cowork ("copilot"). */
29822
+ isMicrosoftCopilotClient() {
29823
+ const clientName = this.getClientName?.()?.toLowerCase() ?? "";
29824
+ return clientName.includes("sydney") || clientName.includes("copilot");
29825
+ }
29821
29826
  shouldRenderMcpApps() {
29822
29827
  const clientName = this.getClientName?.()?.toLowerCase();
29823
29828
  const isOpenAi = clientName?.includes("openai") ?? false;
@@ -30942,6 +30947,8 @@ var SITE_CREATION_COPY = {
30942
30947
  var SITE_GUIDANCE = dedent_default`
30943
30948
  A new-site request has two things to settle: what the site is for, and how to build it. The how is AI generation vs. starting from a template, so naming templates, a template id or Wix Studio (Wix Studio is also the template side) already settles it.
30944
30949
 
30950
+ One case skips all of this: the user ALREADY HAS the finished site as files — hand-written HTML/CSS/JS, a zip, or the export of an AI builder. There is nothing to build, so don't offer AI or templates and don't call any site-creation tool. Send them to https://www.wix.com/headless/drop?utm_campaign=mcp — they drag the files in and get a live Wix-hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
30951
+
30945
30952
  Settle what the site is for first: its purpose, topic, business type, audience, or main visitor action. Naming a method is not a description of the site, and neither is the business or industry on its own.
30946
30953
  If you can't tell yet, ask the preferred question below and nothing else — one question, no creation-method question in the same reply, and no internal tool names.
30947
30954
  Once the purpose is clear, unless the user already named a method, ${SITE_CREATION_COPY.unstatedMethod.nonWidget}. A method they named is settled — never re-open it. Never default to AI or to templates, and never ask the user to choose between Harmony and Wix Studio; infer that from their words.
@@ -31274,7 +31281,8 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
31274
31281
  After calling, you MUST speak the message provided in the tool result to the user as your reply — do not stay silent and do not replace it with a one-line pointer to the widget. Write out ALL of it, word for word: its opening line (the "Ready to set up your … site?" question INCLUDING "Choose your path in the widget above:"), BOTH of its option bullets, and its "Next up:" line, each on its own line and in that order. Do not summarize, shorten, drop any line, invent your own opener, rename the options, or add an intro or outro.
31275
31282
  `,
31276
31283
  "import-claude-design-from-url": dedent_default`
31277
- Import a design into Wix from a publicly fetchable URL. The file is a self-contained HTML bundle with all images, fonts, and styles inlined. Creates a live Wix-hosted site and returns its URL.
31284
+ Import a design created in Claude's design tool into Wix. Takes the signed claudeusercontent.com URL Claude Design produces for its self-contained HTML bundle (all images, fonts, and styles inlined); any other host is rejected. Creates a live Wix-hosted site and returns its URL.
31285
+ NOT for site files the user provides themselves (their own HTML/CSS/JS, a zip, another builder's export) — for those, don't call this tool: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp, where they upload the files and get a live hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
31278
31286
  `,
31279
31287
  RunWixCliCommand: dedent_default`
31280
31288
  Executes Wix CLI commands for Wix app development and management.
@@ -31675,6 +31683,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
31675
31683
  CreateWixBusinessGuide: dedent_default`
31676
31684
  Provides comprehensive documentation for creating a new Wix business (site, app, etc.).
31677
31685
  Call this ONLY when the user explicitly asks for a headless site, a Wix Classic Editor site, or manual/advanced account/API-based site creation — these don't need the site's purpose first. For normal site-creation ${SITE_CREATION_COPY.normalCreationRoute.nonWidget}; for a specific template id, call \`CreateSiteFromTemplate\`.
31686
+ Exception, even when the user says "headless": if they ALREADY HAVE the finished site as files (their own HTML/CSS/JS, a zip, an AI-builder export) and want those files hosted, don't call this tool — send them to https://www.wix.com/headless/drop?utm_campaign=mcp to upload the files and get a live hosted site (give that URL exactly, keeping the utm_campaign=mcp parameter). This guide's CLI flow is for BUILDING a headless frontend, not for hosting ready-made files.
31678
31687
 
31679
31688
  ## What This Tool Contains
31680
31689
 
@@ -32140,7 +32149,16 @@ var known_apps_default = {
32140
32149
  "1480c568-5cbd-9392-5604-1148f5faffa0": "Promote SEO",
32141
32150
  "ff5d6eb1-65e4-4f9a-8b14-64d34c12cc2e": "Wix Rentals"
32142
32151
  };
32143
- var DYNAMIC_CONTEXT_URL = "https://dev.wix.com/_api/dynamic-context/v1/dynamic-context";
32152
+ var DYNAMIC_CONTEXT_PATH = "/_api/dynamic-context/v1/dynamic-context";
32153
+ var DYNAMIC_CONTEXT_URL = `https://dev.wix.com${DYNAMIC_CONTEXT_PATH}`;
32154
+ var isWixHost = (hostname2) => hostname2 === "wix.com" || hostname2.endsWith(".wix.com");
32155
+ var dynamicContextUrl = () => {
32156
+ if (typeof window === "undefined") {
32157
+ return DYNAMIC_CONTEXT_URL;
32158
+ }
32159
+ const hostname2 = window.location?.hostname;
32160
+ return typeof hostname2 === "string" && isWixHost(hostname2) ? DYNAMIC_CONTEXT_PATH : DYNAMIC_CONTEXT_URL;
32161
+ };
32144
32162
  var COUNT_SITES_URL = "https://www.wixapis.com/site-list/v2/sites/count";
32145
32163
  var MAX_SITES_FOR_DYNAMIC_CONTEXT = 10;
32146
32164
  var DYNAMIC_CONTEXT_PETRI_OVERRIDE = "shouldReturnDynamicContextInMCP#B";
@@ -32192,7 +32210,7 @@ async function getDynamicContext(auth, httpClient6, filter, options) {
32192
32210
  if (filter?.siteId) body.site_id = filter.siteId;
32193
32211
  else if (filter?.siteName) body.site_name = filter.siteName;
32194
32212
  const dynamicContextPromise = httpClient6.request({
32195
- url: DYNAMIC_CONTEXT_URL,
32213
+ url: dynamicContextUrl(),
32196
32214
  method: "POST",
32197
32215
  headers: {
32198
32216
  ...accountHeaders,
@@ -34643,9 +34661,18 @@ var SITE_CREATION_CUSTOM_ACTIONS_GUIDANCE = `2\u20133 specific, high-value setup
34643
34661
  * Events / Weddings / Real Estate: "add event schedules, display listings, and manage RSVP forms"
34644
34662
  * General / Unspecified: "${SITE_CREATION_DEFAULT_ACTIONS}"
34645
34663
  If none of these patterns fit the site, infer 2\u20133 actions that suit what that kind of business would manage on its site.`;
34646
- function buildSiteCreationSelectorMessage(siteType, customActions) {
34664
+ function buildSiteCreationSelectorMessage(siteType, customActions, { plain = false } = {}) {
34647
34665
  const type = (siteType ?? "").trim() || "new";
34648
34666
  const actions = (customActions ?? "").trim() || SITE_CREATION_DEFAULT_ACTIONS;
34667
+ const body = `Ready to set up your ${type} site? Choose your path in the widget above:
34668
+
34669
+ * **Build with AI** for a custom, tailor-made layout
34670
+ * **Pick a template** to start with a pre-designed layout
34671
+
34672
+ **Next up:** Once your site is created, you can customize it in Wix or ask me to ${actions}\u2014right here in the chat!`;
34673
+ if (plain) {
34674
+ return body;
34675
+ }
34649
34676
  return `You are the assistant replying to the user \u2014 say this message out loud in chat (do NOT stay silent, and do NOT just point at the widget). Your reply is only complete if it includes ALL of the following, word for word, each on its own line and in this order:
34650
34677
  1. "Ready to set up your ${type} site? Choose your path in the widget above:" \u2014 keep the "Choose your path in the widget above:" part.
34651
34678
  2. "* **Build with AI** for a custom, tailor-made layout"
@@ -34654,12 +34681,7 @@ function buildSiteCreationSelectorMessage(siteType, customActions) {
34654
34681
 
34655
34682
  Copy those four lines as written; do not summarize, shorten, reorder, or reword any of them. Here is the full message to send:
34656
34683
 
34657
- Ready to set up your ${type} site? Choose your path in the widget above:
34658
-
34659
- * **Build with AI** for a custom, tailor-made layout
34660
- * **Pick a template** to start with a pre-designed layout
34661
-
34662
- **Next up:** Once your site is created, you can customize it in Wix or ask me to ${actions}\u2014right here in the chat!`;
34684
+ ${body}`;
34663
34685
  }
34664
34686
  var OPENAI_WIDGET_MIME_TYPE = "text/html+skybridge";
34665
34687
  var SITE_WIDGET_MCP_CSP = {
@@ -41614,7 +41636,7 @@ function addCreateSiteWidgetTool(server, authStrategy, options) {
41614
41636
  `The prompt to build the site. If not provided, the user will be asked to provide a prompt.`
41615
41637
  ),
41616
41638
  suggestedSiteName: external_exports.string().optional().describe(
41617
- "Suggested site name to use for the site based on the site prompt."
41639
+ "You must provide this on every call, including updates to an existing job, in English. A short name for the site: the business name the user gave, or one you derive from the site prompt."
41618
41640
  )
41619
41641
  },
41620
41642
  _meta: toolDefinitionMeta,
@@ -41771,6 +41793,10 @@ async function buildHarmonySite({
41771
41793
 
41772
41794
  // src/site-widget-tools/suggested-domain-tool/index.ts
41773
41795
  var WIX_APIS_BASE_URL3 = "https://www.wixapis.com";
41796
+ var DEFAULT_SITE_NAME = /^my site(\s+\d+)?$/i;
41797
+ function isDefaultSiteName(siteName) {
41798
+ return DEFAULT_SITE_NAME.test(siteName.trim());
41799
+ }
41774
41800
  async function fetchSiteDisplayName(siteAuthorization, siteId) {
41775
41801
  const response = await fetch(
41776
41802
  `${WIX_APIS_BASE_URL3}/site-properties/v4/properties`,
@@ -41795,7 +41821,15 @@ function addSuggestedDomainTool(server, authStrategy) {
41795
41821
  GET_SUGGESTED_DOMAINS_TOOL_NAME,
41796
41822
  {
41797
41823
  title: "Get Suggested Domains",
41798
- description: 'Suggest available domain names. Provide either a free-text query (e.g. "pancakes business", "modern yoga studio") OR a siteId to auto-suggest based on the site name. At least one of query or siteId is required.',
41824
+ description: dedent_default`
41825
+ Suggests available domain names for a business, brand, or Wix site.
41826
+
41827
+ Call this when the user asks for domain name ideas, wants to know which domains are available, or wants a domain for a new or existing site.
41828
+
41829
+ Provide either a free-text \`query\` (the user's own words, e.g. "pancakes business", "modern yoga studio") OR a \`siteId\` to base the suggestions on that site's name. At least one of them is required.
41830
+
41831
+ Present the returned domains to the user as a short list. This tool only suggests domains — it does not purchase or connect them.
41832
+ `,
41799
41833
  inputSchema: {
41800
41834
  query: zod_default.string().optional().describe(
41801
41835
  "Free-text keywords, business idea, or brand concept to base suggestions on. Use the user's own words."
@@ -41815,10 +41849,11 @@ function addSuggestedDomainTool(server, authStrategy) {
41815
41849
  },
41816
41850
  _meta: {
41817
41851
  securitySchemes: [{ type: "oauth2", scopes: ["offline_access"] }],
41818
- ui: { visibility: ["app"] },
41852
+ // Model-visible so hosts (e.g. Microsoft 365 Copilot) can call it directly and show it
41853
+ // in their debug info; 'app' keeps it callable from the site-builder widget.
41854
+ ui: { visibility: ["app", "model"] },
41819
41855
  "openai/toolInvocation/invoking": "Fetching suggested domains",
41820
- "openai/toolInvocation/invoked": "Suggested domains retrieved",
41821
- "openai/visibility": "private"
41856
+ "openai/toolInvocation/invoked": "Suggested domains retrieved"
41822
41857
  }
41823
41858
  },
41824
41859
  async (args, { panorama }) => {
@@ -41866,7 +41901,9 @@ function addSuggestedDomainTool(server, authStrategy) {
41866
41901
  structuredContent: { domains: [] }
41867
41902
  };
41868
41903
  }
41869
- resolvedQuery = siteName;
41904
+ if (!isDefaultSiteName(siteName) || !resolvedQuery) {
41905
+ resolvedQuery = siteName;
41906
+ }
41870
41907
  } catch (error2) {
41871
41908
  panorama.logger().error(
41872
41909
  `[getSuggestedDomains] Error fetching site name for siteId: ${siteId}`,
@@ -42322,7 +42359,8 @@ function addWixSiteCreationTool(server, _authStrategy, options) {
42322
42359
  };
42323
42360
  const message = buildSiteCreationSelectorMessage(
42324
42361
  args.query,
42325
- args.customActions
42362
+ args.customActions,
42363
+ { plain: server.isMicrosoftCopilotClient() }
42326
42364
  );
42327
42365
  return withJsonContent({
42328
42366
  content: [
@@ -45178,10 +45216,14 @@ function addImportClaudeDesignTool(server, authStrategy, options) {
45178
45216
  try {
45179
45217
  designUrl = new URL(args.url);
45180
45218
  } catch {
45181
- return errorResult("Invalid design URL.");
45219
+ return errorResult(
45220
+ "Invalid design URL \u2014 this tool only accepts the claudeusercontent.com URL produced by Claude Design. For site files the user provided themselves, do not retry: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp to upload them and get a live hosted site."
45221
+ );
45182
45222
  }
45183
45223
  if (designUrl.protocol !== "https:" || !designUrl.hostname.endsWith(CLAUDE_USER_CONTENT_HOST_SUFFIX)) {
45184
- return errorResult("Invalid design URL.");
45224
+ return errorResult(
45225
+ "Invalid design URL \u2014 this tool only accepts the claudeusercontent.com URL produced by Claude Design. For site files the user provided themselves, do not retry: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp to upload them and get a live hosted site."
45226
+ );
45185
45227
  }
45186
45228
  const accountHeaders = await authStrategy.getAccountAuthHeaders();
45187
45229
  const wixstroOptions = { baseUrl: wixstroBaseUrl, accountHeaders };
@@ -12177,6 +12177,8 @@ var SITE_CREATION_COPY = {
12177
12177
  var SITE_GUIDANCE = dedent_default`
12178
12178
  A new-site request has two things to settle: what the site is for, and how to build it. The how is AI generation vs. starting from a template, so naming templates, a template id or Wix Studio (Wix Studio is also the template side) already settles it.
12179
12179
 
12180
+ One case skips all of this: the user ALREADY HAS the finished site as files — hand-written HTML/CSS/JS, a zip, or the export of an AI builder. There is nothing to build, so don't offer AI or templates and don't call any site-creation tool. Send them to https://www.wix.com/headless/drop?utm_campaign=mcp — they drag the files in and get a live Wix-hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
12181
+
12180
12182
  Settle what the site is for first: its purpose, topic, business type, audience, or main visitor action. Naming a method is not a description of the site, and neither is the business or industry on its own.
12181
12183
  If you can't tell yet, ask the preferred question below and nothing else — one question, no creation-method question in the same reply, and no internal tool names.
12182
12184
  Once the purpose is clear, unless the user already named a method, ${SITE_CREATION_COPY.unstatedMethod.nonWidget}. A method they named is settled — never re-open it. Never default to AI or to templates, and never ask the user to choose between Harmony and Wix Studio; infer that from their words.
@@ -12509,7 +12511,8 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
12509
12511
  After calling, you MUST speak the message provided in the tool result to the user as your reply — do not stay silent and do not replace it with a one-line pointer to the widget. Write out ALL of it, word for word: its opening line (the "Ready to set up your … site?" question INCLUDING "Choose your path in the widget above:"), BOTH of its option bullets, and its "Next up:" line, each on its own line and in that order. Do not summarize, shorten, drop any line, invent your own opener, rename the options, or add an intro or outro.
12510
12512
  `,
12511
12513
  "import-claude-design-from-url": dedent_default`
12512
- Import a design into Wix from a publicly fetchable URL. The file is a self-contained HTML bundle with all images, fonts, and styles inlined. Creates a live Wix-hosted site and returns its URL.
12514
+ Import a design created in Claude's design tool into Wix. Takes the signed claudeusercontent.com URL Claude Design produces for its self-contained HTML bundle (all images, fonts, and styles inlined); any other host is rejected. Creates a live Wix-hosted site and returns its URL.
12515
+ NOT for site files the user provides themselves (their own HTML/CSS/JS, a zip, another builder's export) — for those, don't call this tool: send the user to https://www.wix.com/headless/drop?utm_campaign=mcp, where they upload the files and get a live hosted site. Give that URL exactly as written, keeping the utm_campaign=mcp parameter.
12513
12516
  `,
12514
12517
  RunWixCliCommand: dedent_default`
12515
12518
  Executes Wix CLI commands for Wix app development and management.
@@ -12910,6 +12913,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
12910
12913
  CreateWixBusinessGuide: dedent_default`
12911
12914
  Provides comprehensive documentation for creating a new Wix business (site, app, etc.).
12912
12915
  Call this ONLY when the user explicitly asks for a headless site, a Wix Classic Editor site, or manual/advanced account/API-based site creation — these don't need the site's purpose first. For normal site-creation ${SITE_CREATION_COPY.normalCreationRoute.nonWidget}; for a specific template id, call \`CreateSiteFromTemplate\`.
12916
+ Exception, even when the user says "headless": if they ALREADY HAVE the finished site as files (their own HTML/CSS/JS, a zip, an AI-builder export) and want those files hosted, don't call this tool — send them to https://www.wix.com/headless/drop?utm_campaign=mcp to upload the files and get a live hosted site (give that URL exactly, keeping the utm_campaign=mcp parameter). This guide's CLI flow is for BUILDING a headless frontend, not for hosting ready-made files.
12913
12917
 
12914
12918
  ## What This Tool Contains
12915
12919
 
@@ -13375,7 +13379,16 @@ var known_apps_default = {
13375
13379
  "1480c568-5cbd-9392-5604-1148f5faffa0": "Promote SEO",
13376
13380
  "ff5d6eb1-65e4-4f9a-8b14-64d34c12cc2e": "Wix Rentals"
13377
13381
  };
13378
- var DYNAMIC_CONTEXT_URL = "https://dev.wix.com/_api/dynamic-context/v1/dynamic-context";
13382
+ var DYNAMIC_CONTEXT_PATH = "/_api/dynamic-context/v1/dynamic-context";
13383
+ var DYNAMIC_CONTEXT_URL = `https://dev.wix.com${DYNAMIC_CONTEXT_PATH}`;
13384
+ var isWixHost = (hostname) => hostname === "wix.com" || hostname.endsWith(".wix.com");
13385
+ var dynamicContextUrl = () => {
13386
+ if (typeof window === "undefined") {
13387
+ return DYNAMIC_CONTEXT_URL;
13388
+ }
13389
+ const hostname = window.location?.hostname;
13390
+ return typeof hostname === "string" && isWixHost(hostname) ? DYNAMIC_CONTEXT_PATH : DYNAMIC_CONTEXT_URL;
13391
+ };
13379
13392
  var COUNT_SITES_URL = "https://www.wixapis.com/site-list/v2/sites/count";
13380
13393
  var MAX_SITES_FOR_DYNAMIC_CONTEXT = 10;
13381
13394
  var DYNAMIC_CONTEXT_PETRI_OVERRIDE = "shouldReturnDynamicContextInMCP#B";
@@ -13427,7 +13440,7 @@ async function getDynamicContext(auth, httpClient, filter, options) {
13427
13440
  if (filter?.siteId) body.site_id = filter.siteId;
13428
13441
  else if (filter?.siteName) body.site_name = filter.siteName;
13429
13442
  const dynamicContextPromise = httpClient.request({
13430
- url: DYNAMIC_CONTEXT_URL,
13443
+ url: dynamicContextUrl(),
13431
13444
  method: "POST",
13432
13445
  headers: {
13433
13446
  ...accountHeaders,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/mcp",
3
- "version": "1.0.81",
3
+ "version": "1.0.82",
4
4
  "description": "A Model Context Protocol server for Wix AI tools",
5
5
  "bin": "./build/bin-standalone.js",
6
6
  "dependencies": {
@@ -133,5 +133,5 @@
133
133
  ]
134
134
  }
135
135
  },
136
- "falconPackageHash": "04c1a3fafda823896c3a8c44537812f0689d6738d5369629956fdaf4"
136
+ "falconPackageHash": "b8ae29303e3809101199412477e8e9124437d8603c423399ed88697d"
137
137
  }