@wix/mcp 1.0.16 → 1.0.17

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.
Files changed (48) hide show
  1. package/build/bin-standalone.js +12687 -12854
  2. package/build/bin-standalone.js.map +4 -4
  3. package/build/cjs/index.cjs +286 -226
  4. package/build/cjs/index.cjs.map +4 -4
  5. package/build/dts/api-call/index.d.ts +1 -1
  6. package/build/dts/api-call/index.d.ts.map +1 -1
  7. package/build/dts/api-call/index.js +161 -128
  8. package/build/dts/api-call/index.js.map +1 -1
  9. package/build/dts/api-call/validation.d.ts +8 -0
  10. package/build/dts/api-call/validation.d.ts.map +1 -0
  11. package/build/dts/api-call/validation.js +31 -0
  12. package/build/dts/api-call/validation.js.map +1 -0
  13. package/build/dts/api-call/validation.test.d.ts +2 -0
  14. package/build/dts/api-call/validation.test.d.ts.map +1 -0
  15. package/build/dts/api-call/validation.test.js +42 -0
  16. package/build/dts/api-call/validation.test.js.map +1 -0
  17. package/build/dts/bin.d.ts.map +1 -1
  18. package/build/dts/bin.js +22 -0
  19. package/build/dts/bin.js.map +1 -1
  20. package/build/dts/cli-tools/cli.d.ts +1 -1
  21. package/build/dts/cli-tools/cli.d.ts.map +1 -1
  22. package/build/dts/cli-tools/cli.js +2 -223
  23. package/build/dts/cli-tools/cli.js.map +1 -1
  24. package/build/dts/docs/docs.d.ts.map +1 -1
  25. package/build/dts/docs/docs.js +6 -2
  26. package/build/dts/docs/docs.js.map +1 -1
  27. package/build/dts/docs/fetch-article.d.ts.map +1 -1
  28. package/build/dts/docs/fetch-article.js +11 -0
  29. package/build/dts/docs/fetch-article.js.map +1 -1
  30. package/build/dts/docs/fetch-article.test.d.ts +2 -0
  31. package/build/dts/docs/fetch-article.test.d.ts.map +1 -0
  32. package/build/dts/docs/fetch-article.test.js +12 -0
  33. package/build/dts/docs/fetch-article.test.js.map +1 -0
  34. package/build/dts/infra/panorama.d.ts +2 -0
  35. package/build/dts/infra/panorama.d.ts.map +1 -1
  36. package/build/dts/infra/panorama.js +1 -0
  37. package/build/dts/infra/panorama.js.map +1 -1
  38. package/build/dts/wix-mcp-server.d.ts +3 -0
  39. package/build/dts/wix-mcp-server.d.ts.map +1 -1
  40. package/build/dts/wix-mcp-server.js +9 -2
  41. package/build/dts/wix-mcp-server.js.map +1 -1
  42. package/build/esm/index.js +254 -188
  43. package/build/esm/index.js.map +3 -3
  44. package/package.json +4 -4
  45. package/build/dts/cli-tools/utils.d.ts +0 -3
  46. package/build/dts/cli-tools/utils.d.ts.map +0 -1
  47. package/build/dts/cli-tools/utils.js +0 -26
  48. package/build/dts/cli-tools/utils.js.map +0 -1
@@ -6833,19 +6833,6 @@ var errorUtil;
6833
6833
  })(errorUtil || (errorUtil = {}));
6834
6834
 
6835
6835
  // ../../node_modules/zod/dist/esm/v3/types.js
6836
- var __classPrivateFieldGet = function(receiver, state, kind, f) {
6837
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
6838
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
6839
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6840
- };
6841
- var __classPrivateFieldSet = function(receiver, state, value, kind, f) {
6842
- if (kind === "m") throw new TypeError("Private method is not writable");
6843
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
6844
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6845
- return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
6846
- };
6847
- var _ZodEnum_cache;
6848
- var _ZodNativeEnum_cache;
6849
6836
  var ParseInputLazyPath = class {
6850
6837
  constructor(parent, value, path2, key) {
6851
6838
  this._cachedPath = [];
@@ -9670,10 +9657,6 @@ function createZodEnum(values, params) {
9670
9657
  });
9671
9658
  }
