@respira/wordpress-mcp-server 6.11.13 → 6.13.0
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/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +268 -140
- package/dist/server.js.map +1 -1
- package/dist/wordpress-client.d.ts +18 -1
- package/dist/wordpress-client.d.ts.map +1 -1
- package/dist/wordpress-client.js +108 -16
- package/dist/wordpress-client.js.map +1 -1
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -58,6 +58,43 @@ class ToolTimeoutError extends Error {
|
|
|
58
58
|
function getMaxToolTimeoutMs() {
|
|
59
59
|
return Math.max(5000, parseInt(process.env.RESPIRA_MAX_TOOL_TIMEOUT_MS || '120000', 10));
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* v6.12.0: Tool names that do NOT receive the optional site_id input parameter.
|
|
63
|
+
* These tools operate on global Respira config or pre-site setup state, so a
|
|
64
|
+
* per-call site override doesn't apply:
|
|
65
|
+
* - list_sites: returns all configured sites
|
|
66
|
+
* - get_active_site: returns the global current site (a per-call override
|
|
67
|
+
* would be meaningless here; if you want a specific site's summary, look
|
|
68
|
+
* at list_sites)
|
|
69
|
+
* - switch_site: already takes site_id with the explicit semantics of
|
|
70
|
+
* flipping the global current site (different intent from per-call override)
|
|
71
|
+
* - redeem_token: pre-site setup; no site exists yet
|
|
72
|
+
*/
|
|
73
|
+
const SITE_AGNOSTIC_TOOLS = new Set([
|
|
74
|
+
'wordpress_list_sites',
|
|
75
|
+
'wordpress_get_active_site',
|
|
76
|
+
'wordpress_switch_site',
|
|
77
|
+
'wordpress_redeem_token',
|
|
78
|
+
'respira_list_sites',
|
|
79
|
+
'respira_get_active_site',
|
|
80
|
+
'respira_switch_site',
|
|
81
|
+
'respira_redeem_token',
|
|
82
|
+
]);
|
|
83
|
+
/**
|
|
84
|
+
* v6.12.0: Schema fragment auto-injected into every non-agnostic tool's
|
|
85
|
+
* inputSchema.properties. Lets callers override the active site on a single
|
|
86
|
+
* tool call without flipping the global current site.
|
|
87
|
+
*
|
|
88
|
+
* Solves the Cowork multi-chat contamination: when Cowork runs many chat
|
|
89
|
+
* sessions through one shared MCP server process, switch_site mutates the
|
|
90
|
+
* global current site for all sessions. Passing site_id per call sidesteps
|
|
91
|
+
* the shared state entirely. T.S. (studioscaler) reported the symptom
|
|
92
|
+
* 2026-05-16 across his multi-site workflow.
|
|
93
|
+
*/
|
|
94
|
+
const SITE_ID_PROPERTY = {
|
|
95
|
+
type: 'string',
|
|
96
|
+
description: 'Optional. Override the active site for this single call without changing the global current site. Use this when running multiple Cowork chats against different WordPress sites in parallel so each chat can pin its own target site per tool call.',
|
|
97
|
+
};
|
|
61
98
|
export class RespiraWordPressServer {
|
|
62
99
|
server;
|
|
63
100
|
currentSite = null;
|
|
@@ -359,6 +396,35 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
359
396
|
}
|
|
360
397
|
return this.getSiteSummary(this.currentSite);
|
|
361
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* Resolve which WordPressClient should service this tool call.
|
|
401
|
+
*
|
|
402
|
+
* Order:
|
|
403
|
+
* 1) explicit args.site_id (per-call override; introduced in v6.12.0)
|
|
404
|
+
* 2) the global current site (`this.currentSite`)
|
|
405
|
+
*
|
|
406
|
+
* Throws if neither is set, or if the supplied site_id is unknown / not
|
|
407
|
+
* allowed for this MCP configuration group.
|
|
408
|
+
*
|
|
409
|
+
* @since 6.12.0
|
|
410
|
+
*/
|
|
411
|
+
resolveClient(args) {
|
|
412
|
+
if (args && typeof args.site_id === 'string' && args.site_id.length > 0) {
|
|
413
|
+
const explicit = this.sites.get(args.site_id);
|
|
414
|
+
if (!explicit) {
|
|
415
|
+
const available = Array.from(this.sites.keys()).join(', ') || '(none configured)';
|
|
416
|
+
throw new Error(`Site with ID "${args.site_id}" not found in this MCP configuration. Available: ${available}`);
|
|
417
|
+
}
|
|
418
|
+
if (!this.isSiteAllowed(explicit)) {
|
|
419
|
+
throw new Error(`Site "${args.site_id}" is not in this MCP configuration group.`);
|
|
420
|
+
}
|
|
421
|
+
return explicit;
|
|
422
|
+
}
|
|
423
|
+
if (!this.currentSite) {
|
|
424
|
+
throw new Error('No active site. Either pass site_id on this tool call or run respira_switch_site / respira_redeem_token first.');
|
|
425
|
+
}
|
|
426
|
+
return this.currentSite;
|
|
427
|
+
}
|
|
362
428
|
/** Check if a site is visible given RESPIRA_SITES filtering. */
|
|
363
429
|
isSiteAllowed(site) {
|
|
364
430
|
if (!this.allowedSites)
|
|
@@ -1182,7 +1248,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1182
1248
|
},
|
|
1183
1249
|
{
|
|
1184
1250
|
name: 'wordpress_find_builder_targets',
|
|
1185
|
-
description: 'List all editable builder modules/blocks on a page with their types, labels, and text content — without returning the full builder JSON. Use this for a quick overview of what is on a page. For finding a specific element by text or class, use find_element instead.',
|
|
1251
|
+
description: 'List all editable builder modules/blocks on a page with their types, labels, and text content — without returning the full builder JSON. Use this for a quick overview of what is on a page. For finding a specific element by text or class, use find_element instead. Returns `total_matches` (true total independent of limit), `offset`, `has_more`, and `next_offset` for pagination. WPBakery / Uncode targets now surface a populated `label` / `admin_label` / `text` so you do not have to grep the raw shortcode preview.',
|
|
1186
1252
|
inputSchema: {
|
|
1187
1253
|
type: 'object',
|
|
1188
1254
|
properties: {
|
|
@@ -1200,16 +1266,59 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1200
1266
|
},
|
|
1201
1267
|
limit: {
|
|
1202
1268
|
type: 'number',
|
|
1203
|
-
description: 'Maximum number of matches to return (default 10)',
|
|
1269
|
+
description: 'Maximum number of matches to return per page (default 10). The full match count is always returned as `total_matches` independent of this limit.',
|
|
1270
|
+
},
|
|
1271
|
+
offset: {
|
|
1272
|
+
type: 'number',
|
|
1273
|
+
description: 'Skip the first N matches before slicing the page. Defaults to 0. Paginate by passing the previous response\'s `next_offset` value.',
|
|
1204
1274
|
},
|
|
1205
1275
|
},
|
|
1206
1276
|
required: ['builder', 'page_id'],
|
|
1207
1277
|
},
|
|
1208
1278
|
readOnlyHint: true,
|
|
1209
1279
|
},
|
|
1280
|
+
{
|
|
1281
|
+
name: 'wordpress_get_page_outline',
|
|
1282
|
+
description: 'Row-level outline of a builder page. Lighter than extract_builder_content; one entry per top-level row with { index, type, kind, primary_heading, child_count, child_types } so you can answer "what is the structure of this page" without walking the full tree client-side. Works on every supported builder; adapters with a dedicated outline implementation (WPBakery + Uncode today) return a richer per-row child-type histogram.',
|
|
1283
|
+
inputSchema: {
|
|
1284
|
+
type: 'object',
|
|
1285
|
+
properties: {
|
|
1286
|
+
builder: {
|
|
1287
|
+
type: 'string',
|
|
1288
|
+
description: 'Builder name. Optional — auto-detected from the active site builder when omitted.',
|
|
1289
|
+
},
|
|
1290
|
+
page_id: {
|
|
1291
|
+
type: 'number',
|
|
1292
|
+
description: 'Page or post ID',
|
|
1293
|
+
},
|
|
1294
|
+
},
|
|
1295
|
+
required: ['page_id'],
|
|
1296
|
+
},
|
|
1297
|
+
readOnlyHint: true,
|
|
1298
|
+
},
|
|
1299
|
+
{
|
|
1300
|
+
name: 'wordpress_get_builder_inline_schemas',
|
|
1301
|
+
description: 'Per-shortcode / per-block inline attribute schemas for the requested builder. Currently populated for WPBakery + Uncode + TagDiv via vc_map() at runtime (cached as a transient for 1h). Other builders return `schemas: {}` + `supported: false` + a structured hint. Use this to discover what attributes a specific `vc_*` / `uncode_*` shortcode accepts before writing.',
|
|
1302
|
+
inputSchema: {
|
|
1303
|
+
type: 'object',
|
|
1304
|
+
properties: {
|
|
1305
|
+
builder: {
|
|
1306
|
+
type: 'string',
|
|
1307
|
+
description: 'Builder name. Optional — auto-detected from the active site builder when omitted. Pass "wpbakery" explicitly for non-WPBakery sites that want to inspect the catalog anyway.',
|
|
1308
|
+
},
|
|
1309
|
+
types: {
|
|
1310
|
+
type: 'array',
|
|
1311
|
+
items: { type: 'string' },
|
|
1312
|
+
description: 'Optional filter — only return schemas for these shortcode types (e.g. ["vc_custom_heading", "vc_button"]). Omit to return all registered schemas.',
|
|
1313
|
+
},
|
|
1314
|
+
},
|
|
1315
|
+
required: [],
|
|
1316
|
+
},
|
|
1317
|
+
readOnlyHint: true,
|
|
1318
|
+
},
|
|
1210
1319
|
{
|
|
1211
1320
|
name: 'wordpress_inject_builder_content',
|
|
1212
|
-
description: 'REPLACE (or append to) the entire page builder layout. WARNING: By default this REPLACES all existing content — use mode:"append" to add content without destroying existing elements. For editing a single module, use wordpress_update_module instead. Use exactly: gutenberg, divi, elementor, bricks, beaver, oxygen, breakdance, brizy, thrive, visual-composer, wpbakery. For Divi, divi_version is required ("4" or "5"). Starting in plugin v7.0.16, calling this against a page that already has content with mode="replace" (the default) without also passing confirm_replace=true returns a 409 respira_replace_confirmation_required — pass mode="append" to add to existing content,
|
|
1321
|
+
description: 'REPLACE (or append to) the entire page builder layout. WARNING: By default this REPLACES all existing content — use mode:"append" to add content without destroying existing elements. For editing a single module, use wordpress_update_module instead. Use exactly: gutenberg, divi, elementor, bricks, beaver, oxygen, breakdance, brizy, thrive, visual-composer, wpbakery. For Divi, divi_version is required ("4" or "5"). Starting in plugin v7.0.16, calling this against a page that already has content with mode="replace" (the default) without also passing confirm_replace=true returns a 409 respira_replace_confirmation_required — pass mode="append" to add to existing content, pass mode="replace" AND confirm_replace=true to overwrite, or pass edit_target="live" to overwrite the live page directly (plugin v7.0.22+ accepts an authorized live edit as the confirmation). The gate prevents silent data loss.',
|
|
1213
1322
|
inputSchema: {
|
|
1214
1323
|
type: 'object',
|
|
1215
1324
|
properties: {
|
|
@@ -2851,6 +2960,18 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
2851
2960
|
if (await this.isAcfAvailable()) {
|
|
2852
2961
|
tools.push(...getAcfTools());
|
|
2853
2962
|
}
|
|
2963
|
+
// v6.12.0: inject optional site_id into every non-agnostic tool schema.
|
|
2964
|
+
// Agnostic tools (list_sites, get_active_site, switch_site, redeem_token)
|
|
2965
|
+
// skip the injection because they operate on global state.
|
|
2966
|
+
for (const t of tools) {
|
|
2967
|
+
if (SITE_AGNOSTIC_TOOLS.has(t.name))
|
|
2968
|
+
continue;
|
|
2969
|
+
if (!t.inputSchema || t.inputSchema.type !== 'object')
|
|
2970
|
+
continue;
|
|
2971
|
+
const props = (t.inputSchema.properties ||= {});
|
|
2972
|
+
if (!props.site_id)
|
|
2973
|
+
props.site_id = SITE_ID_PROPERTY;
|
|
2974
|
+
}
|
|
2854
2975
|
// Generate respira_* aliases for all wordpress_* tools.
|
|
2855
2976
|
const allTools = this.generateDualTools(tools);
|
|
2856
2977
|
// Context-aware tool filtering: expose only relevant tools based on
|
|
@@ -3318,9 +3439,11 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3318
3439
|
return args;
|
|
3319
3440
|
}
|
|
3320
3441
|
async handleToolCall(name, args) {
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3442
|
+
// v6.12.0: relaxed top-of-handler guard. dispatchToolCall / resolveClient
|
|
3443
|
+
// now decides whether a site is needed for THIS call (some tools are
|
|
3444
|
+
// site-agnostic, others accept a per-call site_id override). The old
|
|
3445
|
+
// eager `if (!this.currentSite) throw` blocked the new "call with just
|
|
3446
|
+
// site_id on a server with no default site" path.
|
|
3324
3447
|
// Normalize respira_* ↔ wordpress_* names.
|
|
3325
3448
|
const { canonical, deprecated } = this.normalizeToolName(name);
|
|
3326
3449
|
// mcp-v6.11.1: snake_case sweep across tool catalog. Schemas advertise
|
|
@@ -3338,14 +3461,15 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3338
3461
|
return result;
|
|
3339
3462
|
}
|
|
3340
3463
|
async dispatchToolCall(name, args) {
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3464
|
+
// v6.12.0: per-call site resolution. Agnostic tools work without a
|
|
3465
|
+
// resolved client; everything else requires either args.site_id or a
|
|
3466
|
+
// global currentSite. resolveClient throws cleanly if neither is set.
|
|
3467
|
+
const client = SITE_AGNOSTIC_TOOLS.has(name) ? this.currentSite : this.resolveClient(args);
|
|
3344
3468
|
switch (name) {
|
|
3345
3469
|
case 'wordpress_get_site_context':
|
|
3346
3470
|
return args.detail === 'full'
|
|
3347
|
-
? await
|
|
3348
|
-
: await
|
|
3471
|
+
? await client.getSiteContext()
|
|
3472
|
+
: await client.getCompactSiteContext();
|
|
3349
3473
|
case 'wordpress_list_sites': {
|
|
3350
3474
|
const allSites = Array.from(this.sites.values());
|
|
3351
3475
|
const visibleSites = allSites.filter((site) => this.isSiteAllowed(site));
|
|
@@ -3359,21 +3483,21 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3359
3483
|
site: this.getActiveSiteSummary(),
|
|
3360
3484
|
};
|
|
3361
3485
|
case 'wordpress_get_theme_docs':
|
|
3362
|
-
return await
|
|
3486
|
+
return await client.getThemeDocs();
|
|
3363
3487
|
case 'wordpress_get_builder_info':
|
|
3364
|
-
return await
|
|
3488
|
+
return await client.getBuilderInfo({ debug: Boolean(args?.debug) });
|
|
3365
3489
|
case 'wordpress_list_pages':
|
|
3366
|
-
return await
|
|
3490
|
+
return await client.listPages(args);
|
|
3367
3491
|
case 'wordpress_read_page':
|
|
3368
|
-
return await
|
|
3492
|
+
return await client.getPage(args.id, args.include);
|
|
3369
3493
|
case 'wordpress_create_page_duplicate':
|
|
3370
3494
|
return {
|
|
3371
|
-
...(await
|
|
3372
|
-
respira_approvals_url:
|
|
3495
|
+
...(await client.duplicatePage(args.original_id, args.suffix, args.include)),
|
|
3496
|
+
respira_approvals_url: client.getApprovalsUrl(),
|
|
3373
3497
|
};
|
|
3374
3498
|
case 'wordpress_update_page': {
|
|
3375
|
-
const approvalsUrl =
|
|
3376
|
-
const page = await
|
|
3499
|
+
const approvalsUrl = client.getApprovalsUrl();
|
|
3500
|
+
const page = await client.updatePage(args.id, args);
|
|
3377
3501
|
// Check if Respira created a duplicate
|
|
3378
3502
|
if (page.__respira_duplicate_info) {
|
|
3379
3503
|
const info = page.__respira_duplicate_info;
|
|
@@ -3394,19 +3518,19 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3394
3518
|
};
|
|
3395
3519
|
}
|
|
3396
3520
|
case 'wordpress_delete_page':
|
|
3397
|
-
return await
|
|
3521
|
+
return await client.deletePage(args.id, args.force);
|
|
3398
3522
|
case 'wordpress_list_posts':
|
|
3399
|
-
return await
|
|
3523
|
+
return await client.listPosts(args);
|
|
3400
3524
|
case 'wordpress_read_post':
|
|
3401
|
-
return await
|
|
3525
|
+
return await client.getPost(args.id, args.include);
|
|
3402
3526
|
case 'wordpress_create_post_duplicate':
|
|
3403
3527
|
return {
|
|
3404
|
-
...(await
|
|
3405
|
-
respira_approvals_url:
|
|
3528
|
+
...(await client.duplicatePost(args.original_id, args.suffix, args.include)),
|
|
3529
|
+
respira_approvals_url: client.getApprovalsUrl(),
|
|
3406
3530
|
};
|
|
3407
3531
|
case 'wordpress_update_post': {
|
|
3408
|
-
const approvalsUrl =
|
|
3409
|
-
const post = await
|
|
3532
|
+
const approvalsUrl = client.getApprovalsUrl();
|
|
3533
|
+
const post = await client.updatePost(args.id, args);
|
|
3410
3534
|
// Check if Respira created a duplicate
|
|
3411
3535
|
if (post.__respira_duplicate_info) {
|
|
3412
3536
|
const info = post.__respira_duplicate_info;
|
|
@@ -3427,27 +3551,31 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3427
3551
|
};
|
|
3428
3552
|
}
|
|
3429
3553
|
case 'wordpress_delete_post':
|
|
3430
|
-
return await
|
|
3554
|
+
return await client.deletePost(args.id, args.force);
|
|
3431
3555
|
case 'wordpress_list_media':
|
|
3432
|
-
return await
|
|
3556
|
+
return await client.listMedia(args);
|
|
3433
3557
|
case 'wordpress_upload_media':
|
|
3434
|
-
return await
|
|
3558
|
+
return await client.uploadMedia(args.file, args.filename, args.mime_type, args.title, args.alt, args.caption);
|
|
3435
3559
|
case 'wordpress_extract_builder_content':
|
|
3436
|
-
return await
|
|
3560
|
+
return await client.extractBuilderContent(args.builder, args.page_id);
|
|
3437
3561
|
case 'wordpress_find_builder_targets':
|
|
3438
|
-
return await
|
|
3562
|
+
return await client.findBuilderTargets(args.builder, args.page_id, args.query, args.limit, args.offset);
|
|
3563
|
+
case 'wordpress_get_page_outline':
|
|
3564
|
+
return await client.getPageOutline(args.builder, args.page_id);
|
|
3565
|
+
case 'wordpress_get_builder_inline_schemas':
|
|
3566
|
+
return await client.getBuilderInlineSchemas(args.builder, args.types);
|
|
3439
3567
|
case 'wordpress_inject_builder_content':
|
|
3440
3568
|
return {
|
|
3441
|
-
...(await
|
|
3442
|
-
respira_approvals_url:
|
|
3569
|
+
...(await client.injectBuilderContent(args.builder, args.page_id, args.content, args.divi_version, args.edit_target, args.mode, args.confirm_replace)),
|
|
3570
|
+
respira_approvals_url: client.getApprovalsUrl(),
|
|
3443
3571
|
};
|
|
3444
3572
|
case 'wordpress_update_module':
|
|
3445
3573
|
return {
|
|
3446
|
-
...(await
|
|
3447
|
-
respira_approvals_url:
|
|
3574
|
+
...(await client.updateModule(args.builder, args.page_id, args.module_identifier, args.updates, args.edit_target)),
|
|
3575
|
+
respira_approvals_url: client.getApprovalsUrl(),
|
|
3448
3576
|
};
|
|
3449
3577
|
case 'wordpress_validate_security':
|
|
3450
|
-
return await
|
|
3578
|
+
return await client.validateSecurity(args.content);
|
|
3451
3579
|
case 'wordpress_switch_site': {
|
|
3452
3580
|
const newSite = this.sites.get(args.site_id);
|
|
3453
3581
|
if (!newSite) {
|
|
@@ -3465,7 +3593,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3465
3593
|
};
|
|
3466
3594
|
}
|
|
3467
3595
|
case 'wordpress_diagnose_connection':
|
|
3468
|
-
return await
|
|
3596
|
+
return await client.diagnoseConnection({ post_id: args.post_id });
|
|
3469
3597
|
// Canonical name (normalizeToolName rewrites respira_* → wordpress_*
|
|
3470
3598
|
// before this switch runs). The early-route guard in setRequestHandler
|
|
3471
3599
|
// catches the redeem call before we ever land here when no site is
|
|
@@ -3475,245 +3603,245 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3475
3603
|
return await this.redeemInstallToken(String(args.token || ''));
|
|
3476
3604
|
// Page Speed Analysis
|
|
3477
3605
|
case 'wordpress_analyze_performance':
|
|
3478
|
-
return await
|
|
3606
|
+
return await client.analyzePerformance(args.page_id);
|
|
3479
3607
|
case 'wordpress_get_core_web_vitals':
|
|
3480
|
-
return await
|
|
3608
|
+
return await client.getCoreWebVitals(args.page_id);
|
|
3481
3609
|
case 'wordpress_analyze_images':
|
|
3482
|
-
return await
|
|
3610
|
+
return await client.analyzeImages(args.page_id);
|
|
3483
3611
|
// SEO Analysis
|
|
3484
3612
|
case 'wordpress_analyze_seo':
|
|
3485
|
-
return await
|
|
3613
|
+
return await client.analyzeSEO(args.page_id);
|
|
3486
3614
|
case 'wordpress_check_seo_issues':
|
|
3487
|
-
return await
|
|
3615
|
+
return await client.checkSEOIssues(args.page_id);
|
|
3488
3616
|
case 'wordpress_analyze_readability':
|
|
3489
|
-
return await
|
|
3617
|
+
return await client.analyzeReadability(args.page_id);
|
|
3490
3618
|
case 'wordpress_analyze_rankmath':
|
|
3491
|
-
return await
|
|
3619
|
+
return await client.analyzeRankMath(args.post_id);
|
|
3492
3620
|
// AEO Analysis
|
|
3493
3621
|
case 'wordpress_analyze_aeo':
|
|
3494
|
-
return await
|
|
3622
|
+
return await client.analyzeAEO(args.page_id);
|
|
3495
3623
|
case 'wordpress_check_structured_data':
|
|
3496
|
-
return await
|
|
3624
|
+
return await client.checkStructuredData(args.page_id);
|
|
3497
3625
|
// Accessibility
|
|
3498
3626
|
case 'wordpress_list_accessibility_scans':
|
|
3499
|
-
return await
|
|
3627
|
+
return await client.listAccessibilityScans();
|
|
3500
3628
|
case 'wordpress_get_accessibility_scan':
|
|
3501
|
-
return await
|
|
3629
|
+
return await client.getAccessibilityScan(args.scan_id);
|
|
3502
3630
|
case 'wordpress_scan_page_accessibility':
|
|
3503
|
-
return await
|
|
3631
|
+
return await client.scanPageAccessibility(args.page_id, args.standard);
|
|
3504
3632
|
case 'wordpress_apply_accessibility_fixes':
|
|
3505
|
-
return await
|
|
3633
|
+
return await client.applyAccessibilityFixes(args.scan_id, args.rule_ids);
|
|
3506
3634
|
// Plugin Management (EXPERIMENTAL)
|
|
3507
3635
|
case 'wordpress_list_plugins':
|
|
3508
|
-
return await
|
|
3636
|
+
return await client.listPlugins();
|
|
3509
3637
|
case 'wordpress_install_plugin':
|
|
3510
|
-
return await
|
|
3638
|
+
return await client.installPlugin(args.slug_or_url, args.source || 'wordpress.org', args.approval_token);
|
|
3511
3639
|
case 'wordpress_activate_plugin':
|
|
3512
|
-
return await
|
|
3640
|
+
return await client.activatePlugin(args.slug, args.approval_token);
|
|
3513
3641
|
case 'wordpress_deactivate_plugin':
|
|
3514
|
-
return await
|
|
3642
|
+
return await client.deactivatePlugin(args.slug, args.approval_token);
|
|
3515
3643
|
case 'wordpress_update_plugin':
|
|
3516
|
-
return await
|
|
3644
|
+
return await client.updatePlugin(args.slug, args.approval_token);
|
|
3517
3645
|
case 'wordpress_delete_plugin':
|
|
3518
|
-
return await
|
|
3646
|
+
return await client.deletePlugin(args.slug, args.approval_token);
|
|
3519
3647
|
// Users Management
|
|
3520
3648
|
case 'wordpress_list_users':
|
|
3521
|
-
return await
|
|
3649
|
+
return await client.listUsers(args);
|
|
3522
3650
|
case 'wordpress_get_user':
|
|
3523
|
-
return await
|
|
3651
|
+
return await client.getUser(args.id);
|
|
3524
3652
|
case 'wordpress_create_user':
|
|
3525
|
-
return await
|
|
3653
|
+
return await client.createUser(args);
|
|
3526
3654
|
case 'wordpress_update_user':
|
|
3527
|
-
return await
|
|
3655
|
+
return await client.updateUser(args.id, args);
|
|
3528
3656
|
case 'wordpress_delete_user':
|
|
3529
|
-
return await
|
|
3657
|
+
return await client.deleteUser(args.id, args.reassign);
|
|
3530
3658
|
// Comments
|
|
3531
3659
|
case 'wordpress_list_comments':
|
|
3532
|
-
return await
|
|
3660
|
+
return await client.listComments(args);
|
|
3533
3661
|
case 'wordpress_get_comment':
|
|
3534
|
-
return await
|
|
3662
|
+
return await client.getComment(args.id);
|
|
3535
3663
|
case 'wordpress_create_comment':
|
|
3536
|
-
return await
|
|
3664
|
+
return await client.createComment(args);
|
|
3537
3665
|
case 'wordpress_update_comment':
|
|
3538
|
-
return await
|
|
3666
|
+
return await client.updateComment(args.id, args);
|
|
3539
3667
|
case 'wordpress_delete_comment':
|
|
3540
|
-
return await
|
|
3668
|
+
return await client.deleteComment(args.id);
|
|
3541
3669
|
// Taxonomies
|
|
3542
3670
|
case 'wordpress_list_taxonomies':
|
|
3543
|
-
return await
|
|
3671
|
+
return await client.listTaxonomies();
|
|
3544
3672
|
case 'wordpress_get_taxonomy':
|
|
3545
|
-
return await
|
|
3673
|
+
return await client.getTaxonomy(args.taxonomy);
|
|
3546
3674
|
case 'wordpress_list_terms':
|
|
3547
|
-
return await
|
|
3675
|
+
return await client.listTerms(args.taxonomy, args);
|
|
3548
3676
|
case 'wordpress_get_term':
|
|
3549
|
-
return await
|
|
3677
|
+
return await client.getTerm(args.taxonomy, args.id);
|
|
3550
3678
|
case 'wordpress_create_term':
|
|
3551
|
-
return await
|
|
3679
|
+
return await client.createTerm(args.taxonomy, args);
|
|
3552
3680
|
case 'wordpress_update_term':
|
|
3553
|
-
return await
|
|
3681
|
+
return await client.updateTerm(args.taxonomy, args.id, args);
|
|
3554
3682
|
case 'wordpress_delete_term':
|
|
3555
|
-
return await
|
|
3683
|
+
return await client.deleteTerm(args.taxonomy, args.id);
|
|
3556
3684
|
// Custom Post Types
|
|
3557
3685
|
case 'wordpress_list_post_types':
|
|
3558
|
-
return await
|
|
3686
|
+
return await client.listPostTypes();
|
|
3559
3687
|
case 'wordpress_get_post_type':
|
|
3560
|
-
return await
|
|
3688
|
+
return await client.getPostType(args.type);
|
|
3561
3689
|
case 'wordpress_list_custom_posts':
|
|
3562
|
-
return await
|
|
3690
|
+
return await client.listCustomPosts(args.type, args);
|
|
3563
3691
|
case 'wordpress_get_custom_post':
|
|
3564
|
-
return await
|
|
3692
|
+
return await client.getCustomPost(args.type, args.id, args.include);
|
|
3565
3693
|
case 'wordpress_create_custom_post':
|
|
3566
|
-
return await
|
|
3694
|
+
return await client.createCustomPost(args.type, args);
|
|
3567
3695
|
case 'wordpress_update_custom_post':
|
|
3568
|
-
return await
|
|
3696
|
+
return await client.updateCustomPost(args.type, args.id, args);
|
|
3569
3697
|
case 'wordpress_delete_custom_post':
|
|
3570
|
-
return await
|
|
3698
|
+
return await client.deleteCustomPost(args.type, args.id);
|
|
3571
3699
|
// Options
|
|
3572
3700
|
case 'wordpress_list_options':
|
|
3573
|
-
return await
|
|
3701
|
+
return await client.listOptions(args.search);
|
|
3574
3702
|
case 'wordpress_get_option':
|
|
3575
|
-
return await
|
|
3703
|
+
return await client.getOption(args.option);
|
|
3576
3704
|
case 'wordpress_update_option':
|
|
3577
|
-
return await
|
|
3705
|
+
return await client.updateOption(args.option, args.value);
|
|
3578
3706
|
case 'wordpress_delete_option':
|
|
3579
|
-
return await
|
|
3707
|
+
return await client.deleteOption(args.option);
|
|
3580
3708
|
// Media enhancements
|
|
3581
3709
|
case 'wordpress_get_media':
|
|
3582
|
-
return await
|
|
3710
|
+
return await client.getMedia(args.id);
|
|
3583
3711
|
case 'wordpress_update_media':
|
|
3584
|
-
return await
|
|
3712
|
+
return await client.updateMedia(args.id, args);
|
|
3585
3713
|
case 'wordpress_update_media_batch':
|
|
3586
|
-
return await
|
|
3714
|
+
return await client.updateMediaBatch(args.items);
|
|
3587
3715
|
case 'wordpress_delete_media':
|
|
3588
|
-
return await
|
|
3716
|
+
return await client.deleteMedia(args.id);
|
|
3589
3717
|
// Menu Management
|
|
3590
3718
|
case 'wordpress_list_menus':
|
|
3591
|
-
return await
|
|
3719
|
+
return await client.listMenus();
|
|
3592
3720
|
case 'wordpress_get_menu':
|
|
3593
|
-
return await
|
|
3721
|
+
return await client.getMenu(args.id);
|
|
3594
3722
|
case 'wordpress_create_menu':
|
|
3595
|
-
return await
|
|
3723
|
+
return await client.createMenu(args);
|
|
3596
3724
|
case 'wordpress_update_menu':
|
|
3597
|
-
return await
|
|
3725
|
+
return await client.updateMenu(args.id, args);
|
|
3598
3726
|
case 'wordpress_delete_menu':
|
|
3599
|
-
return await
|
|
3727
|
+
return await client.deleteMenu(args.id);
|
|
3600
3728
|
// Menu Locations
|
|
3601
3729
|
case 'wordpress_list_menu_locations':
|
|
3602
|
-
return await
|
|
3730
|
+
return await client.listMenuLocations();
|
|
3603
3731
|
case 'wordpress_assign_menu_location':
|
|
3604
|
-
return await
|
|
3732
|
+
return await client.assignMenuToLocation(args.location, args.menu_id);
|
|
3605
3733
|
// Menu Items
|
|
3606
3734
|
case 'wordpress_list_menu_items':
|
|
3607
|
-
return await
|
|
3735
|
+
return await client.listMenuItems(args.menu_id);
|
|
3608
3736
|
case 'wordpress_create_menu_item':
|
|
3609
|
-
return await
|
|
3737
|
+
return await client.createMenuItem(args.menu_id, args);
|
|
3610
3738
|
case 'wordpress_get_menu_item':
|
|
3611
|
-
return await
|
|
3739
|
+
return await client.getMenuItem(args.item_id);
|
|
3612
3740
|
case 'wordpress_update_menu_item':
|
|
3613
|
-
return await
|
|
3741
|
+
return await client.updateMenuItem(args.item_id, args);
|
|
3614
3742
|
case 'wordpress_delete_menu_item':
|
|
3615
|
-
return await
|
|
3743
|
+
return await client.deleteMenuItem(args.item_id);
|
|
3616
3744
|
case 'wordpress_list_snapshots':
|
|
3617
|
-
return await
|
|
3745
|
+
return await client.listSnapshots(args);
|
|
3618
3746
|
case 'wordpress_get_snapshot':
|
|
3619
|
-
return await
|
|
3747
|
+
return await client.getSnapshot(args.snapshot_uuid);
|
|
3620
3748
|
case 'wordpress_diff_snapshots':
|
|
3621
|
-
return await
|
|
3749
|
+
return await client.diffSnapshots(args.snapshot_uuid_a, args.snapshot_uuid_b);
|
|
3622
3750
|
case 'wordpress_restore_snapshot':
|
|
3623
|
-
return await
|
|
3751
|
+
return await client.restoreSnapshot(args.snapshot_uuid);
|
|
3624
3752
|
case 'wordpress_apply_builder_patch':
|
|
3625
|
-
return await
|
|
3753
|
+
return await client.applyBuilderPatch(args.builder, args.post_id, args.operations, args.include, args.edit_target);
|
|
3626
3754
|
case 'woocommerce_list_products':
|
|
3627
|
-
return await
|
|
3755
|
+
return await client.woocommerceListProducts(args);
|
|
3628
3756
|
case 'woocommerce_get_product':
|
|
3629
|
-
return await
|
|
3757
|
+
return await client.woocommerceGetProduct(args.id);
|
|
3630
3758
|
case 'woocommerce_create_product':
|
|
3631
|
-
return await
|
|
3759
|
+
return await client.woocommerceCreateProduct(args);
|
|
3632
3760
|
case 'woocommerce_update_product': {
|
|
3633
3761
|
const { id, ...payload } = args;
|
|
3634
|
-
return await
|
|
3762
|
+
return await client.woocommerceUpdateProduct(id, payload);
|
|
3635
3763
|
}
|
|
3636
3764
|
case 'woocommerce_duplicate_product':
|
|
3637
|
-
return await
|
|
3765
|
+
return await client.woocommerceDuplicateProduct(args.id);
|
|
3638
3766
|
case 'woocommerce_list_categories':
|
|
3639
|
-
return await
|
|
3767
|
+
return await client.woocommerceListCategories(args);
|
|
3640
3768
|
case 'woocommerce_get_category':
|
|
3641
|
-
return await
|
|
3769
|
+
return await client.woocommerceGetCategory(args.id);
|
|
3642
3770
|
case 'woocommerce_create_category':
|
|
3643
|
-
return await
|
|
3771
|
+
return await client.woocommerceCreateCategory(args);
|
|
3644
3772
|
case 'woocommerce_update_category': {
|
|
3645
3773
|
const { id, ...payload } = args;
|
|
3646
|
-
return await
|
|
3774
|
+
return await client.woocommerceUpdateCategory(id, payload);
|
|
3647
3775
|
}
|
|
3648
3776
|
case 'woocommerce_delete_category':
|
|
3649
|
-
return await
|
|
3777
|
+
return await client.woocommerceDeleteCategory(args.id);
|
|
3650
3778
|
case 'woocommerce_list_tags':
|
|
3651
|
-
return await
|
|
3779
|
+
return await client.woocommerceListTags(args);
|
|
3652
3780
|
case 'woocommerce_get_tag':
|
|
3653
|
-
return await
|
|
3781
|
+
return await client.woocommerceGetTag(args.id);
|
|
3654
3782
|
case 'woocommerce_create_tag':
|
|
3655
|
-
return await
|
|
3783
|
+
return await client.woocommerceCreateTag(args);
|
|
3656
3784
|
case 'woocommerce_update_tag': {
|
|
3657
3785
|
const { id, ...payload } = args;
|
|
3658
|
-
return await
|
|
3786
|
+
return await client.woocommerceUpdateTag(id, payload);
|
|
3659
3787
|
}
|
|
3660
3788
|
case 'woocommerce_delete_tag':
|
|
3661
|
-
return await
|
|
3789
|
+
return await client.woocommerceDeleteTag(args.id);
|
|
3662
3790
|
case 'woocommerce_list_orders':
|
|
3663
|
-
return await
|
|
3791
|
+
return await client.woocommerceListOrders(args);
|
|
3664
3792
|
case 'woocommerce_get_order':
|
|
3665
|
-
return await
|
|
3793
|
+
return await client.woocommerceGetOrder(args.id);
|
|
3666
3794
|
case 'woocommerce_update_order_status':
|
|
3667
|
-
return await
|
|
3795
|
+
return await client.woocommerceUpdateOrderStatus(args.id, args.status);
|
|
3668
3796
|
case 'woocommerce_get_stock_status':
|
|
3669
|
-
return await
|
|
3797
|
+
return await client.woocommerceGetStockStatus();
|
|
3670
3798
|
case 'woocommerce_update_stock': {
|
|
3671
3799
|
const { id, ...payload } = args;
|
|
3672
|
-
return await
|
|
3800
|
+
return await client.woocommerceUpdateStock(id, payload);
|
|
3673
3801
|
}
|
|
3674
3802
|
case 'woocommerce_sales_report':
|
|
3675
|
-
return await
|
|
3803
|
+
return await client.woocommerceSalesReport(args);
|
|
3676
3804
|
// --- v5.2.0 Elemental tools ---
|
|
3677
3805
|
case 'wordpress_find_element': {
|
|
3678
3806
|
const { post_id, ...rest } = args;
|
|
3679
|
-
return await
|
|
3807
|
+
return await client.callRestV2('POST', `/builder/elements/find/${post_id}`, rest);
|
|
3680
3808
|
}
|
|
3681
3809
|
case 'wordpress_update_element': {
|
|
3682
3810
|
const { post_id, ...rest } = args;
|
|
3683
|
-
return await
|
|
3811
|
+
return await client.callRestV2('POST', `/builder/elements/update/${post_id}`, rest);
|
|
3684
3812
|
}
|
|
3685
3813
|
case 'wordpress_move_element': {
|
|
3686
3814
|
const { post_id, ...rest } = args;
|
|
3687
|
-
return await
|
|
3815
|
+
return await client.callRestV2('POST', `/builder/elements/move/${post_id}`, rest);
|
|
3688
3816
|
}
|
|
3689
3817
|
case 'wordpress_duplicate_element': {
|
|
3690
3818
|
const { post_id, ...rest } = args;
|
|
3691
|
-
return await
|
|
3819
|
+
return await client.callRestV2('POST', `/builder/elements/duplicate/${post_id}`, rest);
|
|
3692
3820
|
}
|
|
3693
3821
|
case 'wordpress_remove_element': {
|
|
3694
3822
|
const { post_id, ...rest } = args;
|
|
3695
|
-
return await
|
|
3823
|
+
return await client.callRestV2('POST', `/builder/elements/remove/${post_id}`, rest);
|
|
3696
3824
|
}
|
|
3697
3825
|
case 'wordpress_batch_update': {
|
|
3698
3826
|
const { post_id, ...rest } = args;
|
|
3699
|
-
return await
|
|
3827
|
+
return await client.callRestV2('POST', `/builder/elements/batch/${post_id}`, rest);
|
|
3700
3828
|
}
|
|
3701
3829
|
case 'wordpress_reorder_elements': {
|
|
3702
3830
|
const { post_id, ...rest } = args;
|
|
3703
|
-
return await
|
|
3831
|
+
return await client.callRestV2('POST', `/builder/elements/reorder/${post_id}`, rest);
|
|
3704
3832
|
}
|
|
3705
3833
|
case 'wordpress_build_page':
|
|
3706
|
-
return await
|
|
3834
|
+
return await client.callRestV2('POST', '/builder/build', args);
|
|
3707
3835
|
case 'wordpress_convert_html_to_builder':
|
|
3708
|
-
return await
|
|
3836
|
+
return await client.callRestV2('POST', '/builder/convert', args);
|
|
3709
3837
|
case 'wordpress_bulk_pages_operation':
|
|
3710
|
-
return await
|
|
3838
|
+
return await client.callRestV2('POST', '/builder/bulk', args);
|
|
3711
3839
|
case 'wordpress_search_stock_images':
|
|
3712
|
-
return await
|
|
3840
|
+
return await client.callRestV2('GET', '/stock-images/search', args);
|
|
3713
3841
|
case 'wordpress_sideload_image':
|
|
3714
|
-
return await
|
|
3842
|
+
return await client.callRestV2('POST', '/stock-images/sideload', args);
|
|
3715
3843
|
case 'wordpress_get_server_compatibility':
|
|
3716
|
-
return await
|
|
3844
|
+
return await client.callRestV2('GET', '/server/compatibility');
|
|
3717
3845
|
// Widget shortcuts and Bricks tools — dynamic dispatch.
|
|
3718
3846
|
default: {
|
|
3719
3847
|
// Check if this is a Bricks deep tool.
|
|
@@ -3745,7 +3873,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3745
3873
|
throw new Error(`Widget shortcut "${shortcutName}" requires a post_id parameter.`);
|
|
3746
3874
|
}
|
|
3747
3875
|
const { post_id: _pid, ...settings } = args;
|
|
3748
|
-
return await
|
|
3876
|
+
return await client.callRestV2('POST', `/builder/widget/${shortcutName}/${postId}`, settings);
|
|
3749
3877
|
}
|
|
3750
3878
|
// Return isError result instead of throwing — unknown tool is an execution
|
|
3751
3879
|
// error, not a protocol error. This lets LLMs self-correct gracefully.
|