@elementor/editor-mcp 4.2.0-942 → 4.2.0-943

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/dist/index.d.mts CHANGED
@@ -71,10 +71,9 @@ type ResourceList = {
71
71
 
72
72
  declare const registerMcpAdapter: (adapter: IMcpRegistrationAdapter) => void;
73
73
  declare const signalMcpReady: () => void;
74
- declare const activateAdapters: () => Promise<void>;
74
+ declare const createAndRegisterAdapters: () => void;
75
75
  declare const registerMcp: (mcp: McpServer, name: string) => void;
76
76
  declare const getRegisteredMcpServers: () => Array<[string, McpServer, string]>;
77
- declare const toMCPTitle: (namespace: string) => string;
78
77
  /**
79
78
  * @param namespace The namespace of the MCP server. It should contain only lowercase alphabetic characters.
80
79
  * @param options
@@ -398,8 +397,8 @@ declare const installAngiePlugin: () => Promise<InstallAngieResult>;
398
397
 
399
398
  declare const saveAngieConsent: () => Promise<void>;
400
399
 
401
- declare function startMCPServer(): Promise<void>;
400
+ declare function startMCPServer(): void;
402
401
 
403
402
  declare const getAngieSdk: () => _elementor_external_angie_sdk.AngieMcpSdk;
404
403
 
405
- export { ANGIE_MODEL_PREFERENCES, ANGIE_REQUIRED_RESOURCES, type ActiveChatInfo, type AngieModelPreferences, type InstallAngieResult, type MCPRegistryEntry, activateAdapters, createSampler, getActiveChatInfo, getAngieSdk, getMCPByDomain, getRegisteredMcpServers, installAngiePlugin, isAngieAvailable, isAngieSidebarOpen, redirectToAppAdmin, redirectToInstallation, registerMcp, registerMcpAdapter, saveAngieConsent, sendPromptToAngie, signalMcpReady, startMCPServer, toMCPTitle, toolPrompts };
404
+ export { ANGIE_MODEL_PREFERENCES, ANGIE_REQUIRED_RESOURCES, type ActiveChatInfo, type AngieModelPreferences, type InstallAngieResult, type MCPRegistryEntry, createAndRegisterAdapters, createSampler, getActiveChatInfo, getAngieSdk, getMCPByDomain, getRegisteredMcpServers, installAngiePlugin, isAngieAvailable, isAngieSidebarOpen, redirectToAppAdmin, redirectToInstallation, registerMcp, registerMcpAdapter, saveAngieConsent, sendPromptToAngie, signalMcpReady, startMCPServer, toolPrompts };
package/dist/index.d.ts CHANGED
@@ -71,10 +71,9 @@ type ResourceList = {
71
71
 
72
72
  declare const registerMcpAdapter: (adapter: IMcpRegistrationAdapter) => void;
73
73
  declare const signalMcpReady: () => void;
74
- declare const activateAdapters: () => Promise<void>;
74
+ declare const createAndRegisterAdapters: () => void;
75
75
  declare const registerMcp: (mcp: McpServer, name: string) => void;
76
76
  declare const getRegisteredMcpServers: () => Array<[string, McpServer, string]>;
77
- declare const toMCPTitle: (namespace: string) => string;
78
77
  /**
79
78
  * @param namespace The namespace of the MCP server. It should contain only lowercase alphabetic characters.
80
79
  * @param options
@@ -398,8 +397,8 @@ declare const installAngiePlugin: () => Promise<InstallAngieResult>;
398
397
 
399
398
  declare const saveAngieConsent: () => Promise<void>;
400
399
 
401
- declare function startMCPServer(): Promise<void>;
400
+ declare function startMCPServer(): void;
402
401
 
403
402
  declare const getAngieSdk: () => _elementor_external_angie_sdk.AngieMcpSdk;
404
403
 
405
- export { ANGIE_MODEL_PREFERENCES, ANGIE_REQUIRED_RESOURCES, type ActiveChatInfo, type AngieModelPreferences, type InstallAngieResult, type MCPRegistryEntry, activateAdapters, createSampler, getActiveChatInfo, getAngieSdk, getMCPByDomain, getRegisteredMcpServers, installAngiePlugin, isAngieAvailable, isAngieSidebarOpen, redirectToAppAdmin, redirectToInstallation, registerMcp, registerMcpAdapter, saveAngieConsent, sendPromptToAngie, signalMcpReady, startMCPServer, toMCPTitle, toolPrompts };
404
+ export { ANGIE_MODEL_PREFERENCES, ANGIE_REQUIRED_RESOURCES, type ActiveChatInfo, type AngieModelPreferences, type InstallAngieResult, type MCPRegistryEntry, createAndRegisterAdapters, createSampler, getActiveChatInfo, getAngieSdk, getMCPByDomain, getRegisteredMcpServers, installAngiePlugin, isAngieAvailable, isAngieSidebarOpen, redirectToAppAdmin, redirectToInstallation, registerMcp, registerMcpAdapter, saveAngieConsent, sendPromptToAngie, signalMcpReady, startMCPServer, toolPrompts };
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ __export(index_exports, {
36
36
  McpServer: () => import_mcp2.McpServer,
37
37
  ResourceTemplate: () => import_mcp2.ResourceTemplate,
38
38
  SamplingMessageSchema: () => import_types2.SamplingMessageSchema,
39
- activateAdapters: () => activateAdapters,
39
+ createAndRegisterAdapters: () => createAndRegisterAdapters,
40
40
  createSampler: () => createSampler,
41
41
  getActiveChatInfo: () => getActiveChatInfo,
42
42
  getAngieIframe: () => import_angie_sdk2.getAngieIframe,
@@ -54,7 +54,6 @@ __export(index_exports, {
54
54
  sendPromptToAngie: () => sendPromptToAngie,
55
55
  signalMcpReady: () => signalMcpReady,
56
56
  startMCPServer: () => startMCPServer,
57
- toMCPTitle: () => toMCPTitle,
58
57
  toolPrompts: () => toolPrompts
59
58
  });
60
59
  module.exports = __toCommonJS(index_exports);
@@ -63,13 +62,32 @@ module.exports = __toCommonJS(index_exports);
63
62
  var import_angie_sdk = require("@elementor-external/angie-sdk");
64
63
  var import_angie_sdk2 = require("@elementor-external/angie-sdk");
65
64
  var sdk;
65
+ var RetriableAngieSDK = class extends import_angie_sdk.AngieMcpSdk {
66
+ async waitForReady() {
67
+ let retryCount = 3;
68
+ while (retryCount > 0) {
69
+ try {
70
+ await super.waitForReady();
71
+ return;
72
+ } catch {
73
+ retryCount--;
74
+ await sleep();
75
+ }
76
+ }
77
+ return new Promise(() => {
78
+ });
79
+ }
80
+ };
81
+ var sleep = (ms = 1e4) => new Promise((resolve) => {
82
+ setTimeout(resolve, ms);
83
+ });
66
84
  var getSDK = () => {
67
85
  const isMCPDisabled = !!globalThis.__ELEMENTOR_MCP_DISABLED__;
68
86
  if (isMCPDisabled) {
69
87
  return {};
70
88
  }
71
89
  if (!sdk) {
72
- sdk = new import_angie_sdk.AngieMcpSdk();
90
+ sdk = new RetriableAngieSDK();
73
91
  }
74
92
  return sdk;
75
93
  };
@@ -91,9 +109,180 @@ var isAngieSidebarOpen = () => {
91
109
  };
92
110
 
93
111
  // src/mcp-registry.ts
94
- var import_schema = require("@elementor/schema");
112
+ var import_schema2 = require("@elementor/schema");
95
113
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
96
114
 
115
+ // src/utils/to-mcp-title.ts
116
+ var toMCPTitle = (namespace) => {
117
+ const capitalized = namespace.charAt(0).toUpperCase() + namespace.slice(1);
118
+ return `Editor ${capitalized}`;
119
+ };
120
+
121
+ // src/adapters/angie-adapter.ts
122
+ var MAX_RETRIES = 3;
123
+ var AngieMcpAdapter = class {
124
+ constructor(sdk2, getRegisteredMcpServers2) {
125
+ this.sdk = sdk2;
126
+ this.getRegisteredMcpServers = getRegisteredMcpServers2;
127
+ }
128
+ async activate() {
129
+ await this.sdk.waitForReady();
130
+ await this.registerEntries(this.getRegisteredMcpServers(), MAX_RETRIES);
131
+ }
132
+ async registerEntries(entries, retry) {
133
+ if (retry === 0) {
134
+ console.error(
135
+ "Failed to register MCP after 3 retries. failed entries: ",
136
+ entries.map(([key]) => key)
137
+ );
138
+ return;
139
+ }
140
+ const failed = [];
141
+ for (const [key, mcpServer, description] of entries) {
142
+ try {
143
+ await this.sdk.registerLocalServer({
144
+ title: toMCPTitle(key),
145
+ name: `editor-${key}`,
146
+ server: mcpServer,
147
+ version: "1.0.0",
148
+ description
149
+ });
150
+ } catch {
151
+ failed.push([key, mcpServer, description]);
152
+ }
153
+ }
154
+ if (failed.length > 0) {
155
+ return this.registerEntries(failed, retry - 1);
156
+ }
157
+ }
158
+ onToolRegistered() {
159
+ }
160
+ onResourceRegistered() {
161
+ }
162
+ sendResourceUpdated() {
163
+ }
164
+ };
165
+
166
+ // src/adapters/web-mcp-adapter.ts
167
+ var import_zod_to_json_schema = require("zod-to-json-schema");
168
+ var import_schema = require("@elementor/schema");
169
+ var WebMCPAdapter = class {
170
+ constructor(ctx) {
171
+ this.ctx = ctx;
172
+ }
173
+ registeredToolNames = /* @__PURE__ */ new Set();
174
+ resourceEntries = [];
175
+ activated = false;
176
+ activate() {
177
+ if (this.activated) {
178
+ return;
179
+ }
180
+ this.activated = true;
181
+ this.ctx.registerTool({
182
+ name: "editor-resource-getter",
183
+ description: "Get an editor resource by URI, or search for available resources by partial URI. Pass a full URI to retrieve content, or a partial string to discover matching patterns.",
184
+ inputSchema: {
185
+ type: "object",
186
+ properties: {
187
+ uri: {
188
+ type: "string",
189
+ description: "A full resource URI (e.g. elementor://styles/best-practices) or a partial string to search across available resource patterns."
190
+ }
191
+ },
192
+ required: ["uri"]
193
+ },
194
+ execute: async (params) => {
195
+ const query = params.uri;
196
+ const entries = this.resourceEntries;
197
+ if (entries.length === 0) {
198
+ return "No resources are registered yet.";
199
+ }
200
+ for (const entry of entries) {
201
+ const variables = entry.match(query);
202
+ if (variables !== null) {
203
+ let resourceUrl;
204
+ try {
205
+ resourceUrl = new URL(query);
206
+ } catch {
207
+ return `Invalid URI '${query}'. Provide a valid resource URI or a partial string to search patterns.`;
208
+ }
209
+ const result = await entry.handler(resourceUrl, variables);
210
+ return result.contents?.[0]?.text ?? JSON.stringify(result);
211
+ }
212
+ }
213
+ const matches = entries.map((e) => e.pattern).filter((pattern) => pattern.includes(query));
214
+ if (matches.length > 0) {
215
+ return `Found ${matches.length} matching resource pattern(s):
216
+ ${matches.join(
217
+ "\n"
218
+ )}
219
+
220
+ Provide a full URI to retrieve the resource content.`;
221
+ }
222
+ const available = entries.map((e) => e.pattern).join("\n");
223
+ throw new Error(`No resource matched '${query}'.
224
+
225
+ Available patterns:
226
+ ${available}`);
227
+ }
228
+ });
229
+ }
230
+ onToolRegistered(tool, extraData) {
231
+ let jsonSchema;
232
+ try {
233
+ jsonSchema = (0, import_zod_to_json_schema.zodToJsonSchema)(import_schema.z.object(tool.inputSchema));
234
+ } catch {
235
+ jsonSchema = tool.inputSchema;
236
+ }
237
+ if (this.registeredToolNames.has(tool.name)) {
238
+ this.ctx.unregisterTool(tool.name);
239
+ }
240
+ let resourcesDescription = "";
241
+ if (extraData) {
242
+ if (extraData.resources?.length > 0) {
243
+ resourcesDescription += `#Resources:
244
+ ${extraData.resources?.join("\n")}
245
+
246
+ `;
247
+ }
248
+ if (extraData.requiredResources?.length > 0) {
249
+ resourcesDescription += `#Required Resources:
250
+ ${extraData.requiredResources?.join("\n")}
251
+
252
+ `;
253
+ }
254
+ resourcesDescription += `To read resources, use editor-resource-getter tool.
255
+
256
+ `;
257
+ }
258
+ this.ctx.registerTool({
259
+ name: tool.name,
260
+ description: `${resourcesDescription}${tool.description}`,
261
+ inputSchema: jsonSchema,
262
+ execute: tool.execute
263
+ });
264
+ this.registeredToolNames.add(tool.name);
265
+ }
266
+ onResourceRegistered(_name, uriOrTemplate, handler) {
267
+ if (typeof uriOrTemplate === "string") {
268
+ this.resourceEntries.push({
269
+ pattern: uriOrTemplate,
270
+ match: (uri) => uri === uriOrTemplate ? {} : null,
271
+ handler
272
+ });
273
+ } else {
274
+ const template = uriOrTemplate.uriTemplate;
275
+ this.resourceEntries.push({
276
+ pattern: template.toString(),
277
+ match: (uri) => template.match(uri),
278
+ handler
279
+ });
280
+ }
281
+ }
282
+ sendResourceUpdated() {
283
+ }
284
+ };
285
+
97
286
  // src/angie-annotations.ts
