WP Manifestindependent plugin directory
manifest / ai / wordpress-mcp-agent-bridge

Agent Bridge for WordPress releases

WordPress MCP + REST bridge for AI agents — verified Rank Math SEO and schema writes, hashed snapshots, verified restore, additive-only gates. Claude Code, Cursor, any MCP client. Pairs with EMCP.

by Nipun Arora · github.com/nipun-arora/wordpress-mcp-agent-bridge · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/nipun-arora/wordpress-mcp-agent-bridge/archive/refs/heads/main.zip

Readme

Agent Bridge — WordPress MCP for Claude Code and any MCP agent

Agent Bridge is the safety and SEO layer for AI-edited WordPress: it proves every write, snapshots everything it touches, and refuses the writes you didn't authorize. It pairs with EMCP, which does the Elementor editing.

What it is

Agent Bridge is a WordPress MCP for Claude Code and every other MCP client, built for self-hosted WordPress (WordPress.org installs, not WordPress.com) where an AI agent manages a site's SEO, schema, and safety net alongside, or instead of, a human editor in wp-admin. Claude Code is the primary documented client, but nothing here is Claude-specific: Cursor, Windsurf, Codex CLI, Gemini CLI, or any MCP client connects through the same official WordPress MCP Adapter endpoint, and the REST surface needs nothing beyond an Application Password. It's designed to pair with EMCP, the Elementor MCP for Claude Code most agents already reach for on layout work. EMCP edits the page. Agent Bridge never writes _elementor_data at all; what it covers is the layer builder tools consistently skip: Rank Math SEO fields, JSON-LD schema, content snapshots, and a restore that proves it converged.

Every write Agent Bridge makes is read back from the database before it's reported saved. Every page and post gets a stable content hash, so an agent can tell in one request whether anything has changed since it last looked, and a write aimed at content that predates the plugin's own activation is refused unless the caller proves it just captured a fresh snapshot of that exact post. Two kill switches, set in wp-config.php, let an operator take the whole thing offline or lock it to read-only without touching the plugin itself.

Why this exists

Most WordPress MCP servers report a write successful the moment their API returns HTTP 200. Of the safety-focused ones surveyed for this project's own competitive research, none publish a write that reads its own result back from the database before saying so, and none document a hash-verified restore, a proof that a rollback actually converged to what it claims, rather than just a note that a snapshot exists somewhere. See How Agent Bridge compares below for the specific tools, what each documents, and the sources.

A live example of what a capability gap actually costs: in 2026, the AI Engine plugin's MCP module shipped a privilege-escalation flaw that let subscriber-level WordPress accounts hijack MCP-authenticated actions, on more than 100,000 sites (gbhackers.com/over-100000-wordpress-sites-exposed). The root cause was a capability check gap on MCP-authenticated calls: a request carrying a valid credential wasn't also checked against the specific WordPress capability the action required.

Agent Bridge closes that exact class of bug in its route design, not in a promise. Every route scoped to one post checks edit_post for that exact post ID (Agent_Bridge_Auth::can_edit_post()), never the blanket edit_posts grant a lower-privilege account might also hold. Routes that affect the whole site (restore, cache purge, health, the snapshot hash backfill) require manage_options. The Abilities API layer runs the identical checks per ability, not a looser mirror of them (Agent_Bridge_Abilities::permission_*).

Verified Writes

Every SEO field write and every schema write is followed immediately by a fresh get_post_meta() read from the database. A value is only reported saved once that read-back matches what was written, accounting for WordPress's own type coercion (array order, numeric-string image IDs). A caller never has to trust an HTTP 200: if the write-back doesn't match, the route returns a 500 with the field name, the value it tried to write, and what the database actually holds (Agent_Bridge_Seo::write(), Agent_Bridge_Schema::write()).

Stable Content Hash

Every page and post gets one SHA-256 hash, recomputed automatically whenever the post itself, its Elementor data, its bridge-scope SEO fields, or its Rank Math schema meta changes (hooked on save_post and the added_post_meta / updated_post_meta / deleted_post_meta actions in Agent_Bridge_Snapshot::init_hooks()). The hash covers post_content, the verbatim Elementor blob, and the sorted SEO plus schema meta, so one call to /snapshot/manifest tells a caller, for every page and post on the site, whether anything has touched it since the last time the caller looked.

Verified Restore

Restoring a snapshot doc is not "trust this backup." The request has to clear two separate proofs before anything is written. First, the document itself has to be self-consistent: the confirm token sent with the request has to equal the doc's own stated hash, and recomputing that hash from the doc's own content, Elementor data, SEO, and schema fields has to produce the same value (proof the doc is untampered, not just plausible-looking). Second, the caller has to prove it just read the post's real live state, via the same additive-only header the Additive-Only Gate below requires. Only once both gates pass does restore converge the post (content, Elementor data, SEO, and schema) to exactly what the doc says, deleting fields the doc doesn't mention rather than merely patching over them, and it hands back the resulting document so the convergence can be checked directly instead of assumed.

Additive-Only Gate

A write aimed at a post that already existed before Agent Bridge was activated is refused by default, unless the request proves it just captured a fresh snapshot of that exact post by sending the post's current content hash back in an X-Agent-Bridge-Confirm header. Content created after activation is exempt, since there is nothing pre-existing to protect. In practice this means an agent cannot silently overwrite content it never looked at: it has to read a post's real current state first, on every post that predates the plugin. A site can turn this off with the agent_bridge_additive_only filter.

Kill Switches

