@wix/mcp 1.0.16 → 1.0.18

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 +12691 -12854
  2. package/build/bin-standalone.js.map +4 -4
  3. package/build/cjs/index.cjs +290 -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 +4 -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 +258 -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,
@@ -16525,12 +16510,16 @@ var axiosErrorFields3 = [
16525
16510
  ];
16526
16511
  var HttpError3 = class _HttpError extends Error {
16527
16512
  constructor(error) {
16513
+ var _a;
16528
16514
  super(error.message);
16529
16515
  this.isWixHttpError = true;
16530
16516
  Object.setPrototypeOf(this, _HttpError.prototype);
16531
16517
  axiosErrorFields3.forEach((key) => {
16532
16518
  this[key] = error[key];
16533
16519
  });
16520
+ if ((_a = this.response) === null || _a === void 0 ? void 0 : _a.headers) {
16521
+ this.response.requestId = requestIdOrEmptyString3(this.response);
16522
+ }
16534
16523
  }
16535
16524
  get requestId() {
16536
16525
  return requestIdOrEmptyString3(this.response);
@@ -16863,12 +16852,9 @@ var logger2 = createNullLogger();
16863
16852
 
16864
16853
  // src/wix-mcp-server.ts
16865
16854
  var WixMcpServer = class extends McpServer {
16866
- biLogger;
16867
- nodeEnv;
16868
- sessionId;
16869
- getUserId;
16870
16855
  constructor(serverInfo, options, nodeEnv) {
16871
16856
  super(serverInfo, options);
16857
+ this.serverInfo = serverInfo;
16872
16858
  this.sessionId = v4_default();
16873
16859
  this.nodeEnv = getEnvironment(nodeEnv);
16874
16860
  this.biLogger = createBiLogger({
@@ -16876,9 +16862,17 @@ var WixMcpServer = class extends McpServer {
16876
16862
  });
16877
16863
  logger2.log(`WixMcpServer created with sessionId: ${this.sessionId}`);
16878
16864
  }
16865
+ biLogger;
16866
+ nodeEnv;
16867
+ sessionId;
16868
+ getUserId;
16869
+ getClientName;
16879
16870
  setUserIdGetter(getUserId) {
16880
16871
  this.getUserId = getUserId;
16881
16872
  }
16873
+ setClientNameGetter(getClientName) {
16874
+ this.getClientName = getClientName;
16875
+ }
16882
16876
  tool(...args) {
16883
16877
  const cbIndex = args.findIndex((arg) => typeof arg === "function");
16884
16878
  if (cbIndex !== -1) {
@@ -16893,7 +16887,8 @@ var WixMcpServer = class extends McpServer {
16893
16887
  environment: this.nodeEnv,
16894
16888
  sessionId: this.sessionId,
16895
16889
  componentId: toolName,
16896
- uuid: this.getUserId?.()
16890
+ uuid: this.getUserId?.(),
16891
+ serverInfo: this.serverInfo
16897
16892
  });
16898
16893
  const toolInvocationId = v4_default();
16899
16894
  const httpClient = new HttpClient3({
@@ -16952,7 +16947,7 @@ var WixMcpServer = class extends McpServer {
16952
16947
  }
16953
16948
  this.biLogger.report(
16954
16949
  wixMcpRequestSrc39Evid1607({
16955
- clientName,
16950
+ clientName: this.getClientName?.() || clientName,
16956
16951
  duration,
16957
16952
  errorBody,
16958
16953
  toolInvocationId,
@@ -17118,6 +17113,18 @@ async function fetchArticleContentFromDigor(httpClient, articleUrl, mode, stripH
17118
17113
  }
17119
17114
  async function fetchArticleContent(httpClient, articleUrl, mode, stripHeader = false) {
17120
17115
  if (mode === "raw") {
17116
+ let parsedUrl;
17117
+ try {
17118
+ parsedUrl = new URL(articleUrl);
17119
+ } catch {
17120
+ throw new Error(`Invalid URL format: ${articleUrl}`);
17121
+ }
17122
+ const hostname = parsedUrl.hostname.replace("www.", "");
17123
+ if (hostname !== "dev.wix.com") {
17124
+ throw new Error(
17125
+ `Unsupported URL domain: ${hostname}. Article URL must be from dev.wix.com`
17126
+ );
17127
+ }
17121
17128
  const { data: doc } = await httpClient.get(articleUrl);
17122
17129
  return doc;
17123
17130
  }
@@ -17609,7 +17616,7 @@ var addDocsTools = (server, allowedTools = [
17609
17616
  getToKnowWixEnabled ? WixREADME_DEPENDENT_DESCRIPTION : ""
17610
17617
  ].join("\n"),
17611
17618
  {
17612
- articleUrl: external_exports.string().describe(
17619
+ articleUrl: external_exports.string().url().describe(
17613
17620
  "The URL of the docs article or method article to fetch. Should be something like https://dev.wix.com/docs/.../.../..."
17614
17621
  )
17615
17622
  },
@@ -17646,7 +17653,7 @@ var addDocsTools = (server, allowedTools = [
17646
17653
  content: [
17647
17654
  {
17648
17655
  type: "text",
17649
- text: "Could not fetch article content, you should try completing the task without it."
17656
+ text: `Could not fetch article content: "${error.message}". You should try completing the task without it.`
17650
17657
  }
17651
17658
  ]
17652
17659
  };
@@ -17660,7 +17667,7 @@ var addDocsTools = (server, allowedTools = [
17660
17667
  "This will give you the entire request/response schema with all the fields and their descriptions."
17661
17668
  ].join("\n"),
17662
17669
  {
17663
- articleUrl: external_exports.string().describe(
17670
+ articleUrl: external_exports.string().url().describe(
17664
17671
  "The URL of the documentation to fetch. Should be something like https://dev.wix.com/docs/.../.../..."
17665
17672
  )
17666
17673
  },
@@ -17690,7 +17697,7 @@ var addDocsTools = (server, allowedTools = [
17690
17697
  content: [
17691
17698
  {
17692
17699
  type: "text",
17693
- text: "Could not fetch method schema, you should try completing the task without it."
17700
+ text: `Could not fetch method schema: "${error.message}". You should try completing the task without it.`
17694
17701
  }
17695
17702
  ]
17696
17703
  };
@@ -17737,164 +17744,227 @@ var handleWixAPIResponse = async (response) => {
17737
17744
  return responseData;
17738
17745
  };
17739
17746
 
17747
+ // src/api-call/validation.ts
17748
+ function isApiUrlAllowed(url) {
17749
+ let parsedUrl;
17750
+ try {
17751
+ parsedUrl = new URL(url);
17752
+ } catch {
17753
+ return {
17754
+ isAllowed: false,
17755
+ error: `Invalid URL format: ${url}`
17756
+ };
17757
+ }
17758
+ const ALLOWED_HOSTNAMES = [
17759
+ "wix.com",
17760
+ "dev.wix.com",
17761
+ "manage.wix.com",
17762
+ "editor.wix.com",
17763
+ "wixapis.com"
17764
+ ];
17765
+ const hostname = parsedUrl.hostname.replace("www.", "");
17766
+ const isAllowedHostname = ALLOWED_HOSTNAMES.some(
17767
+ (domain) => hostname === domain
17768
+ );
17769
+ if (!isAllowedHostname) {
17770
+ return {
17771
+ isAllowed: false,
17772
+ error: `Unsupported URL domain: ${hostname}. URL must be from one of the allowed domains: ${ALLOWED_HOSTNAMES.join(", ")}`
17773
+ };
17774
+ }
17775
+ return {
17776
+ isAllowed: true
17777
+ };
17778
+ }
17779
+
17740
17780
  // 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}`);
17781
+ function addApiCallTool(server, strategy, allowedTools = ["CallWixSiteAPI", "ListWixSites", "ManageWixSite"]) {
17782
+ if (allowedTools.includes("CallWixSiteAPI")) {
17783
+ server.tool(
17784
+ "CallWixSiteAPI",
17785
+ [
17786
+ "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,",
17787
+ `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`,
17788
+ "Error Handling:",
17789
+ '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',
17790
+ "**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.",
17791
+ "For any other error, use your default error handling mechanism"
17792
+ ].join("\n"),
17793
+ {
17794
+ siteId: external_exports.string().describe("The id of the site selected using site selection tool"),
17795
+ url: external_exports.string().url().describe(
17796
+ "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"
17797
+ ),
17798
+ method: external_exports.string().describe(
17799
+ "The HTTP method to use for the API call (e.g. GET, POST, PUT, DELETE)"
17800
+ ),
17801
+ body: external_exports.string().optional().describe(
17802
+ "A string representing of a valid JSON object to describe the body of the request"
17803
+ )
17804
+ },
17805
+ async ({ url, body, method, siteId }, { httpClient }) => {
17806
+ logger2.log(
17807
+ `Calling Wix Site API: ${siteId} ${url}, body: ${JSON.stringify(body)}`
17808
+ );
17809
+ const { isAllowed, error: urlError } = isApiUrlAllowed(url);
17810
+ if (!isAllowed) {
17811
+ return {
17812
+ content: [
17813
+ {
17814
+ isError: true,
17815
+ type: "text",
17816
+ text: `Error validating URL: ${urlError}`
17817
+ }
17818
+ ]
17819
+ };
17792
17820
  }
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"]
17821
+ try {
17822
+ const response = await httpClient.request({
17823
+ url,
17824
+ method,
17825
+ headers: {
17826
+ ...await strategy.getSiteAuthHeaders(siteId),
17827
+ ...body ? { "Content-Type": "application/json" } : {}
17828
+ },
17829
+ data: method === "GET" ? void 0 : body
17830
+ });
17831
+ const responseData = await handleWixAPIResponse(response);
17832
+ return {
17833
+ content: [
17834
+ {
17835
+ type: "text",
17836
+ text: `Wix Site API call successful: ${JSON.stringify(responseData)}`
17819
17837
  }
17820
- }
17821
- }
17822
- },
17823
- {
17824
- headers: {
17825
- ...await strategy.getAccountAuthHeaders(),
17826
- "Content-Type": "application/json",
17827
- Accept: "application/json, text/plain, */*"
17838
+ ]
17839
+ };
17840
+ } catch (error) {
17841
+ logger2.error(`Failed to call Wix Site API: ${error}`);
17842
+ const response = error.response;
17843
+ if (!response) {
17844
+ throw new Error(`Failed to call Wix Site API: ${error}`);
17828
17845
  }
17846
+ return handleWixAPIResponse(response);
17829
17847
  }
17830
- );
17831
- const result = sitesRes.data.sites?.map(({ id, displayName }) => ({
17832
- id,
17833
- name: displayName
17834
- })) ?? [];
17835
- return {
17836
- content: [
17848
+ }
17849
+ );
17850
+ }
17851
+ if (allowedTools.includes("ListWixSites")) {
17852
+ server.tool(
17853
+ "ListWixSites",
17854
+ "List Wix sites for the current user, by default it will return all sites, but you can filter by name",
17855
+ {
17856
+ nameSearch: external_exports.string().optional().describe(
17857
+ "optional filer by name, if not provided all sites will be returned"
17858
+ ),
17859
+ // Hack for Cursor ignoring tools with no params (when nameSearch is optional)
17860
+ alwaysTrue: external_exports.boolean().describe("Always pass true to this parameter")
17861
+ },
17862
+ async ({ nameSearch }, { httpClient }) => {
17863
+ const sitesRes = await httpClient.post(
17864
+ "https://www.wixapis.com/site-list/v2/sites/query",
17837
17865
  {
17838
- type: "text",
17839
- text: JSON.stringify(result)
17866
+ query: {
17867
+ cursorPaging: { limit: 21 },
17868
+ filter: {
17869
+ ...nameSearch ? {
17870
+ name: nameSearch
17871
+ } : {},
17872
+ namespace: {
17873
+ $in: ["WIX", "DASHBOARD_FIRST", "ANYWHERE", "HEADLESS"]
17874
+ }
17875
+ }
17876
+ }
17840
17877
  },
17841
17878
  {
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"
17879
+ headers: {
17880
+ ...await strategy.getAccountAuthHeaders(),
17881
+ "Content-Type": "application/json",
17882
+ Accept: "application/json, text/plain, */*"
17883
+ }
17844
17884
  }
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);
17885
+ );
17886
+ const result = sitesRes.data.sites?.map(({ id, displayName }) => ({
17887
+ id,
17888
+ name: displayName
17889
+ })) ?? [];
17880
17890
  return {
17881
17891
  content: [
17882
17892
  {
17883
17893
  type: "text",
17884
- text: `Wix Account API call successful: ${JSON.stringify(responseData)}`
17894
+ text: JSON.stringify(result)
17895
+ },
17896
+ {
17897
+ type: "text",
17898
+ 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
17899
  }
17886
17900
  ]
17887
17901
  };
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}`);
17902
+ }
17903
+ );
17904
+ }
17905
+ if (allowedTools.includes("ManageWixSite")) {
17906
+ server.tool(
17907
+ "ManageWixSite",
17908
+ `Use account level API in order to create a site, update a site and publish site.
17909
+ ALWAYS use "SearchWixRESTDocumentation" to search for the API you should invoke, NEVER GUESS THE SITE API URL
17910
+ 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`,
17911
+ {
17912
+ url: external_exports.string().url().describe(
17913
+ "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"
17914
+ ),
17915
+ method: external_exports.string().describe(
17916
+ "The HTTP method to use for the API call (e.g. GET, POST, PUT, DELETE)"
17917
+ ),
17918
+ body: external_exports.string().optional().describe(
17919
+ "A string representing of a valid JSON object to describe the body of the request"
17920
+ )
17921
+ },
17922
+ async ({ url, body, method }, { httpClient }) => {
17923
+ logger2.log(
17924
+ `Calling Wix Account level API: ${url}, body: ${JSON.stringify(body)}`
17925
+ );
17926
+ const { isAllowed, error: urlError } = isApiUrlAllowed(url);
17927
+ if (!isAllowed) {
17928
+ return {
17929
+ content: [
17930
+ {
17931
+ isError: true,
17932
+ type: "text",
17933
+ text: `Error validating URL: ${urlError}`
17934
+ }
17935
+ ]
17936
+ };
17937
+ }
17938
+ try {
17939
+ const response = await httpClient.request({
17940
+ url,
17941
+ method,
17942
+ headers: {
17943
+ ...await strategy.getAccountAuthHeaders(),
17944
+ ...body ? { "Content-Type": "application/json" } : {}
17945
+ },
17946
+ data: method === "GET" ? void 0 : body
17947
+ });
17948
+ const responseData = await handleWixAPIResponse(response);
17949
+ return {
17950
+ content: [
17951
+ {
17952
+ type: "text",
17953
+ text: `Wix Account API call successful: ${JSON.stringify(responseData)}`
17954
+ }
17955
+ ]
17956
+ };
17957
+ } catch (error) {
17958
+ logger2.error(`Failed to call Wix Account API: ${error}`);
17959
+ const response = error.response;
17960
+ if (!response) {
17961
+ throw new Error(`Failed to call Wix Account API: ${error}`);
17962
+ }
17963
+ return handleWixAPIResponse(response);
17893
17964
  }
17894
- return handleWixAPIResponse(response);
17895
17965
  }
17896
- }
17897
- );
17966
+ );
17967
+ }
17898
17968
  }
17899
17969
 
17900
17970
  // src/resources/docs.ts