98
287
  var ANGIE_MODEL_PREFERENCES = "angie/modelPreferences";
99
288
  var ANGIE_REQUIRED_RESOURCES = "angie/requiredResources";
@@ -132,6 +321,13 @@ var mockMcpRegistry = () => {
132
321
  };
133
322
  };
134
323
 
324
+ // src/utils/get-model-context.ts
325
+ function getModelContext() {
326
+ const documentModelContext = typeof document !== "undefined" ? document.modelContext : void 0;
327
+ const navigatorModelContext = typeof navigator !== "undefined" ? navigator.modelContext : void 0;
328
+ return documentModelContext || navigatorModelContext;
329
+ }
330
+
135
331
  // src/utils/merge-required-resources.ts
136
332
  var mergeRequiredResources = (toolResources, serverDocsUri) => {
137
333
  if (!serverDocsUri) {
@@ -192,12 +388,23 @@ var registerMcpAdapter = (adapter) => {
192
388
  }
193
389
  }
194
390
  };
195
- var signalMcpReady = () => resolveReady();
196
- var activateAdapters = () => callAdapters((adapter) => adapter.activate());
197
- async function callAdapters(fn) {
391
+ var signalMcpReady = () => {
392
+ resolveReady();
393
+ };
394
+ var createAndRegisterAdapters = () => {
395
+ const modelContext = getModelContext();
396
+ if (modelContext) {
397
+ registerMcpAdapter(new WebMCPAdapter(modelContext));
398
+ }
399
+ if (isAngieAvailable()) {
400
+ registerMcpAdapter(new AngieMcpAdapter(getSDK(), getRegisteredMcpServers));
401
+ }
402
+ registrationAdapters.forEach((adapter) => adapter.activate());
403
+ };
404
+ function callAdapters(fn) {
198
405
  for (const adapter of registrationAdapters) {
199
406
  try {
200
- await Promise.resolve(fn(adapter));
407
+ fn(adapter);
201
408
  } catch {
202
409
  }
203
410
  }
@@ -216,10 +423,6 @@ var isAlphabet = (str) => {
216
423
  }
217
424
  return str;
218
425
  };
219
- var toMCPTitle = (namespace) => {
220
- const capitalized = namespace.charAt(0).toUpperCase() + namespace.slice(1);
221
- return `Editor ${capitalized}`;
222
- };
223
426
  var getMCPByDomain = (namespace, options) => {
224
427
  const mcpName = `editor-${isAlphabet(namespace)}`;
225
428
  const title = toMCPTitle(namespace);
@@ -281,7 +484,7 @@ function createToolRegistry(server, serverName, serverDocsUri) {
281
484
  Object.assign(
282
485
  outputSchema,
283
486
  outputSchema.errors ?? {
284
- errors: import_schema.z.string().optional().describe("Error message if the tool failed")
487
+ errors: import_schema2.z.string().optional().describe("Error message if the tool failed")
285
488
  }
286
489
  );
287
490
  }
@@ -558,185 +761,15 @@ var saveAngieConsent = async () => {
558
761
  });
559
762
  };
