@wix/mcp 1.0.79 → 1.0.81
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/README.md +1 -1
- package/build/bin-standalone.js +94 -36
- package/build/cjs/index.cjs +449 -459
- package/build/cjs/toolkit.cjs +112 -44
- package/build/dts/account-tools/get-profile-tool.d.ts +5 -0
- package/build/dts/account-tools/get-profile-tool.js +49 -0
- package/build/dts/api-call/index.js +41 -3
- package/build/dts/code-mode/index.js +8 -2
- package/build/dts/config/api-request-rules.d.ts +11 -0
- package/build/dts/config/api-request-rules.js +11 -0
- package/build/dts/config/default-config.d.ts +2 -2
- package/build/dts/config/default-config.js +19 -9
- package/build/dts/config/param-descriptions.d.ts +1 -1
- package/build/dts/config/param-descriptions.js +5 -3
- package/build/dts/docs/docs.js +6 -6
- package/build/dts/index.d.ts +1 -0
- package/build/dts/index.js +1 -0
- package/build/dts/infra/tool-bi.d.ts +1 -1
- package/build/dts/infra/tool-bi.js +3 -2
- package/build/dts/toolkit-entry.d.cts +3 -1
- package/build/dts/toolkit-entry.d.ts +3 -1
- package/build/dts/toolkit.d.ts +2 -0
- package/build/dts/toolkit.js +18 -21
- package/build/dts/wix-mcp-server.d.ts +2 -0
- package/build/dts/wix-mcp-server.js +4 -1
- package/build/dts/wixel/api.d.ts +0 -60
- package/build/dts/wixel/api.js +1 -50
- package/build/dts/wixel/constants.d.ts +0 -1
- package/build/dts/wixel/constants.js +0 -1
- package/build/dts/wixel/index.d.ts +0 -3
- package/build/dts/wixel/index.js +0 -9
- package/build/esm/index.js +367 -401
- package/build/esm/toolkit.js +112 -44
- package/package.json +4 -3
- package/build/dts/wixel/open-headless-wixel-project-tool.d.ts +0 -6
- package/build/dts/wixel/open-headless-wixel-project-tool.js +0 -84
- package/build/dts/wixel/pull-headless-wixel-job-tool.d.ts +0 -6
- package/build/dts/wixel/pull-headless-wixel-job-tool.js +0 -61
- package/build/dts/wixel/update-headless-wixel-job-tool.d.ts +0 -6
- package/build/dts/wixel/update-headless-wixel-job-tool.js +0 -106
package/build/cjs/toolkit.cjs
CHANGED
|
@@ -17648,6 +17648,9 @@ function rethrowIfUnauthorized(error) {
|
|
|
17648
17648
|
}
|
|
17649
17649
|
}
|
|
17650
17650
|
|
|
17651
|
+
// src/config/api-request-rules.ts
|
|
17652
|
+
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).";
|
|
17653
|
+
|
|
17651
17654
|
// src/config/default-config.ts
|
|
17652
17655
|
var AGENT_GOAL = dedent_default`
|
|
17653
17656
|
You are an agent that helps the user manage their Wix site.
|
|
@@ -17658,7 +17661,7 @@ var DISCOVERY_FLOWS = [
|
|
|
17658
17661
|
"- METHOD CODE EXAMPLE BASED: BrowseWixRESTDocsMenu() or SearchWixRESTDocumentation() -> find relevant method -> read method article using ReadFullDocsArticle() to get method code examples -> call API using CallWixSiteAPI() based on the method code examples",
|
|
17659
17662
|
"- FULL SCHEMA BASED: BrowseWixRESTDocsMenu() or SearchWixRESTDocumentation() -> find relevant method -> read method article using ReadFullDocsArticle() -> no method code examples found -> inspect the method schema using SearchWixAPISpec or ReadFullDocsMethodSchema -> call API using CallWixSiteAPI() based on the schema"
|
|
17660
17663
|
];
|
|
17661
|
-
function buildSystemReminderGuidelines(includeReadme) {
|
|
17664
|
+
function buildSystemReminderGuidelines(includeReadme, includeImageUploadGuidance) {
|
|
17662
17665
|
const exception = includeReadme ? "**Exception:** " : "";
|
|
17663
17666
|
const lines = [];
|
|
17664
17667
|
if (includeReadme) {
|
|
@@ -17670,9 +17673,13 @@ function buildSystemReminderGuidelines(includeReadme) {
|
|
|
17670
17673
|
);
|
|
17671
17674
|
}
|
|
17672
17675
|
lines.push(
|
|
17673
|
-
`${exception}If the user asks to list, show, or find their Wix sites, ${includeReadme ? "skip WixREADME and " : ""}call ListWixSites directly
|
|
17674
|
-
`${exception}If the user wants to upload local or attached image files to a Wix site, skip ${includeReadme ? "WixREADME and " : ""}all docs/schema/API flows \u2014 call UploadImageToWixSite directly. Do NOT use ExecuteWixAPI, SearchWixAPISpec, or any Media Manager REST API for image uploads.`
|
|
17676
|
+
`${exception}If the user asks to list, show, or find their Wix sites, ${includeReadme ? "skip WixREADME and " : ""}call ListWixSites directly.`
|
|
17675
17677
|
);
|
|
17678
|
+
if (includeImageUploadGuidance) {
|
|
17679
|
+
lines.push(
|
|
17680
|
+
`${exception}If the user wants to upload local or attached image files to a Wix site, skip ${includeReadme ? "WixREADME and " : ""}all docs/schema/API flows \u2014 call UploadImageToWixSite directly. Do NOT use ExecuteWixAPI, SearchWixAPISpec, or any Media Manager REST API for image uploads.`
|
|
17681
|
+
);
|
|
17682
|
+
}
|
|
17676
17683
|
if (includeReadme) {
|
|
17677
17684
|
lines.push(
|
|
17678
17685
|
"If the WixREADME tool is not available to you, you should use the other flows as described without using the WixREADME tool until the task is completed."
|
|
@@ -17699,9 +17706,15 @@ function buildSystemReminderFlows(includeReadme) {
|
|
|
17699
17706
|
lines.push(...DISCOVERY_FLOWS);
|
|
17700
17707
|
return lines.join("\n");
|
|
17701
17708
|
}
|
|
17702
|
-
var SYSTEM_REMINDER_GUIDELINES = buildSystemReminderGuidelines(
|
|
17703
|
-
|
|
17704
|
-
|
|
17709
|
+
var SYSTEM_REMINDER_GUIDELINES = buildSystemReminderGuidelines(
|
|
17710
|
+
true,
|
|
17711
|
+
true
|
|
17712
|
+
);
|
|
17713
|
+
function buildSystemReminder(includeReadme, includeImageUploadGuidance = true) {
|
|
17714
|
+
const guidelines = buildSystemReminderGuidelines(
|
|
17715
|
+
includeReadme,
|
|
17716
|
+
includeImageUploadGuidance
|
|
17717
|
+
);
|
|
17705
17718
|
const flows = buildSystemReminderFlows(includeReadme);
|
|
17706
17719
|
return dedent_default`
|
|
17707
17720
|
<agent-mandatory-instructions>
|
|
@@ -17759,11 +17772,13 @@ var EXECUTE_WIX_API_INTRO = dedent_default`
|
|
|
17759
17772
|
CODE CONTRACT:
|
|
17760
17773
|
- Pass an async function expression: \`async function() { ... }\` or \`async () => { ... }\`. Put every declaration, \`await\`, and \`return\` inside it, and do not invoke it yourself.
|
|
17761
17774
|
- Use only \`wix.request({ method, url, body })\` and in-memory JavaScript. Node.js modules, filesystem access, and downloadable-file creation are unavailable.
|
|
17775
|
+
- Do not minify the code. Put each object property on its own line, with spaces after colons and commas, and declare deep literals (request bodies, filters, patch lists) as a named \`const\` before use so each \`wix.request({ ... })\` argument stays short.
|
|
17762
17776
|
|
|
17763
17777
|
CONFIRM API CONTRACTS:
|
|
17764
17778
|
- Do not rely on memory for endpoints, methods, bodies, response paths, filters, enum values, or auth scope. Confirm every method from conversation-provided details, a complete matching docs example, or the schema/docs tools before executing.
|
|
17765
17779
|
- Prefer \`method.publicUrl\` from SearchWixAPISpec; never use \`method.servers[0]\`. Pass all supporting documentation URLs through \`sourceDocUrls\`.
|
|
17766
17780
|
- A response field is not automatically filterable or sortable. Use only capabilities declared for that exact query/search method. If an unsupported filter is unavoidable, fetch a bounded result set and filter it in code.
|
|
17781
|
+
- ${ARRAY_QUERY_PARAMS_RULE}
|
|
17767
17782
|
- Read-only probes may inspect state or resolve IDs. Never use speculative create/update/delete calls to discover request or response shapes, and never repeat a successful mutation merely to obtain more response data.
|
|
17768
17783
|
`;
|
|
17769
17784
|
var EXECUTE_WIX_API_OUTPUT_AND_ERRORS = dedent_default`
|
|
@@ -17779,6 +17794,7 @@ var ACCOUNT_SITE_EXECUTE_SCOPE = dedent_default`
|
|
|
17779
17794
|
SCOPE AND SITE TARGETING:
|
|
17780
17795
|
- Set \`scope: "site"\` for site-level APIs and \`scope: "account"\` for account-level APIs. Account-level acts on the account itself, or on sites as objects within it; anything that reads or writes inside a site is site-level.
|
|
17781
17796
|
- If \`scope\` is omitted it defaults to site when either the ExecuteWixAPI call or \`wix.request\` provides a \`siteId\`; otherwise it defaults to account.
|
|
17797
|
+
- Site-level calls need a site ID; there is no implicit current site. Before any \`scope: "site"\` call, pass the site's ID as the ExecuteWixAPI \`siteId\` parameter or per request. \`scope: "site"\` without a \`siteId\` fails.
|
|
17782
17798
|
- \`scope: "account"\` ignores any \`siteId\` you pass, so a site-level endpoint called that way fails.
|
|
17783
17799
|
- Authentication is injected automatically; never set Authorization, wix-site-id, or wix-account-id headers.
|
|
17784
17800
|
- For one named site, prefer GetSiteContext. If it is unavailable, resolve the exact site and perform the action in the same invocation.
|
|
@@ -17912,8 +17928,11 @@ var executeWixApiDescription = dedent_default`
|
|
|
17912
17928
|
|
|
17913
17929
|
${EXECUTE_WIX_API_MULTI_SITE_EXAMPLE}
|
|
17914
17930
|
`;
|
|
17915
|
-
function buildToolDescriptions(includeReadme) {
|
|
17916
|
-
const reminder = buildSystemReminder(
|
|
17931
|
+
function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true) {
|
|
17932
|
+
const reminder = buildSystemReminder(
|
|
17933
|
+
includeReadme,
|
|
17934
|
+
includeImageUploadGuidance
|
|
17935
|
+
);
|
|
17917
17936
|
return {
|
|
17918
17937
|
WixREADME: dedent_default`
|
|
17919
17938
|
# Tool: WixREADME
|
|
@@ -17964,6 +17983,7 @@ function buildToolDescriptions(includeReadme) {
|
|
|
17964
17983
|
**Prefer this tool over CallWixSiteAPI for listing sites.** Call this tool directly — it already knows the correct API and handles everything needed. Only fall back to CallWixSiteAPI if the user needs advanced filtering or specific site details beyond what this tool provides.
|
|
17965
17984
|
${reminder}
|
|
17966
17985
|
`,
|
|
17986
|
+
get_profile: "Returns the authenticated user's email address",
|
|
17967
17987
|
GetSiteContext: dedent_default`
|
|
17968
17988
|
Fetches deep context for a specific Wix site and returns it as structured markdown.
|
|
17969
17989
|
|
|
@@ -18095,8 +18115,10 @@ function buildToolDescriptions(includeReadme) {
|
|
|
18095
18115
|
SearchBuildAppsDocumentation: dedent_default`
|
|
18096
18116
|
Searches the Wix Build Apps documentation.
|
|
18097
18117
|
`,
|
|
18098
|
-
|
|
18099
|
-
|
|
18118
|
+
SearchDevelopmentDocumentation: dedent_default`
|
|
18119
|
+
Broad Wix development documentation (platform concepts, developer guides, getting started). **Last resort — development tasks only.**
|
|
18120
|
+
Skip it entirely for general, business, support, or Wix-editor questions.
|
|
18121
|
+
Call it only after the specific search for your task returned nothing useful: \`SearchWixRESTDocumentation\` (REST), \`SearchWixSDKDocumentation\` (JS SDK), \`SearchWixCLIDocumentation\` (CLI), \`SearchBuildAppsDocumentation\` (apps), \`SearchWixHeadlessDocumentation\` (Headless), \`SearchWixWDSDocumentation\` (WDS). Never use it as a first search.
|
|
18100
18122
|
`,
|
|
18101
18123
|
SearchWixHeadlessDocumentation: dedent_default`
|
|
18102
18124
|
Searches the Wix Headless documentation.
|
|
@@ -18748,14 +18770,20 @@ function renderApps(apps, knownApps) {
|
|
|
18748
18770
|
}
|
|
18749
18771
|
function renderProperties(props) {
|
|
18750
18772
|
const sections = [];
|
|
18751
|
-
const
|
|
18752
|
-
if (props.language)
|
|
18753
|
-
if (props.locale?.country)
|
|
18754
|
-
|
|
18755
|
-
if (props.
|
|
18756
|
-
if (
|
|
18757
|
-
|
|
18758
|
-
|
|
18773
|
+
const regionalFormat = [];
|
|
18774
|
+
if (props.language) regionalFormat.push(`- Language: **${props.language}**`);
|
|
18775
|
+
if (props.locale?.country)
|
|
18776
|
+
regionalFormat.push(`- Locale region: **${props.locale.country}**`);
|
|
18777
|
+
if (props.timeZone) regionalFormat.push(`- Timezone: **${props.timeZone}**`);
|
|
18778
|
+
if (props.paymentCurrency)
|
|
18779
|
+
regionalFormat.push(`- Currency: **${props.paymentCurrency}**`);
|
|
18780
|
+
if (regionalFormat.length) {
|
|
18781
|
+
sections.push(`**Regional Format**
|
|
18782
|
+
${regionalFormat.join("\n")}`);
|
|
18783
|
+
}
|
|
18784
|
+
if (props.address?.country) {
|
|
18785
|
+
sections.push(`**Location**
|
|
18786
|
+
- Country: **${props.address.country}**`);
|
|
18759
18787
|
}
|
|
18760
18788
|
const contact = [];
|
|
18761
18789
|
if (props.email) contact.push(`- Email: **${props.email}**`);
|
|
@@ -18902,6 +18930,7 @@ var known_apps_default = {
|
|
|
18902
18930
|
"225dd912-7dea-4738-8688-4b8c6955ffc2": "Wix Forms",
|
|
18903
18931
|
"d80111c5-a0f4-47a8-b63a-65b54d774a27": "Wix Gift Cards",
|
|
18904
18932
|
"148c2287-c669-d849-d153-463c7486a694": "Wix Groups",
|
|
18933
|
+
"14bca956-e09f-f4d6-14d7-466cb3f09103": "Wix Hotels",
|
|
18905
18934
|
"13ee94c1-b635-8505-3391-97919052c16f": "Wix Invoices",
|
|
18906
18935
|
"14cc59bc-f0b7-15b8-e1c7-89ce41d0e0c9": "Wix Members Area",
|
|
18907
18936
|
"14d84998-ae09-1abf-c6fc-3f3cace5bf19": "Wix Multilingual",
|
|
@@ -18936,8 +18965,8 @@ async function getDynamicContext(auth, httpClient, filter, options) {
|
|
|
18936
18965
|
partnerContextEnabled: options,
|
|
18937
18966
|
includeAccountContext: options
|
|
18938
18967
|
} : options;
|
|
18939
|
-
const includePartnerContext = contextOptions?.partnerContextEnabled ??
|
|
18940
|
-
const includeAccountContext = contextOptions?.includeAccountContext ??
|
|
18968
|
+
const includePartnerContext = contextOptions?.partnerContextEnabled ?? true;
|
|
18969
|
+
const includeAccountContext = contextOptions?.includeAccountContext ?? true;
|
|
18941
18970
|
try {
|
|
18942
18971
|
const accountHeaders = await auth.getAccountAuthHeaders();
|
|
18943
18972
|
const noFilter = !filter?.siteId && !filter?.siteName;
|
|
@@ -19051,7 +19080,8 @@ var paramDescriptions = {
|
|
|
19051
19080
|
"The url of the api to call - ALWAYS get the API url from the Wix REST docs or from the conversation context, the URL MUST BE ABSOLUTE URL",
|
|
19052
19081
|
'NEVER guess the API url, ALWAYS get it from the conversation context, i.e from the user prompt or from the "WixREADME" tool or from the "SearchWixRESTDocumentation" tool or from the "BrowseWixRESTDocsMenu" tool or from the "ReadFullDocsArticle" tool',
|
|
19053
19082
|
`Allowed API urls are: ${ALLOWED_HOSTNAMES.join(", ")}`,
|
|
19054
|
-
`Docs urls like https://dev.wix.com/docs/... are not API urls, if you want to read the docs, use the "ReadFullDocsArticle" tool
|
|
19083
|
+
`Docs urls like https://dev.wix.com/docs/... are not API urls, if you want to read the docs, use the "ReadFullDocsArticle" tool`,
|
|
19084
|
+
ARRAY_QUERY_PARAMS_RULE
|
|
19055
19085
|
].join("\n"),
|
|
19056
19086
|
method: "The HTTP method to use for the API call (e.g. GET, POST, PUT, DELETE)",
|
|
19057
19087
|
body: '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.',
|
|
@@ -19124,8 +19154,8 @@ var paramDescriptions = {
|
|
|
19124
19154
|
searchTerm: "The search term to search for in the Build Apps Documentation",
|
|
19125
19155
|
maxResults: "The maximum number of results to return, default is 10, max is 15"
|
|
19126
19156
|
},
|
|
19127
|
-
|
|
19128
|
-
searchTerm: "The search term
|
|
19157
|
+
SearchDevelopmentDocumentation: {
|
|
19158
|
+
searchTerm: "The development-related search term. Use only after a more specific docs search (REST/SDK/CLI/Build Apps/Headless/WDS) came back empty.",
|
|
19129
19159
|
maxResults: "The maximum number of results to return, default is 10, max is 15"
|
|
19130
19160
|
},
|
|
19131
19161
|
SearchWixHeadlessDocumentation: {
|
|
@@ -19921,15 +19951,15 @@ var addDocsTools = (server, allowedTools = [
|
|
|
19921
19951
|
}
|
|
19922
19952
|
);
|
|
19923
19953
|
}
|
|
19924
|
-
if (allowedTools.includes("OVERVIEW") && !disableTools?.includes("
|
|
19954
|
+
if (allowedTools.includes("OVERVIEW") && !disableTools?.includes("SearchDevelopmentDocumentation")) {
|
|
19925
19955
|
server.tool(
|
|
19926
|
-
"
|
|
19956
|
+
"SearchDevelopmentDocumentation",
|
|
19927
19957
|
getDescription(
|
|
19928
|
-
"
|
|
19929
|
-
defaultToolDescriptions.
|
|
19958
|
+
"SearchDevelopmentDocumentation",
|
|
19959
|
+
defaultToolDescriptions.SearchDevelopmentDocumentation ?? ""
|
|
19930
19960
|
),
|
|
19931
19961
|
(() => {
|
|
19932
|
-
const d = desc("
|
|
19962
|
+
const d = desc("SearchDevelopmentDocumentation");
|
|
19933
19963
|
return {
|
|
19934
19964
|
searchTerm: external_exports.string().describe(d.searchTerm),
|
|
19935
19965
|
maxResults: external_exports.number().describe(d.maxResults).min(1).max(15).optional().default(15)
|
|
@@ -19959,8 +19989,8 @@ var addDocsTools = (server, allowedTools = [
|
|
|
19959
19989
|
panorama.errorMonitor().reportError(error);
|
|
19960
19990
|
captureException(error, {
|
|
19961
19991
|
tags: {
|
|
19962
|
-
componentId: "
|
|
19963
|
-
toolName: "
|
|
19992
|
+
componentId: "SearchDevelopmentDocumentation",
|
|
19993
|
+
toolName: "SearchDevelopmentDocumentation"
|
|
19964
19994
|
}
|
|
19965
19995
|
});
|
|
19966
19996
|
logger.error(
|
|
@@ -20824,6 +20854,19 @@ var MAX_ALLOWED_RESPONSE_CHARS = 2e6;
|
|
|
20824
20854
|
|
|
20825
20855
|
// src/api-call/index.ts
|
|
20826
20856
|
var DEFAULT_MAX_RESPONSE_SIZE = 5e4;
|
|
20857
|
+
function extractReturnedRows(responseData) {
|
|
20858
|
+
if (responseData === null || typeof responseData !== "object") {
|
|
20859
|
+
return void 0;
|
|
20860
|
+
}
|
|
20861
|
+
const data = responseData;
|
|
20862
|
+
const block = data.pagingMetadata ?? data.cursorPagingMetadata ?? data.pagingOffsetMetadata ?? data.metaData ?? data.metadata;
|
|
20863
|
+
const raw = block?.count;
|
|
20864
|
+
if (typeof raw !== "number" && (typeof raw !== "string" || raw.trim() === "")) {
|
|
20865
|
+
return void 0;
|
|
20866
|
+
}
|
|
20867
|
+
const count = Number(raw);
|
|
20868
|
+
return Number.isFinite(count) ? count : void 0;
|
|
20869
|
+
}
|
|
20827
20870
|
function formatApiResponse(responseData, maxResponseSize = DEFAULT_MAX_RESPONSE_SIZE) {
|
|
20828
20871
|
if (typeof responseData === "string" && responseData.trim().startsWith("<!DOCTYPE")) {
|
|
20829
20872
|
return {
|
|
@@ -20831,13 +20874,15 @@ function formatApiResponse(responseData, maxResponseSize = DEFAULT_MAX_RESPONSE_
|
|
|
20831
20874
|
isError: true
|
|
20832
20875
|
};
|
|
20833
20876
|
}
|
|
20877
|
+
const returnedRows = extractReturnedRows(responseData);
|
|
20834
20878
|
let responseText = JSON.stringify(responseData);
|
|
20879
|
+
const originalLength = responseText.length;
|
|
20835
20880
|
const effectiveMax = Math.min(maxResponseSize, MAX_ALLOWED_RESPONSE_CHARS);
|
|
20836
20881
|
if (responseText.length > effectiveMax) {
|
|
20837
20882
|
responseText = responseText.slice(0, effectiveMax) + `
|
|
20838
20883
|
...[TRUNCATED - response was ${responseText.length} chars, showing first ${effectiveMax}]`;
|
|
20839
20884
|
}
|
|
20840
|
-
return { text: responseText, isError: false };
|
|
20885
|
+
return { text: responseText, isError: false, originalLength, returnedRows };
|
|
20841
20886
|
}
|
|
20842
20887
|
function addApiCallTool(server, strategy, allowedTools = ["CallWixSiteAPI", "ListWixSites", "ManageWixSite"], disableTools = [], enableTools = [], toolDescriptions, toolHints, maxResponseSize) {
|
|
20843
20888
|
const effectiveAllowedTools = [
|
|
@@ -20900,9 +20945,14 @@ function addApiCallTool(server, strategy, allowedTools = ["CallWixSiteAPI", "Lis
|
|
|
20900
20945
|
data: method === "GET" ? void 0 : body
|
|
20901
20946
|
});
|
|
20902
20947
|
const requestId = response.headers?.["x-wix-request-id"];
|
|
20903
|
-
setToolBiParams({ requestId, siteId });
|
|
20904
20948
|
const responseData = await handleWixAPIResponse(response);
|
|
20905
20949
|
const formatted = formatApiResponse(responseData, maxResponseSize);
|
|
20950
|
+
setToolBiParams({
|
|
20951
|
+
requestId,
|
|
20952
|
+
siteId,
|
|
20953
|
+
returnedRows: formatted.returnedRows,
|
|
20954
|
+
originalLength: formatted.originalLength
|
|
20955
|
+
});
|
|
20906
20956
|
if (formatted.isError) {
|
|
20907
20957
|
return {
|
|
20908
20958
|
content: [
|
|
@@ -21041,7 +21091,7 @@ function addApiCallTool(server, strategy, allowedTools = ["CallWixSiteAPI", "Lis
|
|
|
21041
21091
|
destructiveHint: true,
|
|
21042
21092
|
openWorldHint: false
|
|
21043
21093
|
}),
|
|
21044
|
-
async ({ url, body, method, reason }, { httpClient }) => {
|
|
21094
|
+
async ({ url, body, method, reason }, { httpClient, setToolBiParams }) => {
|
|
21045
21095
|
logger.log(
|
|
21046
21096
|
`Calling Wix Account level API: ${url}, reason="${reason}", body: ${JSON.stringify(body)}`
|
|
21047
21097
|
);
|
|
@@ -21070,6 +21120,10 @@ function addApiCallTool(server, strategy, allowedTools = ["CallWixSiteAPI", "Lis
|
|
|
21070
21120
|
});
|
|
21071
21121
|
const responseData = await handleWixAPIResponse(response);
|
|
21072
21122
|
const formatted = formatApiResponse(responseData, maxResponseSize);
|
|
21123
|
+
setToolBiParams({
|
|
21124
|
+
returnedRows: formatted.returnedRows,
|
|
21125
|
+
originalLength: formatted.originalLength
|
|
21126
|
+
});
|
|
21073
21127
|
if (formatted.isError) {
|
|
21074
21128
|
return {
|
|
21075
21129
|
content: [
|
|
@@ -21292,10 +21346,13 @@ function executeTextResult(message) {
|
|
|
21292
21346
|
content: [{ type: "text", text: message }]
|
|
21293
21347
|
};
|
|
21294
21348
|
}
|
|
21295
|
-
function formatExecuteResult(data, maxResponseSize) {
|
|
21349
|
+
function formatExecuteResult(data, maxResponseSize, reportBi) {
|
|
21296
21350
|
if (data.error) {
|
|
21297
21351
|
return executeErrorResult(data.error);
|
|
21298
21352
|
}
|
|
21353
|
+
reportBi?.({
|
|
21354
|
+
originalLength: typeof data.result === "string" ? data.result.length : JSON.stringify(data.result)?.length
|
|
21355
|
+
});
|
|
21299
21356
|
return {
|
|
21300
21357
|
content: [
|
|
21301
21358
|
{ type: "text", text: truncateResponse(data.result, maxResponseSize) }
|
|
@@ -21405,7 +21462,11 @@ function addExecuteTool(server, options) {
|
|
|
21405
21462
|
status: data.authErrorStatus
|
|
21406
21463
|
});
|
|
21407
21464
|
}
|
|
21408
|
-
return formatExecuteResult(
|
|
21465
|
+
return formatExecuteResult(
|
|
21466
|
+
data,
|
|
21467
|
+
maxResponseSize,
|
|
21468
|
+
extra?.setToolBiParams
|
|
21469
|
+
);
|
|
21409
21470
|
} catch (err) {
|
|
21410
21471
|
const message = err instanceof Error ? err.message : String(err);
|
|
21411
21472
|
logger.log(
|
|
@@ -21497,7 +21558,7 @@ function extractText(result) {
|
|
|
21497
21558
|
return result.content.filter((content) => content.type === "text" && content.text != null).map((content) => content.text).join("\n");
|
|
21498
21559
|
}
|
|
21499
21560
|
var TOOL_RESULT_PREVIEW_MAX_CHARS = 4e3;
|
|
21500
|
-
function formatToolResultAdditionalFields(result) {
|
|
21561
|
+
function formatToolResultAdditionalFields(result, extras) {
|
|
21501
21562
|
const resultText = extractText(result);
|
|
21502
21563
|
const contentTypes = [
|
|
21503
21564
|
...new Set(
|
|
@@ -21513,7 +21574,8 @@ function formatToolResultAdditionalFields(result) {
|
|
|
21513
21574
|
resultPreview: resultText.slice(0, TOOL_RESULT_PREVIEW_MAX_CHARS),
|
|
21514
21575
|
resultTextLength: resultText.length,
|
|
21515
21576
|
resultPreviewTruncated: resultText.length > TOOL_RESULT_PREVIEW_MAX_CHARS,
|
|
21516
|
-
resultContentTypes: contentTypes
|
|
21577
|
+
resultContentTypes: contentTypes,
|
|
21578
|
+
...extras
|
|
21517
21579
|
});
|
|
21518
21580
|
}
|
|
21519
21581
|
function createToolBiEvent(params) {
|
|
@@ -21607,13 +21669,13 @@ function createWixToolkit(options) {
|
|
|
21607
21669
|
clientName,
|
|
21608
21670
|
hooks,
|
|
21609
21671
|
conversationId,
|
|
21610
|
-
includeReadmeMentions = false
|
|
21672
|
+
includeReadmeMentions = false,
|
|
21673
|
+
includeImageUploadGuidance = false
|
|
21611
21674
|
} = options;
|
|
21612
21675
|
const authStrategy = normalizeAuth(auth);
|
|
21613
21676
|
const executeWixApiRequested = isExecuteWixApiRequested(api);
|
|
21614
|
-
|
|
21677
|
+
const descriptionsWithoutReadme = buildToolDescriptions(includeReadmeMentions, includeImageUploadGuidance);
|
|
21615
21678
|
if (!includeReadmeMentions) {
|
|
21616
|
-
descriptionsWithoutReadme = buildToolDescriptions(false);
|
|
21617
21679
|
delete descriptionsWithoutReadme.WixREADME;
|
|
21618
21680
|
}
|
|
21619
21681
|
const sessionId = v4_default();
|
|
@@ -21630,13 +21692,16 @@ function createWixToolkit(options) {
|
|
|
21630
21692
|
authStrategy,
|
|
21631
21693
|
dynamicContextEnabled: true,
|
|
21632
21694
|
// README-free defaults first so consumer overrides still win.
|
|
21633
|
-
toolDescriptions:
|
|
21695
|
+
toolDescriptions: {
|
|
21696
|
+
...descriptionsWithoutReadme,
|
|
21697
|
+
...docsOptions.toolDescriptions
|
|
21698
|
+
}
|
|
21634
21699
|
});
|
|
21635
21700
|
} else {
|
|
21636
21701
|
addDocsTools(server, void 0, {
|
|
21637
21702
|
authStrategy,
|
|
21638
21703
|
dynamicContextEnabled: true,
|
|
21639
|
-
|
|
21704
|
+
toolDescriptions: descriptionsWithoutReadme
|
|
21640
21705
|
});
|
|
21641
21706
|
}
|
|
21642
21707
|
if (api) {
|
|
@@ -21649,7 +21714,7 @@ function createWixToolkit(options) {
|
|
|
21649
21714
|
maxResponseSize,
|
|
21650
21715
|
codeModeBaseUrl = "https://mcp.wix.com"
|
|
21651
21716
|
} = api;
|
|
21652
|
-
const effectiveToolDescriptions =
|
|
21717
|
+
const effectiveToolDescriptions = {
|
|
21653
21718
|
...descriptionsWithoutReadme,
|
|
21654
21719
|
...executeWixApiRequested ? executeCodeModeToolDescriptions : {},
|
|
21655
21720
|
...toolDescriptions
|
|
@@ -21748,7 +21813,10 @@ function createWixToolkit(options) {
|
|
|
21748
21813
|
if (!toolSucceeded) {
|
|
21749
21814
|
errorBody = extractText(cbResult);
|
|
21750
21815
|
} else {
|
|
21751
|
-
additionalFields = formatToolResultAdditionalFields(cbResult
|
|
21816
|
+
additionalFields = formatToolResultAdditionalFields(cbResult, {
|
|
21817
|
+
returnedRows: toolBiParams.returnedRows,
|
|
21818
|
+
originalLength: toolBiParams.originalLength
|
|
21819
|
+
});
|
|
21752
21820
|
}
|
|
21753
21821
|
if (!isDevEnvironment) {
|
|
21754
21822
|
if (toolSucceeded) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type McpAuthenticationStrategy } from '../auth/index.js';
|
|
2
|
+
import type { WixMcpServer } from '../wix-mcp-server.js';
|
|
3
|
+
import type { ToolHintsConfig } from '../api-call/index.js';
|
|
4
|
+
export declare function addGetProfileTool(server: WixMcpServer, authStrategy: McpAuthenticationStrategy, disableTools?: string[], toolDescriptions?: Record<string, string>, toolHints?: Record<string, ToolHintsConfig>): void;
|
|
5
|
+
//# sourceMappingURL=get-profile-tool.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { rethrowIfUnauthorized } from '../auth/index.js';
|
|
2
|
+
import { defaultToolDescriptions } from '../config/default-config.js';
|
|
3
|
+
import { createHttpClient } from '@wix/http-client';
|
|
4
|
+
import { getTeamMember } from '@wix/ambassador-identity-account-v1-user/http';
|
|
5
|
+
const WIX_APIS_BASE_URL = 'https://www.wixapis.com';
|
|
6
|
+
const GET_PROFILE_TOOL_NAME = 'get_profile';
|
|
7
|
+
export function addGetProfileTool(server, authStrategy, disableTools = [], toolDescriptions, toolHints) {
|
|
8
|
+
if (disableTools.includes(GET_PROFILE_TOOL_NAME)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const cache = {};
|
|
12
|
+
const hints = toolHints?.[GET_PROFILE_TOOL_NAME];
|
|
13
|
+
server.tool(GET_PROFILE_TOOL_NAME, toolDescriptions?.[GET_PROFILE_TOOL_NAME] ??
|
|
14
|
+
defaultToolDescriptions[GET_PROFILE_TOOL_NAME], {}, {
|
|
15
|
+
readOnlyHint: hints?.readOnlyHint ?? true,
|
|
16
|
+
destructiveHint: hints?.destructiveHint ?? false,
|
|
17
|
+
openWorldHint: hints?.openWorldHint ?? false
|
|
18
|
+
}, async () => {
|
|
19
|
+
const profilePromise = (cache.profilePromise ??= (async () => {
|
|
20
|
+
const accountAuthHeaders = await authStrategy.getAccountAuthHeaders();
|
|
21
|
+
const httpClient = createHttpClient({
|
|
22
|
+
baseURL: WIX_APIS_BASE_URL,
|
|
23
|
+
headers: accountAuthHeaders
|
|
24
|
+
});
|
|
25
|
+
const response = await httpClient.request(getTeamMember({}));
|
|
26
|
+
const email = response.data.user?.email;
|
|
27
|
+
if (!email) {
|
|
28
|
+
throw new Error('The current Wix user profile has no email address.');
|
|
29
|
+
}
|
|
30
|
+
return { email };
|
|
31
|
+
})());
|
|
32
|
+
const profile = await profilePromise.catch(async (error) => {
|
|
33
|
+
cache.profilePromise = undefined;
|
|
34
|
+
rethrowIfUnauthorized(error);
|
|
35
|
+
await authStrategy.enforceValidWixToken?.(error);
|
|
36
|
+
throw error;
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: 'text',
|
|
42
|
+
text: profile.email
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
structuredContent: profile
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=get-profile-tool.js.map
|
|
@@ -10,6 +10,32 @@ import { desc } from '../config/param-descriptions.js';
|
|
|
10
10
|
import { MAX_ALLOWED_RESPONSE_CHARS } from '../infra/response-size-limits.js';
|
|
11
11
|
export { addUploadImageTool } from './upload-image-tool.js';
|
|
12
12
|
const DEFAULT_MAX_RESPONSE_SIZE = 50000; // ~50KB cap
|
|
13
|
+
/**
|
|
14
|
+
* Rows the API actually served, read before truncation. Endpoints often return
|
|
15
|
+
* fewer than asked for, so an offset advance that does not match
|
|
16
|
+
* offset + requested limit can still be correct -- without this, BI cannot tell
|
|
17
|
+
* a paging defect from a short page.
|
|
18
|
+
*/
|
|
19
|
+
function extractReturnedRows(responseData) {
|
|
20
|
+
if (responseData === null || typeof responseData !== 'object') {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
const data = responseData;
|
|
24
|
+
const block = (data.pagingMetadata ??
|
|
25
|
+
data.cursorPagingMetadata ??
|
|
26
|
+
data.pagingOffsetMetadata ??
|
|
27
|
+
data.metaData ??
|
|
28
|
+
data.metadata);
|
|
29
|
+
const raw = block?.count;
|
|
30
|
+
// A blank string coerces to 0, which would report a page size the endpoint
|
|
31
|
+
// never sent -- worse than reporting nothing.
|
|
32
|
+
if (typeof raw !== 'number' &&
|
|
33
|
+
(typeof raw !== 'string' || raw.trim() === '')) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const count = Number(raw);
|
|
37
|
+
return Number.isFinite(count) ? count : undefined;
|
|
38
|
+
}
|
|
13
39
|
function formatApiResponse(responseData, maxResponseSize = DEFAULT_MAX_RESPONSE_SIZE) {
|
|
14
40
|
// Detect if response is HTML (likely wrong endpoint or auth redirect)
|
|
15
41
|
if (typeof responseData === 'string' &&
|
|
@@ -19,14 +45,16 @@ function formatApiResponse(responseData, maxResponseSize = DEFAULT_MAX_RESPONSE_
|
|
|
19
45
|
isError: true
|
|
20
46
|
};
|
|
21
47
|
}
|
|
48
|
+
const returnedRows = extractReturnedRows(responseData);
|
|
22
49
|
let responseText = JSON.stringify(responseData);
|
|
50
|
+
const originalLength = responseText.length;
|
|
23
51
|
const effectiveMax = Math.min(maxResponseSize, MAX_ALLOWED_RESPONSE_CHARS);
|
|
24
52
|
if (responseText.length > effectiveMax) {
|
|
25
53
|
responseText =
|
|
26
54
|
responseText.slice(0, effectiveMax) +
|
|
27
55
|
`\n...[TRUNCATED - response was ${responseText.length} chars, showing first ${effectiveMax}]`;
|
|
28
56
|
}
|
|
29
|
-
return { text: responseText, isError: false };
|
|
57
|
+
return { text: responseText, isError: false, originalLength, returnedRows };
|
|
30
58
|
}
|
|
31
59
|
export function addApiCallTool(server, strategy, allowedTools = ['CallWixSiteAPI', 'ListWixSites', 'ManageWixSite'], disableTools = [], enableTools = [], toolDescriptions, toolHints, maxResponseSize) {
|
|
32
60
|
// Compute effective allowed tools: (default + enableTools) - disableTools
|
|
@@ -89,9 +117,15 @@ export function addApiCallTool(server, strategy, allowedTools = ['CallWixSiteAPI
|
|
|
89
117
|
data: method === 'GET' ? undefined : body
|
|
90
118
|
});
|
|
91
119
|
const requestId = response.headers?.['x-wix-request-id'];
|
|
92
|
-
setToolBiParams({ requestId, siteId });
|
|
93
120
|
const responseData = await handleWixAPIResponse(response);
|
|
94
121
|
const formatted = formatApiResponse(responseData, maxResponseSize);
|
|
122
|
+
// One call only -- setToolBiParams replaces rather than merges.
|
|
123
|
+
setToolBiParams({
|
|
124
|
+
requestId,
|
|
125
|
+
siteId,
|
|
126
|
+
returnedRows: formatted.returnedRows,
|
|
127
|
+
originalLength: formatted.originalLength
|
|
128
|
+
});
|
|
95
129
|
if (formatted.isError) {
|
|
96
130
|
return {
|
|
97
131
|
content: [
|
|
@@ -222,7 +256,7 @@ export function addApiCallTool(server, strategy, allowedTools = ['CallWixSiteAPI
|
|
|
222
256
|
readOnlyHint: false,
|
|
223
257
|
destructiveHint: true,
|
|
224
258
|
openWorldHint: false
|
|
225
|
-
}), async ({ url, body, method, reason }, { httpClient }) => {
|
|
259
|
+
}), async ({ url, body, method, reason }, { httpClient, setToolBiParams }) => {
|
|
226
260
|
logger.log(`Calling Wix Account level API: ${url}, reason="${reason}", body: ${JSON.stringify(body)}`);
|
|
227
261
|
const { isAllowed, error: urlError } = isApiUrlAllowed(url);
|
|
228
262
|
if (!isAllowed) {
|
|
@@ -251,6 +285,10 @@ export function addApiCallTool(server, strategy, allowedTools = ['CallWixSiteAPI
|
|
|
251
285
|
});
|
|
252
286
|
const responseData = await handleWixAPIResponse(response);
|
|
253
287
|
const formatted = formatApiResponse(responseData, maxResponseSize);
|
|
288
|
+
setToolBiParams({
|
|
289
|
+
returnedRows: formatted.returnedRows,
|
|
290
|
+
originalLength: formatted.originalLength
|
|
291
|
+
});
|
|
254
292
|
if (formatted.isError) {
|
|
255
293
|
return {
|
|
256
294
|
content: [
|
|
@@ -162,10 +162,16 @@ function executeTextResult(message) {
|
|
|
162
162
|
content: [{ type: 'text', text: message }]
|
|
163
163
|
};
|
|
164
164
|
}
|
|
165
|
-
function formatExecuteResult(data, maxResponseSize) {
|
|
165
|
+
function formatExecuteResult(data, maxResponseSize, reportBi) {
|
|
166
166
|
if (data.error) {
|
|
167
167
|
return executeErrorResult(data.error);
|
|
168
168
|
}
|
|
169
|
+
// Before the slice -- resultTextLength is measured after it and saturates.
|
|
170
|
+
reportBi?.({
|
|
171
|
+
originalLength: typeof data.result === 'string'
|
|
172
|
+
? data.result.length
|
|
173
|
+
: JSON.stringify(data.result)?.length
|
|
174
|
+
});
|
|
169
175
|
return {
|
|
170
176
|
content: [
|
|
171
177
|
{ type: 'text', text: truncateResponse(data.result, maxResponseSize) }
|
|
@@ -293,7 +299,7 @@ function addExecuteTool(server, options) {
|
|
|
293
299
|
status: data.authErrorStatus
|
|
294
300
|
});
|
|
295
301
|
}
|
|
296
|
-
return formatExecuteResult(data, maxResponseSize);
|
|
302
|
+
return formatExecuteResult(data, maxResponseSize, extra?.setToolBiParams);
|
|
297
303
|
}
|
|
298
304
|
catch (err) {
|
|
299
305
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request-shape rules shared by every tool that lets an agent write a Wix REST
|
|
3
|
+
* URL by hand (ExecuteWixAPI's `wix.request` and CallWixSiteAPI's `url`).
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The Wix API gateway deserializes enum-typed array query params only when the
|
|
7
|
+
* parameter is repeated once per value. Comma-joined values are read as a
|
|
8
|
+
* single unknown enum member and rejected with HTTP 400.
|
|
9
|
+
*/
|
|
10
|
+
export declare const 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).";
|
|
11
|
+
//# sourceMappingURL=api-request-rules.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request-shape rules shared by every tool that lets an agent write a Wix REST
|
|
3
|
+
* URL by hand (ExecuteWixAPI's `wix.request` and CallWixSiteAPI's `url`).
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The Wix API gateway deserializes enum-typed array query params only when the
|
|
7
|
+
* parameter is repeated once per value. Comma-joined values are read as a
|
|
8
|
+
* single unknown enum member and rejected with HTTP 400.
|
|
9
|
+
*/
|
|
10
|
+
export const 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).';
|
|
11
|
+
//# sourceMappingURL=api-request-rules.js.map
|
|
@@ -21,7 +21,7 @@ export interface ModeDefaultConfig {
|
|
|
21
21
|
skillsPrOverrideEnabled?: boolean;
|
|
22
22
|
}
|
|
23
23
|
export declare const SYSTEM_REMINDER_GUIDELINES: string;
|
|
24
|
-
export declare function buildSystemReminder(includeReadme: boolean): string;
|
|
24
|
+
export declare function buildSystemReminder(includeReadme: boolean, includeImageUploadGuidance?: boolean): string;
|
|
25
25
|
export declare const SYSTEM_REMINDER: string;
|
|
26
26
|
export declare const SITE_CREATION_COPY: {
|
|
27
27
|
readonly templatePick: {
|
|
@@ -40,7 +40,7 @@ export declare const SITE_CREATION_COPY: {
|
|
|
40
40
|
/** Rewrites non-widget copy into its widget form; a no-op on text that carries no divergence. */
|
|
41
41
|
export declare const toWidget: (text: string) => string;
|
|
42
42
|
export declare const executeWixApiDescription: string;
|
|
43
|
-
export declare function buildToolDescriptions(includeReadme: boolean): Record<string, string>;
|
|
43
|
+
export declare function buildToolDescriptions(includeReadme: boolean, includeImageUploadGuidance?: boolean): Record<string, string>;
|
|
44
44
|
/**
|
|
45
45
|
* Canonical (README-inclusive) tool descriptions used by the live MCP server and
|
|
46
46
|
* all existing importers.
|