@wix/mcp 1.0.86 → 1.0.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin-standalone.js +61 -8
- package/build/cjs/index.cjs +93 -12
- package/build/cjs/toolkit.cjs +91 -10
- package/build/dts/code-mode/index.js +40 -2
- package/build/dts/config/api-request-rules.d.ts +1 -0
- package/build/dts/config/api-request-rules.js +1 -0
- package/build/dts/config/default-config.js +42 -3
- package/build/dts/config/param-descriptions.js +5 -2
- package/build/dts/docs/get-to-know.js +14 -11
- package/build/dts/import-claude-design-tool/index.js +2 -2
- package/build/dts/tool-utils.js +12 -1
- package/build/esm/index.js +93 -12
- package/build/esm/toolkit.js +91 -10
- package/package.json +2 -2
package/build/bin-standalone.js
CHANGED
|
@@ -71552,6 +71552,7 @@ function rethrowIfUnauthorized(error2) {
|
|
|
71552
71552
|
|
|
71553
71553
|
// src/config/api-request-rules.ts
|
|
71554
71554
|
var ARRAY_QUERY_PARAMS_RULE = "Repeat array query params once per value: `?fieldsets=URL&fieldsets=RICH_CONTENT`. Do NOT comma-join values (`fieldsets=URL,RICH_CONTENT`), do NOT leave a trailing comma, and do NOT use a value the method schema does not list, even if a sibling method accepts it (draft posts have no `SEO` fieldset).";
|
|
71555
|
+
var WQL_FILTER_RULE = "Query and search filters are written in WQL: each field takes a single operator, so combine conditions with the logical operators \u2014 `$and` and `$or` take an array of expressions, `$not` takes one, and they can nest.";
|
|
71555
71556
|
|
|
71556
71557
|
// src/config/default-config.ts
|
|
71557
71558
|
var AGENT_GOAL = dedent_default`
|
|
@@ -71652,7 +71653,7 @@ var SITE_CREATION_COPY = {
|
|
|
71652
71653
|
var SITE_GUIDANCE = dedent_default`
|
|
71653
71654
|
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
71655
|
|
|
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.
|
|
71656
|
+
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. For a full agentic flow, read the recipe first and publish the files yourself: https://dev.wix.com/docs/api-reference/account-level/sites/skills/upload-a-website-or-html-files.md — it walks you through creating the site and uploading the files end to end. If you can't follow it, or it doesn't apply (you can't reach the file bytes, or something fails), fall back to sending the user 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
71657
|
|
|
71657
71658
|
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.
|
|
71658
71659
|
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.
|
|
@@ -71711,18 +71712,56 @@ var ACCOUNT_SITE_EXECUTE_SCOPE = dedent_default`
|
|
|
71711
71712
|
siteId?: string;
|
|
71712
71713
|
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
71713
71714
|
url: string;
|
|
71715
|
+
// Plain object → JSON. A string is sent verbatim (set your own Content-Type,
|
|
71716
|
+
// e.g. multipart/form-data). A Uint8Array/ArrayBuffer is sent as raw bytes
|
|
71717
|
+
// for binary uploads (set your own Content-Type).
|
|
71714
71718
|
body?: unknown;
|
|
71715
71719
|
headers?: Record<string, string>;
|
|
71720
|
+
// "base64" returns the response body as a base64 string (data), with
|
|
71721
|
+
// encoding: "base64" on the result — use it for binary downloads (zip,
|
|
71722
|
+
// image, pdf); decoding those as text corrupts them. Binary content types
|
|
71723
|
+
// are returned as base64 automatically even without this. Decode, edit and
|
|
71724
|
+
// re-upload binary WITHIN this script and return only a small summary. If you
|
|
71725
|
+
// must return the bytes, return the wix.request response object itself (so
|
|
71726
|
+
// encoding: "base64" is preserved and it isn't truncated); a bare base64
|
|
71727
|
+
// string you return is treated as plain text and may be truncated.
|
|
71728
|
+
responseType?: "base64";
|
|
71716
71729
|
}
|
|
71717
71730
|
interface WixResponse<T = unknown> {
|
|
71718
71731
|
status: number;
|
|
71719
71732
|
data: T;
|
|
71733
|
+
encoding?: "base64";
|
|
71720
71734
|
json(): Promise<T>;
|
|
71721
71735
|
}
|
|
71722
71736
|
declare const wix: {
|
|
71723
71737
|
request<T = unknown>(options: WixRequestOptions): Promise<WixResponse<T>>;
|
|
71738
|
+
// Build a multipart/form-data body from files (defaults to the \`files\`
|
|
71739
|
+
// global). Each file becomes a part named fieldName (default "files") with
|
|
71740
|
+
// its path as the filename. Pass body + contentType to wix.request.
|
|
71741
|
+
multipart(
|
|
71742
|
+
files?: Array<{ path: string; content: string; contentType?: string }>,
|
|
71743
|
+
options?: { fieldName?: string }
|
|
71744
|
+
): { body: string; contentType: string };
|
|
71724
71745
|
};
|
|
71725
71746
|
declare const siteId: string | undefined;
|
|
71747
|
+
// Files from the ExecuteWixAPI \`files\` param (raw content, no escaping).
|
|
71748
|
+
declare const files: Array<{ path: string; content: string }>;
|
|
71749
|
+
\`\`\`
|
|
71750
|
+
|
|
71751
|
+
FILE UPLOADS: pass file bodies via the \`files\` param (not inside \`code\` — no escaping), then build the multipart body with \`wix.multipart()\`:
|
|
71752
|
+
\`\`\`javascript
|
|
71753
|
+
// files param: "=== FILE: index.html ===\\n<!doctype html>...\\n=== FILE: app.js ===\\nconsole.log(1)"
|
|
71754
|
+
async () => {
|
|
71755
|
+
const mp = wix.multipart(); // parts named "files", filename = each path
|
|
71756
|
+
const res = await wix.request({
|
|
71757
|
+
scope: "account",
|
|
71758
|
+
method: "POST",
|
|
71759
|
+
url: "https://www.wixapis.com/.../upload",
|
|
71760
|
+
headers: { "Content-Type": mp.contentType },
|
|
71761
|
+
body: mp.body
|
|
71762
|
+
});
|
|
71763
|
+
return res.data;
|
|
71764
|
+
}
|
|
71726
71765
|
\`\`\`
|
|
71727
71766
|
`;
|
|
71728
71767
|
var EXECUTE_WIX_API_WQL = dedent_default`
|
|
@@ -71855,6 +71894,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
|
|
|
71855
71894
|
ReadFullDocsArticle: dedent_default`
|
|
71856
71895
|
Fetches the full Wix docs article or method article with code examples for using the method.
|
|
71857
71896
|
Docs articles looks like this: https://dev.wix.com/docs/... and they can either be general docs articles or method articles.
|
|
71897
|
+
Take the URL from the user's message or an earlier tool result. To reach an article you have no URL for, search or browse the docs first.
|
|
71858
71898
|
For REST docs, use the URL as-is. For SDK docs, the URL SHOULD include ?apiView=SDK.
|
|
71859
71899
|
${reminder}
|
|
71860
71900
|
`,
|
|
@@ -71987,7 +72027,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
|
|
|
71987
72027
|
`,
|
|
71988
72028
|
"import-claude-design-from-url": dedent_default`
|
|
71989
72029
|
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:
|
|
72030
|
+
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. For a full agentic flow, read the recipe and publish the files yourself: https://dev.wix.com/docs/api-reference/account-level/sites/skills/upload-a-website-or-html-files.md — it covers creating the site and uploading the files end to end. If you can't follow it, or it doesn't apply, fall back to sending 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.
|
|
71991
72031
|
`,
|
|
71992
72032
|
RunWixCliCommand: dedent_default`
|
|
71993
72033
|
Executes Wix CLI commands for Wix app development and management.
|
|
@@ -72414,7 +72454,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
|
|
|
72414
72454
|
CreateWixBusinessGuide: dedent_default`
|
|
72415
72455
|
Provides comprehensive documentation for creating a new Wix business (site, app, etc.).
|
|
72416
72456
|
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\`.
|
|
72417
|
-
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 —
|
|
72457
|
+
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. For a full agentic flow, read the recipe and publish the files yourself: https://dev.wix.com/docs/api-reference/account-level/sites/skills/upload-a-website-or-html-files.md — it covers creating the site and uploading the files end to end. If you can't follow it, or it doesn't apply, fall back to sending the user 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.
|
|
72418
72458
|
|
|
72419
72459
|
## What This Tool Contains
|
|
72420
72460
|
|
|
@@ -73013,7 +73053,10 @@ var paramDescriptions = {
|
|
|
73013
73053
|
ARRAY_QUERY_PARAMS_RULE
|
|
73014
73054
|
].join("\n"),
|
|
73015
73055
|
method: "The HTTP method to use for the API call (e.g. GET, POST, PUT, DELETE)",
|
|
73016
|
-
body:
|
|
73056
|
+
body: [
|
|
73057
|
+
'The request body as a JSON object or array with all the required fields and values, including nested objects. Pass the actual value (object or array), NOT a JSON string. YOU MUST NEVER MAKE UP A BODY - the body should be based on the conversation context, i.e from the user prompt OR got into the conversation context by the "ReadFullDocsArticle" tool OR by the "SearchWixAPISpec" tool OR by the "ReadFullDocsMethodSchema" tool - i.e based on the API docs, a relevant recipe you read (preferably), a code example you found in the docs, a schema you read etc.. YOU MUST NEVER ASSUME YOU KNOW WHAT THE BODY SCHEMA IS WITHOUT CONCRETE EXAMPLES OR SCHEMA DEFINITIONS FROM THE CONVERSATION CONTEXT. Prefer reading relevant recipes if you have them in context for understand the body schema for API calls.',
|
|
73058
|
+
WQL_FILTER_RULE
|
|
73059
|
+
].join("\n"),
|
|
73017
73060
|
reason: "One sentence explaining the original user request and why you are calling this API to complete it.",
|
|
73018
73061
|
sourceDocUrl: [
|
|
73019
73062
|
"The URL of the documentation or recipe where you found this API endpoint.",
|
|
@@ -73337,15 +73380,17 @@ Failed to fetch content: ${errorMsg}`
|
|
|
73337
73380
|
const baseContentsPromise = Promise.all(
|
|
73338
73381
|
baseDocsWithoutRecipes.map(fetchDoc)
|
|
73339
73382
|
);
|
|
73340
|
-
const skillsContentPromise = getSkillsByPortal(httpClient, {
|
|
73383
|
+
const skillsContentPromise = skillsTags?.length ? getSkillsByPortal(httpClient, {
|
|
73341
73384
|
portalId: REST_PORTAL_ID,
|
|
73342
73385
|
...repo && { repo },
|
|
73343
73386
|
...commitHash && { commitHash },
|
|
73344
|
-
|
|
73387
|
+
tags: skillsTags
|
|
73345
73388
|
}).catch((err) => {
|
|
73346
73389
|
console.error("[WixREADME] Failed to fetch skills by portal:", err);
|
|
73347
73390
|
return null;
|
|
73348
|
-
})
|
|
73391
|
+
}) : fetchDoc({ action: "include", url: RECIPES_INDEX_URL }).then(
|
|
73392
|
+
(doc) => doc?.text ?? null
|
|
73393
|
+
);
|
|
73349
73394
|
const filter = {};
|
|
73350
73395
|
if (siteId) filter.siteId = siteId;
|
|
73351
73396
|
else if (siteName) filter.siteName = siteName;
|
|
@@ -85253,6 +85298,14 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
85253
85298
|
|
|
85254
85299
|
// src/tool-utils.ts
|
|
85255
85300
|
var REST_METHOD_CONTRACT_RETRY_HINT = "Before retrying, make sure you have everything needed for a correct call: the right endpoint URL, HTTP method, request body shape, and response shape. Use the SearchWixRESTDocumentation tool or BrowseWixRESTDocsMenu tool to find the correct method or relevant related articles, the ReadFullDocsArticle tool to read the method description and all code examples, and the SearchWixAPISpec tool for precise field names and schema details.";
|
|
85301
|
+
var SINGLE_OPERATOR_PER_FIELD_HINT = 'WQL takes one operator per field object. Split the conditions into separate expressions under the matching logical operator \u2014 `{"$and": [{"field": {"$gte": ...}}, {"field": {"$lte": ...}}]}` \u2014 and retry without re-searching the docs.';
|
|
85302
|
+
var FIELD_CAPABILITIES_HINT = "This endpoint declares its filterable and sortable fields with their operators. Read the map with SearchWixAPISpec (`queryMethodData.queryFieldsCapabilitiesMap`, or `searchMethodData.searchFieldsCapabilitiesMap` on search methods) and use only what it lists; otherwise fetch a bounded page and filter or sort the results yourself.";
|
|
85303
|
+
var getRetryHint = (errorDetails) => {
|
|
85304
|
+
if (!/Filter contains unsupported operator/i.test(errorDetails)) {
|
|
85305
|
+
return REST_METHOD_CONTRACT_RETRY_HINT;
|
|
85306
|
+
}
|
|
85307
|
+
return /"operator":"\{/.test(errorDetails) ? SINGLE_OPERATOR_PER_FIELD_HINT : FIELD_CAPABILITIES_HINT;
|
|
85308
|
+
};
|
|
85256
85309
|
var DEFAULT_OPENAI_SECURITY_SCHEMES = [
|
|
85257
85310
|
{ type: "oauth2", scopes: ["offline_access"] }
|
|
85258
85311
|
];
|
|
@@ -85279,7 +85332,7 @@ var buildErrorMessage = ({
|
|
|
85279
85332
|
].filter((str) => !!str).join("\n");
|
|
85280
85333
|
return `${baseMessage}
|
|
85281
85334
|
|
|
85282
|
-
${
|
|
85335
|
+
${getRetryHint(String(errorDetails))}`;
|
|
85283
85336
|
};
|
|
85284
85337
|
var handleWixAPIResponse = async (response) => {
|
|
85285
85338
|
const requestId = response.headers?.["x-wix-request-id"];
|
package/build/cjs/index.cjs
CHANGED
|
@@ -35867,6 +35867,14 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
35867
35867
|
|
|
35868
35868
|
// src/tool-utils.ts
|
|
35869
35869
|
var REST_METHOD_CONTRACT_RETRY_HINT = "Before retrying, make sure you have everything needed for a correct call: the right endpoint URL, HTTP method, request body shape, and response shape. Use the SearchWixRESTDocumentation tool or BrowseWixRESTDocsMenu tool to find the correct method or relevant related articles, the ReadFullDocsArticle tool to read the method description and all code examples, and the SearchWixAPISpec tool for precise field names and schema details.";
|
|
35870
|
+
var SINGLE_OPERATOR_PER_FIELD_HINT = 'WQL takes one operator per field object. Split the conditions into separate expressions under the matching logical operator \u2014 `{"$and": [{"field": {"$gte": ...}}, {"field": {"$lte": ...}}]}` \u2014 and retry without re-searching the docs.';
|
|
35871
|
+
var FIELD_CAPABILITIES_HINT = "This endpoint declares its filterable and sortable fields with their operators. Read the map with SearchWixAPISpec (`queryMethodData.queryFieldsCapabilitiesMap`, or `searchMethodData.searchFieldsCapabilitiesMap` on search methods) and use only what it lists; otherwise fetch a bounded page and filter or sort the results yourself.";
|
|
35872
|
+
var getRetryHint = (errorDetails) => {
|
|
35873
|
+
if (!/Filter contains unsupported operator/i.test(errorDetails)) {
|
|
35874
|
+
return REST_METHOD_CONTRACT_RETRY_HINT;
|
|
35875
|
+
}
|
|
35876
|
+
return /"operator":"\{/.test(errorDetails) ? SINGLE_OPERATOR_PER_FIELD_HINT : FIELD_CAPABILITIES_HINT;
|
|
35877
|
+
};
|
|
35870
35878
|
var DEFAULT_OPENAI_SECURITY_SCHEMES = [
|
|
35871
35879
|
{ type: "oauth2", scopes: ["offline_access"] }
|
|
35872
35880
|
];
|
|
@@ -35893,7 +35901,7 @@ var buildErrorMessage = ({
|
|
|
35893
35901
|
].filter((str) => !!str).join("\n");
|
|
35894
35902
|
return `${baseMessage}
|
|
35895
35903
|
|
|
35896
|
-
${
|
|
35904
|
+
${getRetryHint(String(errorDetails))}`;
|
|
35897
35905
|
};
|
|
35898
35906
|
var handleWixAPIResponse = async (response) => {
|
|
35899
35907
|
const requestId = response.headers?.["x-wix-request-id"];
|
|
@@ -37160,6 +37168,7 @@ function rethrowIfUnauthorized(error2) {
|
|
|
37160
37168
|
|
|
37161
37169
|
// src/config/api-request-rules.ts
|
|
37162
37170
|
var ARRAY_QUERY_PARAMS_RULE = "Repeat array query params once per value: `?fieldsets=URL&fieldsets=RICH_CONTENT`. Do NOT comma-join values (`fieldsets=URL,RICH_CONTENT`), do NOT leave a trailing comma, and do NOT use a value the method schema does not list, even if a sibling method accepts it (draft posts have no `SEO` fieldset).";
|
|
37171
|
+
var WQL_FILTER_RULE = "Query and search filters are written in WQL: each field takes a single operator, so combine conditions with the logical operators \u2014 `$and` and `$or` take an array of expressions, `$not` takes one, and they can nest.";
|
|
37163
37172
|
|
|
37164
37173
|
// src/config/default-config.ts
|
|
37165
37174
|
var AGENT_GOAL = dedent_default`
|
|
@@ -37260,7 +37269,7 @@ var SITE_CREATION_COPY = {
|
|
|
37260
37269
|
var SITE_GUIDANCE = dedent_default`
|
|
37261
37270
|
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.
|
|
37262
37271
|
|
|
37263
|
-
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.
|
|
37272
|
+
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. For a full agentic flow, read the recipe first and publish the files yourself: https://dev.wix.com/docs/api-reference/account-level/sites/skills/upload-a-website-or-html-files.md — it walks you through creating the site and uploading the files end to end. If you can't follow it, or it doesn't apply (you can't reach the file bytes, or something fails), fall back to sending the user 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.
|
|
37264
37273
|
|
|
37265
37274
|
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.
|
|
37266
37275
|
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.
|
|
@@ -37319,18 +37328,56 @@ var ACCOUNT_SITE_EXECUTE_SCOPE = dedent_default`
|
|
|
37319
37328
|
siteId?: string;
|
|
37320
37329
|
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
37321
37330
|
url: string;
|
|
37331
|
+
// Plain object → JSON. A string is sent verbatim (set your own Content-Type,
|
|
37332
|
+
// e.g. multipart/form-data). A Uint8Array/ArrayBuffer is sent as raw bytes
|
|
37333
|
+
// for binary uploads (set your own Content-Type).
|
|
37322
37334
|
body?: unknown;
|
|
37323
37335
|
headers?: Record<string, string>;
|
|
37336
|
+
// "base64" returns the response body as a base64 string (data), with
|
|
37337
|
+
// encoding: "base64" on the result — use it for binary downloads (zip,
|
|
37338
|
+
// image, pdf); decoding those as text corrupts them. Binary content types
|
|
37339
|
+
// are returned as base64 automatically even without this. Decode, edit and
|
|
37340
|
+
// re-upload binary WITHIN this script and return only a small summary. If you
|
|
37341
|
+
// must return the bytes, return the wix.request response object itself (so
|
|
37342
|
+
// encoding: "base64" is preserved and it isn't truncated); a bare base64
|
|
37343
|
+
// string you return is treated as plain text and may be truncated.
|
|
37344
|
+
responseType?: "base64";
|
|
37324
37345
|
}
|
|
37325
37346
|
interface WixResponse<T = unknown> {
|
|
37326
37347
|
status: number;
|
|
37327
37348
|
data: T;
|
|
37349
|
+
encoding?: "base64";
|
|
37328
37350
|
json(): Promise<T>;
|
|
37329
37351
|
}
|
|
37330
37352
|
declare const wix: {
|
|
37331
37353
|
request<T = unknown>(options: WixRequestOptions): Promise<WixResponse<T>>;
|
|
37354
|
+
// Build a multipart/form-data body from files (defaults to the \`files\`
|
|
37355
|
+
// global). Each file becomes a part named fieldName (default "files") with
|
|
37356
|
+
// its path as the filename. Pass body + contentType to wix.request.
|
|
37357
|
+
multipart(
|
|
37358
|
+
files?: Array<{ path: string; content: string; contentType?: string }>,
|
|
37359
|
+
options?: { fieldName?: string }
|
|
37360
|
+
): { body: string; contentType: string };
|
|
37332
37361
|
};
|
|
37333
37362
|
declare const siteId: string | undefined;
|
|
37363
|
+
// Files from the ExecuteWixAPI \`files\` param (raw content, no escaping).
|
|
37364
|
+
declare const files: Array<{ path: string; content: string }>;
|
|
37365
|
+
\`\`\`
|
|
37366
|
+
|
|
37367
|
+
FILE UPLOADS: pass file bodies via the \`files\` param (not inside \`code\` — no escaping), then build the multipart body with \`wix.multipart()\`:
|
|
37368
|
+
\`\`\`javascript
|
|
37369
|
+
// files param: "=== FILE: index.html ===\\n<!doctype html>...\\n=== FILE: app.js ===\\nconsole.log(1)"
|
|
37370
|
+
async () => {
|
|
37371
|
+
const mp = wix.multipart(); // parts named "files", filename = each path
|
|
37372
|
+
const res = await wix.request({
|
|
37373
|
+
scope: "account",
|
|
37374
|
+
method: "POST",
|
|
37375
|
+
url: "https://www.wixapis.com/.../upload",
|
|
37376
|
+
headers: { "Content-Type": mp.contentType },
|
|
37377
|
+
body: mp.body
|
|
37378
|
+
});
|
|
37379
|
+
return res.data;
|
|
37380
|
+
}
|
|
37334
37381
|
\`\`\`
|
|
37335
37382
|
`;
|
|
37336
37383
|
var EXECUTE_WIX_API_WQL = dedent_default`
|
|
@@ -37463,6 +37510,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
|
|
|
37463
37510
|
ReadFullDocsArticle: dedent_default`
|
|
37464
37511
|
Fetches the full Wix docs article or method article with code examples for using the method.
|
|
37465
37512
|
Docs articles looks like this: https://dev.wix.com/docs/... and they can either be general docs articles or method articles.
|
|
37513
|
+
Take the URL from the user's message or an earlier tool result. To reach an article you have no URL for, search or browse the docs first.
|
|
37466
37514
|
For REST docs, use the URL as-is. For SDK docs, the URL SHOULD include ?apiView=SDK.
|
|
37467
37515
|
${reminder}
|
|
37468
37516
|
`,
|
|
@@ -37595,7 +37643,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
|
|
|
37595
37643
|
`,
|
|
37596
37644
|
"import-claude-design-from-url": dedent_default`
|
|
37597
37645
|
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.
|
|
37598
|
-
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:
|
|
37646
|
+
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. For a full agentic flow, read the recipe and publish the files yourself: https://dev.wix.com/docs/api-reference/account-level/sites/skills/upload-a-website-or-html-files.md — it covers creating the site and uploading the files end to end. If you can't follow it, or it doesn't apply, fall back to sending 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.
|
|
37599
37647
|
`,
|
|
37600
37648
|
RunWixCliCommand: dedent_default`
|
|
37601
37649
|
Executes Wix CLI commands for Wix app development and management.
|
|
@@ -38022,7 +38070,7 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
|
|
|
38022
38070
|
CreateWixBusinessGuide: dedent_default`
|
|
38023
38071
|
Provides comprehensive documentation for creating a new Wix business (site, app, etc.).
|
|
38024
38072
|
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\`.
|
|
38025
|
-
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 —
|
|
38073
|
+
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. For a full agentic flow, read the recipe and publish the files yourself: https://dev.wix.com/docs/api-reference/account-level/sites/skills/upload-a-website-or-html-files.md — it covers creating the site and uploading the files end to end. If you can't follow it, or it doesn't apply, fall back to sending the user 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.
|
|
38026
38074
|
|
|
38027
38075
|
## What This Tool Contains
|
|
38028
38076
|
|
|
@@ -38659,7 +38707,10 @@ var paramDescriptions = {
|
|
|
38659
38707
|
ARRAY_QUERY_PARAMS_RULE
|
|
38660
38708
|
].join("\n"),
|
|
38661
38709
|
method: "The HTTP method to use for the API call (e.g. GET, POST, PUT, DELETE)",
|
|
38662
|
-
body:
|
|
38710
|
+
body: [
|
|
38711
|
+
'The request body as a JSON object or array with all the required fields and values, including nested objects. Pass the actual value (object or array), NOT a JSON string. YOU MUST NEVER MAKE UP A BODY - the body should be based on the conversation context, i.e from the user prompt OR got into the conversation context by the "ReadFullDocsArticle" tool OR by the "SearchWixAPISpec" tool OR by the "ReadFullDocsMethodSchema" tool - i.e based on the API docs, a relevant recipe you read (preferably), a code example you found in the docs, a schema you read etc.. YOU MUST NEVER ASSUME YOU KNOW WHAT THE BODY SCHEMA IS WITHOUT CONCRETE EXAMPLES OR SCHEMA DEFINITIONS FROM THE CONVERSATION CONTEXT. Prefer reading relevant recipes if you have them in context for understand the body schema for API calls.',
|
|
38712
|
+
WQL_FILTER_RULE
|
|
38713
|
+
].join("\n"),
|
|
38663
38714
|
reason: "One sentence explaining the original user request and why you are calling this API to complete it.",
|
|
38664
38715
|
sourceDocUrl: [
|
|
38665
38716
|
"The URL of the documentation or recipe where you found this API endpoint.",
|
|
@@ -38983,15 +39034,17 @@ Failed to fetch content: ${errorMsg}`
|
|
|
38983
39034
|
const baseContentsPromise = Promise.all(
|
|
38984
39035
|
baseDocsWithoutRecipes.map(fetchDoc)
|
|
38985
39036
|
);
|
|
38986
|
-
const skillsContentPromise = getSkillsByPortal(httpClient6, {
|
|
39037
|
+
const skillsContentPromise = skillsTags?.length ? getSkillsByPortal(httpClient6, {
|
|
38987
39038
|
portalId: REST_PORTAL_ID,
|
|
38988
39039
|
...repo && { repo },
|
|
38989
39040
|
...commitHash && { commitHash },
|
|
38990
|
-
|
|
39041
|
+
tags: skillsTags
|
|
38991
39042
|
}).catch((err) => {
|
|
38992
39043
|
console.error("[WixREADME] Failed to fetch skills by portal:", err);
|
|
38993
39044
|
return null;
|
|
38994
|
-
})
|
|
39045
|
+
}) : fetchDoc({ action: "include", url: RECIPES_INDEX_URL }).then(
|
|
39046
|
+
(doc) => doc?.text ?? null
|
|
39047
|
+
);
|
|
38995
39048
|
const filter = {};
|
|
38996
39049
|
if (siteId) filter.siteId = siteId;
|
|
38997
39050
|
else if (siteName) filter.siteName = siteName;
|
|
@@ -52009,12 +52062,12 @@ function addImportClaudeDesignTool(server, authStrategy, options) {
|
|
|
52009
52062
|
designUrl = new URL(args.url);
|
|
52010
52063
|
} catch {
|
|
52011
52064
|
return errorResult(
|
|
52012
|
-
"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."
|
|
52065
|
+
"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 this tool. For a full agentic flow, read the recipe and publish the files yourself: https://dev.wix.com/docs/api-reference/account-level/sites/skills/upload-a-website-or-html-files.md \u2014 it covers creating the site and uploading the files end to end. If you can't follow it, or it doesn't apply, send the user to https://www.wix.com/headless/drop?utm_campaign=mcp to upload them and get a live hosted site."
|
|
52013
52066
|
);
|
|
52014
52067
|
}
|
|
52015
52068
|
if (designUrl.protocol !== "https:" || !designUrl.hostname.endsWith(CLAUDE_USER_CONTENT_HOST_SUFFIX)) {
|
|
52016
52069
|
return errorResult(
|
|
52017
|
-
"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."
|
|
52070
|
+
"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 this tool. For a full agentic flow, read the recipe and publish the files yourself: https://dev.wix.com/docs/api-reference/account-level/sites/skills/upload-a-website-or-html-files.md \u2014 it covers creating the site and uploading the files end to end. If you can't follow it, or it doesn't apply, send the user to https://www.wix.com/headless/drop?utm_campaign=mcp to upload them and get a live hosted site."
|
|
52018
52071
|
);
|
|
52019
52072
|
}
|
|
52020
52073
|
const accountHeaders = await authStrategy.getAccountAuthHeaders();
|
|
@@ -53072,12 +53125,31 @@ function formatExecuteResult(data, maxResponseSize, reportBi) {
|
|
|
53072
53125
|
reportBi?.({
|
|
53073
53126
|
originalLength: typeof data.result === "string" ? data.result.length : JSON.stringify(data.result)?.length
|
|
53074
53127
|
});
|
|
53128
|
+
const base64Text = base64PayloadText(data.result);
|
|
53129
|
+
if (base64Text !== null) {
|
|
53130
|
+
if (base64Text.length <= MAX_ALLOWED_RESPONSE_CHARS) {
|
|
53131
|
+
return { content: [{ type: "text", text: base64Text }] };
|
|
53132
|
+
}
|
|
53133
|
+
const approxKb = Math.ceil(base64Text.length / 1024).toLocaleString();
|
|
53134
|
+
const limitKb = Math.floor(
|
|
53135
|
+
MAX_ALLOWED_RESPONSE_CHARS / 1024
|
|
53136
|
+
).toLocaleString();
|
|
53137
|
+
return executeErrorResult(
|
|
53138
|
+
`Binary (base64) result is ~${approxKb} KB, too large to return intact (limit ~${limitKb} KB); truncating it would corrupt the base64. Process the bytes inside your ExecuteWixAPI script \u2014 decode, edit, and re-upload in the same call \u2014 and return only a small summary.`
|
|
53139
|
+
);
|
|
53140
|
+
}
|
|
53075
53141
|
return {
|
|
53076
53142
|
content: [
|
|
53077
53143
|
{ type: "text", text: truncateResponse(data.result, maxResponseSize) }
|
|
53078
53144
|
]
|
|
53079
53145
|
};
|
|
53080
53146
|
}
|
|
53147
|
+
function base64PayloadText(result) {
|
|
53148
|
+
if (result !== null && typeof result === "object" && result.encoding === "base64" && typeof result.data === "string") {
|
|
53149
|
+
return JSON.stringify(result);
|
|
53150
|
+
}
|
|
53151
|
+
return null;
|
|
53152
|
+
}
|
|
53081
53153
|
function addExecuteTool(server, options) {
|
|
53082
53154
|
const {
|
|
53083
53155
|
codeModeBaseUrl,
|
|
@@ -53109,6 +53181,14 @@ function addExecuteTool(server, options) {
|
|
|
53109
53181
|
visitor ? "Whether this code creates, updates, deletes, publishes, imports, uploads, or otherwise mutates site data on the visitor\u2019s behalf. Set this to true for create/update/delete/bulk create/import/upload calls even if the reason is inspection, verification, or response-shape discovery. Read-only GET/query/list/search calls can use false." : "Whether this code creates, updates, deletes, publishes, installs, imports, uploads, or otherwise mutates Wix data or site/account state. Set this to true for create/update/delete/bulk create/import/upload calls even if the reason is inspection, verification, or response-shape discovery. Read-only GET/query/list/search calls can use false."
|
|
53110
53182
|
),
|
|
53111
53183
|
sourceDocUrls: external_exports.array(external_exports.string()).describe(d2.sourceDocUrls),
|
|
53184
|
+
files: external_exports.string().optional().describe(
|
|
53185
|
+
[
|
|
53186
|
+
"Optional bundle of raw file contents for uploads, so file bytes never go through the `code` JavaScript (no escaping, no string-literal/`${}`/backtick pitfalls).",
|
|
53187
|
+
"Format: one or more sections, each a line `=== FILE: <path> ===` on its own, followed by that file's raw text content; `<path>` is the path relative to the site root (e.g. `index.html`, `assets/app.js`). Example: `=== FILE: index.html ===\\n<!doctype html>...\\n=== FILE: assets/app.js ===\\nconsole.log(1)`.",
|
|
53188
|
+
'In `code`, the parsed files are the `files` global (array of `{ path, content }`), and `wix.multipart(files)` returns `{ body, contentType }` for a `multipart/form-data` upload \u2014 e.g. `const mp = wix.multipart(); await wix.request({ scope: "account", method: "POST", url, headers: { "Content-Type": mp.contentType }, body: mp.body });`.',
|
|
53189
|
+
"Text files only; for binary assets pass bytes as a base64 request body instead. A file whose content itself contains a line exactly like the delimiter is not supported."
|
|
53190
|
+
].join(" ")
|
|
53191
|
+
),
|
|
53112
53192
|
// Visitor mode takes an agent-supplied token and pins the site; account/site
|
|
53113
53193
|
// mode lets the agent pick the site.
|
|
53114
53194
|
...visitor ? {
|
|
@@ -53123,7 +53203,7 @@ function addExecuteTool(server, options) {
|
|
|
53123
53203
|
},
|
|
53124
53204
|
{ readOnlyHint: false, destructiveHint: true, openWorldHint: false },
|
|
53125
53205
|
async (rawArgs, extra) => {
|
|
53126
|
-
const { code, reason, hasMutations, sourceDocUrls, visitorToken } = rawArgs;
|
|
53206
|
+
const { code, reason, hasMutations, sourceDocUrls, visitorToken, files } = rawArgs;
|
|
53127
53207
|
const siteId = visitor ? visitor.siteId : rawArgs.siteId;
|
|
53128
53208
|
logger2.log(
|
|
53129
53209
|
`[ExecuteWixAPI]${visitor ? " (visitor)" : ""} Executing code (${code.length} chars), siteId=${siteId ?? "none"}, hasMutations=${hasMutations}, sourceDocUrls=${JSON.stringify(sourceDocUrls)}, reason="${reason}"`
|
|
@@ -53168,7 +53248,8 @@ function addExecuteTool(server, options) {
|
|
|
53168
53248
|
siteToken: visitor ? visitorToken : siteHeaders?.Authorization,
|
|
53169
53249
|
accountToken: visitor ? visitorToken : accountHeaders?.Authorization,
|
|
53170
53250
|
accountId: accountHeaders?.["wix-account-id"],
|
|
53171
|
-
siteAuthContext
|
|
53251
|
+
siteAuthContext,
|
|
53252
|
+
...files ? { files } : {}
|
|
53172
53253
|
},
|
|
53173
53254
|
visitor ? visitorToken : accountHeaders?.Authorization ?? siteHeaders?.Authorization,
|
|
53174
53255
|
codeModeFetch
|