@respira/wordpress-mcp-server 6.19.1 → 6.19.3
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.map +1 -1
- package/dist/server.js +44 -60
- package/dist/server.js.map +1 -1
- package/dist/wordpress-client.d.ts +27 -14
- package/dist/wordpress-client.d.ts.map +1 -1
- package/dist/wordpress-client.js +140 -15
- package/dist/wordpress-client.js.map +1 -1
- package/package.json +1 -1
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAoBH,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,kBAAkB,CAAC;AAiLzE,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,YAAY,CAA4B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,YAAY,CAA4B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,mBAAmB,CAAS;IAEpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IAEhE;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;gBA4Bb,WAAW,EAAE,mBAAmB,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE;IAmUvE,OAAO,CAAC,cAAc;IAItB;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAkB5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IA4BrB,gEAAgE;IAChE,OAAO,CAAC,aAAa;IAUrB;;;;;;OAMG;YACW,UAAU;IA2CxB;;;;;;;;;;;;;;OAcG;YACW,WAAW;IAyIzB;;;;;;;;;OASG;YACW,kBAAkB;IA6FhC,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,aAAa;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAoBH,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,kBAAkB,CAAC;AAiLzE,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,YAAY,CAA4B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,YAAY,CAA4B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,mBAAmB,CAAS;IAEpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IAEhE;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;gBA4Bb,WAAW,EAAE,mBAAmB,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE;IAmUvE,OAAO,CAAC,cAAc;IAItB;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAkB5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IA4BrB,gEAAgE;IAChE,OAAO,CAAC,aAAa;IAUrB;;;;;;OAMG;YACW,UAAU;IA2CxB;;;;;;;;;;;;;;OAcG;YACW,WAAW;IAyIzB;;;;;;;;;OASG;YACW,kBAAkB;IA6FhC,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,aAAa;YAuOP,kBAAkB;YA6BlB,yBAAyB;IASvC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;YAyBd,QAAQ;IA28EtB;;;;;;OAMG;IACH,yEAAyE;IACzE,OAAO,CAAC,mBAAmB,CAAoD;IAC/E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAU;YAEpC,oBAAoB;YAqDpB,2BAA2B;IAazC;;;;OAIG;YACW,cAAc;IAY5B,OAAO,CAAC,mBAAmB;IAwT3B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAe3C;IAEF;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;YAmCpB,cAAc;IAqG5B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,eAAe;YAuCT,gBAAgB;IAisB9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA+SzB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA6UxB,GAAG;CAyCV"}
|
package/dist/server.js
CHANGED
|
@@ -968,13 +968,30 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
968
968
|
}
|
|
969
969
|
// Per-call watchdog: a single hung handler must never wedge the stdio
|
|
970
970
|
// loop for every subsequent tool call. If the deadline fires, the race
|
|
971
|
-
// rejects with ToolTimeoutError
|
|
972
|
-
//
|
|
973
|
-
//
|
|
971
|
+
// rejects with ToolTimeoutError, AND we destroy the WP client's HTTP
|
|
972
|
+
// agents to free the orphaned socket so the next tool call doesn't
|
|
973
|
+
// queue behind it at the agent layer. v6.19.3 bug fc2bfdf3 — Mauricio
|
|
974
|
+
// Piper (Fischers Fritze) reported that after one tool deadlocked
|
|
975
|
+
// every subsequent call, including diagnose_connection, also hung 4
|
|
976
|
+
// min; only killing Claude Desktop recovered. Per-client agents (now
|
|
977
|
+
// bounded at maxSockets:16, keepAlive:false) plus this destroy-on-
|
|
978
|
+
// trip make orphans cost at most one socket for at most the axios
|
|
979
|
+
// 30s response timeout, instead of indefinitely blocking the pool.
|
|
974
980
|
const toolTimeoutMs = getMaxToolTimeoutMs();
|
|
975
981
|
let timeoutHandle;
|
|
982
|
+
const siteForAbort = this.currentSite;
|
|
976
983
|
const toolTimeout = new Promise((_, reject) => {
|
|
977
|
-
timeoutHandle = setTimeout(() =>
|
|
984
|
+
timeoutHandle = setTimeout(() => {
|
|
985
|
+
try {
|
|
986
|
+
if (siteForAbort && typeof siteForAbort.abortInFlightRequests === 'function') {
|
|
987
|
+
siteForAbort.abortInFlightRequests();
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
catch {
|
|
991
|
+
// Don't block the rejection on cleanup.
|
|
992
|
+
}
|
|
993
|
+
reject(new ToolTimeoutError(name, toolTimeoutMs));
|
|
994
|
+
}, toolTimeoutMs);
|
|
978
995
|
});
|
|
979
996
|
try {
|
|
980
997
|
this.currentSite.setCurrentToolName(name);
|
|
@@ -1254,42 +1271,6 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
1254
1271
|
},
|
|
1255
1272
|
readOnlyHint: true,
|
|
1256
1273
|
},
|
|
1257
|
-
{
|
|
1258
|
-
name: 'wordpress_search_abilities',
|
|
1259
|
-
description: 'SEARCH the curated WordPress abilities directory across all known plugins (Elementor, Yoast SEO, WooCommerce, Jetpack, ACF, Akismet, plus Respira\'s own 151 tools — 163 total today, growing weekly via auto-pull). ' +
|
|
1260
|
-
'Use this whenever the user asks "is there an ability that does X", "can WordPress do Y", "what plugins expose Z as MCP", "how do i automate W on my site". ' +
|
|
1261
|
-
'Each result is enriched with per-site context: is_installed (is the plugin active on THIS site), is_inhaled (has the admin opted the ability into Respira\'s MCP surface), install_url (wp.org page when not installed), inhale_admin_url (Respira admin tab when installed but not inhaled), and how_to_invoke (the exact tool call to make when ready). ' +
|
|
1262
|
-
'After finding a matching ability, if is_inhaled is true you can call it via wordpress_invoke_ability. Otherwise surface install_url or inhale_admin_url to the user so they can opt in. ' +
|
|
1263
|
-
'No auth gates: this surface is open to every agent connected to Respira. The directory itself is global; the enrichment is per-site.',
|
|
1264
|
-
inputSchema: {
|
|
1265
|
-
type: 'object',
|
|
1266
|
-
properties: {
|
|
1267
|
-
q: {
|
|
1268
|
-
type: 'string',
|
|
1269
|
-
description: 'Free-text query — matches against ability_name, label, description, plugin_name, category. Optional; an empty query returns the top of the directory.',
|
|
1270
|
-
},
|
|
1271
|
-
plugin: {
|
|
1272
|
-
type: 'string',
|
|
1273
|
-
description: 'Restrict to a single plugin by wp.org slug (e.g. "wordpress-seo") or display name ("Yoast SEO"). Optional.',
|
|
1274
|
-
},
|
|
1275
|
-
category: {
|
|
1276
|
-
type: 'string',
|
|
1277
|
-
description: 'Restrict to a single category (e.g. "SEO", "E-commerce", "Page Builder", "Custom Fields"). Optional.',
|
|
1278
|
-
},
|
|
1279
|
-
kind: {
|
|
1280
|
-
type: 'string',
|
|
1281
|
-
enum: ['read', 'write'],
|
|
1282
|
-
description: 'Restrict to read-only or write abilities. Optional.',
|
|
1283
|
-
},
|
|
1284
|
-
limit: {
|
|
1285
|
-
type: 'integer',
|
|
1286
|
-
description: 'Max results to return (default 20, max 100).',
|
|
1287
|
-
default: 20,
|
|
1288
|
-
},
|
|
1289
|
-
},
|
|
1290
|
-
},
|
|
1291
|
-
readOnlyHint: true,
|
|
1292
|
-
},
|
|
1293
1274
|
{
|
|
1294
1275
|
name: 'wordpress_invoke_ability',
|
|
1295
1276
|
description: 'Invoke an inhaled WordPress Abilities API ability through the Respira safety wrapper. ' +
|
|
@@ -1845,7 +1826,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
1845
1826
|
},
|
|
1846
1827
|
{
|
|
1847
1828
|
name: 'wordpress_inject_builder_content',
|
|
1848
|
-
description: 'REPLACE (or append to) the entire page builder layout. WARNING: By default this REPLACES all existing content
|
|
1829
|
+
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.\n\nNested Divi 5 content shape (canonical): `content: [{ type: "section", settings: {...}, children: [{ type: "row", children: [{ type: "column", children: [{ type: "heading", settings: {...} }, ...] }] }] }]`. Plugin v7.0.32 also accepts `rows / cols / columns / modules / elements / innerBlocks` as aliases for `children` on Divi (Divi-vocabulary; soft warning surfaces in response.warnings). Plugin v7.0.32 hard-errors with `respira_children_dropped` (HTTP 500) if any container payload declares children but the emit produced fewer innerBlocks (silent data-loss is no longer possible).\n\nDivi render-critical attrs (the plugin returns `respira_divi_required_attrs_missing` if any are absent, because the module would render empty): `divi/heading` requires `title`; `divi/text` requires `content`; `divi/code` requires `raw_content`; `divi/blurb` requires `title`; `divi/team-member` requires `name`; `divi/testimonial` requires `author`; `divi/cta` requires `title`; `divi/pricing-table` requires `title` and `sum`; `divi/number-counter` requires `number`; `divi/button` requires `button_text`. Set each via the module\'s `settings` object.',
|
|
1849
1830
|
inputSchema: {
|
|
1850
1831
|
type: 'object',
|
|
1851
1832
|
properties: {
|
|
@@ -2103,7 +2084,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
2103
2084
|
},
|
|
2104
2085
|
{
|
|
2105
2086
|
name: 'wordpress_read_theme_file',
|
|
2106
|
-
description: 'Read the contents of a theme stylesheet on disk (
|
|
2087
|
+
description: 'Read the contents of a theme stylesheet on disk. ONLY these extensions are accepted: `.css`, `.scss`, `.less`, `.json`. Any other extension (`.php`, `.html`, `.twig`, `.js`, `.svg`, `.md`, `.txt`, etc.) returns `respira_theme_file_extension_not_allowed` and the tool does NOT support reading them. PHP/HTML theme files are out of scope on purpose; ask the human to edit those by hand or via a code editor over SFTP. Path is relative to wp-content/themes, e.g. `vds/css/custom.css`. Useful for diffing before a write and for handing the existing stylesheet to an LLM as context. Requires plugin v7.0.42+ and the user behind the API key must have the WP `edit_themes` capability. Returns content, content_md5, byte_size, mtime, theme_role (active_stylesheet | active_template | other), is_writable.',
|
|
2107
2088
|
inputSchema: {
|
|
2108
2089
|
type: 'object',
|
|
2109
2090
|
properties: {
|
|
@@ -4379,14 +4360,6 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
4379
4360
|
return await client.getDiviMigrationReadiness();
|
|
4380
4361
|
case 'wordpress_abilities_gap_report':
|
|
4381
4362
|
return await client.getAbilitiesGapReport();
|
|
4382
|
-
case 'wordpress_search_abilities':
|
|
4383
|
-
return await client.searchAbilities({
|
|
4384
|
-
q: args?.q,
|
|
4385
|
-
plugin: args?.plugin,
|
|
4386
|
-
category: args?.category,
|
|
4387
|
-
kind: args?.kind,
|
|
4388
|
-
limit: args?.limit,
|
|
4389
|
-
});
|
|
4390
4363
|
case 'wordpress_invoke_ability':
|
|
4391
4364
|
return await client.invokeInhaledAbility(args?.ability, args?.args || {});
|
|
4392
4365
|
case 'wordpress_list_pages':
|
|
@@ -4921,22 +4894,30 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
4921
4894
|
},
|
|
4922
4895
|
{
|
|
4923
4896
|
name: 'wordpress_move_element',
|
|
4924
|
-
description: 'Move an element to a different container or position within the page.',
|
|
4897
|
+
description: 'Move an element to a different container or position within the page. Locate the element using the same identifier_type/identifier_value pattern as respira_find_element / respira_remove_element. The destination is a container PATH (e.g. "0.1" for sections[0].rows[1], or "root"/empty for top level), not a container element id.',
|
|
4925
4898
|
inputSchema: {
|
|
4926
4899
|
type: 'object',
|
|
4927
4900
|
properties: {
|
|
4928
4901
|
post_id: { type: 'number', description: 'Page/post ID' },
|
|
4929
|
-
|
|
4930
|
-
|
|
4902
|
+
identifier_type: {
|
|
4903
|
+
type: 'string',
|
|
4904
|
+
enum: ['id', 'css_class', 'text', 'widget_type', 'global_id', 'admin_label', 'type', 'path'],
|
|
4905
|
+
description: 'How to locate the element to move (same enum as respira_find_element).',
|
|
4906
|
+
},
|
|
4907
|
+
identifier_value: {
|
|
4931
4908
|
type: 'string',
|
|
4932
|
-
description: '
|
|
4909
|
+
description: 'Value matching identifier_type.',
|
|
4910
|
+
},
|
|
4911
|
+
target_container_path: {
|
|
4912
|
+
type: 'string',
|
|
4913
|
+
description: 'Dot-separated container path inside the target page (e.g. "0.1.0"). Pass "root" or "" to move to the top level.',
|
|
4933
4914
|
},
|
|
4934
4915
|
position: {
|
|
4935
4916
|
type: 'number',
|
|
4936
|
-
description: 'Position index within the target container (0-based)',
|
|
4917
|
+
description: 'Position index within the target container (0-based). Pass -1 to append.',
|
|
4937
4918
|
},
|
|
4938
4919
|
},
|
|
4939
|
-
required: ['post_id', '
|
|
4920
|
+
required: ['post_id', 'identifier_type', 'identifier_value', 'target_container_path', 'position'],
|
|
4940
4921
|
},
|
|
4941
4922
|
},
|
|
4942
4923
|
{
|
|
@@ -5002,19 +4983,22 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5002
4983
|
},
|
|
5003
4984
|
{
|
|
5004
4985
|
name: 'wordpress_reorder_elements',
|
|
5005
|
-
description: 'Reorder child elements within a container.',
|
|
4986
|
+
description: 'Reorder child elements within a container. The container is identified by its PATH inside the page (e.g. "0.1" for sections[0].rows[1], or "root"/"" for the top level).',
|
|
5006
4987
|
inputSchema: {
|
|
5007
4988
|
type: 'object',
|
|
5008
4989
|
properties: {
|
|
5009
4990
|
post_id: { type: 'number', description: 'Page/post ID' },
|
|
5010
|
-
|
|
4991
|
+
container_path: {
|
|
4992
|
+
type: 'string',
|
|
4993
|
+
description: 'Dot-separated container path (e.g. "0.1.0"). Pass "root" or "" for the top-level container.',
|
|
4994
|
+
},
|
|
5011
4995
|
new_order: {
|
|
5012
4996
|
type: 'array',
|
|
5013
|
-
description: 'Array of element IDs in the desired order',
|
|
4997
|
+
description: 'Array of element IDs in the desired order.',
|
|
5014
4998
|
items: { type: 'string' },
|
|
5015
4999
|
},
|
|
5016
5000
|
},
|
|
5017
|
-
required: ['post_id', '
|
|
5001
|
+
required: ['post_id', 'container_path', 'new_order'],
|
|
5018
5002
|
},
|
|
5019
5003
|
},
|
|
5020
5004
|
// --- Composite Tools ---
|