@respira/wordpress-mcp-server 6.6.5 → 6.11.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/dist/server.d.ts +20 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +186 -93
- package/dist/server.js.map +1 -1
- package/dist/wordpress-client.d.ts +29 -0
- package/dist/wordpress-client.d.ts.map +1 -1
- package/dist/wordpress-client.js +228 -4
- package/dist/wordpress-client.js.map +1 -1
- package/package.json +1 -5
package/dist/server.js
CHANGED
|
@@ -43,7 +43,7 @@ export class RespiraWordPressServer {
|
|
|
43
43
|
allowedSites = null;
|
|
44
44
|
/** Whether the plugin version warning has already been shown this session. */
|
|
45
45
|
versionWarningShown = false;
|
|
46
|
-
static MCP_SERVER_VERSION = '6.
|
|
46
|
+
static MCP_SERVER_VERSION = '6.11.1';
|
|
47
47
|
/**
|
|
48
48
|
* Normalize a tool name: respira_* → wordpress_* for switch dispatch.
|
|
49
49
|
* Tracks whether the deprecated wordpress_* name was used.
|
|
@@ -103,6 +103,8 @@ export class RespiraWordPressServer {
|
|
|
103
103
|
|
|
104
104
|
IMPORTANT: Always use Respira tools to read and edit WordPress content. NEVER access the database directly (SQL queries, wp_postmeta, wp_options), edit PHP files, or modify theme templates to change page content. Respira tools handle all content operations safely with snapshots, cache invalidation, and builder-native formats. Even for simple changes like updating a copyright year in a footer — use respira_find_element, not SQL.
|
|
105
105
|
|
|
106
|
+
CRITICAL TOOL CHOICE: For ANY in-page content edit (changing text, images, buttons, headings, links, colors, settings on existing widgets), use respira_find_element + respira_update_element. Do NOT use respira_update_page for content edits. respira_update_page replaces the ENTIRE page body and bypasses the page builder's structure — it produces "all code" pages where the builder treats every widget as a single text blob. respira_update_page is ONLY for: page title, slug, status, custom CSS, or full HTML replacement (e.g. "convert this Word doc into a page"). Telemetry across the user base shows respira_update_page being chosen ~13× more often than respira_update_element, but the right tool for "change the headline text" or "swap the hero image" is always respira_update_element.
|
|
107
|
+
|
|
106
108
|
## Tool naming
|
|
107
109
|
|
|
108
110
|
Always use respira_* tool names (e.g. respira_update_page, respira_find_element). The wordpress_* names are deprecated aliases and will be removed in v6.0.
|
|
@@ -194,7 +196,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
194
196
|
- Module names use et_pb_ prefix: et_pb_text, et_pb_blurb, et_pb_image, et_pb_button, et_pb_cta, et_pb_slider, etc.
|
|
195
197
|
- Settings are shortcode attributes: [et_pb_text text_font="Roboto" text_text_color="#333333"]
|
|
196
198
|
- Button uses url/url_new_window attributes (different from Divi 5's linkUrl/linkTarget)
|
|
197
|
-
- IMPORTANT: When injecting content, set
|
|
199
|
+
- IMPORTANT: When injecting content, set divi_version to "4" in respira_inject_builder_content
|
|
198
200
|
- Respira auto-detects whether the site runs Divi 4 or Divi 5 — check respira_get_builder_info for the version
|
|
199
201
|
- Element-level operations work via shortcode tree parsing
|
|
200
202
|
|
|
@@ -666,7 +668,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
666
668
|
type: 'number',
|
|
667
669
|
description: 'Page number for pagination',
|
|
668
670
|
},
|
|
669
|
-
|
|
671
|
+
per_page: {
|
|
670
672
|
type: 'number',
|
|
671
673
|
description: 'Number of items per page',
|
|
672
674
|
},
|
|
@@ -703,7 +705,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
703
705
|
inputSchema: {
|
|
704
706
|
type: 'object',
|
|
705
707
|
properties: {
|
|
706
|
-
|
|
708
|
+
original_id: {
|
|
707
709
|
type: 'number',
|
|
708
710
|
description: 'ID of the original page to duplicate',
|
|
709
711
|
},
|
|
@@ -712,12 +714,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
712
714
|
description: 'Optional suffix for the duplicated page title',
|
|
713
715
|
},
|
|
714
716
|
},
|
|
715
|
-
required: ['
|
|
717
|
+
required: ['original_id'],
|
|
716
718
|
},
|
|
717
719
|
},
|
|
718
720
|
{
|
|
719
721
|
name: 'wordpress_update_page',
|
|
720
|
-
description: 'Update a page. When direct editing is enabled and you target an original page, Respira returns a confirmation_required preflight by default so you can choose live/original or duplicate.',
|
|
722
|
+
description: 'Update PAGE-LEVEL fields (title, status, slug, full HTML content replacement, custom CSS). For editing SPECIFIC elements WITHIN a page (text widgets, images, buttons, headings), use respira_update_element instead — it is element-aware, builder-aware, snapshot-safe, and works across all 12 page builders. Use respira_update_page only when you need to replace the entire content body, change the page title/slug/status, or set page-level metadata. When direct editing is enabled and you target an original page, Respira returns a confirmation_required preflight by default so you can choose live/original or duplicate.',
|
|
721
723
|
inputSchema: {
|
|
722
724
|
type: 'object',
|
|
723
725
|
properties: {
|
|
@@ -741,7 +743,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
741
743
|
type: 'string',
|
|
742
744
|
description: 'URL slug (post_name). Example: "about-us" produces /about-us/.',
|
|
743
745
|
},
|
|
744
|
-
|
|
746
|
+
custom_css: {
|
|
745
747
|
type: 'string',
|
|
746
748
|
description: 'Custom CSS for the page. Auto-detects builder: Divi → _et_pb_custom_css, Elementor → _elementor_page_settings.custom_css.',
|
|
747
749
|
},
|
|
@@ -749,7 +751,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
749
751
|
type: 'object',
|
|
750
752
|
description: 'Post meta data',
|
|
751
753
|
},
|
|
752
|
-
|
|
754
|
+
edit_target: {
|
|
753
755
|
type: 'string',
|
|
754
756
|
description: 'Choose ask, live, or duplicate when the target is an original page.',
|
|
755
757
|
enum: ['ask', 'live', 'duplicate'],
|
|
@@ -758,7 +760,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
758
760
|
type: 'boolean',
|
|
759
761
|
description: 'Backward-compatible alias for explicit live editing when direct editing is enabled.',
|
|
760
762
|
},
|
|
761
|
-
|
|
763
|
+
skip_security_check: {
|
|
762
764
|
type: 'boolean',
|
|
763
765
|
description: 'Advanced: bypass Respira content security checks and sanitization for this update. Use only with trusted content.',
|
|
764
766
|
},
|
|
@@ -804,7 +806,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
804
806
|
type: 'number',
|
|
805
807
|
description: 'Page number',
|
|
806
808
|
},
|
|
807
|
-
|
|
809
|
+
per_page: {
|
|
808
810
|
type: 'number',
|
|
809
811
|
description: 'Items per page',
|
|
810
812
|
},
|
|
@@ -841,7 +843,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
841
843
|
inputSchema: {
|
|
842
844
|
type: 'object',
|
|
843
845
|
properties: {
|
|
844
|
-
|
|
846
|
+
original_id: {
|
|
845
847
|
type: 'number',
|
|
846
848
|
description: 'Original post ID',
|
|
847
849
|
},
|
|
@@ -850,7 +852,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
850
852
|
description: 'Optional suffix',
|
|
851
853
|
},
|
|
852
854
|
},
|
|
853
|
-
required: ['
|
|
855
|
+
required: ['original_id'],
|
|
854
856
|
},
|
|
855
857
|
},
|
|
856
858
|
{
|
|
@@ -910,19 +912,19 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
910
912
|
type: 'object',
|
|
911
913
|
description: 'Generic map of taxonomy slug to array of term ids/slugs for custom taxonomies (e.g. product_cat). Example: { "product_cat": [12, "featured"] }.',
|
|
912
914
|
},
|
|
913
|
-
|
|
915
|
+
featured_media: {
|
|
914
916
|
type: 'number',
|
|
915
917
|
description: 'Attachment ID to set as the featured image. Pass 0 to clear.',
|
|
916
918
|
},
|
|
917
|
-
|
|
919
|
+
create_missing_terms: {
|
|
918
920
|
type: 'boolean',
|
|
919
921
|
description: 'When true, auto-create taxonomy terms that do not exist by name. Default false (strict: unknown slug returns 400).',
|
|
920
922
|
},
|
|
921
|
-
|
|
923
|
+
append_terms: {
|
|
922
924
|
type: 'boolean',
|
|
923
925
|
description: 'When true, append to existing taxonomy terms instead of replacing. Default false (replace).',
|
|
924
926
|
},
|
|
925
|
-
|
|
927
|
+
custom_css: {
|
|
926
928
|
type: 'string',
|
|
927
929
|
description: 'Custom CSS for the post. Auto-detects builder: Divi → _et_pb_custom_css, Elementor → _elementor_page_settings.custom_css.',
|
|
928
930
|
},
|
|
@@ -930,7 +932,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
930
932
|
type: 'object',
|
|
931
933
|
description: 'Post meta data',
|
|
932
934
|
},
|
|
933
|
-
|
|
935
|
+
edit_target: {
|
|
934
936
|
type: 'string',
|
|
935
937
|
description: 'Choose ask, live, or duplicate when the target is an original post.',
|
|
936
938
|
enum: ['ask', 'live', 'duplicate'],
|
|
@@ -939,7 +941,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
939
941
|
type: 'boolean',
|
|
940
942
|
description: 'Backward-compatible alias for explicit live editing when direct editing is enabled.',
|
|
941
943
|
},
|
|
942
|
-
|
|
944
|
+
skip_security_check: {
|
|
943
945
|
type: 'boolean',
|
|
944
946
|
description: 'Advanced: bypass Respira content security checks and sanitization for this update. Use only with trusted content.',
|
|
945
947
|
},
|
|
@@ -981,7 +983,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
981
983
|
type: 'number',
|
|
982
984
|
description: 'Page number',
|
|
983
985
|
},
|
|
984
|
-
|
|
986
|
+
per_page: {
|
|
985
987
|
type: 'number',
|
|
986
988
|
description: 'Items per page',
|
|
987
989
|
},
|
|
@@ -1003,7 +1005,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1003
1005
|
type: 'string',
|
|
1004
1006
|
description: 'Filename for the uploaded file',
|
|
1005
1007
|
},
|
|
1006
|
-
|
|
1008
|
+
mime_type: {
|
|
1007
1009
|
type: 'string',
|
|
1008
1010
|
description: 'MIME type of the file (e.g., image/jpeg, image/png, application/pdf)',
|
|
1009
1011
|
},
|
|
@@ -1033,12 +1035,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1033
1035
|
type: 'string',
|
|
1034
1036
|
description: 'Builder name. Use exactly: gutenberg, divi, elementor, bricks, beaver, oxygen, breakdance, brizy, thrive, visual-composer, wpbakery. Use get_builder_info to discover the active builder first.',
|
|
1035
1037
|
},
|
|
1036
|
-
|
|
1038
|
+
page_id: {
|
|
1037
1039
|
type: 'number',
|
|
1038
1040
|
description: 'Page ID',
|
|
1039
1041
|
},
|
|
1040
1042
|
},
|
|
1041
|
-
required: ['builder', '
|
|
1043
|
+
required: ['builder', 'page_id'],
|
|
1042
1044
|
},
|
|
1043
1045
|
readOnlyHint: true,
|
|
1044
1046
|
},
|
|
@@ -1052,7 +1054,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1052
1054
|
type: 'string',
|
|
1053
1055
|
description: 'Builder name. Use exactly: gutenberg, divi, elementor, bricks, beaver, oxygen, breakdance, brizy, thrive, visual-composer, wpbakery. Use get_builder_info to discover the active builder first.',
|
|
1054
1056
|
},
|
|
1055
|
-
|
|
1057
|
+
page_id: {
|
|
1056
1058
|
type: 'number',
|
|
1057
1059
|
description: 'Page or post ID',
|
|
1058
1060
|
},
|
|
@@ -1065,13 +1067,13 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1065
1067
|
description: 'Maximum number of matches to return (default 10)',
|
|
1066
1068
|
},
|
|
1067
1069
|
},
|
|
1068
|
-
required: ['builder', '
|
|
1070
|
+
required: ['builder', 'page_id'],
|
|
1069
1071
|
},
|
|
1070
1072
|
readOnlyHint: true,
|
|
1071
1073
|
},
|
|
1072
1074
|
{
|
|
1073
1075
|
name: 'wordpress_inject_builder_content',
|
|
1074
|
-
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,
|
|
1076
|
+
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").',
|
|
1075
1077
|
inputSchema: {
|
|
1076
1078
|
type: 'object',
|
|
1077
1079
|
properties: {
|
|
@@ -1079,7 +1081,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1079
1081
|
type: 'string',
|
|
1080
1082
|
description: 'Builder identifier. Use exactly: gutenberg, divi, elementor, bricks, beaver, oxygen, breakdance, brizy, thrive, visual-composer, wpbakery.',
|
|
1081
1083
|
},
|
|
1082
|
-
|
|
1084
|
+
page_id: {
|
|
1083
1085
|
type: 'number',
|
|
1084
1086
|
description: 'Page ID',
|
|
1085
1087
|
},
|
|
@@ -1092,18 +1094,18 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1092
1094
|
description: 'replace (default): OVERWRITES all existing page content. append: adds new content after existing elements, preserving the current layout.',
|
|
1093
1095
|
enum: ['replace', 'append'],
|
|
1094
1096
|
},
|
|
1095
|
-
|
|
1097
|
+
edit_target: {
|
|
1096
1098
|
type: 'string',
|
|
1097
1099
|
description: 'When editing an original, choose ask, live, or duplicate. Defaults to ask when direct editing is enabled.',
|
|
1098
1100
|
enum: ['ask', 'live', 'duplicate'],
|
|
1099
1101
|
},
|
|
1100
|
-
|
|
1102
|
+
divi_version: {
|
|
1101
1103
|
type: 'string',
|
|
1102
1104
|
description: 'Divi generation hint ("4" for shortcode format, "5" for block format). Required for all Divi inject calls.',
|
|
1103
1105
|
enum: ['4', '5'],
|
|
1104
1106
|
},
|
|
1105
1107
|
},
|
|
1106
|
-
required: ['builder', '
|
|
1108
|
+
required: ['builder', 'page_id', 'content'],
|
|
1107
1109
|
},
|
|
1108
1110
|
idempotentHint: true,
|
|
1109
1111
|
},
|
|
@@ -1117,11 +1119,11 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1117
1119
|
type: 'string',
|
|
1118
1120
|
description: 'Builder name. Use exactly: gutenberg, divi, elementor, bricks, beaver, oxygen, breakdance, brizy, thrive, visual-composer, wpbakery.',
|
|
1119
1121
|
},
|
|
1120
|
-
|
|
1122
|
+
page_id: {
|
|
1121
1123
|
type: 'number',
|
|
1122
1124
|
description: 'Page ID',
|
|
1123
1125
|
},
|
|
1124
|
-
|
|
1126
|
+
module_identifier: {
|
|
1125
1127
|
type: 'object',
|
|
1126
1128
|
description: 'Module identifier - use one of: admin_label, path, or type. For Elementor: prefer id or path (dot notation like "0.0.1"). admin_label maps to Navigator label or CSS ID. For Divi: admin_label maps to Admin Label field.',
|
|
1127
1129
|
properties: {
|
|
@@ -1161,13 +1163,13 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1161
1163
|
},
|
|
1162
1164
|
},
|
|
1163
1165
|
},
|
|
1164
|
-
|
|
1166
|
+
edit_target: {
|
|
1165
1167
|
type: 'string',
|
|
1166
1168
|
description: 'When editing an original, choose ask, live, or duplicate. Defaults to ask when direct editing is enabled.',
|
|
1167
1169
|
enum: ['ask', 'live', 'duplicate'],
|
|
1168
1170
|
},
|
|
1169
1171
|
},
|
|
1170
|
-
required: ['builder', '
|
|
1172
|
+
required: ['builder', 'page_id', 'module_identifier', 'updates'],
|
|
1171
1173
|
},
|
|
1172
1174
|
idempotentHint: true,
|
|
1173
1175
|
},
|
|
@@ -1260,7 +1262,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1260
1262
|
type: 'string',
|
|
1261
1263
|
description: 'Builder slug',
|
|
1262
1264
|
},
|
|
1263
|
-
|
|
1265
|
+
post_id: {
|
|
1264
1266
|
type: 'number',
|
|
1265
1267
|
description: 'Post ID',
|
|
1266
1268
|
},
|
|
@@ -1273,13 +1275,13 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1273
1275
|
description: 'Patch operations[]',
|
|
1274
1276
|
items: { type: 'object' },
|
|
1275
1277
|
},
|
|
1276
|
-
|
|
1278
|
+
edit_target: {
|
|
1277
1279
|
type: 'string',
|
|
1278
1280
|
description: 'When editing an original, choose ask, live, or duplicate. Defaults to ask when direct editing is enabled.',
|
|
1279
1281
|
enum: ['ask', 'live', 'duplicate'],
|
|
1280
1282
|
},
|
|
1281
1283
|
},
|
|
1282
|
-
required: ['builder', '
|
|
1284
|
+
required: ['builder', 'post_id', 'operations'],
|
|
1283
1285
|
},
|
|
1284
1286
|
idempotentHint: true,
|
|
1285
1287
|
},
|
|
@@ -1303,14 +1305,28 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1303
1305
|
inputSchema: {
|
|
1304
1306
|
type: 'object',
|
|
1305
1307
|
properties: {
|
|
1306
|
-
|
|
1308
|
+
site_id: {
|
|
1307
1309
|
type: 'string',
|
|
1308
1310
|
description: 'Site ID from configuration',
|
|
1309
1311
|
},
|
|
1310
1312
|
},
|
|
1311
|
-
required: ['
|
|
1313
|
+
required: ['site_id'],
|
|
1312
1314
|
},
|
|
1313
1315
|
},
|
|
1316
|
+
{
|
|
1317
|
+
name: 'wordpress_diagnose_connection',
|
|
1318
|
+
description: 'Run a connection-fingerprint diagnostic for the active site. Combines the plugin\'s server-side report (route registration, php/wp/plugin versions, edge plugin presence) with outside-in probes from the MCP server (REST root reachability, content-type sanity check on Respira routes, edge-layer headers). Use when a tool returns "html instead of json", an opaque 5xx, or when a connection that worked yesterday silently breaks. Returns a structured object including detected edge layers (Cloudflare, Wordfence, Sucuri) and concrete remediation recommendations.',
|
|
1319
|
+
inputSchema: {
|
|
1320
|
+
type: 'object',
|
|
1321
|
+
properties: {
|
|
1322
|
+
post_id: {
|
|
1323
|
+
type: 'number',
|
|
1324
|
+
description: 'Optional target post ID for a more specific probe.',
|
|
1325
|
+
},
|
|
1326
|
+
},
|
|
1327
|
+
},
|
|
1328
|
+
readOnlyHint: true,
|
|
1329
|
+
},
|
|
1314
1330
|
// Page Speed Analysis tools
|
|
1315
1331
|
{
|
|
1316
1332
|
name: 'wordpress_analyze_performance',
|
|
@@ -1318,12 +1334,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1318
1334
|
inputSchema: {
|
|
1319
1335
|
type: 'object',
|
|
1320
1336
|
properties: {
|
|
1321
|
-
|
|
1337
|
+
page_id: {
|
|
1322
1338
|
type: 'number',
|
|
1323
1339
|
description: 'Page ID to analyze',
|
|
1324
1340
|
},
|
|
1325
1341
|
},
|
|
1326
|
-
required: ['
|
|
1342
|
+
required: ['page_id'],
|
|
1327
1343
|
},
|
|
1328
1344
|
readOnlyHint: true,
|
|
1329
1345
|
},
|
|
@@ -1333,12 +1349,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1333
1349
|
inputSchema: {
|
|
1334
1350
|
type: 'object',
|
|
1335
1351
|
properties: {
|
|
1336
|
-
|
|
1352
|
+
page_id: {
|
|
1337
1353
|
type: 'number',
|
|
1338
1354
|
description: 'Page ID to analyze',
|
|
1339
1355
|
},
|
|
1340
1356
|
},
|
|
1341
|
-
required: ['
|
|
1357
|
+
required: ['page_id'],
|
|
1342
1358
|
},
|
|
1343
1359
|
readOnlyHint: true,
|
|
1344
1360
|
},
|
|
@@ -1348,12 +1364,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1348
1364
|
inputSchema: {
|
|
1349
1365
|
type: 'object',
|
|
1350
1366
|
properties: {
|
|
1351
|
-
|
|
1367
|
+
page_id: {
|
|
1352
1368
|
type: 'number',
|
|
1353
1369
|
description: 'Page ID to analyze',
|
|
1354
1370
|
},
|
|
1355
1371
|
},
|
|
1356
|
-
required: ['
|
|
1372
|
+
required: ['page_id'],
|
|
1357
1373
|
},
|
|
1358
1374
|
readOnlyHint: true,
|
|
1359
1375
|
},
|
|
@@ -1364,12 +1380,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1364
1380
|
inputSchema: {
|
|
1365
1381
|
type: 'object',
|
|
1366
1382
|
properties: {
|
|
1367
|
-
|
|
1383
|
+
page_id: {
|
|
1368
1384
|
type: 'number',
|
|
1369
1385
|
description: 'Page ID to analyze',
|
|
1370
1386
|
},
|
|
1371
1387
|
},
|
|
1372
|
-
required: ['
|
|
1388
|
+
required: ['page_id'],
|
|
1373
1389
|
},
|
|
1374
1390
|
readOnlyHint: true,
|
|
1375
1391
|
},
|
|
@@ -1379,12 +1395,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1379
1395
|
inputSchema: {
|
|
1380
1396
|
type: 'object',
|
|
1381
1397
|
properties: {
|
|
1382
|
-
|
|
1398
|
+
page_id: {
|
|
1383
1399
|
type: 'number',
|
|
1384
1400
|
description: 'Page ID to analyze',
|
|
1385
1401
|
},
|
|
1386
1402
|
},
|
|
1387
|
-
required: ['
|
|
1403
|
+
required: ['page_id'],
|
|
1388
1404
|
},
|
|
1389
1405
|
readOnlyHint: true,
|
|
1390
1406
|
},
|
|
@@ -1394,12 +1410,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1394
1410
|
inputSchema: {
|
|
1395
1411
|
type: 'object',
|
|
1396
1412
|
properties: {
|
|
1397
|
-
|
|
1413
|
+
page_id: {
|
|
1398
1414
|
type: 'number',
|
|
1399
1415
|
description: 'Page ID to analyze',
|
|
1400
1416
|
},
|
|
1401
1417
|
},
|
|
1402
|
-
required: ['
|
|
1418
|
+
required: ['page_id'],
|
|
1403
1419
|
},
|
|
1404
1420
|
readOnlyHint: true,
|
|
1405
1421
|
},
|
|
@@ -1409,12 +1425,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1409
1425
|
inputSchema: {
|
|
1410
1426
|
type: 'object',
|
|
1411
1427
|
properties: {
|
|
1412
|
-
|
|
1428
|
+
post_id: {
|
|
1413
1429
|
type: 'number',
|
|
1414
1430
|
description: 'Post or page ID to analyze',
|
|
1415
1431
|
},
|
|
1416
1432
|
},
|
|
1417
|
-
required: ['
|
|
1433
|
+
required: ['post_id'],
|
|
1418
1434
|
},
|
|
1419
1435
|
readOnlyHint: true,
|
|
1420
1436
|
},
|
|
@@ -1425,12 +1441,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1425
1441
|
inputSchema: {
|
|
1426
1442
|
type: 'object',
|
|
1427
1443
|
properties: {
|
|
1428
|
-
|
|
1444
|
+
page_id: {
|
|
1429
1445
|
type: 'number',
|
|
1430
1446
|
description: 'Page ID to analyze',
|
|
1431
1447
|
},
|
|
1432
1448
|
},
|
|
1433
|
-
required: ['
|
|
1449
|
+
required: ['page_id'],
|
|
1434
1450
|
},
|
|
1435
1451
|
readOnlyHint: true,
|
|
1436
1452
|
},
|
|
@@ -1440,12 +1456,12 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1440
1456
|
inputSchema: {
|
|
1441
1457
|
type: 'object',
|
|
1442
1458
|
properties: {
|
|
1443
|
-
|
|
1459
|
+
page_id: {
|
|
1444
1460
|
type: 'number',
|
|
1445
1461
|
description: 'Page ID to analyze',
|
|
1446
1462
|
},
|
|
1447
1463
|
},
|
|
1448
|
-
required: ['
|
|
1464
|
+
required: ['page_id'],
|
|
1449
1465
|
},
|
|
1450
1466
|
readOnlyHint: true,
|
|
1451
1467
|
},
|
|
@@ -1515,7 +1531,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1515
1531
|
inputSchema: {
|
|
1516
1532
|
type: 'object',
|
|
1517
1533
|
properties: {
|
|
1518
|
-
|
|
1534
|
+
slug_or_url: {
|
|
1519
1535
|
type: 'string',
|
|
1520
1536
|
description: 'Plugin slug (from WordPress.org) or ZIP file URL',
|
|
1521
1537
|
},
|
|
@@ -1525,7 +1541,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1525
1541
|
enum: ['wordpress.org', 'url'],
|
|
1526
1542
|
},
|
|
1527
1543
|
},
|
|
1528
|
-
required: ['
|
|
1544
|
+
required: ['slug_or_url'],
|
|
1529
1545
|
},
|
|
1530
1546
|
},
|
|
1531
1547
|
{
|
|
@@ -1601,7 +1617,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1601
1617
|
type: 'number',
|
|
1602
1618
|
description: 'Page number',
|
|
1603
1619
|
},
|
|
1604
|
-
|
|
1620
|
+
per_page: {
|
|
1605
1621
|
type: 'number',
|
|
1606
1622
|
description: 'Items per page',
|
|
1607
1623
|
},
|
|
@@ -1719,7 +1735,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1719
1735
|
type: 'number',
|
|
1720
1736
|
description: 'Page number',
|
|
1721
1737
|
},
|
|
1722
|
-
|
|
1738
|
+
per_page: {
|
|
1723
1739
|
type: 'number',
|
|
1724
1740
|
description: 'Items per page',
|
|
1725
1741
|
},
|
|
@@ -1857,7 +1873,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
1857
1873
|
type: 'number',
|
|
1858
1874
|
description: 'Page number',
|
|
1859
1875
|
},
|
|
1860
|
-
|
|
1876
|
+
per_page: {
|
|
1861
1877
|
type: 'number',
|
|
1862
1878
|
description: 'Items per page',
|
|
1863
1879
|
},
|
|
@@ -2016,7 +2032,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
2016
2032
|
type: 'number',
|
|
2017
2033
|
description: 'Page number',
|
|
2018
2034
|
},
|
|
2019
|
-
|
|
2035
|
+
per_page: {
|
|
2020
2036
|
type: 'number',
|
|
2021
2037
|
description: 'Items per page',
|
|
2022
2038
|
},
|
|
@@ -2117,11 +2133,11 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
2117
2133
|
type: 'object',
|
|
2118
2134
|
description: 'Generic map of taxonomy slug to array of term ids/slugs for custom taxonomies (e.g. product_cat). Example: { "product_cat": [12, "featured"] }.',
|
|
2119
2135
|
},
|
|
2120
|
-
|
|
2136
|
+
featured_media: {
|
|
2121
2137
|
type: 'number',
|
|
2122
2138
|
description: 'Attachment ID to set as the featured image.',
|
|
2123
2139
|
},
|
|
2124
|
-
|
|
2140
|
+
create_missing_terms: {
|
|
2125
2141
|
type: 'boolean',
|
|
2126
2142
|
description: 'When true, auto-create taxonomy terms that do not exist by name. Default false (strict: unknown slug returns 400 and the post is rolled back).',
|
|
2127
2143
|
},
|
|
@@ -2194,15 +2210,15 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
2194
2210
|
type: 'object',
|
|
2195
2211
|
description: 'Generic map of taxonomy slug to array of term ids/slugs for custom taxonomies.',
|
|
2196
2212
|
},
|
|
2197
|
-
|
|
2213
|
+
featured_media: {
|
|
2198
2214
|
type: 'number',
|
|
2199
2215
|
description: 'Attachment ID to set as the featured image. Pass 0 to clear.',
|
|
2200
2216
|
},
|
|
2201
|
-
|
|
2217
|
+
create_missing_terms: {
|
|
2202
2218
|
type: 'boolean',
|
|
2203
2219
|
description: 'When true, auto-create taxonomy terms that do not exist by name. Default false (strict).',
|
|
2204
2220
|
},
|
|
2205
|
-
|
|
2221
|
+
append_terms: {
|
|
2206
2222
|
type: 'boolean',
|
|
2207
2223
|
description: 'When true, append to existing taxonomy terms instead of replacing. Default false (replace).',
|
|
2208
2224
|
},
|
|
@@ -2210,11 +2226,11 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
2210
2226
|
type: 'object',
|
|
2211
2227
|
description: 'Post meta data (e.g., { "_et_pb_custom_css": "/* CSS */" })',
|
|
2212
2228
|
},
|
|
2213
|
-
|
|
2229
|
+
custom_css: {
|
|
2214
2230
|
type: 'string',
|
|
2215
2231
|
description: 'Custom CSS for page builders (Divi/Elementor). Automatically saved to the appropriate meta field based on detected builder.',
|
|
2216
2232
|
},
|
|
2217
|
-
|
|
2233
|
+
edit_target: {
|
|
2218
2234
|
type: 'string',
|
|
2219
2235
|
description: 'Choose ask, live, or duplicate when the target is an original item.',
|
|
2220
2236
|
enum: ['ask', 'live', 'duplicate'],
|
|
@@ -3057,12 +3073,79 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3057
3073
|
},
|
|
3058
3074
|
];
|
|
3059
3075
|
}
|
|
3076
|
+
/**
|
|
3077
|
+
* camelCase → snake_case rename map (mcp-v6.11.1).
|
|
3078
|
+
*
|
|
3079
|
+
* Schemas advertise snake_case only. Handlers can read either form for one
|
|
3080
|
+
* release; camelCase emits a deprecation warning to stderr and will be
|
|
3081
|
+
* removed in mcp-v6.13.
|
|
3082
|
+
*
|
|
3083
|
+
* Mirrors both directions so wordpress-client.ts (which still reads
|
|
3084
|
+
* camelCase fields like data.customCss / data.featuredMedia / args.edit_target
|
|
3085
|
+
* before mapping them to plugin-side snake_case) keeps working unchanged.
|
|
3086
|
+
* The wordpress-client surface is purely internal — its rename can ride
|
|
3087
|
+
* along in a follow-up release without breaking callers.
|
|
3088
|
+
*/
|
|
3089
|
+
static CAMEL_TO_SNAKE_PARAMS = {
|
|
3090
|
+
pageId: 'page_id',
|
|
3091
|
+
postId: 'post_id',
|
|
3092
|
+
perPage: 'per_page',
|
|
3093
|
+
editTarget: 'edit_target',
|
|
3094
|
+
originalId: 'original_id',
|
|
3095
|
+
customCss: 'custom_css',
|
|
3096
|
+
skipSecurityCheck: 'skip_security_check',
|
|
3097
|
+
featuredMedia: 'featured_media',
|
|
3098
|
+
createMissingTerms: 'create_missing_terms',
|
|
3099
|
+
appendTerms: 'append_terms',
|
|
3100
|
+
mimeType: 'mime_type',
|
|
3101
|
+
moduleIdentifier: 'module_identifier',
|
|
3102
|
+
diviVersion: 'divi_version',
|
|
3103
|
+
slugOrUrl: 'slug_or_url',
|
|
3104
|
+
};
|
|
3105
|
+
/**
|
|
3106
|
+
* Normalize tool args so handlers see both snake_case (new, advertised in
|
|
3107
|
+
* the schema) and camelCase (legacy, kept working for one release with a
|
|
3108
|
+
* deprecation warning). Mutates the args object in place and returns it.
|
|
3109
|
+
*/
|
|
3110
|
+
normalizeArgsForBackCompat(toolName, args) {
|
|
3111
|
+
if (!args || typeof args !== 'object' || Array.isArray(args)) {
|
|
3112
|
+
return args;
|
|
3113
|
+
}
|
|
3114
|
+
for (const [camel, snake] of Object.entries(RespiraWordPressServer.CAMEL_TO_SNAKE_PARAMS)) {
|
|
3115
|
+
const hasCamel = Object.prototype.hasOwnProperty.call(args, camel);
|
|
3116
|
+
const hasSnake = Object.prototype.hasOwnProperty.call(args, snake);
|
|
3117
|
+
if (hasCamel && !hasSnake) {
|
|
3118
|
+
// Caller is on the legacy camelCase path. Mirror to snake_case so
|
|
3119
|
+
// schema-aware downstream code can read it; warn once.
|
|
3120
|
+
args[snake] = args[camel];
|
|
3121
|
+
try {
|
|
3122
|
+
process.stderr.write(`[respira-mcp] deprecated: '${camel}' is renamed to '${snake}', will be removed in mcp-v6.13 (tool: ${toolName})\n`);
|
|
3123
|
+
}
|
|
3124
|
+
catch {
|
|
3125
|
+
// ignore stderr write failures.
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
else if (!hasCamel && hasSnake) {
|
|
3129
|
+
// Caller is on the new snake_case path. Mirror to camelCase so the
|
|
3130
|
+
// wordpress-client.ts layer (which still reads camelCase) keeps
|
|
3131
|
+
// working without further surface changes this release.
|
|
3132
|
+
args[camel] = args[snake];
|
|
3133
|
+
}
|
|
3134
|
+
// If both are present, prefer snake_case as source of truth and leave
|
|
3135
|
+
// both in place. If neither, no-op.
|
|
3136
|
+
}
|
|
3137
|
+
return args;
|
|
3138
|
+
}
|
|
3060
3139
|
async handleToolCall(name, args) {
|
|
3061
3140
|
if (!this.currentSite) {
|
|
3062
3141
|
throw new Error('No WordPress site configured');
|
|
3063
3142
|
}
|
|
3064
3143
|
// Normalize respira_* ↔ wordpress_* names.
|
|
3065
3144
|
const { canonical, deprecated } = this.normalizeToolName(name);
|
|
3145
|
+
// mcp-v6.11.1: snake_case sweep across tool catalog. Schemas advertise
|
|
3146
|
+
// snake_case; legacy camelCase still accepted with a deprecation warning
|
|
3147
|
+
// for one release.
|
|
3148
|
+
args = this.normalizeArgsForBackCompat(canonical, args);
|
|
3066
3149
|
const result = await this.dispatchToolCall(canonical, args);
|
|
3067
3150
|
if (deprecated && result && typeof result === 'object' && !Array.isArray(result)) {
|
|
3068
3151
|
return {
|
|
@@ -3104,7 +3187,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3104
3187
|
return await this.currentSite.getPage(args.id, args.include);
|
|
3105
3188
|
case 'wordpress_create_page_duplicate':
|
|
3106
3189
|
return {
|
|
3107
|
-
...(await this.currentSite.duplicatePage(args.
|
|
3190
|
+
...(await this.currentSite.duplicatePage(args.original_id, args.suffix, args.include)),
|
|
3108
3191
|
respira_approvals_url: this.currentSite.getApprovalsUrl(),
|
|
3109
3192
|
};
|
|
3110
3193
|
case 'wordpress_update_page': {
|
|
@@ -3137,7 +3220,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3137
3220
|
return await this.currentSite.getPost(args.id, args.include);
|
|
3138
3221
|
case 'wordpress_create_post_duplicate':
|
|
3139
3222
|
return {
|
|
3140
|
-
...(await this.currentSite.duplicatePost(args.
|
|
3223
|
+
...(await this.currentSite.duplicatePost(args.original_id, args.suffix, args.include)),
|
|
3141
3224
|
respira_approvals_url: this.currentSite.getApprovalsUrl(),
|
|
3142
3225
|
};
|
|
3143
3226
|
case 'wordpress_update_post': {
|
|
@@ -3167,30 +3250,30 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3167
3250
|
case 'wordpress_list_media':
|
|
3168
3251
|
return await this.currentSite.listMedia(args);
|
|
3169
3252
|
case 'wordpress_upload_media':
|
|
3170
|
-
return await this.currentSite.uploadMedia(args.file, args.filename, args.
|
|
3253
|
+
return await this.currentSite.uploadMedia(args.file, args.filename, args.mime_type, args.title, args.alt, args.caption);
|
|
3171
3254
|
case 'wordpress_extract_builder_content':
|
|
3172
|
-
return await this.currentSite.extractBuilderContent(args.builder, args.
|
|
3255
|
+
return await this.currentSite.extractBuilderContent(args.builder, args.page_id);
|
|
3173
3256
|
case 'wordpress_find_builder_targets':
|
|
3174
|
-
return await this.currentSite.findBuilderTargets(args.builder, args.
|
|
3257
|
+
return await this.currentSite.findBuilderTargets(args.builder, args.page_id, args.query, args.limit);
|
|
3175
3258
|
case 'wordpress_inject_builder_content':
|
|
3176
3259
|
return {
|
|
3177
|
-
...(await this.currentSite.injectBuilderContent(args.builder, args.
|
|
3260
|
+
...(await this.currentSite.injectBuilderContent(args.builder, args.page_id, args.content, args.divi_version, args.edit_target, args.mode)),
|
|
3178
3261
|
respira_approvals_url: this.currentSite.getApprovalsUrl(),
|
|
3179
3262
|
};
|
|
3180
3263
|
case 'wordpress_update_module':
|
|
3181
3264
|
return {
|
|
3182
|
-
...(await this.currentSite.updateModule(args.builder, args.
|
|
3265
|
+
...(await this.currentSite.updateModule(args.builder, args.page_id, args.module_identifier, args.updates, args.edit_target)),
|
|
3183
3266
|
respira_approvals_url: this.currentSite.getApprovalsUrl(),
|
|
3184
3267
|
};
|
|
3185
3268
|
case 'wordpress_validate_security':
|
|
3186
3269
|
return await this.currentSite.validateSecurity(args.content);
|
|
3187
3270
|
case 'wordpress_switch_site': {
|
|
3188
|
-
const newSite = this.sites.get(args.
|
|
3271
|
+
const newSite = this.sites.get(args.site_id);
|
|
3189
3272
|
if (!newSite) {
|
|
3190
|
-
throw new Error(`Site with ID "${args.
|
|
3273
|
+
throw new Error(`Site with ID "${args.site_id}" not found in configuration`);
|
|
3191
3274
|
}
|
|
3192
3275
|
if (!this.isSiteAllowed(newSite)) {
|
|
3193
|
-
throw new Error(`Site "${args.
|
|
3276
|
+
throw new Error(`Site "${args.site_id}" is not in this MCP configuration group.`);
|
|
3194
3277
|
}
|
|
3195
3278
|
this.currentSite = newSite;
|
|
3196
3279
|
this.cachedFilterContext = null; // Invalidate tool filter cache on site switch.
|
|
@@ -3200,27 +3283,29 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3200
3283
|
site: this.getSiteSummary(newSite),
|
|
3201
3284
|
};
|
|
3202
3285
|
}
|
|
3286
|
+
case 'wordpress_diagnose_connection':
|
|
3287
|
+
return await this.currentSite.diagnoseConnection({ post_id: args.post_id });
|
|
3203
3288
|
// Page Speed Analysis
|
|
3204
3289
|
case 'wordpress_analyze_performance':
|
|
3205
|
-
return await this.currentSite.analyzePerformance(args.
|
|
3290
|
+
return await this.currentSite.analyzePerformance(args.page_id);
|
|
3206
3291
|
case 'wordpress_get_core_web_vitals':
|
|
3207
|
-
return await this.currentSite.getCoreWebVitals(args.
|
|
3292
|
+
return await this.currentSite.getCoreWebVitals(args.page_id);
|
|
3208
3293
|
case 'wordpress_analyze_images':
|
|
3209
|
-
return await this.currentSite.analyzeImages(args.
|
|
3294
|
+
return await this.currentSite.analyzeImages(args.page_id);
|
|
3210
3295
|
// SEO Analysis
|
|
3211
3296
|
case 'wordpress_analyze_seo':
|
|
3212
|
-
return await this.currentSite.analyzeSEO(args.
|
|
3297
|
+
return await this.currentSite.analyzeSEO(args.page_id);
|
|
3213
3298
|
case 'wordpress_check_seo_issues':
|
|
3214
|
-
return await this.currentSite.checkSEOIssues(args.
|
|
3299
|
+
return await this.currentSite.checkSEOIssues(args.page_id);
|
|
3215
3300
|
case 'wordpress_analyze_readability':
|
|
3216
|
-
return await this.currentSite.analyzeReadability(args.
|
|
3301
|
+
return await this.currentSite.analyzeReadability(args.page_id);
|
|
3217
3302
|
case 'wordpress_analyze_rankmath':
|
|
3218
|
-
return await this.currentSite.analyzeRankMath(args.
|
|
3303
|
+
return await this.currentSite.analyzeRankMath(args.post_id);
|
|
3219
3304
|
// AEO Analysis
|
|
3220
3305
|
case 'wordpress_analyze_aeo':
|
|
3221
|
-
return await this.currentSite.analyzeAEO(args.
|
|
3306
|
+
return await this.currentSite.analyzeAEO(args.page_id);
|
|
3222
3307
|
case 'wordpress_check_structured_data':
|
|
3223
|
-
return await this.currentSite.checkStructuredData(args.
|
|
3308
|
+
return await this.currentSite.checkStructuredData(args.page_id);
|
|
3224
3309
|
// Accessibility
|
|
3225
3310
|
case 'wordpress_list_accessibility_scans':
|
|
3226
3311
|
return await this.currentSite.listAccessibilityScans();
|
|
@@ -3234,7 +3319,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3234
3319
|
case 'wordpress_list_plugins':
|
|
3235
3320
|
return await this.currentSite.listPlugins();
|
|
3236
3321
|
case 'wordpress_install_plugin':
|
|
3237
|
-
return await this.currentSite.installPlugin(args.
|
|
3322
|
+
return await this.currentSite.installPlugin(args.slug_or_url, args.source || 'wordpress.org');
|
|
3238
3323
|
case 'wordpress_activate_plugin':
|
|
3239
3324
|
return await this.currentSite.activatePlugin(args.slug);
|
|
3240
3325
|
case 'wordpress_deactivate_plugin':
|
|
@@ -3349,7 +3434,7 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3349
3434
|
case 'wordpress_restore_snapshot':
|
|
3350
3435
|
return await this.currentSite.restoreSnapshot(args.snapshot_uuid);
|
|
3351
3436
|
case 'wordpress_apply_builder_patch':
|
|
3352
|
-
return await this.currentSite.applyBuilderPatch(args.builder, args.
|
|
3437
|
+
return await this.currentSite.applyBuilderPatch(args.builder, args.post_id, args.operations, args.include, args.edit_target);
|
|
3353
3438
|
case 'woocommerce_list_products':
|
|
3354
3439
|
return await this.currentSite.woocommerceListProducts(args);
|
|
3355
3440
|
case 'woocommerce_get_product':
|
|
@@ -3566,14 +3651,22 @@ Use respira_get_builder_info first to detect which builder is active. Then use t
|
|
|
3566
3651
|
},
|
|
3567
3652
|
{
|
|
3568
3653
|
name: 'wordpress_remove_element',
|
|
3569
|
-
description: 'Remove an element from a page.',
|
|
3654
|
+
description: 'Remove an element from a page. Use the same identifier_type/identifier_value pattern as find_element and update_element — first locate the element, then pass the matching identifier to remove it.',
|
|
3570
3655
|
inputSchema: {
|
|
3571
3656
|
type: 'object',
|
|
3572
3657
|
properties: {
|
|
3573
3658
|
post_id: { type: 'number', description: 'Page/post ID' },
|
|
3574
|
-
|
|
3659
|
+
identifier_type: {
|
|
3660
|
+
type: 'string',
|
|
3661
|
+
enum: ['id', 'css_class', 'text', 'widget_type', 'global_id'],
|
|
3662
|
+
description: 'How to locate the element: "id" (element ID), "css_class" (CSS class name), "text" (visible text content), "widget_type" (widget/module type), or "global_id" (cross-page global element ID).',
|
|
3663
|
+
},
|
|
3664
|
+
identifier_value: {
|
|
3665
|
+
type: 'string',
|
|
3666
|
+
description: 'Value matching the chosen identifier_type (e.g. the element ID, the class name, the text to match).',
|
|
3667
|
+
},
|
|
3575
3668
|
},
|
|
3576
|
-
required: ['post_id', '
|
|
3669
|
+
required: ['post_id', 'identifier_type', 'identifier_value'],
|
|
3577
3670
|
},
|
|
3578
3671
|
destructiveHint: true,
|
|
3579
3672
|
},
|