@elementor/editor-mcp 4.2.0-941 → 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.mjs CHANGED
@@ -2,13 +2,32 @@
2
2
  import { AngieMcpSdk } from "@elementor-external/angie-sdk";
3
3
  import { getAngieIframe, MessageEventType } from "@elementor-external/angie-sdk";
4
4
  var sdk;
5
+ var RetriableAngieSDK = class extends AngieMcpSdk {
6
+ async waitForReady() {
7
+ let retryCount = 3;
8
+ while (retryCount > 0) {
9
+ try {
10
+ await super.waitForReady();
11
+ return;
12
+ } catch {
13
+ retryCount--;
14
+ await sleep();
15
+ }
16
+ }
17
+ return new Promise(() => {
18
+ });
19
+ }
20
+ };
21
+ var sleep = (ms = 1e4) => new Promise((resolve) => {
22
+ setTimeout(resolve, ms);
23
+ });
5
24
  var getSDK = () => {
6
25
  const isMCPDisabled = !!globalThis.__ELEMENTOR_MCP_DISABLED__;
7
26
  if (isMCPDisabled) {
8
27
  return {};
9
28
  }
10
29
  if (!sdk) {
11
- sdk = new AngieMcpSdk();
30
+ sdk = new RetriableAngieSDK();
12
31
  }
13
32
  return sdk;
14
33
  };
@@ -33,9 +52,180 @@ var isAngieSidebarOpen = () => {
33
52
  };
34
53
 
35
54
  // src/mcp-registry.ts
36
- import { z } from "@elementor/schema";
55
+ import { z as z2 } from "@elementor/schema";
37
56
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
38
57
 