9672
9659
  var ZodEnum = class _ZodEnum extends ZodType {
9673
- constructor() {
9674
- super(...arguments);
9675
- _ZodEnum_cache.set(this, void 0);
9676
- }
9677
9660
  _parse(input) {
9678
9661
  if (typeof input.data !== "string") {
9679
9662
  const ctx = this._getOrReturnCtx(input);
@@ -9685,10 +9668,10 @@ var ZodEnum = class _ZodEnum extends ZodType {
9685
9668
  });
9686
9669
  return INVALID;
9687
9670
  }
9688
- if (!__classPrivateFieldGet(this, _ZodEnum_cache, "f")) {
9689
- __classPrivateFieldSet(this, _ZodEnum_cache, new Set(this._def.values), "f");
9671
+ if (!this._cache) {
9672
+ this._cache = new Set(this._def.values);
9690
9673
  }
9691
- if (!__classPrivateFieldGet(this, _ZodEnum_cache, "f").has(input.data)) {
9674
+ if (!this._cache.has(input.data)) {
9692
9675
  const ctx = this._getOrReturnCtx(input);
9693
9676
  const expectedValues = this._def.values;
9694
9677
  addIssueToContext(ctx, {
@@ -9737,13 +9720,8 @@ var ZodEnum = class _ZodEnum extends ZodType {
9737
9720
  });
9738
9721
  }
9739
9722
  };
9740
- _ZodEnum_cache = /* @__PURE__ */ new WeakMap();
9741
9723
  ZodEnum.create = createZodEnum;
9742
9724
  var ZodNativeEnum = class extends ZodType {
9743
- constructor() {
9744
- super(...arguments);
9745
- _ZodNativeEnum_cache.set(this, void 0);
9746
- }
9747
9725
  _parse(input) {
9748
9726
  const nativeEnumValues = util.getValidEnumValues(this._def.values);
9749
9727
  const ctx = this._getOrReturnCtx(input);
@@ -9756,10 +9734,10 @@ var ZodNativeEnum = class extends ZodType {
9756
9734
  });
9757
9735
  return INVALID;
9758
9736
  }
9759
- if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f")) {
9760
- __classPrivateFieldSet(this, _ZodNativeEnum_cache, new Set(util.getValidEnumValues(this._def.values)), "f");
9737
+ if (!this._cache) {
9738
+ this._cache = new Set(util.getValidEnumValues(this._def.values));
9761
9739
  }
9762
- if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f").has(input.data)) {
9740
+ if (!this._cache.has(input.data)) {
9763
9741
  const expectedValues = util.objectValues(nativeEnumValues);
9764
9742
  addIssueToContext(ctx, {
9765
9743
  received: ctx.data,
@@ -9774,7 +9752,6 @@ var ZodNativeEnum = class extends ZodType {
9774
9752
  return this._def.values;
9775
9753
  }
9776
9754
  };
9777
- _ZodNativeEnum_cache = /* @__PURE__ */ new WeakMap();
9778
9755
  ZodNativeEnum.create = (values, params) => {
9779
9756
  return new ZodNativeEnum({
9780
9757
  values,
@@ -9915,7 +9892,7 @@ var ZodEffects = class extends ZodType {
9915
9892
  parent: ctx
9916
9893
  });
9917
9894
  if (!isValid(base))
9918
- return base;
9895
+ return INVALID;
9919
9896
  const result = effect.transform(base.value, checkCtx);
9920
9897
  if (result instanceof Promise) {
9921
9898
  throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
@@ -9924,7 +9901,7 @@ var ZodEffects = class extends ZodType {
9924
9901
  } else {
9925
9902
  return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
9926
9903
  if (!isValid(base))
9927
- return base;
9904
+ return INVALID;
9928
9905
  return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
9929
9906
  status: status.value,
9930
9907
  value: result
@@ -11337,7 +11314,7 @@ var Protocol = class {
11337
11314
  request(request, resultSchema, options) {
11338
11315
  const { relatedRequestId, resumptionToken, onresumptiontoken } = options !== null && options !== void 0 ? options : {};
11339
11316
  return new Promise((resolve, reject) => {
11340
- var _a, _b, _c, _d, _e;
11317
+ var _a, _b, _c, _d, _e, _f;
11341
11318
  if (!this._transport) {
11342
11319
  reject(new Error("Not connected"));
11343
11320
  return;
@@ -11356,7 +11333,10 @@ var Protocol = class {
11356
11333
  this._progressHandlers.set(messageId, options.onprogress);
11357
11334
  jsonrpcRequest.params = {
11358
11335
  ...request.params,
11359
- _meta: { progressToken: messageId }
11336
+ _meta: {
11337
+ ...((_c = request.params) === null || _c === void 0 ? void 0 : _c._meta) || {},
11338
+ progressToken: messageId
11339
+ }
11360
11340
  };
11361
11341
  }
11362
11342
  const cancel = (reason) => {
@@ -11389,13 +11369,13 @@ var Protocol = class {
11389
11369
  reject(error);
11390
11370
  }
11391
11371
  });
11392
- (_c = options === null || options === void 0 ? void 0 : options.signal) === null || _c === void 0 ? void 0 : _c.addEventListener("abort", () => {
11372
+ (_d = options === null || options === void 0 ? void 0 : options.signal) === null || _d === void 0 ? void 0 : _d.addEventListener("abort", () => {
11393
11373
  var _a2;
11394
11374
  cancel((_a2 = options === null || options === void 0 ? void 0 : options.signal) === null || _a2 === void 0 ? void 0 : _a2.reason);
11395
11375
  });
11396
- const timeout = (_d = options === null || options === void 0 ? void 0 : options.timeout) !== null && _d !== void 0 ? _d : DEFAULT_REQUEST_TIMEOUT_MSEC;
11376
+ const timeout = (_e = options === null || options === void 0 ? void 0 : options.timeout) !== null && _e !== void 0 ? _e : DEFAULT_REQUEST_TIMEOUT_MSEC;
11397
11377
  const timeoutHandler = () => cancel(new McpError(ErrorCode.RequestTimeout, "Request timed out", { timeout }));
11398
- this._setupTimeout(messageId, timeout, options === null || options === void 0 ? void 0 : options.maxTotalTimeout, timeoutHandler, (_e = options === null || options === void 0 ? void 0 : options.resetTimeoutOnProgress) !== null && _e !== void 0 ? _e : false);
11378
+ this._setupTimeout(messageId, timeout, options === null || options === void 0 ? void 0 : options.maxTotalTimeout, timeoutHandler, (_f = options === null || options === void 0 ? void 0 : options.resetTimeoutOnProgress) !== null && _f !== void 0 ? _f : false);
11399
11379
  this._transport.send(jsonrpcRequest, { relatedRequestId, resumptionToken, onresumptiontoken }).catch((error) => {
11400
11380
  this._cleanupTimeout(messageId);
11401
11381
  reject(error);
@@ -13052,6 +13032,9 @@ var McpServer = class {
13052
13032
  return;
13053
13033
  }
13054
13034
  this.server.assertCanSetRequestHandler(CompleteRequestSchema.shape.method.value);
13035
+ this.server.registerCapabilities({
13036
+ completions: {}
13037
+ });
13055
13038
  this.server.setRequestHandler(CompleteRequestSchema, async (request) => {
13056
13039
  switch (request.params.ref.type) {
13057
13040
  case "ref/prompt":
@@ -13124,8 +13107,9 @@ var McpServer = class {
13124
13107
  const result = await template.resourceTemplate.listCallback(extra);
13125
13108
  for (const resource of result.resources) {
13126
13109
  templateResources.push({
13127
- ...resource,
13128
- ...template.metadata
13110
+ ...template.metadata,
13111
+ // the defined resource metadata should override the template metadata if present
13112
+ ...resource
13129
13113
  });
13130
13114
  }
13131
13115
  }
@@ -15264,6 +15248,7 @@ var createPanoramaClient = (opts) => {
15264
15248
  },
15265
15249
  data: {
15266
15250
  environment: opts.environment,
15251
+ serverInfo: opts.serverInfo,
15267
15252
  runtime: {
15268
15253
  packageVersion: packageJson.version,
15269
15254
  versions: process.versions,
@@ -16863,12 +16848,9 @@ var logger2 = createNullLogger();
16863
16848
 
16864
16849
  // src/wix-mcp-server.ts
16865
16850
  var WixMcpServer = class extends McpServer {
16866
- biLogger;
16867
- nodeEnv;
16868
- sessionId;
16869
- getUserId;
16870
16851
  constructor(serverInfo, options, nodeEnv) {
16871
16852
  super(serverInfo, options);
16853
+ this.serverInfo = serverInfo;
16872
16854
  this.sessionId = v4_default();
16873
16855
  this.nodeEnv = getEnvironment(nodeEnv);
16874
16856
  this.biLogger = createBiLogger({
@@ -16876,9 +16858,17 @@ var WixMcpServer = class extends McpServer {
16876
16858
  });
16877
16859
  logger2.log(`WixMcpServer created with sessionId: ${this.sessionId}`);
16878
16860
  }
16861
+ biLogger;
16862
+ nodeEnv;
16863
+ sessionId;
16864
+ getUserId;
16865
+ getClientName;
16879
16866
  setUserIdGetter(getUserId) {
16880
16867
  this.getUserId = getUserId;
16881
16868
  }
16869
+ setClientNameGetter(getClientName) {
16870
+ this.getClientName = getClientName;
16871
+ }
16882
16872
  tool(...args) {
16883
16873
  const cbIndex = args.findIndex((arg) => typeof arg === "function");
16884
16874
  if (cbIndex !== -1) {
@@ -16893,7 +16883,8 @@ var WixMcpServer = class extends McpServer {
16893
16883
  environment: this.nodeEnv,
16894
16884
  sessionId: this.sessionId,
16895
16885
  componentId: toolName,
16896
- uuid: this.getUserId?.()
16886
+ uuid: this.getUserId?.(),
16887
+ serverInfo: this.serverInfo
16897
16888
  });
16898
16889
  const toolInvocationId = v4_default();
16899
16890
  const httpClient = new HttpClient3({
@@ -16952,7 +16943,7 @@ var WixMcpServer = class extends McpServer {
16952
16943
  }
16953
16944
  this.biLogger.report(
16954
16945
  wixMcpRequestSrc39Evid1607({
16955
- clientName,
16946
+ clientName: this.getClientName?.() || clientName,
16956
16947
  duration,
16957
16948
  errorBody,
16958
16949
  toolInvocationId,
@@ -17118,6 +17109,18 @@ async function fetchArticleContentFromDigor(httpClient, articleUrl, mode, stripH
17118
17109
  }
17119
17110
  async function fetchArticleContent(httpClient, articleUrl, mode, stripHeader = false) {
17120
17111
  if (mode === "raw") {
17112
+ let parsedUrl;
17113
+ try {
17114
+ parsedUrl = new URL(articleUrl);
17115
+ } catch {
17116
+ throw new Error(`Invalid URL format: ${articleUrl}`);
17117
+ }
17118
+ const hostname = parsedUrl.hostname.replace("www.", "");
17119
+ if (hostname !== "dev.wix.com") {
17120
+ throw new Error(
17121
+ `Unsupported URL domain: ${hostname}. Article URL must be from dev.wix.com`
17122
+ );
17123
+ }
17121
17124
  const { data: doc } = await httpClient.get(articleUrl);
17122
17125
  return doc;
17123
17126
  }
@@ -17609,7 +17612,7 @@ var addDocsTools = (server, allowedTools = [
17609
17612
  getToKnowWixEnabled ? WixREADME_DEPENDENT_DESCRIPTION : ""
17610
17613
  ].join("\n"),
17611
17614
  {
17612
- articleUrl: external_exports.string().describe(
17615
+ articleUrl: external_exports.string().url().startsWith("https://dev.wix.com/").describe(
17613
17616
  "The URL of the docs article or method article to fetch. Should be something like https://dev.wix.com/docs/.../.../..."
17614
17617
  )
17615
17618
  },
@@ -17646,7 +17649,7 @@ var addDocsTools = (server, allowedTools = [
17646
17649
  content: [
17647
17650
  {
17648
17651
  type: "text",
17649
- text: "Could not fetch article content, you should try completing the task without it."
17652
+ text: `Could not fetch article content: "${error.message}". You should try completing the task without it.`
17650
17653
  }
17651
17654
  ]
17652
17655
  };
@@ -17660,7 +17663,7 @@ var addDocsTools = (server, allowedTools = [
17660
17663
  "This will give you the entire request/response schema with all the fields and their descriptions."
17661
17664
  ].join("\n"),
17662
17665
  {
17663
- articleUrl: external_exports.string().describe(
17666
+ articleUrl: external_exports.string().url().startsWith("https://dev.wix.com/").describe(
17664
17667
  "The URL of the documentation to fetch. Should be something like https://dev.wix.com/docs/.../.../..."
17665
17668
  )
17666
17669
  },
@@ -17690,7 +17693,7 @@ var addDocsTools = (server, allowedTools = [
17690
17693
  content: [
17691
17694
  {
17692
17695
  type: "text",
17693
- text: "Could not fetch method schema, you should try completing the task without it."
17696
+ text: `Could not fetch method schema: "${error.message}". You should try completing the task without it.`
17694
17697
  }
17695
17698
  ]
17696
17699
  };
@@ -17737,164 +17740,227 @@ var handleWixAPIResponse = async (response) => {
17737
17740
  return responseData;
17738
17741
  };
17739
17742
 
17743
+ // src/api-call/validation.ts
17744
+ function isApiUrlAllowed(url) {
17745
+ let parsedUrl;
17746
+ try {
17747
+ parsedUrl = new URL(url);
17748
+ } catch {
17749
+ return {
17750
+ isAllowed: false,
17751
+ error: `Invalid URL format: ${url}`
17752
+ };
17753
+ }
17754
+ const ALLOWED_HOSTNAMES = [
17755
+ "wix.com",
17756
+ "dev.wix.com",
17757
+ "manage.wix.com",
17758
+ "editor.wix.com",
17759
+ "wixapis.com"
17760
+ ];
17761
+ const hostname = parsedUrl.hostname.replace("www.", "");
17762
+ const isAllowedHostname = ALLOWED_HOSTNAMES.some(
17763
+ (domain) => hostname === domain
17764
+ );
17765
+ if (!isAllowedHostname) {
17766
+ return {
17767
+ isAllowed: false,
17768
+ error: `Unsupported URL domain: ${hostname}. URL must be from one of the allowed domains: ${ALLOWED_HOSTNAMES.join(", ")}`
17769
+ };
17770
+ }
17771
+ return {
17772
+ isAllowed: true
17773
+ };
17774
+ }
17775
+
17740
17776
  // src/api-call/index.ts
17741
- function addApiCallTool(server, strategy) {
17742
- server.tool(
17743
- "CallWixSiteAPI",
17744
- [
17745
- "Call Wix apis on a business or site. Use this to create, read, update, and delete data and other Wix entities in your Wix site,",
17746
- `You should ALWAYS check the rest docs - "SearchWixRESTDocumentation" for the specific API you want to call, don't just call it without knowing what it does, CHECK THE DOCS`,
17747
- "Error Handling:",
17748
- 'If the error is related to missing installed app or "WDE0110: Wix Code not enabled", you should install the missing app by using ReadFullDocsArticle tool to fetch the article - https://dev.wix.com/docs/kb-only/MCP_REST_RECIPES_KB_ID/TRAIN_wix.devcenter.apps.installer.v1.AppsInstallerService.InstallApp',
17749
- "**Note:** there is no need to check if an app is installed/ Wix Code enabled in advance, just call the API and handle the error if it occurs, the API error message will state it clearly.",
17750
- "For any other error, use your default error handling mechanism"
17751
- ].join("\n"),
17752
- {
17753
- siteId: external_exports.string().describe("The id of the site selected using site selection tool"),
17754
- url: external_exports.string().describe(
17755
- "The url of the api to call - ALWAYS get the information from the Wix REST docs or from the conversation context, the URL MUST BE ABSOLUTE URL"
17756
- ),
17757
- method: external_exports.string().describe(
17758
- "The HTTP method to use for the API call (e.g. GET, POST, PUT, DELETE)"
17759
- ),
17760
- body: external_exports.string().optional().describe(
17761
- "A string representing of a valid JSON object to describe the body of the request"
17762
- )
17763
- },
17764
- async ({ url, body, method, siteId }, { httpClient }) => {
17765
- logger2.log(
17766
- `Calling Wix Site API: ${siteId} ${url}, body: ${JSON.stringify(body)}`
17767
- );
17768
- try {
17769
- const response = await httpClient.request({
17770
- url,
17771
- method,
17772
- headers: {
17773
- ...await strategy.getSiteAuthHeaders(siteId),
17774
- ...body ? { "Content-Type": "application/json" } : {}
17775
- },
17776
- data: method === "GET" ? void 0 : body
17777
- });
17778
- const responseData = await handleWixAPIResponse(response);
17779
- return {
17780
- content: [
17781
- {
17782
- type: "text",
17783
- text: `Wix Site API call successful: ${JSON.stringify(responseData)}`
17784
- }
17785
- ]
17786
- };
17787
- } catch (error) {
17788
- logger2.error(`Failed to call Wix Site API: ${error}`);
17789
- const response = error.response;
17790
- if (!response) {
17791
- throw new Error(`Failed to call Wix Site API: ${error}`);
17777
+ function addApiCallTool(server, strategy, allowedTools = ["CallWixSiteAPI", "ListWixSites", "ManageWixSite"]) {
17778
+ if (allowedTools.includes("CallWixSiteAPI")) {
17779
+ server.tool(
17780
+ "CallWixSiteAPI",
17781
+ [
17782
+ "Call Wix apis on a business or site. Use this to create, read, update, and delete data and other Wix entities in your Wix site,",
17783
+ `You should ALWAYS check the rest docs - "SearchWixRESTDocumentation" for the specific API you want to call, don't just call it without knowing what it does, CHECK THE DOCS`,
17784
+ "Error Handling:",
17785
+ 'If the error is related to missing installed app or "WDE0110: Wix Code not enabled", you should install the missing app by using ReadFullDocsArticle tool to fetch the article - https://dev.wix.com/docs/kb-only/MCP_REST_RECIPES_KB_ID/TRAIN_wix.devcenter.apps.installer.v1.AppsInstallerService.InstallApp',
17786
+ "**Note:** there is no need to check if an app is installed/ Wix Code enabled in advance, just call the API and handle the error if it occurs, the API error message will state it clearly.",
17787
+ "For any other error, use your default error handling mechanism"
17788
+ ].join("\n"),
17789
+ {
17790
+ siteId: external_exports.string().describe("The id of the site selected using site selection tool"),
17791
+ url: external_exports.string().url().describe(
17792
+ "The url of the api to call - ALWAYS get the information from the Wix REST docs or from the conversation context, the URL MUST BE ABSOLUTE URL"
17793
+ ),
17794
+ method: external_exports.string().describe(
17795
+ "The HTTP method to use for the API call (e.g. GET, POST, PUT, DELETE)"
17796
+ ),
17797
+ body: external_exports.string().optional().describe(
17798
+ "A string representing of a valid JSON object to describe the body of the request"
17799
+ )
17800
+ },
17801
+ async ({ url, body, method, siteId }, { httpClient }) => {
17802
+ logger2.log(
17803
+ `Calling Wix Site API: ${siteId} ${url}, body: ${JSON.stringify(body)}`
17804
+ );
17805
+ const { isAllowed, error: urlError } = isApiUrlAllowed(url);
17806
+ if (!isAllowed) {
17807
+ return {
17808
+ content: [
17809
+ {
17810
+ isError: true,
17811
+ type: "text",
17812
+ text: `Error validating URL: ${urlError}`
17813
+ }
17814
+ ]
17815
+ };
17792
17816
  }
17793
- return handleWixAPIResponse(response);
17794
- }
17795
- }
17796
- );
17797
- server.tool(
17798
- "ListWixSites",
17799
- "List Wix sites for the current user, by default it will return all sites, but you can filter by name",
17800
- {
17801
- nameSearch: external_exports.string().optional().describe(
17802
- "optional filer by name, if not provided all sites will be returned"
17803
- ),
17804
- // Hack for Cursor ignoring tools with no params (when nameSearch is optional)
17805
- alwaysTrue: external_exports.boolean().describe("Always pass true to this parameter")
17806
- },
17807
- async ({ nameSearch }, { httpClient }) => {
17808
- const sitesRes = await httpClient.post(
17809
- "https://www.wixapis.com/site-list/v2/sites/query",
17810
- {
17811
- query: {
17812
- cursorPaging: { limit: 21 },
17813
- filter: {
17814
- ...nameSearch ? {
17815
- name: nameSearch
17816
- } : {},
17817
- namespace: {
17818
- $in: ["WIX", "DASHBOARD_FIRST", "ANYWHERE", "HEADLESS"]
17817
+ try {
17818
+ const response = await httpClient.request({
17819
+ url,
17820
+ method,
17821
+ headers: {
17822
+ ...await strategy.getSiteAuthHeaders(siteId),
17823
+ ...body ? { "Content-Type": "application/json" } : {}
17824
+ },
17825
+ data: method === "GET" ? void 0 : body
17826
+ });
17827
+ const responseData = await handleWixAPIResponse(response);
17828
+ return {
17829
+ content: [
17830
+ {
17831
+ type: "text",
17832
+ text: `Wix Site API call successful: ${JSON.stringify(responseData)}`
17819
17833
  }
17820
- }
17821
- }
17822
- },
17823
- {
17824
- headers: {
17825
- ...await strategy.getAccountAuthHeaders(),
17826
- "Content-Type": "application/json",
17827
- Accept: "application/json, text/plain, */*"
17834
+ ]
17835
+ };
17836
+ } catch (error) {
17837
+ logger2.error(`Failed to call Wix Site API: ${error}`);
17838
+ const response = error.response;
17839
+ if (!response) {
17840
+ throw new Error(`Failed to call Wix Site API: ${error}`);
17828
17841
  }
17842
+ return handleWixAPIResponse(response);
17829
17843
  }
17830
- );
17831
- const result = sitesRes.data.sites?.map(({ id, displayName }) => ({
17832
- id,
17833
- name: displayName
17834
- })) ?? [];
17835
- return {
17836
- content: [
17844
+ }
17845
+ );
17846
+ }
17847
+ if (allowedTools.includes("ListWixSites")) {
17848
+ server.tool(
17849
+ "ListWixSites",
17850
+ "List Wix sites for the current user, by default it will return all sites, but you can filter by name",
17851
+ {
17852
+ nameSearch: external_exports.string().optional().describe(
17853
+ "optional filer by name, if not provided all sites will be returned"
17854
+ ),
17855
+ // Hack for Cursor ignoring tools with no params (when nameSearch is optional)
17856
+ alwaysTrue: external_exports.boolean().describe("Always pass true to this parameter")
17857
+ },
17858
+ async ({ nameSearch }, { httpClient }) => {
17859
+ const sitesRes = await httpClient.post(
17860
+ "https://www.wixapis.com/site-list/v2/sites/query",
17837
17861
  {
17838
- type: "text",
17839
- text: JSON.stringify(result)
17862
+ query: {
17863
+ cursorPaging: { limit: 21 },
17864
+ filter: {
17865
+ ...nameSearch ? {
17866
+ name: nameSearch
17867
+ } : {},
17868
+ namespace: {
17869
+ $in: ["WIX", "DASHBOARD_FIRST", "ANYWHERE", "HEADLESS"]
17870
+ }
17871
+ }
17872
+ }
17840
17873
  },
17841
17874
  {
17842
- type: "text",
17843
- text: "if there is more than one site returned, the user should pick one from a list, list the sites (only name) for the user and ask them to pick one,If more than 20 are found you should list all 20 and suggest to search by the name of the site they are looking for"
17875
+ headers: {
17876
+ ...await strategy.getAccountAuthHeaders(),
17877
+ "Content-Type": "application/json",
17878
+ Accept: "application/json, text/plain, */*"
17879
+ }
17844
17880
  }
17845
- ]
17846
- };
17847
- }
17848
- );
17849
- server.tool(
17850
- "ManageWixSite",
17851
- `Use account level API in order to create a site, update a site and publish site.
17852
- ALWAYS use "SearchWixRESTDocumentation" to search for the API you should invoke, NEVER GUESS THE SITE API URL
17853
- You should ALWAYS check the rest docs - "SearchWixRESTDocumentation" for the specific API you want to call, don't just call it without knowing what it does, CHECK THE DOCS`,
17854
- {
17855
- url: external_exports.string().describe(
17856
- "The url of the api to call - ALWAYS get the information from the Wix REST docs DONT GUESS IT, the URL MUST BE ABSOLUTE URL"
17857
- ),
17858
- method: external_exports.string().describe(
17859
- "The HTTP method to use for the API call (e.g. GET, POST, PUT, DELETE)"
17860
- ),
17861
- body: external_exports.string().optional().describe(
17862
- "A string representing of a valid JSON object to describe the body of the request"
17863
- )
17864
- },
17865
- async ({ url, body, method }, { httpClient }) => {
17866
- logger2.log(
17867
- `Calling Wix Account level API: ${url}, body: ${JSON.stringify(body)}`
17868
- );
17869
- try {
17870
- const response = await httpClient.request({
17871
- url,
17872
- method,
17873
- headers: {
17874
- ...await strategy.getAccountAuthHeaders(),
17875
- ...body ? { "Content-Type": "application/json" } : {}
17876
- },
17877
- data: method === "GET" ? void 0 : body
17878
- });
17879
- const responseData = await handleWixAPIResponse(response);
17881
+ );
17882
+ const result = sitesRes.data.sites?.map(({ id, displayName }) => ({
17883
+ id,
17884
+ name: displayName
17885
+ })) ?? [];
17880
17886
  return {
17881
17887
  content: [
17882
17888
  {
17883
17889
  type: "text",
17884
- text: `Wix Account API call successful: ${JSON.stringify(responseData)}`
17890
+ text: JSON.stringify(result)
17891
+ },
17892
+ {
17893
+ type: "text",
17894
+ text: "if there is more than one site returned, the user should pick one from a list, list the sites (only name) for the user and ask them to pick one,If more than 20 are found you should list all 20 and suggest to search by the name of the site they are looking for"
17885
17895
  }
17886
17896
  ]
17887
17897
  };
17888
- } catch (error) {
17889
- logger2.error(`Failed to call Wix Account API: ${error}`);
17890
- const response = error.response;
17891
- if (!response) {
17892
- throw new Error(`Failed to call Wix Account API: ${error}`);
17898
+ }
17899
+ );
17900
+ }
17901
+ if (allowedTools.includes("ManageWixSite")) {
17902
+ server.tool(
17903
+ "ManageWixSite",
17904
+ `Use account level API in order to create a site, update a site and publish site.
17905
+ ALWAYS use "SearchWixRESTDocumentation" to search for the API you should invoke, NEVER GUESS THE SITE API URL
17906
+ You should ALWAYS check the rest docs - "SearchWixRESTDocumentation" for the specific API you want to call, don't just call it without knowing what it does, CHECK THE DOCS`,
17907
+ {
17908
+ url: external_exports.string().url().describe(
17909
+ "The url of the api to call - ALWAYS get the information from the Wix REST docs DONT GUESS IT, the URL MUST BE ABSOLUTE URL"
17910
+ ),
17911
+ method: external_exports.string().describe(
17912
+ "The HTTP method to use for the API call (e.g. GET, POST, PUT, DELETE)"
17913
+ ),
17914
+ body: external_exports.string().optional().describe(
17915
+ "A string representing of a valid JSON object to describe the body of the request"
17916
+ )
17917
+ },
17918
+ async ({ url, body, method }, { httpClient }) => {
17919
+ logger2.log(
17920
+ `Calling Wix Account level API: ${url}, body: ${JSON.stringify(body)}`
17921
+ );
17922
+ const { isAllowed, error: urlError } = isApiUrlAllowed(url);
17923
+ if (!isAllowed) {
17924
+ return {
17925
+ content: [
17926
+ {
17927
+ isError: true,
17928
+ type: "text",
17929
+ text: `Error validating URL: ${urlError}`
17930
+ }
17931
+ ]
17932
+ };
17933
+ }
17934
+ try {
17935
+ const response = await httpClient.request({
17936
+ url,
17937
+ method,
17938
+ headers: {
17939
+ ...await strategy.getAccountAuthHeaders(),
17940
+ ...body ? { "Content-Type": "application/json" } : {}
17941
+ },
17942
+ data: method === "GET" ? void 0 : body
17943
+ });
17944
+ const responseData = await handleWixAPIResponse(response);
17945
+ return {
17946
+ content: [
17947
+ {
17948
+ type: "text",
17949
+ text: `Wix Account API call successful: ${JSON.stringify(responseData)}`
17950
+ }
17951
+ ]
17952
+ };
17953
+ } catch (error) {
17954
+ logger2.error(`Failed to call Wix Account API: ${error}`);
17955
+ const response = error.response;
17956
+ if (!response) {
17957
+ throw new Error(`Failed to call Wix Account API: ${error}`);
17958
+ }
17959
+ return handleWixAPIResponse(response);
17893
17960
  }
17894
- return handleWixAPIResponse(response);
17895
17961
  }
17896
- }
17897
- );
17962
+ );
17963
+ }
17898
17964
  }
17899
17965
 
17900
17966
  // src/resources/docs.ts