@noleemits/vision-builder-control-mcp 4.31.0 → 4.32.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 +86 -12
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -104,7 +104,7 @@ process.on('SIGINT', () => {
|
|
|
104
104
|
// CONFIG
|
|
105
105
|
// ================================================================
|
|
106
106
|
|
|
107
|
-
const VERSION = '4.
|
|
107
|
+
const VERSION = '4.32.0';
|
|
108
108
|
const MIN_PLUGIN_VERSION = '4.13.0'; // Minimum WP plugin version required by this MCP server
|
|
109
109
|
|
|
110
110
|
// ================================================================
|
|
@@ -2317,7 +2317,7 @@ function getToolDefinitions() {
|
|
|
2317
2317
|
},
|
|
2318
2318
|
{
|
|
2319
2319
|
name: 'create_post',
|
|
2320
|
-
description: 'Create a WordPress post, page, or CPT. Supports content, excerpt, taxonomies, featured image, Elementor setup, and initial RankMath SEO data.',
|
|
2320
|
+
description: 'Create a WordPress post, page, or CPT. Supports content, excerpt, taxonomies, featured image, parent linking (by slug or ID), Elementor setup, and initial RankMath SEO data.',
|
|
2321
2321
|
inputSchema: {
|
|
2322
2322
|
type: 'object',
|
|
2323
2323
|
properties: {
|
|
@@ -2327,8 +2327,11 @@ function getToolDefinitions() {
|
|
|
2327
2327
|
excerpt: { type: 'string', description: 'Post excerpt' },
|
|
2328
2328
|
status: { type: 'string', enum: ['draft', 'publish', 'private', 'pending'], description: 'Post status (default: draft)' },
|
|
2329
2329
|
slug: { type: 'string', description: 'URL slug (auto-generated if omitted)' },
|
|
2330
|
+
parent: { type: 'number', description: 'Parent post ID (for hierarchical types). Use this OR parent_slug.' },
|
|
2331
|
+
parent_slug: { type: 'string', description: 'Parent slug — looked up against the same post_type. Saves a follow-up update_post call.' },
|
|
2330
2332
|
taxonomies: { type: 'object', description: 'Object: {"category": [1,2], "post_tag": ["seo","health"]}' },
|
|
2331
2333
|
featured_image_id: { type: 'number', description: 'Media library attachment ID' },
|
|
2334
|
+
featured_image_basename: { type: 'string', description: 'Filename of an attachment (e.g. "boating-accidents-v2.jpg") — resolves to the matching attachment ID. Use instead of featured_image_id when you have the source filename but not the ID.' },
|
|
2332
2335
|
elementor: { type: 'boolean', description: 'Set up for Elementor editing' },
|
|
2333
2336
|
seo: { type: 'object', description: 'RankMath SEO: {title, description, focus_keyword, robots, ...}' }
|
|
2334
2337
|
},
|
|
@@ -2337,7 +2340,7 @@ function getToolDefinitions() {
|
|
|
2337
2340
|
},
|
|
2338
2341
|
{
|
|
2339
2342
|
name: 'update_post',
|
|
2340
|
-
description: 'Update any field on a WordPress post/page. Only provided fields are changed. Supports title, content, status, slug, excerpt, taxonomies, featured image, and RankMath SEO. Pass preserve_modified_date=true to keep the original last-modified date.',
|
|
2343
|
+
description: 'Update any field on a WordPress post/page. Only provided fields are changed. Supports title, content, status, slug, excerpt, parent (ID or slug), taxonomies, featured image (ID or basename), and RankMath SEO. Pass preserve_modified_date=true to keep the original last-modified date.',
|
|
2341
2344
|
inputSchema: {
|
|
2342
2345
|
type: 'object',
|
|
2343
2346
|
properties: {
|
|
@@ -2348,8 +2351,10 @@ function getToolDefinitions() {
|
|
|
2348
2351
|
status: { type: 'string', enum: ['draft', 'publish', 'private', 'pending', 'trash'] },
|
|
2349
2352
|
slug: { type: 'string' },
|
|
2350
2353
|
parent: { type: 'number', description: 'Parent post/page ID (for hierarchical types like pages). Changes URL structure.' },
|
|
2354
|
+
parent_slug: { type: 'string', description: 'Parent slug — looked up against this post\'s post_type. Use instead of parent when you don\'t know the parent ID.' },
|
|
2351
2355
|
taxonomies: { type: 'object', description: '{"category": [1,2]}' },
|
|
2352
2356
|
featured_image_id: { type: 'number', description: 'Attachment ID (omit to keep, pass null to remove)' },
|
|
2357
|
+
featured_image_basename: { type: 'string', description: 'Filename of an attachment to use as featured image. Resolved to the matching ID server-side.' },
|
|
2353
2358
|
seo: { type: 'object', description: 'RankMath SEO fields to update' },
|
|
2354
2359
|
preserve_modified_date: { type: 'boolean', description: 'If true, keep the original last-modified date instead of updating it to now. Useful for content fixes that should not change the published "updated" date.' }
|
|
2355
2360
|
},
|
|
@@ -2612,6 +2617,56 @@ function getToolDefinitions() {
|
|
|
2612
2617
|
}
|
|
2613
2618
|
},
|
|
2614
2619
|
|
|
2620
|
+
// ── Patch + Migration (v4.32.0) ──
|
|
2621
|
+
{
|
|
2622
|
+
name: 'patch_template',
|
|
2623
|
+
description: 'Apply surgical operations to an Elementor library template without re-uploading the full JSON. Op types: set_settings (merge keys into element.settings), replace_element (swap full element node), insert_element (add child at position 0/end/<int>), remove_element (delete by id), append_custom_css / set_custom_css (add or replace settings.custom_css). Returns per-op success/error so partial failures don\'t roll back the batch.',
|
|
2624
|
+
inputSchema: {
|
|
2625
|
+
type: 'object',
|
|
2626
|
+
properties: {
|
|
2627
|
+
template_id: { type: 'number', description: 'Elementor library template ID' },
|
|
2628
|
+
ops: {
|
|
2629
|
+
type: 'array',
|
|
2630
|
+
description: 'Ordered list of operations to apply.',
|
|
2631
|
+
items: {
|
|
2632
|
+
type: 'object',
|
|
2633
|
+
properties: {
|
|
2634
|
+
type: { type: 'string', enum: ['set_settings', 'replace_element', 'insert_element', 'remove_element', 'append_custom_css', 'set_custom_css'] },
|
|
2635
|
+
id: { type: 'string', description: 'Target element ID (required for set_settings, replace_element, remove_element, append_custom_css, set_custom_css)' },
|
|
2636
|
+
parent_id: { type: 'string', description: 'Parent element ID (required for insert_element)' },
|
|
2637
|
+
position: { description: 'Insert position: 0, "end", or numeric index. Default: end.' },
|
|
2638
|
+
element: { type: 'object', description: 'Full element JSON (required for replace_element, insert_element)' },
|
|
2639
|
+
settings: { type: 'object', description: 'Settings to merge (required for set_settings)' },
|
|
2640
|
+
css: { type: 'string', description: 'CSS text (required for append_custom_css, set_custom_css)' }
|
|
2641
|
+
},
|
|
2642
|
+
required: ['type']
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
},
|
|
2646
|
+
required: ['template_id', 'ops']
|
|
2647
|
+
}
|
|
2648
|
+
},
|
|
2649
|
+
{
|
|
2650
|
+
name: 'migrate_extracted_md',
|
|
2651
|
+
description: 'One-shot migration: take an extract-format markdown chunk and create or update a CPT post with cleaned HTML body, featured image, parent linking, and RankMath SEO. Idempotent: re-running with the same slug+post_type updates instead of duplicating. Pass md_content (preferred) or md_path. Use hero_basename to look up the featured image by filename instead of attachment ID.',
|
|
2652
|
+
inputSchema: {
|
|
2653
|
+
type: 'object',
|
|
2654
|
+
properties: {
|
|
2655
|
+
md_content: { type: 'string', description: 'Raw markdown body (preferred — no server-side path needed)' },
|
|
2656
|
+
md_path: { type: 'string', description: 'Server-side path to MD file. Only useful if WP server can read the path.' },
|
|
2657
|
+
post_type: { type: 'string', description: 'CPT slug (e.g. "practice-area")' },
|
|
2658
|
+
slug: { type: 'string', description: 'Post slug — used as idempotency key' },
|
|
2659
|
+
parent_slug: { type: 'string', description: 'Optional. Looked up against same post_type for hierarchical CPTs.' },
|
|
2660
|
+
hero_basename: { type: 'string', description: 'Optional. Filename like "boating-accidents-v2.jpg" — resolves to the matching attachment.' },
|
|
2661
|
+
title_override: { type: 'string', description: 'Optional. Overrides extracted H1.' },
|
|
2662
|
+
seo_focus_keyword: { type: 'string', description: 'Optional. RankMath focus keyword.' },
|
|
2663
|
+
status: { type: 'string', enum: ['draft', 'publish', 'private', 'pending'], description: 'Default: publish' },
|
|
2664
|
+
strip_first_paragraph: { type: 'boolean', description: 'Drop the first <p> if it duplicates H1+lede (default: true)' }
|
|
2665
|
+
},
|
|
2666
|
+
required: ['post_type', 'slug']
|
|
2667
|
+
}
|
|
2668
|
+
},
|
|
2669
|
+
|
|
2615
2670
|
// ── Custom post types & taxonomies (v4.31.0) ──
|
|
2616
2671
|
{
|
|
2617
2672
|
name: 'register_cpt',
|
|
@@ -4156,15 +4211,10 @@ async function handleToolCall(name, args) {
|
|
|
4156
4211
|
|
|
4157
4212
|
case 'create_post': {
|
|
4158
4213
|
const body = { title: args.title };
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
if (args
|
|
4163
|
-
if (args.slug) body.slug = args.slug;
|
|
4164
|
-
if (args.taxonomies) body.taxonomies = args.taxonomies;
|
|
4165
|
-
if (args.featured_image_id) body.featured_image_id = args.featured_image_id;
|
|
4166
|
-
if (args.elementor) body.elementor = args.elementor;
|
|
4167
|
-
if (args.seo) body.seo = args.seo;
|
|
4214
|
+
const passthrough = ['post_type', 'content', 'excerpt', 'status', 'slug',
|
|
4215
|
+
'parent', 'parent_slug', 'taxonomies', 'featured_image_id',
|
|
4216
|
+
'featured_image_basename', 'elementor', 'seo'];
|
|
4217
|
+
for (const k of passthrough) if (args[k] !== undefined) body[k] = args[k];
|
|
4168
4218
|
const r = await apiCall('/posts', 'POST', body);
|
|
4169
4219
|
if (!r.success) return ok(`Failed: ${r.message || 'Unknown error'}`);
|
|
4170
4220
|
return ok(`Post created!\nID: ${r.id} | Type: ${r.type} | Status: ${r.status}\nTitle: ${r.title}\nSlug: ${r.slug}\nURL: ${r.url}\nEdit: ${r.edit_url}`);
|
|
@@ -4472,6 +4522,30 @@ async function handleToolCall(name, args) {
|
|
|
4472
4522
|
return ok(`Assigned menu #${r.menu_id} to location "${r.location}".`);
|
|
4473
4523
|
}
|
|
4474
4524
|
|
|
4525
|
+
case 'patch_template': {
|
|
4526
|
+
const r = await apiCall(`/templates/${args.template_id}/patch`, 'POST', { ops: args.ops });
|
|
4527
|
+
const okLines = r.applied.map(a => ` ✓ #${a.index} ${a.type}`);
|
|
4528
|
+
const errLines = (r.errors || []).map(e => ` ✗ #${e.index} ${e.type}: ${e.error}`);
|
|
4529
|
+
return ok(
|
|
4530
|
+
`Patched template ${r.template_id}: ${r.applied.length} op(s) applied${r.errors?.length ? ', ' + r.errors.length + ' failed' : ''}\n` +
|
|
4531
|
+
okLines.concat(errLines).join('\n')
|
|
4532
|
+
);
|
|
4533
|
+
}
|
|
4534
|
+
|
|
4535
|
+
case 'migrate_extracted_md': {
|
|
4536
|
+
const body = {};
|
|
4537
|
+
['md_content','md_path','post_type','slug','parent_slug','hero_basename','title_override','seo_focus_keyword','status','strip_first_paragraph']
|
|
4538
|
+
.forEach(k => { if (args[k] !== undefined) body[k] = args[k]; });
|
|
4539
|
+
const r = await apiCall('/migrate/extracted-md', 'POST', body);
|
|
4540
|
+
return ok(
|
|
4541
|
+
`${r.was_existing ? 'Updated' : 'Created'} ${args.post_type} #${r.post_id}\n` +
|
|
4542
|
+
` H1: ${r.parsed.h1}\n` +
|
|
4543
|
+
` Title: ${args.title_override || r.parsed.h1}\n` +
|
|
4544
|
+
` Body: ${r.parsed.body_length} chars\n` +
|
|
4545
|
+
` URL: ${r.url}`
|
|
4546
|
+
);
|
|
4547
|
+
}
|
|
4548
|
+
|
|
4475
4549
|
case 'register_cpt': {
|
|
4476
4550
|
const r = await apiCall('/post-types', 'POST', args);
|
|
4477
4551
|
return ok(`${r.created ? 'Registered' : 'Updated'} CPT "${r.slug}"\n hierarchical: ${r.def.hierarchical}\n rewrite_slug: ${r.def.rewrite_slug || '(default)'}\n has_archive: ${r.def.has_archive}\n supports: ${(r.def.supports || []).join(', ')}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noleemits/vision-builder-control-mcp",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.32.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",
|