Two PHP constants, set in wp-config.php and checked before anything else runs. AGENT_BRIDGE_DISABLED makes every route return 503, reads included. AGENT_BRIDGE_READ_ONLY refuses every write, including the snapshot manifest's ?rebuild=1 hash backfill (a write issued over GET, which a naive HTTP-method check would miss), while every read keeps working. Both are config-time switches an operator with server access controls directly; neither is exposed over the API itself.

Write, Purge, Verify

Cache purge is its own route, POST /cache/purge, deliberately not folded into the write routes, because the sequence that matters is write, then purge LiteSpeed's cache, then read back to verify, in that order. Keeping the purge as an explicit step means a verification read right after a write is never served the stale page a cache is still holding.

Abilities API and MCP

When the WordPress Abilities API is present (built into WordPress 6.9+, or added by the standalone mcp-adapter plugin on an older core), Agent Bridge registers eight abilities under an agent-bridge category. WordPress abilities are private by default; every one of these sets meta.public = true, which is what lets the official mcp-adapter surface it as an MCP tool with no separate integration on Agent Bridge's part. Each ability's permission_callback runs the same capability, read-only, and additive-only checks its REST counterpart does, never a looser copy.

Ability Does Type Requires
agent-bridge/get-health Reads Agent Bridge, WordPress, PHP, Elementor, Rank Math, EMCP, and LiteSpeed versions, plus SSL/proxy diagnostics read-only manage_options
agent-bridge/get-seo Reads every Rank Math SEO field set on one post read-only edit_post for that post
agent-bridge/update-seo Writes one or more Rank Math SEO fields, read back and confirmed from the database write edit_post for that post, plus the additive-only gate on posts that predate activation
agent-bridge/get-schema Reads every Rank Math schema (JSON-LD) entry on one post read-only edit_post for that post
agent-bridge/update-schema Writes one schema entry, or deletes it by sending schema: null write, destructive on delete edit_post for that post, plus the additive-only gate on posts that predate activation
agent-bridge/get-snapshot-manifest Lists page/post ids with content hash, paginated; rebuild: true runs one hash-backfill batch instead read-only (write when rebuilding) edit_posts; manage_options when rebuilding
agent-bridge/get-snapshot-items Exports the full snapshot doc (content, Elementor data, SEO, schema, hash) for up to 20 ids read-only edit_posts, plus edit_post per requested id
agent-bridge/purge-cache Flushes LiteSpeed Cache, site-wide or for specific URLs write manage_options

Restore is deliberately not registered as an ability. It stays REST-only, behind its own double confirm-token gate, because its request body (a full snapshot document) doesn't fit the Abilities API's typed input-schema model the way the other seven do.

Agent Bridge composes with Rank Math's own first-party MCP tools (rank-math/get-post-schema and its meta read/write tools, documented at rankmath.com/kb/mcp-tools) rather than replacing them: both surfaces read and write the same stored Rank Math postmeta, so an agent can use whichever one it already has connected. Disable the whole ability surface independently of the REST API with define( 'AGENT_BRIDGE_ABILITIES', false ) in wp-config.php.

Supported SEO fields

GET/POST /posts/{id}/seo cover 15 Rank Math fields. Sending an empty string, empty array, or null for any of them clears that field back to its default, mirroring how Rank Math's own update_metadata() treats an empty value as a delete.

Field Holds
rank_math_title SEO title
rank_math_description Meta description
rank_math_canonical_url Canonical URL
rank_math_robots Robots directives; only noindex, nofollow, noarchive, noimageindex, nosnippet are accepted, since those are the only literal values Rank Math's own UI ever writes to this field
rank_math_focus_keyword Focus keyword, a single comma-separated string, never an array
rank_math_facebook_title Open Graph title override
rank_math_facebook_description Open Graph description override
rank_math_facebook_image Open Graph image URL
rank_math_facebook_image_id Open Graph image attachment ID; must resolve to a real image attachment, since that is what Rank Math's own front end requires to render it
rank_math_twitter_title Twitter card title override
rank_math_twitter_description Twitter card description override
rank_math_twitter_image Twitter card image URL
rank_math_twitter_image_id Twitter card image attachment ID
rank_math_twitter_card_type One of summary, summary_large_image, app, player
rank_math_twitter_use_facebook on to reuse the Facebook/Open Graph fields for Twitter, off or empty otherwise

The *_image_id fields exist alongside the plain *_image URL fields on purpose: Rank Math's front end resolves a custom Open Graph or Twitter image exclusively through the _id field, so writing only the URL is silently ignored by the renderer even though the write itself succeeds and reads back cleanly. Both fields have to be set together for the image to actually show up.

Requirements

  • WordPress 6.9 or later.
  • PHP 8.1 or later.
  • HTTPS. Enforced on every route, proxy-aware (a trusted reverse proxy's X-Forwarded-Proto header counts), refusable only via the agent_bridge_allow_http filter for local development.
  • Rank Math, for the SEO and schema routes specifically. The plugin activates fine without it; those two routes simply have nothing to read or write until it's installed.
  • LiteSpeed Cache, for the /cache/purge route specifically. Every other route works regardless of which cache layer, if any, sits in front of the site.
  • The WordPress Abilities API and the official mcp-adapter plugin, only if you want the eight abilities exposed as MCP tools rather than calling the REST API directly. Neither is required for the REST API itself.

Quickstart

Read the full README on GitHub →

Releases

TagPublished
v1.0.6 Aug 31, 2026
v1.0.5 Aug 31, 2026
v1.0.0 Aug 31, 2026

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.