@noleemits/vision-builder-control-mcp 4.39.0 → 4.41.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 +35 -3
  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.39.0';
110
+ const VERSION = '4.41.1';
111
111
  const MIN_PLUGIN_VERSION = '4.13.0'; // Minimum WP plugin version required by this MCP server
112
112
 
113
113
  // ================================================================
@@ -2632,9 +2632,20 @@ function getToolDefinitions() {
2632
2632
  required: ['name']
2633
2633
  }
2634
2634
  },
2635
+ {
2636
+ name: 'list_menu_items',
2637
+ description: 'List all items in a nav menu, in order. Returns each item\'s id, title, url, type, object (page/post/category/etc.), object_id, parent (parent item ID, 0 for top-level), order, target, classes (CSS class array), and description. Use before set_menu_items so you can patch one entry without losing the others.',
2638
+ inputSchema: {
2639
+ type: 'object',
2640
+ properties: {
2641
+ menu_id: { type: 'number', description: 'Menu ID from list_nav_menus' }
2642
+ },
2643
+ required: ['menu_id']
2644
+ }
2645
+ },
2635
2646
  {
2636
2647
  name: 'set_menu_items',
2637
- description: 'Bulk-replace all items in a nav menu. Each item: {title, url (for type=custom), type ("custom"|"post_type"|"taxonomy"), object ("page"|"post"|"category"), object_id, parent_index (for nesting — 0-based index of parent in this same array), target ("_blank")}. Items are inserted in order; nested items must come AFTER their parent in the array.',
2648
+ description: 'Bulk-replace all items in a nav menu. Each item: {title, url (for type=custom), type ("custom"|"post_type"|"taxonomy"), object ("page"|"post"|"category"), object_id, parent_index (for nesting — 0-based index of parent in this same array), target ("_blank"), classes (CSS classes — string or array, applied as <li class="...">), description (free text shown by some menu widgets)}. Items are inserted in order; nested items must come AFTER their parent in the array.',
2638
2649
  inputSchema: {
2639
2650
  type: 'object',
2640
2651
  properties: {
@@ -2651,7 +2662,9 @@ function getToolDefinitions() {
2651
2662
  object: { type: 'string', description: 'e.g. "page", "post", "category" — required when type !== "custom"' },
2652
2663
  object_id: { type: 'number', description: 'WP object ID — required when type !== "custom"' },
2653
2664
  parent_index: { type: 'number', description: 'Index in this array of the parent item (for nesting). Omit for top-level.' },
2654
- target: { type: 'string', enum: ['_blank', ''], description: 'Optional. "_blank" opens in new tab.' }
2665
+ target: { type: 'string', enum: ['_blank', ''], description: 'Optional. "_blank" opens in new tab.' },
2666
+ classes: { description: 'CSS classes for the <li>. Pass a string ("mega-menu primary") or an array (["mega-menu", "primary"]). Useful for targeting specific items in CSS without relying on URL substrings.' },
2667
+ description: { type: 'string', description: 'Optional description text. Some menu walkers render it; otherwise stored as data-description.' }
2655
2668
  }
2656
2669
  }
2657
2670
  }
@@ -4729,6 +4742,25 @@ async function handleToolCall(name, args) {
4729
4742
  : `Menu already existed: "${r.name}" (ID ${r.id})`);
4730
4743
  }
4731
4744
 
4745
+ case 'list_menu_items': {
4746
+ const r = await apiCall(`/menus/${args.menu_id}/items`);
4747
+ if (!r.items || !r.items.length) return ok(`Menu ${args.menu_id} has no items.`);
4748
+ const byParent = {};
4749
+ r.items.forEach(it => { (byParent[it.parent || 0] ||= []).push(it); });
4750
+ const lines = [];
4751
+ const renderItem = (it, depth) => {
4752
+ const indent = ' '.repeat(depth);
4753
+ const target = it.type === 'custom'
4754
+ ? it.url
4755
+ : `${it.type}/${it.object}#${it.object_id}`;
4756
+ const cls = Array.isArray(it.classes) && it.classes.length ? ` .${it.classes.join('.')}` : '';
4757
+ lines.push(`${indent}[${it.id}] ${it.title} → ${target}${cls}`);
4758
+ (byParent[it.id] || []).forEach(c => renderItem(c, depth + 1));
4759
+ };
4760
+ (byParent[0] || []).forEach(it => renderItem(it, 0));
4761
+ return ok(`Menu ${r.menu_id} items (${r.items.length}):\n${lines.join('\n')}`);
4762
+ }
4763
+
4732
4764
  case 'set_menu_items': {
4733
4765
  const r = await apiCall(`/menus/${args.menu_id}/items`, 'POST', { items: args.items });
4734
4766
  const errLines = (r.errors || []).map(e => ` • #${e.index}: ${e.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noleemits/vision-builder-control-mcp",
3
- "version": "4.39.0",
3
+ "version": "4.41.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",