@elementor/elementor-kit-mcp 4.1.0-778

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.
@@ -0,0 +1,7 @@
1
+ import { McpServer } from '@elementor/editor-mcp';
2
+
3
+ declare function createElementorKitServer(): Promise<McpServer>;
4
+
5
+ declare function init(): void;
6
+
7
+ export { createElementorKitServer, init };
@@ -0,0 +1,7 @@
1
+ import { McpServer } from '@elementor/editor-mcp';
2
+
3
+ declare function createElementorKitServer(): Promise<McpServer>;
4
+
5
+ declare function init(): void;
6
+
7
+ export { createElementorKitServer, init };
package/dist/index.js ADDED
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ createElementorKitServer: () => createElementorKitServer,
24
+ init: () => init
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/elementor-kit-mcp-server.ts
29
+ var import_editor_mcp = require("@elementor/editor-mcp");
30
+ var import_elementor_mcp_common = require("@elementor/elementor-mcp-common");
31
+ var import_schema = require("@elementor/schema");
32
+ var RESOURCE_NAME_KIT_FONTS = "elementor-kit-fonts";
33
+ var RESOURCE_URI_KIT_FONTS = "elementor://kit/fonts";
34
+ var RESOURCE_NAME_KIT_SCHEMA = "elementor-kit-schema";
35
+ var RESOURCE_URI_KIT_SCHEMA_TEMPLATE = "elementor://kit/schema/{tab}";
36
+ var RESOURCE_NAME_KIT_SETTINGS = "elementor-kit-settings";
37
+ var RESOURCE_URI_KIT_SETTINGS = "elementor://kit/settings";
38
+ var VERSION = "2.0.0";
39
+ async function fetchKitFonts() {
40
+ return (0, import_elementor_mcp_common.callWpApi)(`/angie/v1/elementor-kit/fonts`, "GET");
41
+ }
42
+ async function fetchKitSchema() {
43
+ return (0, import_elementor_mcp_common.callWpApi)(`/angie/v1/elementor-kit/schema`, "GET");
44
+ }
45
+ async function fetchKitSettings() {
46
+ return (0, import_elementor_mcp_common.callWpApi)(`/angie/v1/elementor-kit`, "GET");
47
+ }
48
+ async function validateFonts(systemTypography, customTypography) {
49
+ const fontsResponse = await fetchKitFonts();
50
+ const availableFonts = Object.keys(fontsResponse.data.fonts || {});
51
+ const invalidFonts = [];
52
+ [systemTypography, customTypography].forEach((typography) => {
53
+ if (typography) {
54
+ typography.forEach((item) => {
55
+ if (item.typography_font_family && !availableFonts.includes(item.typography_font_family)) {
56
+ invalidFonts.push(item.typography_font_family);
57
+ }
58
+ });
59
+ }
60
+ });
61
+ if (invalidFonts.length > 0) {
62
+ return `Please use available fonts only. Invalid fonts: ${invalidFonts.join(
63
+ ", "
64
+ )}. Available fonts: ${availableFonts.join(", ")}`;
65
+ }
66
+ return "";
67
+ }
68
+ function sanitizeMediaFields(obj) {
69
+ const mediaFields = ["site_logo", "site_icon"];
70
+ const sanitized = { ...obj };
71
+ for (const field of mediaFields) {
72
+ if (field in sanitized && sanitized[field] === "") {
73
+ sanitized[field] = 0;
74
+ }
75
+ }
76
+ return sanitized;
77
+ }
78
+ var baseColorSchema = import_schema.z.object({
79
+ title: import_schema.z.string(),
80
+ color: import_schema.z.string()
81
+ });
82
+ var baseTypographySchema = import_schema.z.object({
83
+ title: import_schema.z.string(),
84
+ typography_typography: import_schema.z.string(),
85
+ typography_font_family: import_schema.z.string().describe(
86
+ "Font family name that must be from the available Elementor fonts list. Use the get-fonts endpoint (/angie/v1/elementor-kit/fonts) to get the complete list of available fonts. Only use fonts that exist in this list to avoid validation errors."
87
+ ),
88
+ typography_font_weight: import_schema.z.string(),
89
+ typography_font_size: import_schema.z.object({
90
+ unit: import_schema.z.string(),
91
+ size: import_schema.z.number()
92
+ }).optional(),
93
+ typography_font_size_tablet: import_schema.z.object({
94
+ unit: import_schema.z.string(),
95
+ size: import_schema.z.number()
96
+ }).optional(),
97
+ typography_font_size_mobile: import_schema.z.object({
98
+ unit: import_schema.z.string(),
99
+ size: import_schema.z.number()
100
+ }).optional(),
101
+ typography_line_height: import_schema.z.object({
102
+ unit: import_schema.z.string(),
103
+ size: import_schema.z.number()
104
+ }).optional()
105
+ }).passthrough();
106
+ var systemColorItemSchema = baseColorSchema.extend({
107
+ _id: import_schema.z.enum(["primary", "secondary", "text", "accent"])
108
+ });
109
+ var systemTypographyItemSchema = baseTypographySchema.extend({
110
+ _id: import_schema.z.enum(["primary", "secondary", "text", "accent"])
111
+ });
112
+ var customColorItemSchema = baseColorSchema.extend({
113
+ _id: import_schema.z.string()
114
+ });
115
+ var customTypographyItemSchema = baseTypographySchema.extend({
116
+ _id: import_schema.z.string()
117
+ });
118
+ var systemColorsSchema = import_schema.z.array(systemColorItemSchema).length(4);
119
+ var systemTypographySchema = import_schema.z.array(systemTypographyItemSchema).length(4);
120
+ var customColorsSchema = import_schema.z.array(customColorItemSchema);
121
+ var customTypographySchema = import_schema.z.array(customTypographyItemSchema);
122
+ var generalPatchSchema = import_schema.z.record(import_schema.z.unknown()).describe(
123
+ "General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc."
124
+ );
125
+ var SERVER_INSTRUCTIONS = `## Elementor Kit Settings Management
126
+
127
+ ### Capabilities:
128
+ **Global Design System:**
129
+ - Create, update, name, and delete global colors (both system and custom)
130
+ - Create, update, name, and delete global fonts (both system and custom)
131
+
132
+ **Site Identity:**
133
+ - Insert site logo
134
+ - Set site favicon
135
+ - Update site name
136
+ - Modify site description
137
+
138
+ ### Limitations:
139
+ **Theme Style Settings:**
140
+ - Cannot set or update Elementor Theme Style settings including typography, buttons, images, form fields, Hello Theme header, or Hello Theme footer that affect the entire website appearance
141
+
142
+ **Site-Wide Settings:**
143
+ - Cannot set site-wide background (color or image)
144
+ - Cannot configure mobile browser background
145
+ - Cannot modify global layout settings such as content width, container padding, and widget gaps (the default space between widgets)
146
+
147
+ **Note**: Angie can adjust all of these layout properties at the container or page level - just not site-wide.`;
148
+ async function createElementorKitServer() {
149
+ await (0, import_elementor_mcp_common.waitForElementorEditor)();
150
+ const server = new import_editor_mcp.McpServer(
151
+ {
152
+ name: "elementor-kit-server",
153
+ version: VERSION,
154
+ title: "Elementor Kit"
155
+ },
156
+ {
157
+ instructions: SERVER_INSTRUCTIONS,
158
+ capabilities: {
159
+ resources: {
160
+ subscribe: true
161
+ }
162
+ }
163
+ }
164
+ );
165
+ const getAvailableTabs = async () => {
166
+ const kitSchema = await fetchKitSchema();
167
+ return Object.keys(kitSchema.data || {});
168
+ };
169
+ server.registerResource(
170
+ RESOURCE_NAME_KIT_FONTS,
171
+ RESOURCE_URI_KIT_FONTS,
172
+ {
173
+ title: "Elementor Kit Available Fonts",
174
+ description: "Complete list of all available font families that can be used in Elementor, including system fonts, Google fonts, and custom uploaded fonts"
175
+ },
176
+ async (uri) => {
177
+ const fontsResponse = await fetchKitFonts();
178
+ return {
179
+ contents: [
180
+ {
181
+ uri: uri.href,
182
+ mimeType: "application/json",
183
+ text: JSON.stringify(fontsResponse, null, 2)
184
+ }
185
+ ]
186
+ };
187
+ }
188
+ );
189
+ server.registerResource(
190
+ RESOURCE_NAME_KIT_SETTINGS,
191
+ RESOURCE_URI_KIT_SETTINGS,
192
+ {
193
+ title: "Elementor Kit Current Settings",
194
+ description: "Complete current Elementor global kit configuration including all system and custom colors, typography settings, spacing, buttons, forms, and other site-wide design settings"
195
+ },
196
+ async (uri) => {
197
+ const currentSettings = await fetchKitSettings();
198
+ return {
199
+ contents: [
200
+ {
201
+ uri: uri.href,
202
+ mimeType: "application/json",
203
+ text: JSON.stringify(currentSettings, null, 2)
204
+ }
205
+ ]
206
+ };
207
+ }
208
+ );
209
+ const availableTabs = await getAvailableTabs();
210
+ server.registerResource(
211
+ RESOURCE_NAME_KIT_SCHEMA,
212
+ new import_editor_mcp.ResourceTemplate(RESOURCE_URI_KIT_SCHEMA_TEMPLATE, {
213
+ list: async () => {
214
+ return {
215
+ resources: availableTabs.map((tab) => {
216
+ return {
217
+ uri: `elementor://kit/schema/${tab}`,
218
+ name: `${RESOURCE_NAME_KIT_SCHEMA}-${tab}`,
219
+ title: `Elementor Kit Schema - ${tab}`,
220
+ description: `Schema definition for Elementor kit ${tab} settings tab`,
221
+ mimeType: "application/json"
222
+ };
223
+ })
224
+ };
225
+ }
226
+ }),
227
+ {
228
+ title: "Elementor Kit Schema",
229
+ description: "Complete schema definition for a specific Elementor kit settings tab, showing all available fields, their types, valid values, and configuration options"
230
+ },
231
+ async (uri, variables) => {
232
+ const tab = Array.isArray(variables.tab) ? variables.tab[0] : variables.tab;
233
+ if (!tab) {
234
+ throw new Error("Tab parameter is required");
235
+ }
236
+ const kitSchema = await fetchKitSchema();
237
+ const tabSchema = kitSchema.data?.[tab];
238
+ if (!tabSchema) {
239
+ throw new Error(
240
+ `No schema found for tab '${tab}'. Available tabs: ${Object.keys(kitSchema.data).join(
241
+ ", "
242
+ )}`
243
+ );
244
+ }
245
+ return {
246
+ contents: [
247
+ {
248
+ uri: uri.toString(),
249
+ mimeType: "application/json",
250
+ text: JSON.stringify(tabSchema, null, 2)
251
+ }
252
+ ]
253
+ };
254
+ }
255
+ );
256
+ server.registerTool(
257
+ "update-elementor-kit-settings-colors-and-fonts",
258
+ {
259
+ description: `This tool applies configuration changes to Elementor global kit settings that control site-wide design elements. Use this when you need to modify global colors, typography, spacing, buttons, form fields, or other theme-wide settings that affect the entire website appearance.
260
+
261
+ The tool will permanently update the site's global design settings and return a success confirmation with the updated configuration data.`,
262
+ inputSchema: {
263
+ systemColors: systemColorsSchema.optional().nullable().describe(
264
+ "System colors array with exactly 4 items having IDs: primary, secondary, text, accent"
265
+ ),
266
+ systemTypography: systemTypographySchema.optional().nullable().describe(
267
+ "System typography array with exactly 4 items having IDs: primary, secondary, text, accent"
268
+ ),
269
+ customColors: customColorsSchema.optional().nullable().describe("Custom colors array - flexible structure for additional color definitions"),
270
+ customTypography: customTypographySchema.optional().nullable().describe(
271
+ "Custom typography array - flexible structure for additional font definitions (no color field needed)"
272
+ ),
273
+ patchObject: generalPatchSchema.optional().nullable().describe(
274
+ "General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc."
275
+ ),
276
+ confirmationMessage: import_schema.z.string().describe(
277
+ 'REQUIRED: Provide a clear explanation in **markdown format** of what Elementor kit settings will be changed and their potential impact on the site\'s global design. This message will be shown to the user before proceeding. Be specific about which design elements are being modified (colors, typography, spacing, etc.) and how they will affect the entire website. Examples: "You\'re about to update the global **primary color** from `blue` to `green`. This will change **buttons**, **links**, and **accent colors** throughout your entire site." or "You\'re about to change the **primary font** from `Roboto` to `Open Sans`. This will affect **headings** across all pages."'
278
+ )
279
+ },
280
+ annotations: {
281
+ title: "Update Elementor Kit Settings",
282
+ destructiveHint: true
283
+ }
284
+ },
285
+ async ({
286
+ systemColors,
287
+ systemTypography,
288
+ customColors,
289
+ customTypography,
290
+ patchObject,
291
+ confirmationMessage
292
+ }) => {
293
+ (0, import_elementor_mcp_common.requireConfirmationMessage)(confirmationMessage, "Elementor kit settings");
294
+ const invalidFonts = await validateFonts(systemTypography, customTypography);
295
+ if (invalidFonts) {
296
+ throw new Error(invalidFonts);
297
+ }
298
+ const completePatchObject = {
299
+ ...systemColors && { system_colors: systemColors },
300
+ ...systemTypography && { system_typography: systemTypography },
301
+ ...customColors && { custom_colors: customColors },
302
+ ...customTypography && { custom_typography: customTypography },
303
+ ...sanitizeMediaFields(patchObject || {})
304
+ };
305
+ if (Object.keys(completePatchObject).length === 0) {
306
+ throw new Error(
307
+ "At least one update must be provided (systemColors, systemTypography, customColors, customTypography, or patchObject)"
308
+ );
309
+ }
310
+ const response = await (0, import_elementor_mcp_common.callWpApi)(`/angie/v1/elementor-kit`, "POST", completePatchObject);
311
+ return {
312
+ content: [
313
+ {
314
+ type: "text",
315
+ text: JSON.stringify(
316
+ {
317
+ success: true,
318
+ message: "Settings updated successfully",
319
+ data: response,
320
+ appliedSettings: completePatchObject
321
+ },
322
+ null,
323
+ 2
324
+ )
325
+ }
326
+ ]
327
+ };
328
+ }
329
+ );
330
+ const sdk = (0, import_editor_mcp.getAngieSdk)();
331
+ await sdk.waitForReady();
332
+ sdk.registerLocalServer({
333
+ server,
334
+ version: VERSION,
335
+ description: SERVER_INSTRUCTIONS,
336
+ name: "elementor-kit-server"
337
+ });
338
+ return server;
339
+ }
340
+
341
+ // src/init.ts
342
+ function init() {
343
+ createElementorKitServer();
344
+ }
345
+ // Annotate the CommonJS export names for ESM import in node:
346
+ 0 && (module.exports = {
347
+ createElementorKitServer,
348
+ init
349
+ });
350
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/elementor-kit-mcp-server.ts","../src/init.ts"],"sourcesContent":["export { createElementorKitServer } from './elementor-kit-mcp-server';\nexport { init } from './init';\n","import { getAngieSdk, McpServer, ResourceTemplate } from '@elementor/editor-mcp';\nimport { callWpApi, requireConfirmationMessage, waitForElementorEditor } from '@elementor/elementor-mcp-common';\nimport { z } from '@elementor/schema';\n\nconst RESOURCE_NAME_KIT_FONTS = 'elementor-kit-fonts';\nconst RESOURCE_URI_KIT_FONTS = 'elementor://kit/fonts';\nconst RESOURCE_NAME_KIT_SCHEMA = 'elementor-kit-schema';\nconst RESOURCE_URI_KIT_SCHEMA_TEMPLATE = 'elementor://kit/schema/{tab}';\nconst RESOURCE_NAME_KIT_SETTINGS = 'elementor-kit-settings';\nconst RESOURCE_URI_KIT_SETTINGS = 'elementor://kit/settings';\n\ntype KitFontsResponse = {\n\tfonts: Record< string, unknown >;\n};\n\ntype KitSchemaResponse = Record< string, unknown >;\n\nconst VERSION = '2.0.0';\nasync function fetchKitFonts() {\n\treturn callWpApi< KitFontsResponse >( `/angie/v1/elementor-kit/fonts`, 'GET' );\n}\n\nasync function fetchKitSchema() {\n\treturn callWpApi< KitSchemaResponse >( `/angie/v1/elementor-kit/schema`, 'GET' );\n}\n\nasync function fetchKitSettings() {\n\treturn callWpApi( `/angie/v1/elementor-kit`, 'GET' );\n}\n\ntype TypographyItem = {\n\ttypography_font_family?: string;\n};\n\nasync function validateFonts(\n\tsystemTypography: TypographyItem[] | null | undefined,\n\tcustomTypography: TypographyItem[] | null | undefined\n) {\n\tconst fontsResponse = await fetchKitFonts();\n\tconst availableFonts = Object.keys( fontsResponse.data.fonts || {} );\n\tconst invalidFonts: string[] = [];\n\n\t[ systemTypography, customTypography ].forEach( ( typography ) => {\n\t\tif ( typography ) {\n\t\t\ttypography.forEach( ( item ) => {\n\t\t\t\tif ( item.typography_font_family && ! availableFonts.includes( item.typography_font_family ) ) {\n\t\t\t\t\tinvalidFonts.push( item.typography_font_family );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n\n\tif ( invalidFonts.length > 0 ) {\n\t\treturn `Please use available fonts only. Invalid fonts: ${ invalidFonts.join(\n\t\t\t', '\n\t\t) }. Available fonts: ${ availableFonts.join( ', ' ) }`;\n\t}\n\n\treturn '';\n}\n\nfunction sanitizeMediaFields( obj: Record< string, unknown > ): Record< string, unknown > {\n\tconst mediaFields = [ 'site_logo', 'site_icon' ];\n\tconst sanitized = { ...obj };\n\n\tfor ( const field of mediaFields ) {\n\t\tif ( field in sanitized && sanitized[ field ] === '' ) {\n\t\t\tsanitized[ field ] = 0;\n\t\t}\n\t}\n\n\treturn sanitized;\n}\n\nconst baseColorSchema = z.object( {\n\ttitle: z.string(),\n\tcolor: z.string(),\n} );\n\nconst baseTypographySchema = z\n\t.object( {\n\t\ttitle: z.string(),\n\t\ttypography_typography: z.string(),\n\t\ttypography_font_family: z\n\t\t\t.string()\n\t\t\t.describe(\n\t\t\t\t'Font family name that must be from the available Elementor fonts list. Use the get-fonts endpoint (/angie/v1/elementor-kit/fonts) to get the complete list of available fonts. Only use fonts that exist in this list to avoid validation errors.'\n\t\t\t),\n\t\ttypography_font_weight: z.string(),\n\t\ttypography_font_size: z\n\t\t\t.object( {\n\t\t\t\tunit: z.string(),\n\t\t\t\tsize: z.number(),\n\t\t\t} )\n\t\t\t.optional(),\n\t\ttypography_font_size_tablet: z\n\t\t\t.object( {\n\t\t\t\tunit: z.string(),\n\t\t\t\tsize: z.number(),\n\t\t\t} )\n\t\t\t.optional(),\n\t\ttypography_font_size_mobile: z\n\t\t\t.object( {\n\t\t\t\tunit: z.string(),\n\t\t\t\tsize: z.number(),\n\t\t\t} )\n\t\t\t.optional(),\n\t\ttypography_line_height: z\n\t\t\t.object( {\n\t\t\t\tunit: z.string(),\n\t\t\t\tsize: z.number(),\n\t\t\t} )\n\t\t\t.optional(),\n\t} )\n\t.passthrough();\n\nconst systemColorItemSchema = baseColorSchema.extend( {\n\t_id: z.enum( [ 'primary', 'secondary', 'text', 'accent' ] ),\n} );\n\nconst systemTypographyItemSchema = baseTypographySchema.extend( {\n\t_id: z.enum( [ 'primary', 'secondary', 'text', 'accent' ] ),\n} );\n\nconst customColorItemSchema = baseColorSchema.extend( {\n\t_id: z.string(),\n} );\n\nconst customTypographyItemSchema = baseTypographySchema.extend( {\n\t_id: z.string(),\n} );\n\nconst systemColorsSchema = z.array( systemColorItemSchema ).length( 4 );\nconst systemTypographySchema = z.array( systemTypographyItemSchema ).length( 4 );\nconst customColorsSchema = z.array( customColorItemSchema );\nconst customTypographySchema = z.array( customTypographyItemSchema );\n\nconst generalPatchSchema = z\n\t.record( z.unknown() )\n\t.describe(\n\t\t'General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc.'\n\t);\n\nconst SERVER_INSTRUCTIONS = `## Elementor Kit Settings Management\n\n### Capabilities:\n**Global Design System:**\n- Create, update, name, and delete global colors (both system and custom)\n- Create, update, name, and delete global fonts (both system and custom)\n\n**Site Identity:**\n- Insert site logo\n- Set site favicon\n- Update site name\n- Modify site description\n\n### Limitations:\n**Theme Style Settings:**\n- Cannot set or update Elementor Theme Style settings including typography, buttons, images, form fields, Hello Theme header, or Hello Theme footer that affect the entire website appearance\n\n**Site-Wide Settings:**\n- Cannot set site-wide background (color or image)\n- Cannot configure mobile browser background\n- Cannot modify global layout settings such as content width, container padding, and widget gaps (the default space between widgets)\n\n**Note**: Angie can adjust all of these layout properties at the container or page level - just not site-wide.`;\n\nexport async function createElementorKitServer(): Promise< McpServer > {\n\tawait waitForElementorEditor();\n\tconst server = new McpServer(\n\t\t{\n\t\t\tname: 'elementor-kit-server',\n\t\t\tversion: VERSION,\n\t\t\ttitle: 'Elementor Kit',\n\t\t},\n\t\t{\n\t\t\tinstructions: SERVER_INSTRUCTIONS,\n\t\t\tcapabilities: {\n\t\t\t\tresources: {\n\t\t\t\t\tsubscribe: true,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t);\n\n\tconst getAvailableTabs = async (): Promise< string[] > => {\n\t\tconst kitSchema = await fetchKitSchema();\n\t\treturn Object.keys( kitSchema.data || {} );\n\t};\n\n\tserver.registerResource(\n\t\tRESOURCE_NAME_KIT_FONTS,\n\t\tRESOURCE_URI_KIT_FONTS,\n\t\t{\n\t\t\ttitle: 'Elementor Kit Available Fonts',\n\t\t\tdescription:\n\t\t\t\t'Complete list of all available font families that can be used in Elementor, including system fonts, Google fonts, and custom uploaded fonts',\n\t\t},\n\t\tasync ( uri ) => {\n\t\t\tconst fontsResponse = await fetchKitFonts();\n\t\t\treturn {\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.href,\n\t\t\t\t\t\tmimeType: 'application/json',\n\t\t\t\t\t\ttext: JSON.stringify( fontsResponse, null, 2 ),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t);\n\n\tserver.registerResource(\n\t\tRESOURCE_NAME_KIT_SETTINGS,\n\t\tRESOURCE_URI_KIT_SETTINGS,\n\t\t{\n\t\t\ttitle: 'Elementor Kit Current Settings',\n\t\t\tdescription:\n\t\t\t\t'Complete current Elementor global kit configuration including all system and custom colors, typography settings, spacing, buttons, forms, and other site-wide design settings',\n\t\t},\n\t\tasync ( uri ) => {\n\t\t\tconst currentSettings = await fetchKitSettings();\n\t\t\treturn {\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.href,\n\t\t\t\t\t\tmimeType: 'application/json',\n\t\t\t\t\t\ttext: JSON.stringify( currentSettings, null, 2 ),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t);\n\n\tconst availableTabs = await getAvailableTabs();\n\n\tserver.registerResource(\n\t\tRESOURCE_NAME_KIT_SCHEMA,\n\t\tnew ResourceTemplate( RESOURCE_URI_KIT_SCHEMA_TEMPLATE, {\n\t\t\tlist: async () => {\n\t\t\t\treturn {\n\t\t\t\t\tresources: availableTabs.map( ( tab ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\turi: `elementor://kit/schema/${ tab }`,\n\t\t\t\t\t\t\tname: `${ RESOURCE_NAME_KIT_SCHEMA }-${ tab }`,\n\t\t\t\t\t\t\ttitle: `Elementor Kit Schema - ${ tab }`,\n\t\t\t\t\t\t\tdescription: `Schema definition for Elementor kit ${ tab } settings tab`,\n\t\t\t\t\t\t\tmimeType: 'application/json',\n\t\t\t\t\t\t};\n\t\t\t\t\t} ),\n\t\t\t\t};\n\t\t\t},\n\t\t} ),\n\t\t{\n\t\t\ttitle: 'Elementor Kit Schema',\n\t\t\tdescription:\n\t\t\t\t'Complete schema definition for a specific Elementor kit settings tab, showing all available fields, their types, valid values, and configuration options',\n\t\t},\n\t\tasync ( uri, variables ) => {\n\t\t\tconst tab = Array.isArray( variables.tab ) ? variables.tab[ 0 ] : variables.tab;\n\n\t\t\tif ( ! tab ) {\n\t\t\t\tthrow new Error( 'Tab parameter is required' );\n\t\t\t}\n\n\t\t\tconst kitSchema = await fetchKitSchema();\n\t\t\tconst tabSchema = kitSchema.data?.[ tab ];\n\n\t\t\tif ( ! tabSchema ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No schema found for tab '${ tab }'. Available tabs: ${ Object.keys( kitSchema.data ).join(\n\t\t\t\t\t\t', '\n\t\t\t\t\t) }`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.toString(),\n\t\t\t\t\t\tmimeType: 'application/json',\n\t\t\t\t\t\ttext: JSON.stringify( tabSchema, null, 2 ),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t);\n\n\tserver.registerTool(\n\t\t'update-elementor-kit-settings-colors-and-fonts',\n\t\t{\n\t\t\tdescription: `This tool applies configuration changes to Elementor global kit settings that control site-wide design elements. Use this when you need to modify global colors, typography, spacing, buttons, form fields, or other theme-wide settings that affect the entire website appearance.\n\nThe tool will permanently update the site's global design settings and return a success confirmation with the updated configuration data.`,\n\t\t\tinputSchema: {\n\t\t\t\tsystemColors: systemColorsSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'System colors array with exactly 4 items having IDs: primary, secondary, text, accent'\n\t\t\t\t\t),\n\t\t\t\tsystemTypography: systemTypographySchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'System typography array with exactly 4 items having IDs: primary, secondary, text, accent'\n\t\t\t\t\t),\n\t\t\t\tcustomColors: customColorsSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe( 'Custom colors array - flexible structure for additional color definitions' ),\n\t\t\t\tcustomTypography: customTypographySchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'Custom typography array - flexible structure for additional font definitions (no color field needed)'\n\t\t\t\t\t),\n\t\t\t\tpatchObject: generalPatchSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc.'\n\t\t\t\t\t),\n\t\t\t\tconfirmationMessage: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'REQUIRED: Provide a clear explanation in **markdown format** of what Elementor kit settings will be changed and their potential impact on the site\\'s global design. This message will be shown to the user before proceeding. Be specific about which design elements are being modified (colors, typography, spacing, etc.) and how they will affect the entire website. Examples: \"You\\'re about to update the global **primary color** from `blue` to `green`. This will change **buttons**, **links**, and **accent colors** throughout your entire site.\" or \"You\\'re about to change the **primary font** from `Roboto` to `Open Sans`. This will affect **headings** across all pages.\"'\n\t\t\t\t\t),\n\t\t\t},\n\t\t\tannotations: {\n\t\t\t\ttitle: 'Update Elementor Kit Settings',\n\t\t\t\tdestructiveHint: true,\n\t\t\t},\n\t\t},\n\t\tasync ( {\n\t\t\tsystemColors,\n\t\t\tsystemTypography,\n\t\t\tcustomColors,\n\t\t\tcustomTypography,\n\t\t\tpatchObject,\n\t\t\tconfirmationMessage,\n\t\t} ) => {\n\t\t\trequireConfirmationMessage( confirmationMessage, 'Elementor kit settings' );\n\n\t\t\tconst invalidFonts = await validateFonts( systemTypography, customTypography );\n\t\t\tif ( invalidFonts ) {\n\t\t\t\tthrow new Error( invalidFonts );\n\t\t\t}\n\n\t\t\tconst completePatchObject = {\n\t\t\t\t...( systemColors && { system_colors: systemColors } ),\n\t\t\t\t...( systemTypography && { system_typography: systemTypography } ),\n\t\t\t\t...( customColors && { custom_colors: customColors } ),\n\t\t\t\t...( customTypography && { custom_typography: customTypography } ),\n\t\t\t\t...sanitizeMediaFields( patchObject || {} ),\n\t\t\t};\n\n\t\t\tif ( Object.keys( completePatchObject ).length === 0 ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'At least one update must be provided (systemColors, systemTypography, customColors, customTypography, or patchObject)'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst response = await callWpApi( `/angie/v1/elementor-kit`, 'POST', completePatchObject );\n\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\t\ttext: JSON.stringify(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\tmessage: 'Settings updated successfully',\n\t\t\t\t\t\t\t\tdata: response,\n\t\t\t\t\t\t\t\tappliedSettings: completePatchObject,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t2\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t);\n\n\tconst sdk = getAngieSdk();\n\tawait sdk.waitForReady();\n\tsdk.registerLocalServer( {\n\t\tserver,\n\t\tversion: VERSION,\n\t\tdescription: SERVER_INSTRUCTIONS,\n\t\tname: 'elementor-kit-server',\n\t} );\n\treturn server;\n}\n","import { createElementorKitServer } from './elementor-kit-mcp-server';\n\nexport function init() {\n\tcreateElementorKitServer();\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,322 @@
1
+ // src/elementor-kit-mcp-server.ts
2
+ import { getAngieSdk, McpServer, ResourceTemplate } from "@elementor/editor-mcp";
3
+ import { callWpApi, requireConfirmationMessage, waitForElementorEditor } from "@elementor/elementor-mcp-common";
4
+ import { z } from "@elementor/schema";
5
+ var RESOURCE_NAME_KIT_FONTS = "elementor-kit-fonts";
6
+ var RESOURCE_URI_KIT_FONTS = "elementor://kit/fonts";
7
+ var RESOURCE_NAME_KIT_SCHEMA = "elementor-kit-schema";
8
+ var RESOURCE_URI_KIT_SCHEMA_TEMPLATE = "elementor://kit/schema/{tab}";
9
+ var RESOURCE_NAME_KIT_SETTINGS = "elementor-kit-settings";
10
+ var RESOURCE_URI_KIT_SETTINGS = "elementor://kit/settings";
11
+ var VERSION = "2.0.0";
12
+ async function fetchKitFonts() {
13
+ return callWpApi(`/angie/v1/elementor-kit/fonts`, "GET");
14
+ }
15
+ async function fetchKitSchema() {
16
+ return callWpApi(`/angie/v1/elementor-kit/schema`, "GET");
17
+ }
18
+ async function fetchKitSettings() {
19
+ return callWpApi(`/angie/v1/elementor-kit`, "GET");
20
+ }
21
+ async function validateFonts(systemTypography, customTypography) {
22
+ const fontsResponse = await fetchKitFonts();
23
+ const availableFonts = Object.keys(fontsResponse.data.fonts || {});
24
+ const invalidFonts = [];
25
+ [systemTypography, customTypography].forEach((typography) => {
26
+ if (typography) {
27
+ typography.forEach((item) => {
28
+ if (item.typography_font_family && !availableFonts.includes(item.typography_font_family)) {
29
+ invalidFonts.push(item.typography_font_family);
30
+ }
31
+ });
32
+ }
33
+ });
34
+ if (invalidFonts.length > 0) {
35
+ return `Please use available fonts only. Invalid fonts: ${invalidFonts.join(
36
+ ", "
37
+ )}. Available fonts: ${availableFonts.join(", ")}`;
38
+ }
39
+ return "";
40
+ }
41
+ function sanitizeMediaFields(obj) {
42
+ const mediaFields = ["site_logo", "site_icon"];
43
+ const sanitized = { ...obj };
44
+ for (const field of mediaFields) {
45
+ if (field in sanitized && sanitized[field] === "") {
46
+ sanitized[field] = 0;
47
+ }
48
+ }
49
+ return sanitized;
50
+ }
51
+ var baseColorSchema = z.object({
52
+ title: z.string(),
53
+ color: z.string()
54
+ });
55
+ var baseTypographySchema = z.object({
56
+ title: z.string(),
57
+ typography_typography: z.string(),
58
+ typography_font_family: z.string().describe(
59
+ "Font family name that must be from the available Elementor fonts list. Use the get-fonts endpoint (/angie/v1/elementor-kit/fonts) to get the complete list of available fonts. Only use fonts that exist in this list to avoid validation errors."
60
+ ),
61
+ typography_font_weight: z.string(),
62
+ typography_font_size: z.object({
63
+ unit: z.string(),
64
+ size: z.number()
65
+ }).optional(),
66
+ typography_font_size_tablet: z.object({
67
+ unit: z.string(),
68
+ size: z.number()
69
+ }).optional(),
70
+ typography_font_size_mobile: z.object({
71
+ unit: z.string(),
72
+ size: z.number()
73
+ }).optional(),
74
+ typography_line_height: z.object({
75
+ unit: z.string(),
76
+ size: z.number()
77
+ }).optional()
78
+ }).passthrough();
79
+ var systemColorItemSchema = baseColorSchema.extend({
80
+ _id: z.enum(["primary", "secondary", "text", "accent"])
81
+ });
82
+ var systemTypographyItemSchema = baseTypographySchema.extend({
83
+ _id: z.enum(["primary", "secondary", "text", "accent"])
84
+ });
85
+ var customColorItemSchema = baseColorSchema.extend({
86
+ _id: z.string()
87
+ });
88
+ var customTypographyItemSchema = baseTypographySchema.extend({
89
+ _id: z.string()
90
+ });
91
+ var systemColorsSchema = z.array(systemColorItemSchema).length(4);
92
+ var systemTypographySchema = z.array(systemTypographyItemSchema).length(4);
93
+ var customColorsSchema = z.array(customColorItemSchema);
94
+ var customTypographySchema = z.array(customTypographyItemSchema);
95
+ var generalPatchSchema = z.record(z.unknown()).describe(
96
+ "General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc."
97
+ );
98
+ var SERVER_INSTRUCTIONS = `## Elementor Kit Settings Management
99
+
100
+ ### Capabilities:
101
+ **Global Design System:**
102
+ - Create, update, name, and delete global colors (both system and custom)
103
+ - Create, update, name, and delete global fonts (both system and custom)
104
+
105
+ **Site Identity:**
106
+ - Insert site logo
107
+ - Set site favicon
108
+ - Update site name
109
+ - Modify site description
110
+
111
+ ### Limitations:
112
+ **Theme Style Settings:**
113
+ - Cannot set or update Elementor Theme Style settings including typography, buttons, images, form fields, Hello Theme header, or Hello Theme footer that affect the entire website appearance
114
+
115
+ **Site-Wide Settings:**
116
+ - Cannot set site-wide background (color or image)
117
+ - Cannot configure mobile browser background
118
+ - Cannot modify global layout settings such as content width, container padding, and widget gaps (the default space between widgets)
119
+
120
+ **Note**: Angie can adjust all of these layout properties at the container or page level - just not site-wide.`;
121
+ async function createElementorKitServer() {
122
+ await waitForElementorEditor();
123
+ const server = new McpServer(
124
+ {
125
+ name: "elementor-kit-server",
126
+ version: VERSION,
127
+ title: "Elementor Kit"
128
+ },
129
+ {
130
+ instructions: SERVER_INSTRUCTIONS,
131
+ capabilities: {
132
+ resources: {
133
+ subscribe: true
134
+ }
135
+ }
136
+ }
137
+ );
138
+ const getAvailableTabs = async () => {
139
+ const kitSchema = await fetchKitSchema();
140
+ return Object.keys(kitSchema.data || {});
141
+ };
142
+ server.registerResource(
143
+ RESOURCE_NAME_KIT_FONTS,
144
+ RESOURCE_URI_KIT_FONTS,
145
+ {
146
+ title: "Elementor Kit Available Fonts",
147
+ description: "Complete list of all available font families that can be used in Elementor, including system fonts, Google fonts, and custom uploaded fonts"
148
+ },
149
+ async (uri) => {
150
+ const fontsResponse = await fetchKitFonts();
151
+ return {
152
+ contents: [
153
+ {
154
+ uri: uri.href,
155
+ mimeType: "application/json",
156
+ text: JSON.stringify(fontsResponse, null, 2)
157
+ }
158
+ ]
159
+ };
160
+ }
161
+ );
162
+ server.registerResource(
163
+ RESOURCE_NAME_KIT_SETTINGS,
164
+ RESOURCE_URI_KIT_SETTINGS,
165
+ {
166
+ title: "Elementor Kit Current Settings",
167
+ description: "Complete current Elementor global kit configuration including all system and custom colors, typography settings, spacing, buttons, forms, and other site-wide design settings"
168
+ },
169
+ async (uri) => {
170
+ const currentSettings = await fetchKitSettings();
171
+ return {
172
+ contents: [
173
+ {
174
+ uri: uri.href,
175
+ mimeType: "application/json",
176
+ text: JSON.stringify(currentSettings, null, 2)
177
+ }
178
+ ]
179
+ };
180
+ }
181
+ );
182
+ const availableTabs = await getAvailableTabs();
183
+ server.registerResource(
184
+ RESOURCE_NAME_KIT_SCHEMA,
185
+ new ResourceTemplate(RESOURCE_URI_KIT_SCHEMA_TEMPLATE, {
186
+ list: async () => {
187
+ return {
188
+ resources: availableTabs.map((tab) => {
189
+ return {
190
+ uri: `elementor://kit/schema/${tab}`,
191
+ name: `${RESOURCE_NAME_KIT_SCHEMA}-${tab}`,
192
+ title: `Elementor Kit Schema - ${tab}`,
193
+ description: `Schema definition for Elementor kit ${tab} settings tab`,
194
+ mimeType: "application/json"
195
+ };
196
+ })
197
+ };
198
+ }
199
+ }),
200
+ {
201
+ title: "Elementor Kit Schema",
202
+ description: "Complete schema definition for a specific Elementor kit settings tab, showing all available fields, their types, valid values, and configuration options"
203
+ },
204
+ async (uri, variables) => {
205
+ const tab = Array.isArray(variables.tab) ? variables.tab[0] : variables.tab;
206
+ if (!tab) {
207
+ throw new Error("Tab parameter is required");
208
+ }
209
+ const kitSchema = await fetchKitSchema();
210
+ const tabSchema = kitSchema.data?.[tab];
211
+ if (!tabSchema) {
212
+ throw new Error(
213
+ `No schema found for tab '${tab}'. Available tabs: ${Object.keys(kitSchema.data).join(
214
+ ", "
215
+ )}`
216
+ );
217
+ }
218
+ return {
219
+ contents: [
220
+ {
221
+ uri: uri.toString(),
222
+ mimeType: "application/json",
223
+ text: JSON.stringify(tabSchema, null, 2)
224
+ }
225
+ ]
226
+ };
227
+ }
228
+ );
229
+ server.registerTool(
230
+ "update-elementor-kit-settings-colors-and-fonts",
231
+ {
232
+ description: `This tool applies configuration changes to Elementor global kit settings that control site-wide design elements. Use this when you need to modify global colors, typography, spacing, buttons, form fields, or other theme-wide settings that affect the entire website appearance.
233
+
234
+ The tool will permanently update the site's global design settings and return a success confirmation with the updated configuration data.`,
235
+ inputSchema: {
236
+ systemColors: systemColorsSchema.optional().nullable().describe(
237
+ "System colors array with exactly 4 items having IDs: primary, secondary, text, accent"
238
+ ),
239
+ systemTypography: systemTypographySchema.optional().nullable().describe(
240
+ "System typography array with exactly 4 items having IDs: primary, secondary, text, accent"
241
+ ),
242
+ customColors: customColorsSchema.optional().nullable().describe("Custom colors array - flexible structure for additional color definitions"),
243
+ customTypography: customTypographySchema.optional().nullable().describe(
244
+ "Custom typography array - flexible structure for additional font definitions (no color field needed)"
245
+ ),
246
+ patchObject: generalPatchSchema.optional().nullable().describe(
247
+ "General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc."
248
+ ),
249
+ confirmationMessage: z.string().describe(
250
+ 'REQUIRED: Provide a clear explanation in **markdown format** of what Elementor kit settings will be changed and their potential impact on the site\'s global design. This message will be shown to the user before proceeding. Be specific about which design elements are being modified (colors, typography, spacing, etc.) and how they will affect the entire website. Examples: "You\'re about to update the global **primary color** from `blue` to `green`. This will change **buttons**, **links**, and **accent colors** throughout your entire site." or "You\'re about to change the **primary font** from `Roboto` to `Open Sans`. This will affect **headings** across all pages."'
251
+ )
252
+ },
253
+ annotations: {
254
+ title: "Update Elementor Kit Settings",
255
+ destructiveHint: true
256
+ }
257
+ },
258
+ async ({
259
+ systemColors,
260
+ systemTypography,
261
+ customColors,
262
+ customTypography,
263
+ patchObject,
264
+ confirmationMessage
265
+ }) => {
266
+ requireConfirmationMessage(confirmationMessage, "Elementor kit settings");
267
+ const invalidFonts = await validateFonts(systemTypography, customTypography);
268
+ if (invalidFonts) {
269
+ throw new Error(invalidFonts);
270
+ }
271
+ const completePatchObject = {
272
+ ...systemColors && { system_colors: systemColors },
273
+ ...systemTypography && { system_typography: systemTypography },
274
+ ...customColors && { custom_colors: customColors },
275
+ ...customTypography && { custom_typography: customTypography },
276
+ ...sanitizeMediaFields(patchObject || {})
277
+ };
278
+ if (Object.keys(completePatchObject).length === 0) {
279
+ throw new Error(
280
+ "At least one update must be provided (systemColors, systemTypography, customColors, customTypography, or patchObject)"
281
+ );
282
+ }
283
+ const response = await callWpApi(`/angie/v1/elementor-kit`, "POST", completePatchObject);
284
+ return {
285
+ content: [
286
+ {
287
+ type: "text",
288
+ text: JSON.stringify(
289
+ {
290
+ success: true,
291
+ message: "Settings updated successfully",
292
+ data: response,
293
+ appliedSettings: completePatchObject
294
+ },
295
+ null,
296
+ 2
297
+ )
298
+ }
299
+ ]
300
+ };
301
+ }
302
+ );
303
+ const sdk = getAngieSdk();
304
+ await sdk.waitForReady();
305
+ sdk.registerLocalServer({
306
+ server,
307
+ version: VERSION,
308
+ description: SERVER_INSTRUCTIONS,
309
+ name: "elementor-kit-server"
310
+ });
311
+ return server;
312
+ }
313
+
314
+ // src/init.ts
315
+ function init() {
316
+ createElementorKitServer();
317
+ }
318
+ export {
319
+ createElementorKitServer,
320
+ init
321
+ };
322
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/elementor-kit-mcp-server.ts","../src/init.ts"],"sourcesContent":["import { getAngieSdk, McpServer, ResourceTemplate } from '@elementor/editor-mcp';\nimport { callWpApi, requireConfirmationMessage, waitForElementorEditor } from '@elementor/elementor-mcp-common';\nimport { z } from '@elementor/schema';\n\nconst RESOURCE_NAME_KIT_FONTS = 'elementor-kit-fonts';\nconst RESOURCE_URI_KIT_FONTS = 'elementor://kit/fonts';\nconst RESOURCE_NAME_KIT_SCHEMA = 'elementor-kit-schema';\nconst RESOURCE_URI_KIT_SCHEMA_TEMPLATE = 'elementor://kit/schema/{tab}';\nconst RESOURCE_NAME_KIT_SETTINGS = 'elementor-kit-settings';\nconst RESOURCE_URI_KIT_SETTINGS = 'elementor://kit/settings';\n\ntype KitFontsResponse = {\n\tfonts: Record< string, unknown >;\n};\n\ntype KitSchemaResponse = Record< string, unknown >;\n\nconst VERSION = '2.0.0';\nasync function fetchKitFonts() {\n\treturn callWpApi< KitFontsResponse >( `/angie/v1/elementor-kit/fonts`, 'GET' );\n}\n\nasync function fetchKitSchema() {\n\treturn callWpApi< KitSchemaResponse >( `/angie/v1/elementor-kit/schema`, 'GET' );\n}\n\nasync function fetchKitSettings() {\n\treturn callWpApi( `/angie/v1/elementor-kit`, 'GET' );\n}\n\ntype TypographyItem = {\n\ttypography_font_family?: string;\n};\n\nasync function validateFonts(\n\tsystemTypography: TypographyItem[] | null | undefined,\n\tcustomTypography: TypographyItem[] | null | undefined\n) {\n\tconst fontsResponse = await fetchKitFonts();\n\tconst availableFonts = Object.keys( fontsResponse.data.fonts || {} );\n\tconst invalidFonts: string[] = [];\n\n\t[ systemTypography, customTypography ].forEach( ( typography ) => {\n\t\tif ( typography ) {\n\t\t\ttypography.forEach( ( item ) => {\n\t\t\t\tif ( item.typography_font_family && ! availableFonts.includes( item.typography_font_family ) ) {\n\t\t\t\t\tinvalidFonts.push( item.typography_font_family );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n\n\tif ( invalidFonts.length > 0 ) {\n\t\treturn `Please use available fonts only. Invalid fonts: ${ invalidFonts.join(\n\t\t\t', '\n\t\t) }. Available fonts: ${ availableFonts.join( ', ' ) }`;\n\t}\n\n\treturn '';\n}\n\nfunction sanitizeMediaFields( obj: Record< string, unknown > ): Record< string, unknown > {\n\tconst mediaFields = [ 'site_logo', 'site_icon' ];\n\tconst sanitized = { ...obj };\n\n\tfor ( const field of mediaFields ) {\n\t\tif ( field in sanitized && sanitized[ field ] === '' ) {\n\t\t\tsanitized[ field ] = 0;\n\t\t}\n\t}\n\n\treturn sanitized;\n}\n\nconst baseColorSchema = z.object( {\n\ttitle: z.string(),\n\tcolor: z.string(),\n} );\n\nconst baseTypographySchema = z\n\t.object( {\n\t\ttitle: z.string(),\n\t\ttypography_typography: z.string(),\n\t\ttypography_font_family: z\n\t\t\t.string()\n\t\t\t.describe(\n\t\t\t\t'Font family name that must be from the available Elementor fonts list. Use the get-fonts endpoint (/angie/v1/elementor-kit/fonts) to get the complete list of available fonts. Only use fonts that exist in this list to avoid validation errors.'\n\t\t\t),\n\t\ttypography_font_weight: z.string(),\n\t\ttypography_font_size: z\n\t\t\t.object( {\n\t\t\t\tunit: z.string(),\n\t\t\t\tsize: z.number(),\n\t\t\t} )\n\t\t\t.optional(),\n\t\ttypography_font_size_tablet: z\n\t\t\t.object( {\n\t\t\t\tunit: z.string(),\n\t\t\t\tsize: z.number(),\n\t\t\t} )\n\t\t\t.optional(),\n\t\ttypography_font_size_mobile: z\n\t\t\t.object( {\n\t\t\t\tunit: z.string(),\n\t\t\t\tsize: z.number(),\n\t\t\t} )\n\t\t\t.optional(),\n\t\ttypography_line_height: z\n\t\t\t.object( {\n\t\t\t\tunit: z.string(),\n\t\t\t\tsize: z.number(),\n\t\t\t} )\n\t\t\t.optional(),\n\t} )\n\t.passthrough();\n\nconst systemColorItemSchema = baseColorSchema.extend( {\n\t_id: z.enum( [ 'primary', 'secondary', 'text', 'accent' ] ),\n} );\n\nconst systemTypographyItemSchema = baseTypographySchema.extend( {\n\t_id: z.enum( [ 'primary', 'secondary', 'text', 'accent' ] ),\n} );\n\nconst customColorItemSchema = baseColorSchema.extend( {\n\t_id: z.string(),\n} );\n\nconst customTypographyItemSchema = baseTypographySchema.extend( {\n\t_id: z.string(),\n} );\n\nconst systemColorsSchema = z.array( systemColorItemSchema ).length( 4 );\nconst systemTypographySchema = z.array( systemTypographyItemSchema ).length( 4 );\nconst customColorsSchema = z.array( customColorItemSchema );\nconst customTypographySchema = z.array( customTypographyItemSchema );\n\nconst generalPatchSchema = z\n\t.record( z.unknown() )\n\t.describe(\n\t\t'General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc.'\n\t);\n\nconst SERVER_INSTRUCTIONS = `## Elementor Kit Settings Management\n\n### Capabilities:\n**Global Design System:**\n- Create, update, name, and delete global colors (both system and custom)\n- Create, update, name, and delete global fonts (both system and custom)\n\n**Site Identity:**\n- Insert site logo\n- Set site favicon\n- Update site name\n- Modify site description\n\n### Limitations:\n**Theme Style Settings:**\n- Cannot set or update Elementor Theme Style settings including typography, buttons, images, form fields, Hello Theme header, or Hello Theme footer that affect the entire website appearance\n\n**Site-Wide Settings:**\n- Cannot set site-wide background (color or image)\n- Cannot configure mobile browser background\n- Cannot modify global layout settings such as content width, container padding, and widget gaps (the default space between widgets)\n\n**Note**: Angie can adjust all of these layout properties at the container or page level - just not site-wide.`;\n\nexport async function createElementorKitServer(): Promise< McpServer > {\n\tawait waitForElementorEditor();\n\tconst server = new McpServer(\n\t\t{\n\t\t\tname: 'elementor-kit-server',\n\t\t\tversion: VERSION,\n\t\t\ttitle: 'Elementor Kit',\n\t\t},\n\t\t{\n\t\t\tinstructions: SERVER_INSTRUCTIONS,\n\t\t\tcapabilities: {\n\t\t\t\tresources: {\n\t\t\t\t\tsubscribe: true,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t);\n\n\tconst getAvailableTabs = async (): Promise< string[] > => {\n\t\tconst kitSchema = await fetchKitSchema();\n\t\treturn Object.keys( kitSchema.data || {} );\n\t};\n\n\tserver.registerResource(\n\t\tRESOURCE_NAME_KIT_FONTS,\n\t\tRESOURCE_URI_KIT_FONTS,\n\t\t{\n\t\t\ttitle: 'Elementor Kit Available Fonts',\n\t\t\tdescription:\n\t\t\t\t'Complete list of all available font families that can be used in Elementor, including system fonts, Google fonts, and custom uploaded fonts',\n\t\t},\n\t\tasync ( uri ) => {\n\t\t\tconst fontsResponse = await fetchKitFonts();\n\t\t\treturn {\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.href,\n\t\t\t\t\t\tmimeType: 'application/json',\n\t\t\t\t\t\ttext: JSON.stringify( fontsResponse, null, 2 ),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t);\n\n\tserver.registerResource(\n\t\tRESOURCE_NAME_KIT_SETTINGS,\n\t\tRESOURCE_URI_KIT_SETTINGS,\n\t\t{\n\t\t\ttitle: 'Elementor Kit Current Settings',\n\t\t\tdescription:\n\t\t\t\t'Complete current Elementor global kit configuration including all system and custom colors, typography settings, spacing, buttons, forms, and other site-wide design settings',\n\t\t},\n\t\tasync ( uri ) => {\n\t\t\tconst currentSettings = await fetchKitSettings();\n\t\t\treturn {\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.href,\n\t\t\t\t\t\tmimeType: 'application/json',\n\t\t\t\t\t\ttext: JSON.stringify( currentSettings, null, 2 ),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t);\n\n\tconst availableTabs = await getAvailableTabs();\n\n\tserver.registerResource(\n\t\tRESOURCE_NAME_KIT_SCHEMA,\n\t\tnew ResourceTemplate( RESOURCE_URI_KIT_SCHEMA_TEMPLATE, {\n\t\t\tlist: async () => {\n\t\t\t\treturn {\n\t\t\t\t\tresources: availableTabs.map( ( tab ) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\turi: `elementor://kit/schema/${ tab }`,\n\t\t\t\t\t\t\tname: `${ RESOURCE_NAME_KIT_SCHEMA }-${ tab }`,\n\t\t\t\t\t\t\ttitle: `Elementor Kit Schema - ${ tab }`,\n\t\t\t\t\t\t\tdescription: `Schema definition for Elementor kit ${ tab } settings tab`,\n\t\t\t\t\t\t\tmimeType: 'application/json',\n\t\t\t\t\t\t};\n\t\t\t\t\t} ),\n\t\t\t\t};\n\t\t\t},\n\t\t} ),\n\t\t{\n\t\t\ttitle: 'Elementor Kit Schema',\n\t\t\tdescription:\n\t\t\t\t'Complete schema definition for a specific Elementor kit settings tab, showing all available fields, their types, valid values, and configuration options',\n\t\t},\n\t\tasync ( uri, variables ) => {\n\t\t\tconst tab = Array.isArray( variables.tab ) ? variables.tab[ 0 ] : variables.tab;\n\n\t\t\tif ( ! tab ) {\n\t\t\t\tthrow new Error( 'Tab parameter is required' );\n\t\t\t}\n\n\t\t\tconst kitSchema = await fetchKitSchema();\n\t\t\tconst tabSchema = kitSchema.data?.[ tab ];\n\n\t\t\tif ( ! tabSchema ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No schema found for tab '${ tab }'. Available tabs: ${ Object.keys( kitSchema.data ).join(\n\t\t\t\t\t\t', '\n\t\t\t\t\t) }`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.toString(),\n\t\t\t\t\t\tmimeType: 'application/json',\n\t\t\t\t\t\ttext: JSON.stringify( tabSchema, null, 2 ),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t);\n\n\tserver.registerTool(\n\t\t'update-elementor-kit-settings-colors-and-fonts',\n\t\t{\n\t\t\tdescription: `This tool applies configuration changes to Elementor global kit settings that control site-wide design elements. Use this when you need to modify global colors, typography, spacing, buttons, form fields, or other theme-wide settings that affect the entire website appearance.\n\nThe tool will permanently update the site's global design settings and return a success confirmation with the updated configuration data.`,\n\t\t\tinputSchema: {\n\t\t\t\tsystemColors: systemColorsSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'System colors array with exactly 4 items having IDs: primary, secondary, text, accent'\n\t\t\t\t\t),\n\t\t\t\tsystemTypography: systemTypographySchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'System typography array with exactly 4 items having IDs: primary, secondary, text, accent'\n\t\t\t\t\t),\n\t\t\t\tcustomColors: customColorsSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe( 'Custom colors array - flexible structure for additional color definitions' ),\n\t\t\t\tcustomTypography: customTypographySchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'Custom typography array - flexible structure for additional font definitions (no color field needed)'\n\t\t\t\t\t),\n\t\t\t\tpatchObject: generalPatchSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc.'\n\t\t\t\t\t),\n\t\t\t\tconfirmationMessage: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'REQUIRED: Provide a clear explanation in **markdown format** of what Elementor kit settings will be changed and their potential impact on the site\\'s global design. This message will be shown to the user before proceeding. Be specific about which design elements are being modified (colors, typography, spacing, etc.) and how they will affect the entire website. Examples: \"You\\'re about to update the global **primary color** from `blue` to `green`. This will change **buttons**, **links**, and **accent colors** throughout your entire site.\" or \"You\\'re about to change the **primary font** from `Roboto` to `Open Sans`. This will affect **headings** across all pages.\"'\n\t\t\t\t\t),\n\t\t\t},\n\t\t\tannotations: {\n\t\t\t\ttitle: 'Update Elementor Kit Settings',\n\t\t\t\tdestructiveHint: true,\n\t\t\t},\n\t\t},\n\t\tasync ( {\n\t\t\tsystemColors,\n\t\t\tsystemTypography,\n\t\t\tcustomColors,\n\t\t\tcustomTypography,\n\t\t\tpatchObject,\n\t\t\tconfirmationMessage,\n\t\t} ) => {\n\t\t\trequireConfirmationMessage( confirmationMessage, 'Elementor kit settings' );\n\n\t\t\tconst invalidFonts = await validateFonts( systemTypography, customTypography );\n\t\t\tif ( invalidFonts ) {\n\t\t\t\tthrow new Error( invalidFonts );\n\t\t\t}\n\n\t\t\tconst completePatchObject = {\n\t\t\t\t...( systemColors && { system_colors: systemColors } ),\n\t\t\t\t...( systemTypography && { system_typography: systemTypography } ),\n\t\t\t\t...( customColors && { custom_colors: customColors } ),\n\t\t\t\t...( customTypography && { custom_typography: customTypography } ),\n\t\t\t\t...sanitizeMediaFields( patchObject || {} ),\n\t\t\t};\n\n\t\t\tif ( Object.keys( completePatchObject ).length === 0 ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'At least one update must be provided (systemColors, systemTypography, customColors, customTypography, or patchObject)'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst response = await callWpApi( `/angie/v1/elementor-kit`, 'POST', completePatchObject );\n\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text' as const,\n\t\t\t\t\t\ttext: JSON.stringify(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\tmessage: 'Settings updated successfully',\n\t\t\t\t\t\t\t\tdata: response,\n\t\t\t\t\t\t\t\tappliedSettings: completePatchObject,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t2\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t);\n\n\tconst sdk = getAngieSdk();\n\tawait sdk.waitForReady();\n\tsdk.registerLocalServer( {\n\t\tserver,\n\t\tversion: VERSION,\n\t\tdescription: SERVER_INSTRUCTIONS,\n\t\tname: 'elementor-kit-server',\n\t} );\n\treturn server;\n}\n","import { createElementorKitServer } from './elementor-kit-mcp-server';\n\nexport function init() {\n\tcreateElementorKitServer();\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@elementor/elementor-kit-mcp",
3
+ "version": "4.1.0-778",
4
+ "private": false,
5
+ "author": "Elementor Team",
6
+ "homepage": "https://elementor.com/",
7
+ "license": "GPL-3.0-or-later",
8
+ "main": "dist/index.js",
9
+ "module": "dist/index.mjs",
10
+ "types": "dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.mjs",
15
+ "require": "./dist/index.js"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/elementor/elementor.git",
22
+ "directory": "packages/core/elementor-kit-mcp"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/elementor/elementor/issues"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "files": [
31
+ "README.md",
32
+ "CHANGELOG.md",
33
+ "/dist",
34
+ "/src",
35
+ "!**/__tests__"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsup --config=../../tsup.build.ts",
39
+ "dev": "tsup --config=../../tsup.dev.ts"
40
+ },
41
+ "devDependencies": {
42
+ "tsup": "^8.3.5"
43
+ },
44
+ "dependencies": {
45
+ "@elementor/editor-mcp": "4.1.0-778",
46
+ "@elementor/elementor-mcp-common": "4.1.0-778",
47
+ "@elementor/schema": "4.1.0-778"
48
+ }
49
+ }
@@ -0,0 +1,395 @@
1
+ import { getAngieSdk, McpServer, ResourceTemplate } from '@elementor/editor-mcp';
2
+ import { callWpApi, requireConfirmationMessage, waitForElementorEditor } from '@elementor/elementor-mcp-common';
3
+ import { z } from '@elementor/schema';
4
+
5
+ const RESOURCE_NAME_KIT_FONTS = 'elementor-kit-fonts';
6
+ const RESOURCE_URI_KIT_FONTS = 'elementor://kit/fonts';
7
+ const RESOURCE_NAME_KIT_SCHEMA = 'elementor-kit-schema';
8
+ const RESOURCE_URI_KIT_SCHEMA_TEMPLATE = 'elementor://kit/schema/{tab}';
9
+ const RESOURCE_NAME_KIT_SETTINGS = 'elementor-kit-settings';
10
+ const RESOURCE_URI_KIT_SETTINGS = 'elementor://kit/settings';
11
+
12
+ type KitFontsResponse = {
13
+ fonts: Record< string, unknown >;
14
+ };
15
+
16
+ type KitSchemaResponse = Record< string, unknown >;
17
+
18
+ const VERSION = '2.0.0';
19
+ async function fetchKitFonts() {
20
+ return callWpApi< KitFontsResponse >( `/angie/v1/elementor-kit/fonts`, 'GET' );
21
+ }
22
+
23
+ async function fetchKitSchema() {
24
+ return callWpApi< KitSchemaResponse >( `/angie/v1/elementor-kit/schema`, 'GET' );
25
+ }
26
+
27
+ async function fetchKitSettings() {
28
+ return callWpApi( `/angie/v1/elementor-kit`, 'GET' );
29
+ }
30
+
31
+ type TypographyItem = {
32
+ typography_font_family?: string;
33
+ };
34
+
35
+ async function validateFonts(
36
+ systemTypography: TypographyItem[] | null | undefined,
37
+ customTypography: TypographyItem[] | null | undefined
38
+ ) {
39
+ const fontsResponse = await fetchKitFonts();
40
+ const availableFonts = Object.keys( fontsResponse.data.fonts || {} );
41
+ const invalidFonts: string[] = [];
42
+
43
+ [ systemTypography, customTypography ].forEach( ( typography ) => {
44
+ if ( typography ) {
45
+ typography.forEach( ( item ) => {
46
+ if ( item.typography_font_family && ! availableFonts.includes( item.typography_font_family ) ) {
47
+ invalidFonts.push( item.typography_font_family );
48
+ }
49
+ } );
50
+ }
51
+ } );
52
+
53
+ if ( invalidFonts.length > 0 ) {
54
+ return `Please use available fonts only. Invalid fonts: ${ invalidFonts.join(
55
+ ', '
56
+ ) }. Available fonts: ${ availableFonts.join( ', ' ) }`;
57
+ }
58
+
59
+ return '';
60
+ }
61
+
62
+ function sanitizeMediaFields( obj: Record< string, unknown > ): Record< string, unknown > {
63
+ const mediaFields = [ 'site_logo', 'site_icon' ];
64
+ const sanitized = { ...obj };
65
+
66
+ for ( const field of mediaFields ) {
67
+ if ( field in sanitized && sanitized[ field ] === '' ) {
68
+ sanitized[ field ] = 0;
69
+ }
70
+ }
71
+
72
+ return sanitized;
73
+ }
74
+
75
+ const baseColorSchema = z.object( {
76
+ title: z.string(),
77
+ color: z.string(),
78
+ } );
79
+
80
+ const baseTypographySchema = z
81
+ .object( {
82
+ title: z.string(),
83
+ typography_typography: z.string(),
84
+ typography_font_family: z
85
+ .string()
86
+ .describe(
87
+ 'Font family name that must be from the available Elementor fonts list. Use the get-fonts endpoint (/angie/v1/elementor-kit/fonts) to get the complete list of available fonts. Only use fonts that exist in this list to avoid validation errors.'
88
+ ),
89
+ typography_font_weight: z.string(),
90
+ typography_font_size: z
91
+ .object( {
92
+ unit: z.string(),
93
+ size: z.number(),
94
+ } )
95
+ .optional(),
96
+ typography_font_size_tablet: z
97
+ .object( {
98
+ unit: z.string(),
99
+ size: z.number(),
100
+ } )
101
+ .optional(),
102
+ typography_font_size_mobile: z
103
+ .object( {
104
+ unit: z.string(),
105
+ size: z.number(),
106
+ } )
107
+ .optional(),
108
+ typography_line_height: z
109
+ .object( {
110
+ unit: z.string(),
111
+ size: z.number(),
112
+ } )
113
+ .optional(),
114
+ } )
115
+ .passthrough();
116
+
117
+ const systemColorItemSchema = baseColorSchema.extend( {
118
+ _id: z.enum( [ 'primary', 'secondary', 'text', 'accent' ] ),
119
+ } );
120
+
121
+ const systemTypographyItemSchema = baseTypographySchema.extend( {
122
+ _id: z.enum( [ 'primary', 'secondary', 'text', 'accent' ] ),
123
+ } );
124
+
125
+ const customColorItemSchema = baseColorSchema.extend( {
126
+ _id: z.string(),
127
+ } );
128
+
129
+ const customTypographyItemSchema = baseTypographySchema.extend( {
130
+ _id: z.string(),
131
+ } );
132
+
133
+ const systemColorsSchema = z.array( systemColorItemSchema ).length( 4 );
134
+ const systemTypographySchema = z.array( systemTypographyItemSchema ).length( 4 );
135
+ const customColorsSchema = z.array( customColorItemSchema );
136
+ const customTypographySchema = z.array( customTypographyItemSchema );
137
+
138
+ const generalPatchSchema = z
139
+ .record( z.unknown() )
140
+ .describe(
141
+ 'General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc.'
142
+ );
143
+
144
+ const SERVER_INSTRUCTIONS = `## Elementor Kit Settings Management
145
+
146
+ ### Capabilities:
147
+ **Global Design System:**
148
+ - Create, update, name, and delete global colors (both system and custom)
149
+ - Create, update, name, and delete global fonts (both system and custom)
150
+
151
+ **Site Identity:**
152
+ - Insert site logo
153
+ - Set site favicon
154
+ - Update site name
155
+ - Modify site description
156
+
157
+ ### Limitations:
158
+ **Theme Style Settings:**
159
+ - Cannot set or update Elementor Theme Style settings including typography, buttons, images, form fields, Hello Theme header, or Hello Theme footer that affect the entire website appearance
160
+
161
+ **Site-Wide Settings:**
162
+ - Cannot set site-wide background (color or image)
163
+ - Cannot configure mobile browser background
164
+ - Cannot modify global layout settings such as content width, container padding, and widget gaps (the default space between widgets)
165
+
166
+ **Note**: Angie can adjust all of these layout properties at the container or page level - just not site-wide.`;
167
+
168
+ export async function createElementorKitServer(): Promise< McpServer > {
169
+ await waitForElementorEditor();
170
+ const server = new McpServer(
171
+ {
172
+ name: 'elementor-kit-server',
173
+ version: VERSION,
174
+ title: 'Elementor Kit',
175
+ },
176
+ {
177
+ instructions: SERVER_INSTRUCTIONS,
178
+ capabilities: {
179
+ resources: {
180
+ subscribe: true,
181
+ },
182
+ },
183
+ }
184
+ );
185
+
186
+ const getAvailableTabs = async (): Promise< string[] > => {
187
+ const kitSchema = await fetchKitSchema();
188
+ return Object.keys( kitSchema.data || {} );
189
+ };
190
+
191
+ server.registerResource(
192
+ RESOURCE_NAME_KIT_FONTS,
193
+ RESOURCE_URI_KIT_FONTS,
194
+ {
195
+ title: 'Elementor Kit Available Fonts',
196
+ description:
197
+ 'Complete list of all available font families that can be used in Elementor, including system fonts, Google fonts, and custom uploaded fonts',
198
+ },
199
+ async ( uri ) => {
200
+ const fontsResponse = await fetchKitFonts();
201
+ return {
202
+ contents: [
203
+ {
204
+ uri: uri.href,
205
+ mimeType: 'application/json',
206
+ text: JSON.stringify( fontsResponse, null, 2 ),
207
+ },
208
+ ],
209
+ };
210
+ }
211
+ );
212
+
213
+ server.registerResource(
214
+ RESOURCE_NAME_KIT_SETTINGS,
215
+ RESOURCE_URI_KIT_SETTINGS,
216
+ {
217
+ title: 'Elementor Kit Current Settings',
218
+ description:
219
+ 'Complete current Elementor global kit configuration including all system and custom colors, typography settings, spacing, buttons, forms, and other site-wide design settings',
220
+ },
221
+ async ( uri ) => {
222
+ const currentSettings = await fetchKitSettings();
223
+ return {
224
+ contents: [
225
+ {
226
+ uri: uri.href,
227
+ mimeType: 'application/json',
228
+ text: JSON.stringify( currentSettings, null, 2 ),
229
+ },
230
+ ],
231
+ };
232
+ }
233
+ );
234
+
235
+ const availableTabs = await getAvailableTabs();
236
+
237
+ server.registerResource(
238
+ RESOURCE_NAME_KIT_SCHEMA,
239
+ new ResourceTemplate( RESOURCE_URI_KIT_SCHEMA_TEMPLATE, {
240
+ list: async () => {
241
+ return {
242
+ resources: availableTabs.map( ( tab ) => {
243
+ return {
244
+ uri: `elementor://kit/schema/${ tab }`,
245
+ name: `${ RESOURCE_NAME_KIT_SCHEMA }-${ tab }`,
246
+ title: `Elementor Kit Schema - ${ tab }`,
247
+ description: `Schema definition for Elementor kit ${ tab } settings tab`,
248
+ mimeType: 'application/json',
249
+ };
250
+ } ),
251
+ };
252
+ },
253
+ } ),
254
+ {
255
+ title: 'Elementor Kit Schema',
256
+ description:
257
+ 'Complete schema definition for a specific Elementor kit settings tab, showing all available fields, their types, valid values, and configuration options',
258
+ },
259
+ async ( uri, variables ) => {
260
+ const tab = Array.isArray( variables.tab ) ? variables.tab[ 0 ] : variables.tab;
261
+
262
+ if ( ! tab ) {
263
+ throw new Error( 'Tab parameter is required' );
264
+ }
265
+
266
+ const kitSchema = await fetchKitSchema();
267
+ const tabSchema = kitSchema.data?.[ tab ];
268
+
269
+ if ( ! tabSchema ) {
270
+ throw new Error(
271
+ `No schema found for tab '${ tab }'. Available tabs: ${ Object.keys( kitSchema.data ).join(
272
+ ', '
273
+ ) }`
274
+ );
275
+ }
276
+
277
+ return {
278
+ contents: [
279
+ {
280
+ uri: uri.toString(),
281
+ mimeType: 'application/json',
282
+ text: JSON.stringify( tabSchema, null, 2 ),
283
+ },
284
+ ],
285
+ };
286
+ }
287
+ );
288
+
289
+ server.registerTool(
290
+ 'update-elementor-kit-settings-colors-and-fonts',
291
+ {
292
+ description: `This tool applies configuration changes to Elementor global kit settings that control site-wide design elements. Use this when you need to modify global colors, typography, spacing, buttons, form fields, or other theme-wide settings that affect the entire website appearance.
293
+
294
+ The tool will permanently update the site's global design settings and return a success confirmation with the updated configuration data.`,
295
+ inputSchema: {
296
+ systemColors: systemColorsSchema
297
+ .optional()
298
+ .nullable()
299
+ .describe(
300
+ 'System colors array with exactly 4 items having IDs: primary, secondary, text, accent'
301
+ ),
302
+ systemTypography: systemTypographySchema
303
+ .optional()
304
+ .nullable()
305
+ .describe(
306
+ 'System typography array with exactly 4 items having IDs: primary, secondary, text, accent'
307
+ ),
308
+ customColors: customColorsSchema
309
+ .optional()
310
+ .nullable()
311
+ .describe( 'Custom colors array - flexible structure for additional color definitions' ),
312
+ customTypography: customTypographySchema
313
+ .optional()
314
+ .nullable()
315
+ .describe(
316
+ 'Custom typography array - flexible structure for additional font definitions (no color field needed)'
317
+ ),
318
+ patchObject: generalPatchSchema
319
+ .optional()
320
+ .nullable()
321
+ .describe(
322
+ 'General patch object for any other Elementor kit settings like spacing, buttons, forms, layout settings, etc.'
323
+ ),
324
+ confirmationMessage: z
325
+ .string()
326
+ .describe(
327
+ 'REQUIRED: Provide a clear explanation in **markdown format** of what Elementor kit settings will be changed and their potential impact on the site\'s global design. This message will be shown to the user before proceeding. Be specific about which design elements are being modified (colors, typography, spacing, etc.) and how they will affect the entire website. Examples: "You\'re about to update the global **primary color** from `blue` to `green`. This will change **buttons**, **links**, and **accent colors** throughout your entire site." or "You\'re about to change the **primary font** from `Roboto` to `Open Sans`. This will affect **headings** across all pages."'
328
+ ),
329
+ },
330
+ annotations: {
331
+ title: 'Update Elementor Kit Settings',
332
+ destructiveHint: true,
333
+ },
334
+ },
335
+ async ( {
336
+ systemColors,
337
+ systemTypography,
338
+ customColors,
339
+ customTypography,
340
+ patchObject,
341
+ confirmationMessage,
342
+ } ) => {
343
+ requireConfirmationMessage( confirmationMessage, 'Elementor kit settings' );
344
+
345
+ const invalidFonts = await validateFonts( systemTypography, customTypography );
346
+ if ( invalidFonts ) {
347
+ throw new Error( invalidFonts );
348
+ }
349
+
350
+ const completePatchObject = {
351
+ ...( systemColors && { system_colors: systemColors } ),
352
+ ...( systemTypography && { system_typography: systemTypography } ),
353
+ ...( customColors && { custom_colors: customColors } ),
354
+ ...( customTypography && { custom_typography: customTypography } ),
355
+ ...sanitizeMediaFields( patchObject || {} ),
356
+ };
357
+
358
+ if ( Object.keys( completePatchObject ).length === 0 ) {
359
+ throw new Error(
360
+ 'At least one update must be provided (systemColors, systemTypography, customColors, customTypography, or patchObject)'
361
+ );
362
+ }
363
+
364
+ const response = await callWpApi( `/angie/v1/elementor-kit`, 'POST', completePatchObject );
365
+
366
+ return {
367
+ content: [
368
+ {
369
+ type: 'text' as const,
370
+ text: JSON.stringify(
371
+ {
372
+ success: true,
373
+ message: 'Settings updated successfully',
374
+ data: response,
375
+ appliedSettings: completePatchObject,
376
+ },
377
+ null,
378
+ 2
379
+ ),
380
+ },
381
+ ],
382
+ };
383
+ }
384
+ );
385
+
386
+ const sdk = getAngieSdk();
387
+ await sdk.waitForReady();
388
+ sdk.registerLocalServer( {
389
+ server,
390
+ version: VERSION,
391
+ description: SERVER_INSTRUCTIONS,
392
+ name: 'elementor-kit-server',
393
+ } );
394
+ return server;
395
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { createElementorKitServer } from './elementor-kit-mcp-server';
2
+ export { init } from './init';
package/src/init.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { createElementorKitServer } from './elementor-kit-mcp-server';
2
+
3
+ export function init() {
4
+ createElementorKitServer();
5
+ }