@noleemits/vision-builder-control-mcp 4.38.1 → 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.
- package/index.js +137 -3
- 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.
|
|
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
|
// ================================================================
|
|
@@ -2422,6 +2422,62 @@ function getToolDefinitions() {
|
|
|
2422
2422
|
}
|
|
2423
2423
|
}
|
|
2424
2424
|
},
|
|
2425
|
+
{
|
|
2426
|
+
name: 'get_rankmath_global',
|
|
2427
|
+
description: 'Read RankMath sitewide settings: Knowledge Graph / Organization (name, type, logo, phone, email, address), social profiles (Facebook URL, Twitter handle, additional profile URLs), and default Open Graph image. Use to audit before bulk-updating sitewide schema/social data.',
|
|
2428
|
+
inputSchema: {
|
|
2429
|
+
type: 'object',
|
|
2430
|
+
properties: {}
|
|
2431
|
+
}
|
|
2432
|
+
},
|
|
2433
|
+
{
|
|
2434
|
+
name: 'update_rankmath_global',
|
|
2435
|
+
description: 'Update RankMath sitewide settings (Knowledge Graph / Organization, social profiles, defaults). Send a partial structured object — only provided keys are written. Use to push organization name/logo/phone/address, social URLs, and default OG image into RankMath schema in one call.',
|
|
2436
|
+
inputSchema: {
|
|
2437
|
+
type: 'object',
|
|
2438
|
+
properties: {
|
|
2439
|
+
organization: {
|
|
2440
|
+
type: 'object',
|
|
2441
|
+
description: 'Knowledge Graph / Organization fields',
|
|
2442
|
+
properties: {
|
|
2443
|
+
type: { type: 'string', description: '"company" or "person"' },
|
|
2444
|
+
name: { type: 'string' },
|
|
2445
|
+
logo: { type: 'string', description: 'Logo URL (use a media library URL)' },
|
|
2446
|
+
phone: { type: 'string' },
|
|
2447
|
+
email: { type: 'string' },
|
|
2448
|
+
address: {
|
|
2449
|
+
type: 'object',
|
|
2450
|
+
properties: {
|
|
2451
|
+
street: { type: 'string' },
|
|
2452
|
+
city: { type: 'string' },
|
|
2453
|
+
state: { type: 'string' },
|
|
2454
|
+
zip: { type: 'string' },
|
|
2455
|
+
country: { type: 'string' }
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
},
|
|
2460
|
+
social: {
|
|
2461
|
+
type: 'object',
|
|
2462
|
+
description: 'Social profile URLs',
|
|
2463
|
+
properties: {
|
|
2464
|
+
facebook: { type: 'string', description: 'Facebook page URL' },
|
|
2465
|
+
twitter: { type: 'string', description: 'Twitter handle (e.g. "@firmname")' },
|
|
2466
|
+
additional_profiles: { type: 'array', items: { type: 'string' }, description: 'Additional profile URLs (LinkedIn, Instagram, YouTube, etc.) — one URL per array entry' }
|
|
2467
|
+
}
|
|
2468
|
+
},
|
|
2469
|
+
defaults: {
|
|
2470
|
+
type: 'object',
|
|
2471
|
+
description: 'Sitewide defaults',
|
|
2472
|
+
properties: {
|
|
2473
|
+
open_graph_image: { type: 'string', description: 'Default OG image URL' },
|
|
2474
|
+
open_graph_image_id: { type: 'number', description: 'Default OG image attachment ID' }
|
|
2475
|
+
}
|
|
2476
|
+
},
|
|
2477
|
+
local_business_type: { type: 'string', description: 'schema.org Local Business type (e.g. "LegalService")' }
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
},
|
|
2425
2481
|
{
|
|
2426
2482
|
name: 'audit_faq_schema',
|
|
2427
2483
|
description: 'Audit all published posts/pages for FAQ schema issues: duplicate FAQPage markup (NVBC meta + RankMath block), orphaned NVBC schemas, unconverted plain FAQs, invalid JSON, empty Q&As, and encoding issues (bare u003c).',
|
|
@@ -2576,9 +2632,20 @@ function getToolDefinitions() {
|
|
|
2576
2632
|
required: ['name']
|
|
2577
2633
|
}
|
|
2578
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
|
+
},
|
|
2579
2646
|
{
|
|
2580
2647
|
name: 'set_menu_items',
|
|
2581
|
-
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.',
|
|
2582
2649
|
inputSchema: {
|
|
2583
2650
|
type: 'object',
|
|
2584
2651
|
properties: {
|
|
@@ -2595,7 +2662,9 @@ function getToolDefinitions() {
|
|
|
2595
2662
|
object: { type: 'string', description: 'e.g. "page", "post", "category" — required when type !== "custom"' },
|
|
2596
2663
|
object_id: { type: 'number', description: 'WP object ID — required when type !== "custom"' },
|
|
2597
2664
|
parent_index: { type: 'number', description: 'Index in this array of the parent item (for nesting). Omit for top-level.' },
|
|
2598
|
-
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.' }
|
|
2599
2668
|
}
|
|
2600
2669
|
}
|
|
2601
2670
|
}
|
|
@@ -4391,6 +4460,52 @@ async function handleToolCall(name, args) {
|
|
|
4391
4460
|
return ok(out);
|
|
4392
4461
|
}
|
|
4393
4462
|
|
|
4463
|
+
case 'get_rankmath_global': {
|
|
4464
|
+
const r = await apiCall('/seo/global');
|
|
4465
|
+
if (!r.success) return ok(`Failed: ${r.message || 'Unknown error'}`);
|
|
4466
|
+
let out = `=== RANKMATH GLOBAL SETTINGS ===\n`;
|
|
4467
|
+
out += `\n--- Organization ---\n`;
|
|
4468
|
+
out += ` Type: ${r.organization.type || '(unset)'}\n`;
|
|
4469
|
+
out += ` Name: ${r.organization.name || '(unset)'}\n`;
|
|
4470
|
+
out += ` Logo: ${r.organization.logo || '(unset)'}\n`;
|
|
4471
|
+
out += ` Phone: ${r.organization.phone || '(unset)'}\n`;
|
|
4472
|
+
out += ` Email: ${r.organization.email || '(unset)'}\n`;
|
|
4473
|
+
const a = r.organization.address || {};
|
|
4474
|
+
if (a.street || a.city) {
|
|
4475
|
+
out += ` Address: ${a.street || ''}${a.street && a.city ? ', ' : ''}${a.city || ''}${a.state ? ', ' + a.state : ''} ${a.zip || ''}${a.country ? ' ' + a.country : ''}\n`;
|
|
4476
|
+
} else {
|
|
4477
|
+
out += ` Address: (unset)\n`;
|
|
4478
|
+
}
|
|
4479
|
+
out += `\n--- Social ---\n`;
|
|
4480
|
+
out += ` Facebook: ${r.social.facebook || '(unset)'}\n`;
|
|
4481
|
+
out += ` Twitter: ${r.social.twitter || '(unset)'}\n`;
|
|
4482
|
+
if (r.social.additional_profiles && r.social.additional_profiles.length) {
|
|
4483
|
+
out += ` Additional profiles:\n`;
|
|
4484
|
+
r.social.additional_profiles.forEach(u => out += ` - ${u}\n`);
|
|
4485
|
+
} else {
|
|
4486
|
+
out += ` Additional profiles: (none)\n`;
|
|
4487
|
+
}
|
|
4488
|
+
out += `\n--- Defaults ---\n`;
|
|
4489
|
+
out += ` OG image: ${r.defaults.open_graph_image || '(unset)'}\n`;
|
|
4490
|
+
if (r.defaults.open_graph_image_id) out += ` OG image ID: ${r.defaults.open_graph_image_id}\n`;
|
|
4491
|
+
if (r.local_business_type) out += `\nLocal business type: ${r.local_business_type}\n`;
|
|
4492
|
+
return ok(out);
|
|
4493
|
+
}
|
|
4494
|
+
|
|
4495
|
+
case 'update_rankmath_global': {
|
|
4496
|
+
const r = await apiCall('/seo/global', 'POST', args);
|
|
4497
|
+
if (!r.success) return ok(`Failed: ${r.message || 'Unknown error'}`);
|
|
4498
|
+
let out = `RankMath sitewide settings updated!\n`;
|
|
4499
|
+
out += `Updated: ${(r.updated_fields || []).join(', ') || '(none)'}\n`;
|
|
4500
|
+
if (r.current && r.current.organization) {
|
|
4501
|
+
out += `\n--- New state ---\n`;
|
|
4502
|
+
out += ` Org: ${r.current.organization.name || '(unset)'} (${r.current.organization.type || 'unset'})\n`;
|
|
4503
|
+
out += ` Phone: ${r.current.organization.phone || '(unset)'}\n`;
|
|
4504
|
+
out += ` Facebook: ${r.current.social.facebook || '(unset)'}\n`;
|
|
4505
|
+
}
|
|
4506
|
+
return ok(out);
|
|
4507
|
+
}
|
|
4508
|
+
|
|
4394
4509
|
case 'audit_seo': {
|
|
4395
4510
|
const params = new URLSearchParams();
|
|
4396
4511
|
if (args.post_type) params.set('post_type', args.post_type);
|
|
@@ -4627,6 +4742,25 @@ async function handleToolCall(name, args) {
|
|
|
4627
4742
|
: `Menu already existed: "${r.name}" (ID ${r.id})`);
|
|
4628
4743
|
}
|
|
4629
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
|
+
|
|
4630
4764
|
case 'set_menu_items': {
|
|
4631
4765
|
const r = await apiCall(`/menus/${args.menu_id}/items`, 'POST', { items: args.items });
|
|
4632
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.
|
|
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",
|