58
+ // src/utils/to-mcp-title.ts
59
+ var toMCPTitle = (namespace) => {
60
+ const capitalized = namespace.charAt(0).toUpperCase() + namespace.slice(1);
61
+ return `Editor ${capitalized}`;
62
+ };
63
+
64
+ // src/adapters/angie-adapter.ts
65
+ var MAX_RETRIES = 3;
66
+ var AngieMcpAdapter = class {
67
+ constructor(sdk2, getRegisteredMcpServers2) {
68
+ this.sdk = sdk2;
69
+ this.getRegisteredMcpServers = getRegisteredMcpServers2;
70
+ }
71
+ async activate() {
72
+ await this.sdk.waitForReady();
73
+ await this.registerEntries(this.getRegisteredMcpServers(), MAX_RETRIES);
74
+ }
75
+ async registerEntries(entries, retry) {
76
+ if (retry === 0) {
77
+ console.error(
78
+ "Failed to register MCP after 3 retries. failed entries: ",
79
+ entries.map(([key]) => key)
80
+ );
81
+ return;
82
+ }
83
+ const failed = [];
84
+ for (const [key, mcpServer, description] of entries) {
85
+ try {
86
+ await this.sdk.registerLocalServer({
87
+ title: toMCPTitle(key),
88
+ name: `editor-${key}`,
89
+ server: mcpServer,
90
+ version: "1.0.0",
91
+ description
92
+ });
93
+ } catch {
94
+ failed.push([key, mcpServer, description]);
95
+ }
96
+ }
97
+ if (failed.length > 0) {
98
+ return this.registerEntries(failed, retry - 1);
99
+ }
100
+ }
101
+ onToolRegistered() {
102
+ }
103
+ onResourceRegistered() {
104
+ }
105
+ sendResourceUpdated() {
106
+ }
107
+ };
108
+
109
+ // src/adapters/web-mcp-adapter.ts
110
+ import { zodToJsonSchema } from "zod-to-json-schema";
111
+ import { z } from "@elementor/schema";
112
+ var WebMCPAdapter = class {
113
+ constructor(ctx) {
114
+ this.ctx = ctx;
115
+ }
116
+ registeredToolNames = /* @__PURE__ */ new Set();
117
+ resourceEntries = [];
118
+ activated = false;
119
+ activate() {
120
+ if (this.activated) {
121
+ return;
122
+ }
123
+ this.activated = true;
124
+ this.ctx.registerTool({
125
+ name: "editor-resource-getter",
126
+ 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.",
127
+ inputSchema: {
128
+ type: "object",
129
+ properties: {
130
+ uri: {
131
+ type: "string",
132
+ description: "A full resource URI (e.g. elementor://styles/best-practices) or a partial string to search across available resource patterns."
133
+ }
134
+ },
135
+ required: ["uri"]
136
+ },
137
+ execute: async (params) => {
138
+ const query = params.uri;
139
+ const entries = this.resourceEntries;
140
+ if (entries.length === 0) {
141
+ return "No resources are registered yet.";
142
+ }
143
+ for (const entry of entries) {
144
+ const variables = entry.match(query);
145
+ if (variables !== null) {
146
+ let resourceUrl;
147
+ try {
148
+ resourceUrl = new URL(query);
149
+ } catch {
150
+ return `Invalid URI '${query}'. Provide a valid resource URI or a partial string to search patterns.`;
151
+ }
152
+ const result = await entry.handler(resourceUrl, variables);
153
+ return result.contents?.[0]?.text ?? JSON.stringify(result);
154
+ }
155
+ }
156
+ const matches = entries.map((e) => e.pattern).filter((pattern) => pattern.includes(query));
157
+ if (matches.length > 0) {
158
+ return `Found ${matches.length} matching resource pattern(s):
159
+ ${matches.join(
160
+ "\n"
161
+ )}
162
+
163
+ Provide a full URI to retrieve the resource content.`;
164
+ }
165
+ const available = entries.map((e) => e.pattern).join("\n");
166
+ throw new Error(`No resource matched '${query}'.
167
+
168
+ Available patterns:
169
+ ${available}`);
170
+ }
171
+ });
172
+ }
173
+ onToolRegistered(tool, extraData) {
174
+ let jsonSchema;
175
+ try {
176
+ jsonSchema = zodToJsonSchema(z.object(tool.inputSchema));
177
+ } catch {
178
+ jsonSchema = tool.inputSchema;
179
+ }
180
+ if (this.registeredToolNames.has(tool.name)) {
181
+ this.ctx.unregisterTool(tool.name);
182
+ }
183
+ let resourcesDescription = "";
184
+ if (extraData) {
185
+ if (extraData.resources?.length > 0) {
186
+ resourcesDescription += `#Resources:
187
+ ${extraData.resources?.join("\n")}
188
+
189
+ `;
190
+ }
191
+ if (extraData.requiredResources?.length > 0) {
192
+ resourcesDescription += `#Required Resources:
193
+ ${extraData.requiredResources?.join("\n")}
194
+
195
+ `;
196
+ }
197
+ resourcesDescription += `To read resources, use editor-resource-getter tool.
198
+
199
+ `;
200
+ }
201
+ this.ctx.registerTool({
202
+ name: tool.name,
203
+ description: `${resourcesDescription}${tool.description}`,
204
+ inputSchema: jsonSchema,
205
+ execute: tool.execute
206
+ });
207
+ this.registeredToolNames.add(tool.name);
208
+ }
209
+ onResourceRegistered(_name, uriOrTemplate, handler) {
210
+ if (typeof uriOrTemplate === "string") {
211
+ this.resourceEntries.push({
212
+ pattern: uriOrTemplate,
213
+ match: (uri) => uri === uriOrTemplate ? {} : null,
214
+ handler
215
+ });
216
+ } else {
217
+ const template = uriOrTemplate.uriTemplate;
218
+ this.resourceEntries.push({
219
+ pattern: template.toString(),
220
+ match: (uri) => template.match(uri),
221
+ handler
222
+ });
223
+ }
224
+ }
225
+ sendResourceUpdated() {
226
+ }
227
+ };
228
+
39
229
  // src/angie-annotations.ts
40
230
  var ANGIE_MODEL_PREFERENCES = "angie/modelPreferences";
41
231
  var ANGIE_REQUIRED_RESOURCES = "angie/requiredResources";
@@ -74,6 +264,13 @@ var mockMcpRegistry = () => {
74
264
  };
75
265
  };
76
266
 
267
+ // src/utils/get-model-context.ts
268
+ function getModelContext() {
269
+ const documentModelContext = typeof document !== "undefined" ? document.modelContext : void 0;
270
+ const navigatorModelContext = typeof navigator !== "undefined" ? navigator.modelContext : void 0;
271
+ return documentModelContext || navigatorModelContext;
272
+ }
273
+
77
274
  // src/utils/merge-required-resources.ts
78
275
  var mergeRequiredResources = (toolResources, serverDocsUri) => {
79
276
  if (!serverDocsUri) {
@@ -134,12 +331,23 @@ var registerMcpAdapter = (adapter) => {
134
331
  }
135
332
  }
136
333
  };