560
763
 
561
- // src/adapters/angie-adapter.ts
562
- var MAX_RETRIES = 3;
563
- var AngieMcpAdapter = class {
564
- constructor(sdk2) {
565
- this.sdk = sdk2;
566
- }
567
- async activate() {
568
- await this.sdk.waitForReady();
569
- await this.registerEntries(getRegisteredMcpServers(), MAX_RETRIES);
570
- }
571
- async registerEntries(entries, retry) {
572
- if (retry === 0) {
573
- console.error(
574
- "Failed to register MCP after 3 retries. failed entries: ",
575
- entries.map(([key]) => key)
576
- );
577
- return;
578
- }
579
- const failed = [];
580
- for (const [key, mcpServer, description] of entries) {
581
- try {
582
- await this.sdk.registerLocalServer({
583
- title: toMCPTitle(key),
584
- name: `editor-${key}`,
585
- server: mcpServer,
586
- version: "1.0.0",
587
- description
588
- });
589
- } catch {
590
- failed.push([key, mcpServer, description]);
591
- }
592
- }
593
- if (failed.length > 0) {
594
- return this.registerEntries(failed, retry - 1);
595
- }
596
- }
597
- onToolRegistered() {
598
- }
599
- onResourceRegistered() {
600
- }
601
- sendResourceUpdated() {
602
- }
603
- };
604
-
605
- // src/adapters/web-mcp-adapter.ts
606
- var import_zod_to_json_schema = require("zod-to-json-schema");
607
- var import_schema2 = require("@elementor/schema");
608
- var WebMCPAdapter = class {
609
- constructor(ctx) {
610
- this.ctx = ctx;
611
- }
612
- registeredToolNames = /* @__PURE__ */ new Set();
613
- resourceEntries = [];
614
- activated = false;
615
- activate() {
616
- if (this.activated) {
617
- return;
618
- }
619
- this.activated = true;
620
- this.ctx.registerTool({
621
- name: "editor-resource-getter",
622
- description: "Get an editor resource by URI, or search for available resources by partial URI. Pass a full URI to retrieve content, or a partial string to discover matching patterns.",
623
- inputSchema: {
624
- type: "object",
625
- properties: {
626
- uri: {
627
- type: "string",
628
- description: "A full resource URI (e.g. elementor://styles/best-practices) or a partial string to search across available resource patterns."
629
- }
630
- },
631
- required: ["uri"]
632
- },
633
- execute: async (params) => {
634
- const query = params.uri;
635
- const entries = this.resourceEntries;
636
- if (entries.length === 0) {
637
- return "No resources are registered yet.";
638
- }
639
- for (const entry of entries) {
640
- const variables = entry.match(query);
641
- if (variables !== null) {
642
- let resourceUrl;
643
- try {
644
- resourceUrl = new URL(query);
645
- } catch {
646
- return `Invalid URI '${query}'. Provide a valid resource URI or a partial string to search patterns.`;
647
- }
648
- const result = await entry.handler(resourceUrl, variables);
649
- return result.contents?.[0]?.text ?? JSON.stringify(result);
650
- }
651
- }
652
- const matches = entries.map((e) => e.pattern).filter((pattern) => pattern.includes(query));
653
- if (matches.length > 0) {
654
- return `Found ${matches.length} matching resource pattern(s):
655
- ${matches.join(
656
- "\n"
657
- )}
658
-
659
- Provide a full URI to retrieve the resource content.`;
660
- }
661
- const available = entries.map((e) => e.pattern).join("\n");
662
- throw new Error(`No resource matched '${query}'.
663
-
664
- Available patterns:
665
- ${available}`);
666
- }
667
- });
668
- }
669
- onToolRegistered(tool, extraData) {
670
- let jsonSchema;
671
- try {
672
- jsonSchema = (0, import_zod_to_json_schema.zodToJsonSchema)(import_schema2.z.object(tool.inputSchema));
673
- } catch {
674
- jsonSchema = tool.inputSchema;
675
- }
676
- if (this.registeredToolNames.has(tool.name)) {
677
- this.ctx.unregisterTool(tool.name);
678
- }
679
- let resourcesDescription = "";
680
- if (extraData) {
681
- if (extraData.resources?.length > 0) {
682
- resourcesDescription += `#Resources:
683
- ${extraData.resources?.join("\n")}
684
-
685
- `;
686
- }
687
- if (extraData.requiredResources?.length > 0) {
688
- resourcesDescription += `#Required Resources:
689
- ${extraData.requiredResources?.join("\n")}
690
-
691
- `;
692
- }
693
- resourcesDescription += `To read resources, use editor-resource-getter tool.
694
-
695
- `;
696
- }
697
- this.ctx.registerTool({
698
- name: tool.name,
699
- description: `${resourcesDescription}${tool.description}`,
700
- inputSchema: jsonSchema,
701
- execute: tool.execute
702
- });
703
- this.registeredToolNames.add(tool.name);
704
- }
705
- onResourceRegistered(_name, uriOrTemplate, handler) {
706
- if (typeof uriOrTemplate === "string") {
707
- this.resourceEntries.push({
708
- pattern: uriOrTemplate,
709
- match: (uri) => uri === uriOrTemplate ? {} : null,
710
- handler
711
- });
712
- } else {
713
- const template = uriOrTemplate.uriTemplate;
714
- this.resourceEntries.push({
715
- pattern: template.toString(),
716
- match: (uri) => template.match(uri),
717
- handler
718
- });
719
- }
720
- }
721
- sendResourceUpdated() {
722
- }
723
- };
724
-
725
764
  // src/init.ts
