Settings fixes: - MAX_SITES_PER_USER, USER_RATE_LIMIT_PER_MIN/HR now read from DB settings table (DB > ENV > default), so dashboard/settings changes apply without restart. Sync cache refreshed on every save or delete. - /api/me reports the live DB value for max_sites_per_user. Admin improvements: - Admin users bypass per-user rate limiting entirely (role=admin or ADMIN_EMAILS). - Admin Overview now shows platform stats: registered users, new users (7d), total user sites, available tools. Plugin cleanup: - Appwrite and Directus plugins removed from the active registry (8 plugins now: WordPress, WooCommerce, WordPress Specialist, Gitea, n8n, Supabase, OpenPanel, Coolify). Plugin code is retained for future re-enabling. - Settings page plugin visibility list updated to match. Mobile onboarding: - Stepper steps on narrow viewports stack vertically with correct full border and rounded corners on each step. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
33 KiB
Airano MCP Bridge
Version: 2.18.0
Requires WordPress: 5.0+
Tested up to: 6.9
Requires PHP: 7.4+
License: GPLv2 or later
Plugin slug: airano-mcp-bridge (permanent)
Companion plugin for MCP Hub — the AI-native management hub for WordPress, WooCommerce, and self-hosted services.
What this plugin does
MCP Hub lets AI assistants (Claude, ChatGPT, Cursor, VS Code Copilot, …) manage your WordPress site through the Model Context Protocol. The core features work against the stock /wp-json/wp/v2/ REST endpoints — you do not need this plugin to use MCP Hub.
Installing Airano MCP Bridge unlocks a second tier of capabilities that WordPress's built-in REST API can't reach on its own:
- Large-file uploads that bypass
upload_max_filesize - One-round-trip upload + metadata + attach + set-featured (v2.9.0)
- Thumbnail regeneration (no WP-CLI / SSH)
- Cache purge for 6 major cache plugins (LiteSpeed, WP Rocket, W3TC, WP Super Cache, WP Fastest Cache, SG Optimizer)
- Transient cleanup (expired / all / pattern)
- Bulk post-meta writes in a single REST round-trip
- Unified site-health snapshot (5+ stock calls → 1)
- Structured JSON export (posts / pages / products + media + terms + meta)
- Capability probe — tells MCP Hub what the calling application password can actually do
- Audit hook — forwards WordPress action events to MCP Hub with HMAC-signed webhooks
- SEO meta routes for Rank Math and Yoast
- WordPress Specialist admin namespace (v2.11.0+) — read-only inventory of plugins, themes, users, options, cron, maintenance status. Powers the
wordpress_specialistMCP plugin so admins on shared hosting can use the same tools that previously required Docker socket + WP-CLI. - System diagnostics (v2.12.0) —
system-info,phpinfo(curated, not the full HTML dump),disk-usage(bounded directory walks). - Page editing (v2.13.0) — Gutenberg block read/replace/insert/remove, Elementor detect/get/set/regen-css/template-list/template-apply, Classic-editor html replace. Writes are double-gated:
manage_optionsroute-level + per-postedit_postenforcement; raw HTML requiresunfiltered_html; Elementor JSON capped at 5,000 nodes per call. - Theme dev surface (v2.14.0) — install (from URL or base64 zip) / activate / delete + theme file CRUD (list, read, write, delete). All theme paths canonicalise via
realpath()and reject any escape from the slug directory. PHP file writes additionally require!DISALLOW_FILE_EDIT. Optimistic concurrency viaexpected_sha256on writes. Per-call caps 5 MB/file, 1000 files/list, 50 MB/install zip. Refuses to delete the active theme (or its parent) andstyle.cssof the active theme. - Plugin write management (v2.15.0) — install (from wp.org slug, URL, or base64 zip) / activate / deactivate / update / delete. Per-route capability checks (
install_plugins,activate_plugins,delete_plugins). Refuses to deactivate or delete the companion plugin itself (would brick the MCP connection) and refuses to delete active plugins. Update route returnsup_to_date:truecleanly when no update is available. - Site config (v2.16.0) — Settings → General + Reading + Permalinks panels via typed REST.
GET/POST /admin/site/identity(title / tagline / site_icon / custom_logo),GET/POST /admin/site/reading(show_on_front / page_on_front / page_for_posts / posts_per_page / blog_public),GET/POST /admin/permalinks(structure + category_base + tag_base, withflush_rewrite_rules()after each write). - Site layout (v2.17.0) — Settings → Menus + Appearance → Widgets + Customizer surfaces. Menus:
GET /admin/menus,GET /admin/menus/{id},PUT /admin/menus/{id}(full-replace items + optional rename, slug stays frozen, S-22 per-item cap dispatch). Widgets:GET /admin/widgets/areas,GET /admin/widgets/{area_id},PUT /admin/widgets/{area_id}(block-kind areas accept any block raw HTML; legacy areas accepttextwidget settings only this round). Customizer:POST /admin/customizer/changesetwith{action: get|apply|discard}— single-tool wrapper around the changeset queue;applyrequires thecustomizecap (S-24). - Database inspection (v2.18.0) — read-only DB introspection via typed routes that NEVER expose raw SQL.
GET /admin/db/size(singleinformation_schema.TABLESaggregation: database_bytes + table_count + row_count_estimate),GET /admin/db/tables(per-table breakdown),POST /admin/db/search(WP_Querywrapper withs=$query; sanitised + length-capped at 200 chars; S-25 keeps non-readable posts out viaWP_Query's ownposts_clauses). Bundled with the wordpress_advanced sunset on the MCP Hub side: the deprecated WP-CLI/Docker-socket plugin was removed in F.19.3.2-.3;wordpress_specialistis now the only WP-management surface and has no Docker socket dependency.
All operations remain guarded by WordPress's own capability system — this plugin never bypasses auth.
Installation
- Download
airano-mcp-bridge.zipfrom the MCP Hub release page. - In WP Admin → Plugins → Add New → Upload Plugin, choose the zip and Activate.
- Generate an Application Password under Users → Profile (scroll to bottom).
- In MCP Hub dashboard → My Sites, add your WordPress site using that Application Password.
The plugin works out of the box. There are no settings pages to configure; behavior is controlled entirely through the REST API.
REST API endpoints
SEO meta (namespace airano-mcp-bridge/v1)
GET / POST /posts/{id}/seo— Post SEO data (Rank Math or Yoast, auto-detected)GET / POST /pages/{id}/seo— Page SEO dataGET / POST /products/{id}/seo— WooCommerce product SEO dataGET /status— Plugin status + active SEO plugins list
MCP Bridge helpers (namespace airano-mcp/v1)
| Route | Method | Introduced | Purpose |
|---|---|---|---|
/upload-limits |
GET | 2.0.0 | Returns effective PHP + WP upload limits so MCP Hub can pick the right upload path |
/upload-chunk |
POST | 2.0.0 | Raw-body upload that bypasses upload_max_filesize (still bounded by post_max_size) |
/upload-and-attach |
POST | 2.9.0 | Same as /upload-chunk plus query-param metadata (attach_to_post, set_featured, title, alt_text, caption, description) — collapses 3 REST round-trips into 1 |
/capabilities |
GET | 2.1.0 | Effective capabilities of the calling Application Password + feature flags + available routes |
/bulk-meta |
POST | 2.2.0 | Batch post_meta writes in one request (max 500 items, per-item permission check) |
/export |
GET | 2.3.0 | Structured JSON export of posts / pages / products + media + terms + meta, with post_type / status / since / limit / offset paging |
/cache-purge |
POST | 2.4.0 | Auto-detects LiteSpeed, WP Rocket, W3 Total Cache, WP Super Cache, WP Fastest Cache, SiteGround Optimizer and triggers each one's purge API; always flushes object cache |
/transient-flush |
POST | 2.5.0 | Native transient cleanup with expired / all / pattern scopes; optional site-transient handling for multisite |
/site-health |
GET | 2.6.0 | Single-envelope health snapshot: WP/PHP/MySQL versions, disk free, active plugins, theme, writability, SSL — replaces 5+ stock calls |
/audit-hook |
GET / POST / DELETE | 2.7.0 | Configure a webhook that forwards WP action events to MCP Hub. HMAC-SHA256-signed, non-blocking |
/regenerate-thumbnails |
POST | 2.8.0 | Rebuild attachment sub-sizes via wp_generate_attachment_metadata() for a list of IDs or in paged batch mode |
WordPress Specialist admin namespace (airano-mcp/v1/admin/*)
All routes require manage_options. They power the wordpress_specialist MCP plugin (companion-backed advanced WordPress management — no Docker socket required).
| Route | Method | Introduced | Purpose |
|---|---|---|---|
/admin/plugins |
GET | 2.11.0 | Every plugin known to WP with active/network-active/version/author/update flags |
/admin/themes |
GET | 2.11.0 | Installed themes with stylesheet/template/parent/block-theme/active flags |
/admin/users |
GET | 2.11.0 | Paginated user list (cap 200/call) with optional role and search filters |
/admin/options/{name} |
GET | 2.11.0 | Single option fetch with deny-list of credential-shaped keys (*_secret, *_password, *_api_key, *_token, auth_*_key, auth_*_salt) |
/admin/cron |
GET | 2.11.0 | Full cron table with epoch + ISO 8601 next_run, schedule slug, interval, args |
/admin/maintenance |
GET | 2.11.0 | .maintenance sentinel inspection (enabled / started_at / stale, 10-min stale threshold matches WP) |
/admin/system-info |
GET | 2.12.0 | WP/PHP/MySQL/server versions + memory + paths in one envelope |
/admin/phpinfo |
GET | 2.12.0 | Sorted extension list + curated ini whitelist + disabled functions + opcache state (structured JSON, not the full HTML dump) |
/admin/disk-usage |
GET | 2.12.0 | Bytes for uploads/plugins/themes + filesystem disk_total/free/used (bounded 200k files / 5s per tree, with truncated:true flag) |
/admin/blocks/replace |
POST | 2.13.0 | Replace post block tree (companion runs serialize_blocks(); max 200 blocks; wp_kses_post unless caller has unfiltered_html) |
/admin/blocks/insert |
POST | 2.13.0 | Insert one block at index N |
/admin/blocks/remove |
POST | 2.13.0 | Remove block at index N (returns the removed block for rollback) |
/admin/elementor/status |
GET | 2.13.0 | Elementor presence + version + Pro flag + supported post types; installed:false cleanly when absent |
/admin/elementor/{post_id} |
GET | 2.13.0 | Parsed _elementor_data (slash-stripped, JSON-decoded) |
/admin/elementor/{post_id} |
POST | 2.13.0 | Replace _elementor_data; validates id/elType/settings; capped at 5,000 nodes; fires elementor/document/after_save |
/admin/elementor/{post_id}/regen-css |
POST | 2.13.0 | Trigger per-post Elementor CSS regeneration |
/admin/elementor/templates |
GET | 2.13.0 | Saved Elementor templates (id/title/type/modified) |
/admin/elementor/templates/apply |
POST | 2.13.0 | Copy a saved template's _elementor_data into a target post |
/admin/classic/{post_id}/replace |
POST | 2.13.0 | Pure post_content swap for classic-editor sites (wp_kses_post unless caller has unfiltered_html) |
/admin/themes/install |
POST | 2.14.0 | Install theme from zip_url or base64 zip_base64; supports activate, overwrite. Runs WP core's Theme_Upgrader. Requires install_themes (+ switch_themes if activate). 50 MB cap. |
/admin/themes/{slug}/activate |
POST | 2.14.0 | Switch the active theme. Requires switch_themes. |
/admin/themes/{slug} |
DELETE | 2.14.0 | Delete an installed theme. Refuses if active or active parent. Requires delete_themes. |
/admin/themes/files/{slug} |
GET | 2.14.0 | Theme directory walk: each file's relative path, size, mime, sha256, modified_at. Optional glob + max_files (cap 1000). |
/admin/themes/files/{slug}/{path} |
GET | 2.14.0 | Read a theme file as base64 + sha256 + mime + modified_at. 5 MB cap. |
/admin/themes/files/{slug}/{path} |
PUT | 2.14.0 | Write a theme file (base64). Optional expected_sha256 for optimistic concurrency. PHP writes require !DISALLOW_FILE_EDIT. Requires edit_themes. 5 MB cap. |
/admin/themes/files/{slug}/{path} |
DELETE | 2.14.0 | Delete a theme file. Refuses to delete style.css of the active theme. Requires edit_themes. |
/admin/plugins/install |
POST | 2.15.0 | Install via wp.org slug, OR via zip_url, OR via inline zip_base64. Supports activate + overwrite. Runs WP core's Plugin_Upgrader. Requires install_plugins. 50 MB zip cap. |
/admin/plugins/{slug}/activate |
POST | 2.15.0 | Activate an installed plugin. Optional network_wide for multisite. Requires activate_plugins. |
/admin/plugins/{slug}/deactivate |
POST | 2.15.0 | Deactivate. Refuses companion (S-20) and Required plugins (S-21). Requires activate_plugins. |
/admin/plugins/{slug}/update |
POST | 2.15.0 | Update to latest wp.org version. Returns up_to_date:true cleanly when no update available. Requires update_plugins. |
/admin/plugins/{slug} |
DELETE | 2.15.0 | Delete an installed plugin. Refuses active plugins, the companion, and Required plugins. Requires delete_plugins. |
/admin/site/identity |
GET | 2.16.0 | Site title / tagline / site_icon / custom_logo / charset / WP version / admin_email / language / siteurl. |
/admin/site/identity |
POST | 2.16.0 | Update title / tagline / site_icon_id / custom_logo_id (any subset). Attachment ids validated against the media library. |
/admin/site/reading |
GET | 2.16.0 | show_on_front / page_on_front / page_for_posts / posts_per_page / posts_per_rss / blog_public. |
/admin/site/reading |
POST | 2.16.0 | Update reading settings; page_on_front + page_for_posts must reference published Pages. |
/admin/permalinks |
GET | 2.16.0 | permalink_structure + category_base + tag_base. |
/admin/permalinks |
POST | 2.16.0 | Update permalink structure (empty string = plain). Calls flush_rewrite_rules() after the write. |
/admin/menus |
GET | 2.17.0 | Every nav menu with id / name / slug / theme locations / item count. |
/admin/menus/{menu_id} |
GET | 2.17.0 | One menu's items: {id, title, type, object, object_id, parent, order, url, target, classes, xfn}. |
/admin/menus/{menu_id} |
PUT | 2.17.0 | Full-replace items + optional rename. Slug frozen. Two-pass: every item validated against S-22 before any mutation; refusals return forbidden_object_id 403/404 and leave the menu untouched. |
/admin/widgets/areas |
GET | 2.17.0 | Every registered sidebar with id / name / theme_location / widget_count / kind (block or legacy). |
/admin/widgets/{area_id} |
GET | 2.17.0 | One area's widgets. Block-kind: {id, type:'block', blocks:[parsed], raw}. Legacy-kind: {id, type, settings}. |
/admin/widgets/{area_id} |
PUT | 2.17.0 | Full replace. Block areas accept any block raw HTML; legacy areas accept text widget settings only this round (other legacy types remain read-only). HTML sanitised via wp_kses_post unless caller has unfiltered_html (S-23). |
/admin/customizer/changeset |
POST | 2.17.0 | `{action: get |
/admin/db/size |
GET | 2.18.0 | Aggregate database size from information_schema.TABLES: {database_bytes, table_count, row_count_estimate, database_name, table_prefix}. No SQL exposure. |
/admin/db/tables |
GET | 2.18.0 | Per-table breakdown: {name, engine, rows, data_bytes, index_bytes, total_bytes, collation} ordered by total_bytes desc. |
/admin/db/search |
POST | 2.18.0 | WP_Query wrapper. Body {query, post_type?, status?, limit?} (limit default 20, max 100). Sanitises + length-caps query at 200 chars (S-25). Non-readable posts filtered out via WP's own posts_clauses. Never raw SQL. |
Writes added in 2.13.0 require two capabilities: route-level manage_options AND per-post edit_post on the target (S-12 in MCP Hub's security ruleset). Raw-HTML pass-through requires the calling user to also hold unfiltered_html. Elementor JSON node count is capped at 5,000 per call (S-14); oversized payloads return elementor_too_large — switch to /admin/elementor/templates/apply instead.
Theme dev routes added in 2.14.0 layer per-route capability checks on top of manage_options: install_themes, switch_themes, delete_themes, edit_themes. PHP file writes additionally require !DISALLOW_FILE_EDIT (S-17). All file paths canonicalise via realpath() and must resolve under wp-content/themes/{slug} (S-16); attempts to escape return path_invalid. Optimistic concurrency via expected_sha256 returns sha_mismatch (409) if the on-disk sha256 differs (S-19).
Plugin write routes added in 2.15.0 layer per-route capability checks on manage_options: install_plugins (install / update), activate_plugins (activate / deactivate), delete_plugins (delete). New rules: S-20 refuses to deactivate / delete the Airano MCP Bridge companion itself (returns companion_self 409 — would brick the MCP connection); S-21 refuses to deactivate / delete plugins whose header sets Required: yes. The single POST /admin/plugins/install route accepts three mutually-exclusive body shapes — {slug} for wp.org install, {zip_url} for download, {zip_base64} for inline — with the same 50 MB cap (S-18) on zip payloads. Delete refuses any plugin currently active (plugin_active 409 — caller must deactivate first).
Authentication
All routes require HTTP Basic authentication with a WordPress Application Password (Users → Profile → Application Passwords). Per-route capability requirements:
| Route family | Required capability |
|---|---|
| SEO meta (read/write) | edit_posts |
| Upload helpers | upload_files or manage_options |
| Capabilities probe | read (any logged-in user) |
| Bulk meta, Export | edit_posts (per-item edit_post check) |
| Cache purge, Transient flush, Site health, Audit hook, Regenerate thumbnails | manage_options |
Admin namespace (/admin/*) |
manage_options |
Privacy
This plugin makes no outbound network calls on its own. It exposes authenticated REST API endpoints that your MCP Hub instance calls into. The audit-hook route only sends webhooks when you explicitly configure it (POST to /audit-hook with an endpoint URL + secret); without that configuration, zero telemetry leaves your WordPress.
No analytics, no phone-home, no cloud relay.
Security notes
- All write routes enforce capability checks.
- Raw-body uploads go through
wp_handle_sideload()which respects WordPress's allowed-MIME list. - Bulk meta writes check
current_user_can('edit_post', $post_id)per item, not just per batch. - Audit-hook secrets are stored in
wp_optionsand never echoed in responses (only the last 4 characters are returned on read). - Audit-hook webhooks are signed with HMAC-SHA256 so MCP Hub can verify the message came from your site and hasn't been tampered with.
If you find a security issue, please report it privately to the maintainers at the GitHub issues page rather than filing a public issue.
Frequently asked questions
Do I need MCP Hub to use this plugin?
No. Every route is a standard authenticated WordPress REST endpoint and can be called from any HTTP client (curl, Postman, a custom integration). MCP Hub is the reference consumer but not a requirement.
Which SEO plugins are supported?
Rank Math SEO and Yoast SEO. The plugin auto-detects which is active and routes SEO-meta calls accordingly.
Does this plugin work on multisite?
Yes. Route registration, capability checks, and transient flushing all respect multisite boundaries. The optional include_site_transients flag on /transient-flush handles site transients on multisite setups.
Why keep the folder name airano-mcp-bridge even though the plugin now does much more than SEO?
Plugin slugs on WordPress.org are permanent once registered. Existing installs keep working; display name, description, and feature surface are what we can update.
What happens if I uninstall?
Uninstall removes plugin options including the audit-hook secret and endpoint. Media uploaded via the plugin stays in your media library (it's regular WordPress attachments — the plugin just provides the upload pipeline).
How large a file can I upload?
The /upload-chunk route bypasses PHP's upload_max_filesize (typically 2–64 MB on shared hosting), but is still bounded by post_max_size and memory_limit. For files larger than post_max_size, MCP Hub falls back to its own server-side chunked session pipeline that reassembles chunks before handing the full file to this route.
Changelog
2.18.0 — 2026-05-04
- F.19.3.2-.3: Database inspection (read) + bulk fan-out (write) + wordpress_advanced sunset. Three new admin routes —
GET /admin/db/size(singleinformation_schema.TABLESaggregation, returns{database_bytes, table_count, row_count_estimate, database_name, table_prefix}— no SQL exposure),GET /admin/db/tables(per-table breakdown with name / engine / rows / data_bytes / index_bytes / total_bytes / collation, ordered by total_bytes desc),POST /admin/db/search(body{query, post_type?, status?, limit?}— wrapsWP_Querywiths=$query, sanitises viasanitize_text_fieldand length-caps at 200 chars server-side,limitcapped at 100; returns{query, limit, count, hits}). New security rule S-25: db/search wrapsWP_Query, NEVER raw SQL;WP_Query's ownposts_clausesfilter (the same gate the WP search page uses) keeps non-readable posts (private/draft from other authors) out of the result set. Bulk write tools on the MCP Hub side (wp_bulk_post_update,wp_bulk_term_update) ride stock RESTwp/v2/posts/{id}andwp/v2/{taxonomy}/{id}— no companion routes needed for those, but the cap of 50 items per call is documented under S-26 in the MCP Hub spec. All admin routes gated onmanage_optionsroute-level. Bundled with the wordpress_advanced sunset on the MCP Hub side: the deprecated WP-CLI/Docker-socket plugin was removed in F.19.3.2-.3 (2026-05-04);wordpress_specialistis now the only WP-management surface and has no Docker socket dependency.
2.17.0 — 2026-05-03
- F.19.6.B: Site layout (menus + widgets + customizer). Seven new admin routes — three for menus, three for widgets, one for the customizer changeset queue. Menus:
GET /admin/menus,GET /admin/menus/{id},PUT /admin/menus/{id}(body{items:[...], name?}— full replace, items not in the array are deleted, slug stays frozen sotheme_locationmapping survives). Widgets:GET /admin/widgets/areas(each area carrieskind: 'block'|'legacy'),GET /admin/widgets/{area_id}(block-kind returns parsed block tree + roundtrip-saferaw; legacy-kind returns option-keyed settings),PUT /admin/widgets/{area_id}(block areas accept any block raw HTML; legacy areas accepttextwidget settings only this round — other legacy types remain read-only and returnunsupported_legacy_widget; caller-sidekindis ignored, area kind is determined by the area itself). Customizer:POST /admin/customizer/changesetwith{action: get|apply|discard}— single-tool wrapper around the changeset queue, intentionally limited because most modern themes use FSE/site-editor instead of the customizer. New security rules: S-22 dispatches per nav-menu item type —post_typecheckscurrent_user_can('read_post', id);taxonomyallows public taxonomies and otherwise requires the taxonomy'sassign_termscap (deliberately NOTmanage_categorieswhich is a write cap and would refuse routine "add public Category X to footer" flows for editors who don't manage taxonomies);customURL items skip the object validation. Refusals surface asforbidden_object_id403/404. S-23 sanitises widget HTML viawp_kses_postunless the caller hasunfiltered_html(mirrors S-13 from F.19.5). S-24 customizer apply requires thecustomizecap on top ofmanage_options— same bar as/wp-admin/customize.php. All routes gated onmanage_optionsroute-level. Pre-validates every menu item before mutating so a partial S-22 failure leaves the menu untouched. Customizer apply is racy with concurrent edits via the customizer UI — intentional, mirrors WP behaviour.
2.16.0 — 2026-05-03
- F.19.6.A: Site config surface. Six new admin routes covering Settings → General + Reading + Permalinks:
GET/POST /admin/site/identity(title / tagline / site_icon / custom_logo),GET/POST /admin/site/reading(show_on_front / page_on_front / page_for_posts / posts_per_page / posts_per_rss / blog_public),GET/POST /admin/permalinks(permalink_structure + category_base + tag_base). All gated onmanage_options. POST routes validate attachment ids against the media library, reject non-published page ids for page_on_front / page_for_posts, and route every option write through WP's ownsanitize_option_*hooks. After a permalink_structure writeflush_rewrite_rules()runs so the new structure takes effect immediately. First consumer of thesettingstier introduced by F.19.2.0.
2.15.0 — 2026-05-02
- F.19.2.1: Plugin write management. Five new admin routes —
POST /admin/plugins/install(accepts{slug}for wp.org install OR{zip_url|zip_base64}for arbitrary zip; supportsactivate+overwrite),POST /admin/plugins/{slug}/activate,POST /admin/plugins/{slug}/deactivate,POST /admin/plugins/{slug}/update,DELETE /admin/plugins/{slug}. Per-route capability checks:install_plugins(install / update),activate_plugins(activate / deactivate),delete_plugins(delete). New security rules: S-20 refuses to deactivate / delete the Airano MCP Bridge companion itself (returnscompanion_self409 — operator must use WP-Admin → Plugins instead); S-21 refuses to deactivate / delete plugins markedRequired: yesin their header. Reuses S-15 (slug whitelist viaget_plugins()) + S-18 (50 MB cap on install zip). Refuses to delete an active plugin (caller must deactivate first). Update route returnsup_to_date:truecleanly when no update is available. Multisite supportsnetwork_wideactivation/deactivation (requiresmanage_network_pluginsfor activate).
2.14.0 — 2026-05-02
- F.19.7: Theme dev surface (install + activate + delete + file CRUD). Three theme management routes —
POST /admin/themes/install(accepts eitherzip_urlor inlinezip_base64; runs WP core'sTheme_Upgrader; supportsactivate+overwrite),POST /admin/themes/{slug}/activate,DELETE /admin/themes/{slug}— and four file CRUD routes —GET /admin/themes/files/{slug}(glob walk capped at 1000 files, returnspath/size/mime/sha256/modified_atper entry),GET /admin/themes/files/{slug}/{path}(read as base64),PUT /admin/themes/files/{slug}/{path}(write with optionalexpected_sha256for optimistic concurrency andcreate_dirs),DELETE /admin/themes/files/{slug}/{path}. Per-route capability checks:install_themes,switch_themes,delete_themes,edit_themes. PHP file writes additionally require!DISALLOW_FILE_EDIT(S-17). All file paths canonicalise viarealpath()and must stay underwp-content/themes/{slug}(S-16). Per-call caps: 5 MB/file, 1000 files/list, 50 MB/install zip (S-18). Optimistic concurrency onexpected_sha256returnssha_mismatch(409) on drift (S-19). Refuses to delete the active theme, the active parent theme, orstyle.cssof the active theme.
2.13.0 — 2026-05-01
- F.19.5: Page editing surface (Gutenberg + Elementor + Classic). Seven new write routes —
POST /admin/blocks/{replace,insert,remove},POST /admin/elementor/{post_id}(set),POST /admin/elementor/{post_id}/regen-css,POST /admin/elementor/templates/apply,POST /admin/classic/{post_id}/replace— and three new read routes —GET /admin/elementor/status,GET /admin/elementor/{post_id},GET /admin/elementor/templates. Writes requiremanage_optionsAND per-postedit_post(S-12); block + classic content sanitised viawp_kses_postunless caller hasunfiltered_html(S-13); Elementor JSON node count capped at 5,000 per call (S-14). All Elementor writes fireelementor/document/after_saveso caches and CSS regenerate cleanly.
2.12.0 — 2026-05-01
- F.19.3.1: System diagnostic ports from
wordpress_advanced. Three more read-only admin routes —GET /admin/system-info,GET /admin/phpinfo,GET /admin/disk-usage— replace the legacy WP-CLI / Docker-socket flow so admins on shared hosting can use those tools too. All gated onmanage_options.phpinforeturns curated structured JSON (extension list + ini whitelist + opcache state), never the fullphpinfo()HTML dump (which would leak server internals).disk-usagewalks bounded at 200k files / 5s per tree.
2.11.0 — 2026-05-01
- F.19.1: Read-only admin namespace. Six new routes under
airano-mcp/v1/admin/*—plugins,themes,users,options/{name},cron,maintenance— gated onmanage_options.optionsroute uses a deny-list of credential-shaped suffixes on top of the cap check.usersroute paginates up to 200/call with optionalrole+searchfilters. No state changes; write operations land in F.19.2.
2.9.0 — 2026-04-16
- New:
POST /airano-mcp/v1/upload-and-attach— raw-body upload + metadata (title / alt / caption / description) + attach-to-post + set-featured in a single REST round-trip. Saves 2–3 calls for every hero-image or product-image workflow. Per-target permission enforced viacurrent_user_can('edit_post', attach_to_post). - Status + capabilities payloads now advertise
upload_and_attach: true+regenerate_thumbnails: true.
2.8.0 — 2026-04-15
- New:
POST /airano-mcp/v1/regenerate-thumbnails— rebuild attachment sub-sizes viawp_generate_attachment_metadata()after uploads, theme switches, or format conversions. Two modes:{ "ids": [...] }for targeted regeneration (max 50/call) or{ "all": true, "offset": N, "limit": M }for paged batches.
2.7.0
- New:
GET|POST|DELETE /airano-mcp/v1/audit-hook— configure a webhook that forwards WP action events (transition_post_status,deleted_post,user_register,profile_update,deleted_user,activated_plugin,deactivated_plugin,switch_theme) to MCP Hub. HMAC-SHA256-signed, non-blockingwp_remote_post. Permission:manage_options.
2.6.0
- New:
GET /airano-mcp/v1/site-health— single-envelope snapshot: WP version / multisite / locale, PHP version + extensions, server software + disk free, MySQL/MariaDB version + charset, active plugins + theme, writability checks (wp-content, uploads) + SSL.
2.5.0
- New:
POST /airano-mcp/v1/transient-flush— native transient cleanup. Scopes:expired(default),all, orpattern(glob match, e.g.rank_math_*). Optionalinclude_site_transientsfor multisite.
2.4.0
- New:
POST /airano-mcp/v1/cache-purge— auto-detects active page-cache plugins (LiteSpeed, WP Rocket, W3 Total Cache, WP Super Cache, WP Fastest Cache, SiteGround Optimizer) and invokes each one's purge API. Always callswp_cache_flush()for object caches.
2.3.0
- New:
GET /airano-mcp/v1/export— structured JSON export (not WXR). Query params:post_type,status,since,limit(max 500),offset,include_media,include_terms,include_meta.
2.2.0
- New:
POST /airano-mcp/v1/bulk-meta— batch post-meta writes (max 500 items per call). Per-item permission check viacurrent_user_can('edit_post', $post_id). Null meta values delete the key.
2.1.0
- New:
GET /airano-mcp/v1/capabilities— reports the effective capabilities of the calling Application Password plus feature flags (Rank Math / Yoast / WooCommerce / multisite) and the list of companion routes this version ships. Consumed by MCP Hub's F.7e capability probe.
2.0.0
- Rebrand: "Airano MCP SEO Meta Bridge" → "Airano MCP Bridge". No longer SEO-only.
- New:
GET /airano-mcp/v1/upload-limits— returns effective PHP + WP upload limits. - New:
POST /airano-mcp/v1/upload-chunk— raw-body upload route that bypassesupload_max_filesize.
1.3.0
- Added REST API endpoints for posts, pages, and products (GET/POST operations).
- Added authentication requirement for all endpoints (edit_posts).
- Fixed
rank_math_titlemeta key registration.
1.2.0
- Enhanced WooCommerce product support.
- Improved MariaDB compatibility.
1.1.0
- Added status endpoint for plugin detection.
- Improved error handling.
1.0.0
- Initial release with Rank Math and Yoast SEO support.
Upgrade notice
2.16.0
Adds the F.19.6.A site config surface (6 new admin routes — identity / reading / permalinks). All gated on manage_options. Permalink writes flush rewrite rules automatically. No breaking changes; existing routes unchanged.
2.15.0
Adds the F.19.2.1 plugin write management surface (5 new admin routes — install / activate / deactivate / update / delete). Per-route checks for install_plugins / activate_plugins / delete_plugins. Refuses to deactivate or delete the companion plugin itself. No breaking changes; existing routes unchanged.
2.14.0
Adds the F.19.7 theme dev surface (7 new admin routes — install / activate / delete + file CRUD). Per-route checks for install_themes / switch_themes / delete_themes / edit_themes; PHP file writes additionally require !DISALLOW_FILE_EDIT. No breaking changes; existing routes unchanged.
2.13.0
Adds the F.19.5 page editing surface (10 new admin routes — Gutenberg blocks, Elementor read/write/template, Classic html replace). Writes require manage_options AND per-post edit_post; raw-HTML pass-through is gated on unfiltered_html. No breaking changes; existing routes unchanged.
2.9.0
Adds POST /airano-mcp/v1/upload-and-attach — upload + metadata + attach + featured in one REST round-trip. No breaking changes to existing routes.
Credits
Built by the MCP Hub project. Contributions welcome — see the parent repository for contribution guidelines.