137
- var signalMcpReady = () => resolveReady();
138
- var activateAdapters = () => callAdapters((adapter) => adapter.activate());
139
- async function callAdapters(fn) {
334
+ var signalMcpReady = () => {
335
+ resolveReady();
336
+ };
337
+ var createAndRegisterAdapters = () => {
338
+ const modelContext = getModelContext();
339
+ if (modelContext) {
340
+ registerMcpAdapter(new WebMCPAdapter(modelContext));
341
+ }
342
+ if (isAngieAvailable()) {
343
+ registerMcpAdapter(new AngieMcpAdapter(getSDK(), getRegisteredMcpServers));
344
+ }
345
+ registrationAdapters.forEach((adapter) => adapter.activate());
346
+ };
347
+ function callAdapters(fn) {
140
348
  for (const adapter of registrationAdapters) {
141
349
  try {
142
- await Promise.resolve(fn(adapter));
350
+ fn(adapter);
143
351
  } catch {
144
352
  }
145
353
  }
@@ -158,10 +366,6 @@ var isAlphabet = (str) => {
158
366
  }
159
367
  return str;
160
368
  };
161
- var toMCPTitle = (namespace) => {
162
- const capitalized = namespace.charAt(0).toUpperCase() + namespace.slice(1);
163
- return `Editor ${capitalized}`;
164
- };
165
369
  var getMCPByDomain = (namespace, options) => {
166
370
  const mcpName = `editor-${isAlphabet(namespace)}`;
167
371
  const title = toMCPTitle(namespace);
@@ -223,7 +427,7 @@ function createToolRegistry(server, serverName, serverDocsUri) {
223
427
  Object.assign(
224
428
  outputSchema,
225
429
  outputSchema.errors ?? {
226
- errors: z.string().optional().describe("Error message if the tool failed")
430
+ errors: z2.string().optional().describe("Error message if the tool failed")
227
431
  }
228
432
  );
229
433
  }
@@ -500,185 +704,15 @@ var saveAngieConsent = async () => {
500
704
  });
501
705
  };
502
706
 
