@noleemits/vision-builder-control-mcp 4.35.1 → 4.38.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +79 -6
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -107,7 +107,7 @@ process.on('SIGINT', () => {
107
107
  // CONFIG
108
108
  // ================================================================
109
109
 
110
- const VERSION = '4.35.1';
110
+ const VERSION = '4.38.1';
111
111
  const MIN_PLUGIN_VERSION = '4.13.0'; // Minimum WP plugin version required by this MCP server
112
112
 
113
113
  // ================================================================
@@ -2151,7 +2151,7 @@ function getToolDefinitions() {
2151
2151
  },
2152
2152
  {
2153
2153
  name: 'update_element',
2154
- description: 'Update any element\'s settings by its Elementor ID or path. Patch widget properties like hover_color, background_color, __globals__ overrides, text, link URLs, etc. Supports dot-notation for nested keys (e.g. "__globals__.hover_color"). Supports element_path as alternative to element_id (e.g. "sectionId/1/0" = section → child 1 → child 0). Use list_elements or export_page first to find the element ID and current settings. IMPORTANT: Prefer settings_json (JSON string) over settings (object) for reliable MCP transport. AUTO-INJECTED KEYS: background_background:"classic" auto-set when you set background_color; typography_typography:"custom" auto-set when you set font properties; flex_grow expands to all 3 required keys; grid column strings auto-wrapped in object format. ICON WIDGET: For view="default" use "icon_size" for dimensions. For view="stacked" or "framed" (circle/square background) use "size" instead — "icon_size" is silently ignored in stacked/framed mode.',
2154
+ description: 'Update any element\'s settings by its Elementor ID or path. Patch widget properties like hover_color, background_color, __globals__ overrides, text, link URLs, etc. Supports dot-notation for nested keys (e.g. "__globals__.hover_color"). Supports element_path as alternative to element_id (e.g. "sectionId/1/0" = section → child 1 → child 0). Use list_elements or export_page first to find the element ID and current settings. IMPORTANT: Prefer settings_json (JSON string) over settings (object) for reliable MCP transport. AUTO-INJECTED KEYS: background_background:"classic" auto-set when you set background_color; typography_typography:"custom" auto-set when you set font properties; flex_grow expands to all 3 required keys; grid column strings auto-wrapped in object format. ICON WIDGET: For view="default" use "icon_size" for dimensions. For view="stacked" or "framed" (circle/square background) use "size" instead — "icon_size" is silently ignored in stacked/framed mode. LOOP-GRID WIDGET: query settings use the prefix "post_query_" (post_query_post_type, post_query_orderby, post_query_order, post_query_posts_per_page) — NOT "posts_post_type". Setting "posts_post_type" is silently accepted but ignored. RACE CONDITION: when patching multiple elements on the SAME page in parallel, use batch_update_elements instead — parallel update_element calls can clobber each other.',
2155
2155
  inputSchema: {
2156
2156
  type: 'object',
2157
2157
  properties: {
@@ -2309,11 +2309,12 @@ function getToolDefinitions() {
2309
2309
  },
2310
2310
  {
2311
2311
  name: 'get_post',
2312
- description: 'Get a single WordPress post/page with ALL details: content, excerpt, Elementor status, RankMath SEO data (title, description, keywords, score), taxonomies (categories, tags), and featured image.',
2312
+ description: 'Get a single WordPress post/page with ALL details: content, excerpt, Elementor status, RankMath SEO data (title, description, keywords, score), taxonomies (categories, tags), and featured image. Pass full_content=true to return the complete raw post_content (default: 500-char preview).',
2313
2313
  inputSchema: {
2314
2314
  type: 'object',
2315
2315
  properties: {
2316
- post_id: { type: 'number', description: 'WordPress post/page ID' }
2316
+ post_id: { type: 'number', description: 'WordPress post/page ID' },
2317
+ full_content: { type: 'boolean', description: 'If true, return the complete raw post_content instead of a 500-char preview. Default: false.' }
2317
2318
  },
2318
2319
  required: ['post_id']
2319
2320
  }
@@ -3248,6 +3249,21 @@ function getToolDefinitions() {
3248
3249
  required: ['source_id', 'section_index', 'target_id']
3249
3250
  }
3250
3251
  },
3252
+ {
3253
+ name: 'clone_template',
3254
+ description: 'Clone an entire Theme Builder template (single, archive, loop-item, header, footer, popup) in one call. Auto-handles the elementor_library_type taxonomy, _elementor_template_type meta, edit-mode meta, and (optionally) display conditions. Saves 4-5 calls (create_post + copy_section × N + display_conditions) into one. Use this instead of stitching those calls together when you need a brand-new Theme Builder template based on an existing design.',
3255
+ inputSchema: {
3256
+ type: 'object',
3257
+ properties: {
3258
+ source_template_id: { type: 'number', description: 'Existing template ID to clone (must be a post of type elementor_library)' },
3259
+ title: { type: 'string', description: 'Title for the new template (e.g. "WAL Single Location")' },
3260
+ slug: { type: 'string', description: 'Optional URL slug. Auto-derived from title if omitted.' },
3261
+ conditions: { type: 'array', items: { type: 'string' }, description: 'Display conditions to set on the new template, e.g. ["include/singular/location"] or ["include/archive/location_archive"]. Omit to leave unset.' },
3262
+ status: { type: 'string', enum: ['publish', 'draft', 'private', 'pending'], description: 'Post status (default: publish)' }
3263
+ },
3264
+ required: ['source_template_id', 'title']
3265
+ }
3266
+ },
3251
3267
  {
3252
3268
  name: 'append_section',
3253
3269
  description: 'Append a section to an existing page or template without downloading the full template. Pass the section JSON directly — no need to export, merge, and re-upload. Useful for adding CTA sections, footers, or any reusable block.',
@@ -3263,6 +3279,17 @@ function getToolDefinitions() {
3263
3279
  required: ['target_id', 'section']
3264
3280
  }
3265
3281
  },
3282
+ {
3283
+ name: 'validate_section',
3284
+ description: 'Lint a section JSON for known bug patterns BEFORE submitting it via append_section / build_page / import_template. Detects: (1) class_based_selectors_only — [data-id^="prefix"] selectors that match nested elements; (2) grid_target_e_con_inner — grid CSS on outer container instead of `.your-grid > .e-con-inner`; (3) button_styling_needs_scoped_css — button widgets without scoped CSS override; (4) numeric_dimensional_fields — clamp()/var() in padding/margin/font_size; (5) no_id_prefix_collision — child element ids that start with the parent\'s id. Returns warnings array with rule name, message, and offending element/selector. Run this whenever you generate complex section JSON, especially with custom CSS.',
3285
+ inputSchema: {
3286
+ type: 'object',
3287
+ properties: {
3288
+ section: { type: 'object', description: 'Full Elementor section object to validate (same format as append_section.section)' }
3289
+ },
3290
+ required: ['section']
3291
+ }
3292
+ },
3266
3293
 
3267
3294
  // ── Template Library Tools ──
3268
3295
 
@@ -4302,8 +4329,8 @@ async function handleToolCall(name, args) {
4302
4329
  }
4303
4330
  }
4304
4331
  if (r.content) {
4305
- const preview = r.content.length > 500 ? r.content.slice(0, 500) + '...' : r.content;
4306
- out += `\n--- CONTENT (${r.content_length} chars) ---\n${preview}\n`;
4332
+ const body = args.full_content ? r.content : (r.content.length > 500 ? r.content.slice(0, 500) + '...' : r.content);
4333
+ out += `\n--- CONTENT (${r.content_length} chars) ---\n${body}\n`;
4307
4334
  }
4308
4335
  return ok(out);
4309
4336
  }
@@ -5608,6 +5635,31 @@ async function handleToolCall(name, args) {
5608
5635
  return ok(msg);
5609
5636
  }
5610
5637
 
5638
+ case 'clone_template': {
5639
+ const sourceId = args.source_template_id;
5640
+ if (!sourceId || !args.title) {
5641
+ return ok('Failed: source_template_id and title are required.');
5642
+ }
5643
+ const body = { title: args.title };
5644
+ if (args.slug) body.slug = args.slug;
5645
+ if (Array.isArray(args.conditions)) body.conditions = args.conditions;
5646
+ if (args.status) body.status = args.status;
5647
+ const r = await apiCall(`/templates/${sourceId}/clone`, 'POST', body);
5648
+ if (r.code || r.error) return ok(`Failed: ${r.message || r.error || 'Unknown error'}`);
5649
+ let msg = `Template cloned!\n`;
5650
+ msg += `Source: ID ${r.source_id}\n`;
5651
+ msg += `New template: ID ${r.new_id} ("${r.title}")\n`;
5652
+ msg += `Type: ${r.template_type || '(none — taxonomy missing on source)'}\n`;
5653
+ msg += `Sections copied: ${r.sections_copied} | Elements: ${r.elements_copied}\n`;
5654
+ if (r.conditions && r.conditions.length) {
5655
+ msg += `Conditions: ${r.conditions.join(', ')}\n`;
5656
+ } else {
5657
+ msg += `Conditions: (none — set via display_conditions if needed)\n`;
5658
+ }
5659
+ msg += `Edit URL: ${r.edit_url}`;
5660
+ return ok(msg);
5661
+ }
5662
+
5611
5663
  case 'append_section': {
5612
5664
  // Enforce root settings on appended sections
5613
5665
  if (args.section) addBoilerplate(args.section);
@@ -5630,6 +5682,27 @@ async function handleToolCall(name, args) {
5630
5682
  return ok(msg);
5631
5683
  }
5632
5684
 
5685
+ case 'validate_section': {
5686
+ const r = await apiCall('/validate-section', 'POST', { section: args.section });
5687
+ if (r.code || r.error) return ok(`Failed: ${r.message || r.error || 'Unknown error'}`);
5688
+ let msg = `=== SECTION VALIDATION ===\n`;
5689
+ msg += `Section ID: ${r.section_id || '(none)'} | Elements: ${r.element_count}\n`;
5690
+ msg += `${r.summary}\n`;
5691
+ if (r.errors && r.errors.length) {
5692
+ msg += `\n--- ERRORS (${r.errors.length}) ---\n`;
5693
+ for (const e of r.errors) {
5694
+ msg += ` [${e.rule}] ${e.message}\n`;
5695
+ }
5696
+ }
5697
+ if (r.warnings && r.warnings.length) {
5698
+ msg += `\n--- WARNINGS (${r.warnings.length}) ---\n`;
5699
+ for (const w of r.warnings) {
5700
+ msg += ` [${w.rule}] ${w.message}\n`;
5701
+ }
5702
+ }
5703
+ return ok(msg);
5704
+ }
5705
+
5633
5706
  // ── Template Library Tools ──
5634
5707
 
5635
5708
  case 'template_list_kits': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noleemits/vision-builder-control-mcp",
3
- "version": "4.35.1",
3
+ "version": "4.38.1",
4
4
  "description": "Vision Builder Control MCP server - design token-driven page builder tools for WordPress/Elementor websites",
5
5
  "type": "module",
6
6
  "main": "index.js",