726
- function getModelContext() {
727
- const documentModelContext = typeof document !== "undefined" ? document.modelContext : void 0;
728
- const navigatorModelContext = typeof navigator !== "undefined" ? navigator.modelContext : void 0;
729
- return documentModelContext || navigatorModelContext;
730
- }
765
+ var isInitialized = false;
731
766
  function startMCPServer() {
732
- const modelContext = getModelContext();
733
- if (modelContext) {
734
- registerMcpAdapter(new WebMCPAdapter(modelContext));
735
- }
736
- if (isAngieAvailable()) {
737
- registerMcpAdapter(new AngieMcpAdapter(getSDK()));
767
+ if (isInitialized) {
768
+ return;
738
769
  }
739
- return activateAdapters().then(() => signalMcpReady());
770
+ isInitialized = true;
771
+ createAndRegisterAdapters();
772
+ signalMcpReady();
740
773
  }
741
774
  if (typeof document !== "undefined") {
742
775
  document.addEventListener("DOMContentLoaded", () => startMCPServer(), { once: true });
@@ -754,7 +787,7 @@ var getAngieSdk = () => getSDK();
754
787
  McpServer,
755
788
  ResourceTemplate,
756
789
  SamplingMessageSchema,
757
- activateAdapters,
790
+ createAndRegisterAdapters,
758
791
  createSampler,
759
792
  getActiveChatInfo,
760
793
  getAngieIframe,
@@ -772,7 +805,6 @@ var getAngieSdk = () => getSDK();
772
805
  sendPromptToAngie,
773
806
  signalMcpReady,
774
807
  startMCPServer,
775
- toMCPTitle,
776
808
  toolPrompts
777
809
  });
778
810
  //# sourceMappingURL=index.js.map