503
- // src/adapters/angie-adapter.ts
504
- var MAX_RETRIES = 3;
505
- var AngieMcpAdapter = class {
506
- constructor(sdk2) {
507
- this.sdk = sdk2;
508
- }
509
- async activate() {
510
- await this.sdk.waitForReady();
511
- await this.registerEntries(getRegisteredMcpServers(), MAX_RETRIES);
512
- }
513
- async registerEntries(entries, retry) {
514
- if (retry === 0) {
515
- console.error(
516
- "Failed to register MCP after 3 retries. failed entries: ",
517
- entries.map(([key]) => key)
518
- );
519
- return;
520
- }
521
- const failed = [];
522
- for (const [key, mcpServer, description] of entries) {
523
- try {
524
- await this.sdk.registerLocalServer({
525
- title: toMCPTitle(key),
526
- name: `editor-${key}`,
527
- server: mcpServer,
528
- version: "1.0.0",
529
- description
530
- });
531
- } catch {
532
- failed.push([key, mcpServer, description]);
533
- }
534
- }
535
- if (failed.length > 0) {
536
- return this.registerEntries(failed, retry - 1);
537
- }
538
- }
539
- onToolRegistered() {
540
- }
541
- onResourceRegistered() {
542
- }
543
- sendResourceUpdated() {
544
- }
545
- };
546
-
547
- // src/adapters/web-mcp-adapter.ts
548
- import { zodToJsonSchema } from "zod-to-json-schema";
549
- import { z as z2 } from "@elementor/schema";
550
- var WebMCPAdapter = class {
551
- constructor(ctx) {
552
- this.ctx = ctx;
553
- }
554
- registeredToolNames = /* @__PURE__ */ new Set();
555
- resourceEntries = [];
556
- activated = false;
557
- activate() {
558
- if (this.activated) {
559
- return;
560
- }
561
- this.activated = true;
562
- this.ctx.registerTool({
563
- name: "editor-resource-getter",
564
- 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.",
565
- inputSchema: {
566
- type: "object",
567
- properties: {
568
- uri: {
569
- type: "string",
570
- description: "A full resource URI (e.g. elementor://styles/best-practices) or a partial string to search across available resource patterns."
571
- }
572
- },
573
- required: ["uri"]
574
- },
575
- execute: async (params) => {
576
- const query = params.uri;
577
- const entries = this.resourceEntries;
578
- if (entries.length === 0) {
579
- return "No resources are registered yet.";
580
- }
581
- for (const entry of entries) {
582
- const variables = entry.match(query);
583
- if (variables !== null) {
584
- let resourceUrl;
585
- try {
586
- resourceUrl = new URL(query);
587
- } catch {
588
- return `Invalid URI '${query}'. Provide a valid resource URI or a partial string to search patterns.`;
589
- }
590
- const result = await entry.handler(resourceUrl, variables);
591
- return result.contents?.[0]?.text ?? JSON.stringify(result);
592
- }
593
- }
594
- const matches = entries.map((e) => e.pattern).filter((pattern) => pattern.includes(query));
595
- if (matches.length > 0) {
596
- return `Found ${matches.length} matching resource pattern(s):
597
- ${matches.join(
598
- "\n"
599
- )}
600
-
601
- Provide a full URI to retrieve the resource content.`;
602
- }
603
- const available = entries.map((e) => e.pattern).join("\n");
604
- throw new Error(`No resource matched '${query}'.
605
-
606
- Available patterns:
607
- ${available}`);
608
- }
609
- });
610
- }
611
- onToolRegistered(tool, extraData) {
612
- let jsonSchema;
613
- try {
614
- jsonSchema = zodToJsonSchema(z2.object(tool.inputSchema));
615
- } catch {
616
- jsonSchema = tool.inputSchema;
617
- }
618
- if (this.registeredToolNames.has(tool.name)) {
619
- this.ctx.unregisterTool(tool.name);
620
- }
621
- let resourcesDescription = "";
622
- if (extraData) {
623
- if (extraData.resources?.length > 0) {
624
- resourcesDescription += `#Resources:
625
- ${extraData.resources?.join("\n")}
626
-
627
- `;
628
- }
629
- if (extraData.requiredResources?.length > 0) {
630
- resourcesDescription += `#Required Resources:
631
- ${extraData.requiredResources?.join("\n")}
632
-
633
- `;
634
- }
635
- resourcesDescription += `To read resources, use editor-resource-getter tool.
636
-
637
- `;
638
- }
639
- this.ctx.registerTool({
640
- name: tool.name,
641
- description: `${resourcesDescription}${tool.description}`,
642
- inputSchema: jsonSchema,
643
- execute: tool.execute
644
- });
645
- this.registeredToolNames.add(tool.name);
646
- }
647
- onResourceRegistered(_name, uriOrTemplate, handler) {
648
- if (typeof uriOrTemplate === "string") {
649
- this.resourceEntries.push({
650
- pattern: uriOrTemplate,
651
- match: (uri) => uri === uriOrTemplate ? {} : null,
652
- handler
653
- });
654
- } else {
655
- const template = uriOrTemplate.uriTemplate;
656
- this.resourceEntries.push({
657
- pattern: template.toString(),
658
- match: (uri) => template.match(uri),
659
- handler
660
- });
661
- }
662
- }
663
- sendResourceUpdated() {
664
- }
665
- };
666
-
667
707
  // src/init.ts
668
- function getModelContext() {
669
- const documentModelContext = typeof document !== "undefined" ? document.modelContext : void 0;
670
- const navigatorModelContext = typeof navigator !== "undefined" ? navigator.modelContext : void 0;
671
- return documentModelContext || navigatorModelContext;
672
- }
708
+ var isInitialized = false;
673
709
  function startMCPServer() {
674
- const modelContext = getModelContext();
675
- if (modelContext) {
676
- registerMcpAdapter(new WebMCPAdapter(modelContext));
677
- }
678
- if (isAngieAvailable()) {
679
- registerMcpAdapter(new AngieMcpAdapter(getSDK()));
710
+ if (isInitialized) {
711
+ return;
680
712
  }
681
- return activateAdapters().then(() => signalMcpReady());
713
+ isInitialized = true;
714
+ createAndRegisterAdapters();
715
+ signalMcpReady();
682
716
  }
683
717
  if (typeof document !== "undefined") {
684
718
  document.addEventListener("DOMContentLoaded", () => startMCPServer(), { once: true });
@@ -695,7 +729,7 @@ export {
695
729
  McpServer2 as McpServer,
696
730
  ResourceTemplate,
697
731
  SamplingMessageSchema2 as SamplingMessageSchema,
698
- activateAdapters,
732
+ createAndRegisterAdapters,
699
733
  createSampler,
700
734
  getActiveChatInfo,
701
735
  getAngieIframe,
@@ -713,7 +747,6 @@ export {
713
747
  sendPromptToAngie,
714
748
  signalMcpReady,
715
749
  startMCPServer,
716
- toMCPTitle,
717
750
  toolPrompts
718
751
  };
719
752
  //# sourceMappingURL=index.mjs.map