@wix/mcp 1.0.92 → 1.0.93
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 +38 -20
- package/build/cjs/index.cjs +257 -23
- package/build/cjs/toolkit.cjs +257 -23
- package/build/dts/code-mode/attachments.d.ts +37 -0
- package/build/dts/code-mode/attachments.js +218 -0
- package/build/dts/code-mode/index.js +36 -3
- package/build/dts/config/default-config.js +13 -6
- package/build/dts/config/param-descriptions.js +3 -3
- package/build/dts/docs/docs.js +14 -8
- package/build/dts/docs/semanticSearch.d.ts +2 -1
- package/build/dts/docs/semanticSearch.js +12 -5
- package/build/esm/index.js +257 -23
- package/build/esm/toolkit.js +257 -23
- package/package.json +2 -2
package/build/esm/toolkit.js
CHANGED
|
@@ -10714,9 +10714,12 @@ var runSemanticSearch = async (toolName, toolParams, maxResults = 20, rerank = f
|
|
|
10714
10714
|
);
|
|
10715
10715
|
return data?.results;
|
|
10716
10716
|
};
|
|
10717
|
-
var runPlatformizedSemanticSearch = async (toolName, searchTerm, maxResults = 20, linesInEachResult) => {
|
|
10717
|
+
var runPlatformizedSemanticSearch = async (toolName, searchTerm, maxResults = 20, linesInEachResult, extraDocumentTypes) => {
|
|
10718
10718
|
const startTime = Date.now();
|
|
10719
|
-
|
|
10719
|
+
const documentTypes = extraDocumentTypes?.length ? [toolName, ...extraDocumentTypes] : void 0;
|
|
10720
|
+
logger.log(
|
|
10721
|
+
`[SemanticSearch/v2] Tool: ${documentTypes ? documentTypes.join("+") : toolName}, Query: "${searchTerm}"`
|
|
10722
|
+
);
|
|
10720
10723
|
const response = await fetch(
|
|
10721
10724
|
"https://www.wixapis.com/mcp-docs-search/v1/docs/search/markdown",
|
|
10722
10725
|
{
|
|
@@ -10727,7 +10730,7 @@ var runPlatformizedSemanticSearch = async (toolName, searchTerm, maxResults = 20
|
|
|
10727
10730
|
},
|
|
10728
10731
|
body: JSON.stringify({
|
|
10729
10732
|
search_term: searchTerm,
|
|
10730
|
-
document_type: toolName,
|
|
10733
|
+
...documentTypes ? { document_types: documentTypes } : { document_type: toolName },
|
|
10731
10734
|
maximum_results: maxResults,
|
|
10732
10735
|
lines_in_each_result: linesInEachResult
|
|
10733
10736
|
})
|
|
@@ -10756,14 +10759,16 @@ var runSemanticSearchAndFormat = async ({
|
|
|
10756
10759
|
maxResults = DEFAULT_MAX_RESULTS,
|
|
10757
10760
|
rerank,
|
|
10758
10761
|
linesInEachResult,
|
|
10759
|
-
usePlatformizedSearch = true
|
|
10762
|
+
usePlatformizedSearch = true,
|
|
10763
|
+
extraDocumentTypes
|
|
10760
10764
|
}) => {
|
|
10761
10765
|
if (usePlatformizedSearch) {
|
|
10762
10766
|
return runPlatformizedSemanticSearch(
|
|
10763
10767
|
toolName,
|
|
10764
10768
|
toolParams.searchTerm,
|
|
10765
10769
|
maxResults,
|
|
10766
|
-
linesInEachResult
|
|
10770
|
+
linesInEachResult,
|
|
10771
|
+
extraDocumentTypes
|
|
10767
10772
|
);
|
|
10768
10773
|
} else {
|
|
10769
10774
|
const results = await runSemanticSearch(
|
|
@@ -12305,13 +12310,14 @@ var ACCOUNT_SITE_EXECUTE_SCOPE = dedent_default`
|
|
|
12305
12310
|
unzip(input: string | Uint8Array): Promise<Array<{ path: string; bytes: Uint8Array; text(): string }>>;
|
|
12306
12311
|
};
|
|
12307
12312
|
declare const siteId: string | undefined;
|
|
12308
|
-
// Files from the ExecuteWixAPI \`files\` param
|
|
12309
|
-
//
|
|
12310
|
-
//
|
|
12313
|
+
// Files from the ExecuteWixAPI \`files\` param, followed by the resolved
|
|
12314
|
+
// \`attachments\`. Text entries have \`content\`; an entry tagged
|
|
12315
|
+
// \`=== FILE: <path> base64 ===\` — and every attachment, path = its file name —
|
|
12316
|
+
// has encoding:'base64' and base64 \`content\`.
|
|
12311
12317
|
declare const files: Array<{ path: string; content: string; encoding?: "base64" }>;
|
|
12312
12318
|
\`\`\`
|
|
12313
12319
|
|
|
12314
|
-
FILE UPLOADS:
|
|
12320
|
+
FILE UPLOADS: files never go inline in \`code\`; two params feed the \`files\` global. \`attachments\` takes files attached in the chat or created in your file sandbox, of any type and size up to 10 MB per call (a zip of a whole site, HTML, images, PDFs): pass the files themselves, all in one call, and the platform resolves each into \`{ download_url, file_id, file_name?, mime_type? }\` — the bytes are fetched for you and arrive as base64 entries named by file name. The \`files\` param takes content you have as text here: text goes raw; a small binary (icon, logo, font) rides as a \`base64\`-tagged entry — large images/video are referenced by URL (\`<img src="https://...">\`), not bundled. \`wix.multipart()\` turns the whole set into one upload body (bytes, so binary is safe):
|
|
12315
12321
|
\`\`\`javascript
|
|
12316
12322
|
// files param:
|
|
12317
12323
|
// === FILE: index.html ===
|
|
@@ -12326,6 +12332,12 @@ var ACCOUNT_SITE_EXECUTE_SCOPE = dedent_default`
|
|
|
12326
12332
|
return res.data;
|
|
12327
12333
|
}
|
|
12328
12334
|
\`\`\`
|
|
12335
|
+
A site zip passed through \`attachments\` is one base64 entry; unzip it and upload the entries:
|
|
12336
|
+
\`\`\`javascript
|
|
12337
|
+
// attachments: [site.zip] → files = [{ path: "site.zip", content: "<base64>", encoding: "base64" }]
|
|
12338
|
+
const entries = await wix.unzip(files[0].content); // [{ path, bytes, text() }]
|
|
12339
|
+
const mp = wix.multipart(entries);
|
|
12340
|
+
\`\`\`
|
|
12329
12341
|
DOWNLOAD + EDIT + RE-UPLOAD: fetch the zip as base64, \`wix.unzip()\` it, edit text via \`entry.text()\`, keep binary as bytes, and hand the entries back to \`wix.multipart()\`:
|
|
12330
12342
|
\`\`\`javascript
|
|
12331
12343
|
const r = await wix.request({ scope: "account", method: "GET", responseType: "base64", url: zipUrl });
|
|
@@ -12530,12 +12542,12 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
|
|
|
12530
12542
|
NEVER call this tool with a missing, empty, or guessed siteId — ask first instead.
|
|
12531
12543
|
|
|
12532
12544
|
Parameters — provide image input via image and/or imageUrls, OR imageBase64:
|
|
12533
|
-
• image (array): chat file ATTACHMENTS. Each item is an object with download_url and file_id (both required), plus optional file_name and mime_type. Pass ALL attachments in one call.
|
|
12545
|
+
• image (array): chat file ATTACHMENTS — files the user attached, or files you created in your own file sandbox. Each item is an object with download_url and file_id (both required), plus optional file_name and mime_type. Pass ALL attachments in one call.
|
|
12534
12546
|
• imageUrls (array): plain public image URLs the user pasted or other tools produced (no file_id). Pass ALL URLs in one call. Can be combined with image.
|
|
12535
12547
|
• imageBase64 (string): base64-encoded image + mimeType. One image at a time. Do NOT combine with image/imageUrls.
|
|
12536
12548
|
|
|
12537
12549
|
Delivering the bytes — this is where uploads most often fail:
|
|
12538
|
-
•
|
|
12550
|
+
• Pass a file as a file, in image: the platform resolves it into download_url and file_id before it reaches this tool — this includes files you created in your sandbox. This server does not share your filesystem, so a bare path string (e.g. /mnt/..., /home/user/..., /Users/...) is not a file. Without a file to pass, use a public http(s) URL (imageUrls) or the complete base64 (imageBase64).
|
|
12539
12551
|
• imageBase64 must be the WHOLE file, not truncated. For large images prefer imageUrls, since long base64 is easily cut off and will be rejected as unreadable.
|
|
12540
12552
|
`,
|
|
12541
12553
|
SupportAndFeedback: dedent_default`
|
|
@@ -13787,7 +13799,7 @@ var paramDescriptions = {
|
|
|
13787
13799
|
},
|
|
13788
13800
|
SearchWixRESTDocumentation: {
|
|
13789
13801
|
searchTerm: `The search term to look up in the Wix REST API Documentation \u2014 a natural-language description of the endpoint, resource, or action you need across any Wix domain (Stores, eCommerce, Bookings, CRM, Members, CMS, Events, Blog, Forms, Media, site settings, etc.), e.g. "create a catalog item with inventory", "book a service", "update data collection items". Match the wording to how many entities you will act on: a plural term ("update products") surfaces the resource's bulk methods, which a singular term ("update a product") ranks lower or leaves out. Results are ranked by relevance, so describe the goal rather than guessing an exact API name.`,
|
|
13790
|
-
maxResults: "The maximum number of results to return, default
|
|
13802
|
+
maxResults: "The maximum number of results to return (1\u201317, default 17). Results mix REST API documentation with matching recipes and skills.",
|
|
13791
13803
|
reason: "One sentence describing the original user request and the task you are trying to accomplish with this search."
|
|
13792
13804
|
},
|
|
13793
13805
|
WixBusinessFlowsDocumentation: {
|
|
@@ -13808,7 +13820,7 @@ var paramDescriptions = {
|
|
|
13808
13820
|
},
|
|
13809
13821
|
SearchWixHeadlessDocumentation: {
|
|
13810
13822
|
searchTerm: "The search term to search for in the Headless Documentation",
|
|
13811
|
-
maxResults: "The maximum number of results to return, default
|
|
13823
|
+
maxResults: "The maximum number of results to return (1\u201317, default 17). Results mix Headless documentation with matching recipes and skills."
|
|
13812
13824
|
},
|
|
13813
13825
|
SearchWixVeloDocumentation: {
|
|
13814
13826
|
searchTerm: "The search term to search for in the Velo Documentation",
|
|
@@ -13836,7 +13848,7 @@ var paramDescriptions = {
|
|
|
13836
13848
|
},
|
|
13837
13849
|
UploadImageToWixSite: {
|
|
13838
13850
|
siteId: "The ID (UUID) of the Wix site to upload to. REQUIRED. If the user has not clearly specified which site, ASK them which site to upload to (or use ListWixSites to help them pick) BEFORE calling this tool. NEVER call this tool with a missing, empty, placeholder, or guessed siteId \u2014 ask first instead.",
|
|
13839
|
-
image: "Array of file ATTACHMENTS the user uploaded in the chat. Each item requires download_url and file_id, and may optionally include file_name and mime_type \u2014
|
|
13851
|
+
image: "Array of file ATTACHMENTS: files the user uploaded in the chat, or files you created in your own file sandbox. Each item requires download_url and file_id, and may optionally include file_name and mime_type \u2014 the platform resolves a file passed here into these fields automatically, so just include the files. For plain image URLs the user pasted, use imageUrls instead. ALWAYS pass ALL attachments together in a single call \u2014 NEVER call this tool once per image. Do NOT use together with imageBase64.",
|
|
13840
13852
|
imageUrls: "Array of publicly accessible image URLs (e.g. links the user pasted or URLs produced by other tools). Use this for plain URLs that are NOT chat attachments \u2014 no file_id is needed. ALWAYS pass ALL URLs together in a single call. Can be combined with image; do NOT use together with imageBase64.",
|
|
13841
13853
|
imageBase64: 'Base64-encoded image data. Use when the client can read a file and encode it as base64. May include a data URL prefix (e.g. "data:image/jpeg;base64,...") or be raw base64. Do NOT use together with image.',
|
|
13842
13854
|
mimeType: 'MIME type of the image (e.g. "image/jpeg", "image/png", "image/webp"). Required when imageBase64 does not include a data URL prefix.',
|
|
@@ -14495,7 +14507,7 @@ var addDocsTools = (server, allowedTools = [
|
|
|
14495
14507
|
const d = desc("SearchWixRESTDocumentation");
|
|
14496
14508
|
return {
|
|
14497
14509
|
searchTerm: external_exports.string().describe(d.searchTerm),
|
|
14498
|
-
maxResults: external_exports.number().describe(d.maxResults).min(1).max(
|
|
14510
|
+
maxResults: external_exports.number().describe(d.maxResults).min(1).max(17).optional().default(17),
|
|
14499
14511
|
reason: external_exports.string().describe(d.reason)
|
|
14500
14512
|
};
|
|
14501
14513
|
})(),
|
|
@@ -14510,9 +14522,12 @@ var addDocsTools = (server, allowedTools = [
|
|
|
14510
14522
|
toolParams: {
|
|
14511
14523
|
searchTerm
|
|
14512
14524
|
},
|
|
14513
|
-
maxResults: Math.max(1, Math.min(maxResults ??
|
|
14525
|
+
maxResults: Math.max(1, Math.min(maxResults ?? 17, 17)),
|
|
14514
14526
|
linesInEachResult: 30,
|
|
14515
|
-
usePlatformizedSearch
|
|
14527
|
+
usePlatformizedSearch,
|
|
14528
|
+
// Merge recipes/skills into the REST ranking — they live in a
|
|
14529
|
+
// separate corpus the REST document_type doesn't cover on its own.
|
|
14530
|
+
extraDocumentTypes: ["SKILLS"]
|
|
14516
14531
|
});
|
|
14517
14532
|
const grounding = result.includes(QUERY_CAPABILITY_MARKER) ? [
|
|
14518
14533
|
REST_SEARCH_API_GROUNDING_REMINDER,
|
|
@@ -14775,7 +14790,7 @@ var addDocsTools = (server, allowedTools = [
|
|
|
14775
14790
|
const d = desc("SearchWixHeadlessDocumentation");
|
|
14776
14791
|
return {
|
|
14777
14792
|
searchTerm: external_exports.string().describe(d.searchTerm),
|
|
14778
|
-
maxResults: external_exports.number().describe(d.maxResults).min(1).max(
|
|
14793
|
+
maxResults: external_exports.number().describe(d.maxResults).min(1).max(17).optional().default(17)
|
|
14779
14794
|
};
|
|
14780
14795
|
})(),
|
|
14781
14796
|
{ readOnlyHint: true, destructiveHint: false, openWorldHint: false },
|
|
@@ -14787,8 +14802,11 @@ var addDocsTools = (server, allowedTools = [
|
|
|
14787
14802
|
toolParams: {
|
|
14788
14803
|
searchTerm
|
|
14789
14804
|
},
|
|
14790
|
-
maxResults: Math.max(1, Math.min(maxResults ??
|
|
14791
|
-
usePlatformizedSearch
|
|
14805
|
+
maxResults: Math.max(1, Math.min(maxResults ?? 17, 17)),
|
|
14806
|
+
usePlatformizedSearch,
|
|
14807
|
+
// Merge recipes/skills into the headless ranking — same separate
|
|
14808
|
+
// corpus the WIX_HEADLESS document_type doesn't cover on its own.
|
|
14809
|
+
extraDocumentTypes: ["SKILLS"]
|
|
14792
14810
|
});
|
|
14793
14811
|
return {
|
|
14794
14812
|
content: [
|
|
@@ -16705,6 +16723,189 @@ ${text.slice(0, 2e3)}`
|
|
|
16705
16723
|
);
|
|
16706
16724
|
}
|
|
16707
16725
|
|
|
16726
|
+
// src/code-mode/attachments.ts
|
|
16727
|
+
var MAX_ATTACHMENTS_BYTES = 10 * 1024 * 1024;
|
|
16728
|
+
var MAX_REDIRECTS = 4;
|
|
16729
|
+
var OAI_USERCONTENT_HOST = /^[a-z0-9-]+\.oaiusercontent\.com$/;
|
|
16730
|
+
var OAI_BLOB_ACCOUNTS = new Set(
|
|
16731
|
+
[
|
|
16732
|
+
"australiaeast",
|
|
16733
|
+
"brazilsouth",
|
|
16734
|
+
"cacentral",
|
|
16735
|
+
"centralindia",
|
|
16736
|
+
"centralus",
|
|
16737
|
+
"centralusdr",
|
|
16738
|
+
"denmarkeast",
|
|
16739
|
+
"eastus",
|
|
16740
|
+
"eastus2",
|
|
16741
|
+
"indiasocentral",
|
|
16742
|
+
"italynorth",
|
|
16743
|
+
"japaneast",
|
|
16744
|
+
"koreacentral",
|
|
16745
|
+
"northcentralus",
|
|
16746
|
+
"northeu",
|
|
16747
|
+
"nznorth",
|
|
16748
|
+
"polandcentral",
|
|
16749
|
+
"seasia",
|
|
16750
|
+
"southcentralus",
|
|
16751
|
+
"southeastus3",
|
|
16752
|
+
"ukwest",
|
|
16753
|
+
"westcentralus",
|
|
16754
|
+
"westus",
|
|
16755
|
+
"westus2",
|
|
16756
|
+
"westus3"
|
|
16757
|
+
].map((region) => `oaisdmntpr${region}.blob.core.windows.net`)
|
|
16758
|
+
);
|
|
16759
|
+
function isAllowedAttachmentHost(hostname) {
|
|
16760
|
+
const h = hostname.toLowerCase();
|
|
16761
|
+
return OAI_USERCONTENT_HOST.test(h) || OAI_BLOB_ACCOUNTS.has(h);
|
|
16762
|
+
}
|
|
16763
|
+
function checkAttachmentUrl(url) {
|
|
16764
|
+
if (url.protocol !== "https:") return "is not an https URL";
|
|
16765
|
+
if (url.port) return "uses a non-default port";
|
|
16766
|
+
if (!isAllowedAttachmentHost(url.hostname)) {
|
|
16767
|
+
return `host "${url.hostname}" is not a ChatGPT file host`;
|
|
16768
|
+
}
|
|
16769
|
+
return void 0;
|
|
16770
|
+
}
|
|
16771
|
+
var AttachmentError = class extends Error {
|
|
16772
|
+
};
|
|
16773
|
+
function attachmentPath(a, url) {
|
|
16774
|
+
let fromUrl = "";
|
|
16775
|
+
try {
|
|
16776
|
+
fromUrl = decodeURIComponent(
|
|
16777
|
+
url.pathname.split("/").filter(Boolean).pop() ?? ""
|
|
16778
|
+
);
|
|
16779
|
+
} catch {
|
|
16780
|
+
fromUrl = "";
|
|
16781
|
+
}
|
|
16782
|
+
const raw = (a.file_name?.trim() || fromUrl || a.file_id).replace(/\\/g, "/");
|
|
16783
|
+
const segments = raw.split("/").filter((s) => s && s !== "." && s !== "..");
|
|
16784
|
+
return segments.join("/") || a.file_id;
|
|
16785
|
+
}
|
|
16786
|
+
function toBase64(bytes) {
|
|
16787
|
+
let binary = "";
|
|
16788
|
+
const chunk = 32768;
|
|
16789
|
+
for (let i = 0; i < bytes.length; i += chunk) {
|
|
16790
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
|
16791
|
+
}
|
|
16792
|
+
return btoa(binary);
|
|
16793
|
+
}
|
|
16794
|
+
async function fetchAllowed(start, fetchImpl, label) {
|
|
16795
|
+
let url = start;
|
|
16796
|
+
for (let hop = 0; ; hop++) {
|
|
16797
|
+
const res = await fetchImpl(url.toString(), { redirect: "manual" });
|
|
16798
|
+
const location = res.headers.get("location");
|
|
16799
|
+
const isRedirect = res.status >= 300 && res.status < 400 && location;
|
|
16800
|
+
if (!isRedirect) return res;
|
|
16801
|
+
await res.body?.cancel().catch(() => void 0);
|
|
16802
|
+
if (hop >= MAX_REDIRECTS) {
|
|
16803
|
+
throw new AttachmentError(`${label}: too many redirects.`);
|
|
16804
|
+
}
|
|
16805
|
+
let next;
|
|
16806
|
+
try {
|
|
16807
|
+
next = new URL(location, url);
|
|
16808
|
+
} catch {
|
|
16809
|
+
throw new AttachmentError(`${label}: redirect to an invalid URL.`);
|
|
16810
|
+
}
|
|
16811
|
+
const problem = checkAttachmentUrl(next);
|
|
16812
|
+
if (problem) {
|
|
16813
|
+
throw new AttachmentError(
|
|
16814
|
+
`${label}: the download redirected to a URL that ${problem}; refused.`
|
|
16815
|
+
);
|
|
16816
|
+
}
|
|
16817
|
+
url = next;
|
|
16818
|
+
}
|
|
16819
|
+
}
|
|
16820
|
+
async function readWithin(res, budget, overBudget) {
|
|
16821
|
+
const declared = Number(res.headers.get("content-length") ?? 0);
|
|
16822
|
+
if (declared > budget) throw overBudget();
|
|
16823
|
+
if (!res.body) {
|
|
16824
|
+
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
16825
|
+
if (bytes.byteLength > budget) throw overBudget();
|
|
16826
|
+
return bytes;
|
|
16827
|
+
}
|
|
16828
|
+
const reader = res.body.getReader();
|
|
16829
|
+
const chunks = [];
|
|
16830
|
+
let total = 0;
|
|
16831
|
+
for (; ; ) {
|
|
16832
|
+
const { done, value } = await reader.read();
|
|
16833
|
+
if (done) break;
|
|
16834
|
+
total += value.byteLength;
|
|
16835
|
+
if (total > budget) {
|
|
16836
|
+
await reader.cancel().catch(() => void 0);
|
|
16837
|
+
throw overBudget();
|
|
16838
|
+
}
|
|
16839
|
+
chunks.push(value);
|
|
16840
|
+
}
|
|
16841
|
+
const out = new Uint8Array(total);
|
|
16842
|
+
let offset = 0;
|
|
16843
|
+
for (const c of chunks) {
|
|
16844
|
+
out.set(c, offset);
|
|
16845
|
+
offset += c.byteLength;
|
|
16846
|
+
}
|
|
16847
|
+
return out;
|
|
16848
|
+
}
|
|
16849
|
+
async function resolveAttachments(attachments, fetchImpl = fetch) {
|
|
16850
|
+
if (!Array.isArray(attachments) || attachments.length === 0) return [];
|
|
16851
|
+
const items = [];
|
|
16852
|
+
attachments.forEach((raw, i) => {
|
|
16853
|
+
const a = typeof raw === "object" && raw;
|
|
16854
|
+
const downloadUrl = a && typeof a.download_url === "string" ? a.download_url : "";
|
|
16855
|
+
let url;
|
|
16856
|
+
try {
|
|
16857
|
+
url = /^https?:\/\//i.test(downloadUrl) ? new URL(downloadUrl) : void 0;
|
|
16858
|
+
} catch {
|
|
16859
|
+
url = void 0;
|
|
16860
|
+
}
|
|
16861
|
+
if (!a || !url) {
|
|
16862
|
+
throw new AttachmentError(
|
|
16863
|
+
`attachments[${i}] was not resolved to a download URL (got ${JSON.stringify(
|
|
16864
|
+
typeof raw === "string" ? raw : (a && a.download_url) ?? raw
|
|
16865
|
+
)}). The platform did not hydrate this attachment; retry once, and if it still arrives like this put the file in the \`files\` bundle instead (\`=== FILE: <path> base64 ===\` for binary).`
|
|
16866
|
+
);
|
|
16867
|
+
}
|
|
16868
|
+
const problem = checkAttachmentUrl(url);
|
|
16869
|
+
if (problem) {
|
|
16870
|
+
throw new AttachmentError(
|
|
16871
|
+
`attachments[${i}].download_url ${problem}. Only platform-resolved attachments are accepted here; for any other URL fetch it in \`code\` via wix.request or put the bytes in the \`files\` bundle.`
|
|
16872
|
+
);
|
|
16873
|
+
}
|
|
16874
|
+
items.push({ a, url });
|
|
16875
|
+
});
|
|
16876
|
+
let remaining = MAX_ATTACHMENTS_BYTES;
|
|
16877
|
+
const out = [];
|
|
16878
|
+
for (const [i, { a, url }] of items.entries()) {
|
|
16879
|
+
const path = attachmentPath(a, url);
|
|
16880
|
+
const label = `attachments[${i}] (${path})`;
|
|
16881
|
+
let res;
|
|
16882
|
+
try {
|
|
16883
|
+
res = await fetchAllowed(url, fetchImpl, label);
|
|
16884
|
+
} catch (e) {
|
|
16885
|
+
if (e instanceof AttachmentError) throw e;
|
|
16886
|
+
throw new AttachmentError(
|
|
16887
|
+
`${label}: download failed (${e.message}).`
|
|
16888
|
+
);
|
|
16889
|
+
}
|
|
16890
|
+
if (!res.ok) {
|
|
16891
|
+
await res.body?.cancel().catch(() => void 0);
|
|
16892
|
+
throw new AttachmentError(
|
|
16893
|
+
`${label}: download returned HTTP ${res.status}. The download_url may have expired; attach the file again.`
|
|
16894
|
+
);
|
|
16895
|
+
}
|
|
16896
|
+
const bytes = await readWithin(
|
|
16897
|
+
res,
|
|
16898
|
+
remaining,
|
|
16899
|
+
() => new AttachmentError(
|
|
16900
|
+
`${label} pushes the attachments past ${MAX_ATTACHMENTS_BYTES} bytes in total for this call; split the upload across calls.`
|
|
16901
|
+
)
|
|
16902
|
+
);
|
|
16903
|
+
remaining -= bytes.byteLength;
|
|
16904
|
+
out.push({ path, content: toBase64(bytes), encoding: "base64" });
|
|
16905
|
+
}
|
|
16906
|
+
return out;
|
|
16907
|
+
}
|
|
16908
|
+
|
|
16708
16909
|
// src/code-mode/validation.ts
|
|
16709
16910
|
var EXECUTE_FUNCTION_EXPRESSION_HINT = 'ExecuteWixAPI code must be a function expression, not a script body. Pass code like: async () => { const response = await wix.request({ scope: "site", method: "GET", url: "https://www.wixapis.com/..." }); return response.data; }. Do not write top-level const/await/return outside the function and do not invoke the function yourself.';
|
|
16710
16911
|
function validateExecuteCode(code) {
|
|
@@ -16916,7 +17117,7 @@ function addExecuteTool(server, options) {
|
|
|
16916
17117
|
} = options;
|
|
16917
17118
|
const executeUrl = `${codeModeBaseUrl}/api/code-mode/execute`;
|
|
16918
17119
|
const d = desc("ExecuteWixAPI");
|
|
16919
|
-
server.tool(
|
|
17120
|
+
const registered = server.tool(
|
|
16920
17121
|
EXECUTE_TOOL_NAME,
|
|
16921
17122
|
toolDescriptions?.[EXECUTE_TOOL_NAME] ?? defaultToolDescriptions.ExecuteWixAPI,
|
|
16922
17123
|
{
|
|
@@ -16945,6 +17146,20 @@ function addExecuteTool(server, options) {
|
|
|
16945
17146
|
'Use base64 entries for small assets (icons, logos, fonts) and for files you downloaded and are re-uploading; large images/video go in by URL (`<img src="https://...">`), not in the bundle. A file containing a line exactly like the delimiter is not supported.'
|
|
16946
17147
|
].join(" ")
|
|
16947
17148
|
),
|
|
17149
|
+
// ChatGPT file attachments (`openai/fileParams`). Item shape must match
|
|
17150
|
+
// OpenAI's file schema: download_url + file_id required, the rest optional.
|
|
17151
|
+
// Declaring it is what makes the platform hand us a download URL instead
|
|
17152
|
+
// of a sandbox path. Resolved host-side into base64 `files` entries.
|
|
17153
|
+
attachments: external_exports.array(
|
|
17154
|
+
external_exports.object({
|
|
17155
|
+
download_url: external_exports.string(),
|
|
17156
|
+
file_id: external_exports.string(),
|
|
17157
|
+
file_name: external_exports.string().optional(),
|
|
17158
|
+
mime_type: external_exports.string().optional()
|
|
17159
|
+
})
|
|
17160
|
+
).optional().describe(
|
|
17161
|
+
'Files attached in this chat, or files you created in your own file sandbox (any type: a zip of a site, HTML, images, PDFs). Pass the files themselves and the platform resolves each into { download_url, file_id, file_name?, mime_type? }; the bytes are fetched here and appended to the `files` global as { path, content, encoding: "base64" } entries (path = file_name), so `wix.multipart()` and `wix.unzip()` work on them unchanged. Prefer this over base64 in `files` whenever you have a file handle. Up to 10 MB per call.'
|
|
17162
|
+
),
|
|
16948
17163
|
// Visitor mode takes an agent-supplied token and pins the site; account/site
|
|
16949
17164
|
// mode lets the agent pick the site.
|
|
16950
17165
|
...visitor ? {
|
|
@@ -16959,7 +17174,15 @@ function addExecuteTool(server, options) {
|
|
|
16959
17174
|
},
|
|
16960
17175
|
{ readOnlyHint: false, destructiveHint: true, openWorldHint: false },
|
|
16961
17176
|
async (rawArgs, extra) => {
|
|
16962
|
-
const {
|
|
17177
|
+
const {
|
|
17178
|
+
code,
|
|
17179
|
+
reason,
|
|
17180
|
+
hasMutations,
|
|
17181
|
+
sourceDocUrls,
|
|
17182
|
+
visitorToken,
|
|
17183
|
+
files,
|
|
17184
|
+
attachments
|
|
17185
|
+
} = rawArgs;
|
|
16963
17186
|
const siteId = visitor ? visitor.siteId : rawArgs.siteId;
|
|
16964
17187
|
logger.log(
|
|
16965
17188
|
`[ExecuteWixAPI]${visitor ? " (visitor)" : ""} Executing code (${code.length} chars), siteId=${siteId ?? "none"}, hasMutations=${hasMutations}, sourceDocUrls=${JSON.stringify(sourceDocUrls)}, reason="${reason}"`
|
|
@@ -16971,6 +17194,13 @@ function addExecuteTool(server, options) {
|
|
|
16971
17194
|
);
|
|
16972
17195
|
return executeTextResult(validation.error);
|
|
16973
17196
|
}
|
|
17197
|
+
let attachmentFiles = [];
|
|
17198
|
+
try {
|
|
17199
|
+
attachmentFiles = await resolveAttachments(attachments);
|
|
17200
|
+
} catch (e) {
|
|
17201
|
+
if (e instanceof AttachmentError) return executeErrorResult(e.message);
|
|
17202
|
+
throw e;
|
|
17203
|
+
}
|
|
16974
17204
|
const accountHeaders = await authStrategy?.getAccountAuthHeaders();
|
|
16975
17205
|
const siteAuthContext = !visitor && authStrategy?.getSiteAuthContext ? await authStrategy.getSiteAuthContext() : void 0;
|
|
16976
17206
|
let siteHeaders;
|
|
@@ -17005,7 +17235,8 @@ function addExecuteTool(server, options) {
|
|
|
17005
17235
|
accountToken: visitor ? visitorToken : accountHeaders?.Authorization,
|
|
17006
17236
|
accountId: accountHeaders?.["wix-account-id"],
|
|
17007
17237
|
siteAuthContext,
|
|
17008
|
-
...files ? { files } : {}
|
|
17238
|
+
...files ? { files } : {},
|
|
17239
|
+
...attachmentFiles.length ? { attachmentFiles } : {}
|
|
17009
17240
|
},
|
|
17010
17241
|
visitor ? visitorToken : accountHeaders?.Authorization ?? siteHeaders?.Authorization,
|
|
17011
17242
|
codeModeFetch
|
|
@@ -17036,6 +17267,9 @@ function addExecuteTool(server, options) {
|
|
|
17036
17267
|
}
|
|
17037
17268
|
}
|
|
17038
17269
|
);
|
|
17270
|
+
registered?.update?.({
|
|
17271
|
+
_meta: { ...registered._meta, "openai/fileParams": ["attachments"] }
|
|
17272
|
+
});
|
|
17039
17273
|
}
|
|
17040
17274
|
|
|
17041
17275
|
// ../../node_modules/@wix/panorama-common-shared/dist/esm/types/enum-types.js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.93",
|
|
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": "
|
|
136
|
+
"falconPackageHash": "416cbd091ed4f59d7a920a4a98434246c6a211bf9c981dd78ad9a627"
|
|
137
137
|
}
|