WordPress Block MCP
About
Block MCP is the WordPress MCP built for the way agents actually edit: one block at a time, across multiple turns, without corrupting the page.
Details
- Author
- gravitykit
- Categories
- Marketing, Other
Jump to
Setup
Install WordPress Block MCP in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/gravitykit/block-mcp
Follow the installation instructions in the repository README, then restart your MCP client.
Block MCPis the WordPress MCP built for the way agents actually edit — one block at a time, across multiple turns, without corrupting the page. It's an MCP server plus WordPress plugin that exposes Gutenberg content as a structured, addressable block tree instead of raw HTML, so an agent can change a single heading without rewriting the page. Every block carries a stablegk_refUUID that survives sibling shifts (no other WordPress MCP has this), so multi-turn edit chains don't re-fetch the page between calls. Every write creates a WordPress revision for rollback, ETag/If-Match guards against concurrent overwrites, and a server-side tier policy stops legacy blocks from ever hitting disk. Backed by326 PHP tests, 249 TypeScript tests, CI on PHP 8.2/8.3 + Node 20, and translations to 20 languages.
- Edits one block, not the whole page.Change a heading's level without touching the surrounding HTML. Standard MCPs force a full page rewrite on every edit; Block MCP touches just the one heading.
- Editor-safe round-trips.<!-- wp: -->block markers are preserved exactly. No "this block contains unexpected or invalid content" warnings on reopen.
- Stable block refs no other WordPress MCP has.Quickly chain inserts, deletes, and updates across turns from a single read.
- Atomic batch edits.Fix N independent blocks inonerevision withupdate_blocks— all-or-nothing validation, so a stale ref or out-of-range index aborts the whole batch before anything hits disk. Keeps revision history clean instead of 6 entries for one logical change.
- Tier policy enforced server-side.Decide what blocks you want to allow or reject before they are saved, with suggested replacements.
- Optimistic concurrency built in.Two agents working on the same post can't silently overwrite each other.
- Yoast SEO support built in.Read and write Yoast meta (titles, descriptions, focus keywords, canonical URLs, schema types, primary terms, Open Graph / Twitter cards) the moment Yoast SEO is active on the site.
- The numbers
- When you actually ask an AI to edit a page
- 1. Install the WordPress plugin
- 2. Connect your AI assistant
- 3. Manual setup (advanced)
- 4. (Optional) Tune the settings
- Namespace tier scores
- Replacement map
- Blocks that store data in two places
- Post types AI agents can create
- Storage-mode scan + reset
Here's where Block MCP wins. Most other WordPress MCPs are wrappers around the standard WordPress REST API — fine for writing, but wrong for editing. "Change a heading, then add a button, then fix the next paragraph" could result in your post needing major rehab to get back to correct syntax. Block MCP is the answer to an WordPress block editor MCP thatjust works.
When you actually ask an AI to edit a page
What matters is whether the page is correct after the agent finishes. So we put Claude in front of each MCP, typed a real instruction —"change the H2 heading 'Code samples' to H3"— then re-opened the page and inspected it.
27 runs total: three MCP servers × Haiku, Sonnet, Opus × 3 trials each.
Block MCP works on the cheapest model — and finishes fastest.Haiku passes every trial in 10 seconds. The agent doesn't need to think hard about the page because the API is shaped exactly like the task. AI Engine Pro on Haiku takes 44 seconds when it works at all; InstaWP never does.
InstaWP's wp/v2 wrapper fails 7 out of 9 times — even Opus only gets it right 2/3.When the agent reports success, it's technically right that the heading text changed. But the whole-page round-trip throughupdate_pagestrips every<!-- wp: -->block marker. Reopen the page in the block editor and you'll see "This block contains unexpected or invalid content" warnings on most blocks. The standard REST API isn't broken — it does exactly what it's documented to do — but its data shape lets the AI corrupt content without realizing it.
AI Engine Pro is competitive with Sonnet and Opus but stumbles on Haiku.Itswp_alter_posttool is block-aware (the post markup stays valid), but on the failed Haiku trials the rendered HTML and the block's declared attributes drift out of sync — e.g., the comment marker still sayslevel: 2while the inner tag is<h3>. The block editor flags that as broken too. Sonnet and Opus retry until consistent (2–3 tool calls); Haiku sometimes gives up after declaring success.
Reproduce withscripts/mcp-agent-bench.mjs.
Now try the structural ops agents actually need
A single heading-level change is the easy case. The interesting work is when an agent has to move a block, drop a paragraph inside an existing container, modify a table, or delete a block — the kind of multi-step structural editing real content workflows demand.
Five harder scenarios. Same matrix: three MCPs × Claude Haiku.
Block MCP averages 13 seconds and two tool calls per scenario.The agent reads the page once, finds the target block by ref or path, calls one mutation, done.
AI Engine Pro keeps the page intact and finishes correctly,about 2× slower. Itswp_alter_posttool asks the agent to supply both the block-comment markup and the rendered HTML, so most scenarios spend an extra round-trip generating the right shape.
InstaWP/mcp-wp fails every scenario with a "structural fail":the agent (Haiku, givenupdate_page) writes the page back as plain HTML —<h1>...</h1><p>...</p><ol>...— with no<!-- wp: -->block markers. WordPress accepts the save,parse_blocks()collapses the entire page into one freeform chunk, and every distinctive block on the page disappears as a structured entity. The agent thinks it succeeded; the page is broken in the block editor on reopen. That's the penalty of wrapping the standard wp/v2 REST surface and trusting the agent to reconstruct block markup by hand.
Reproduce withscripts/mcp-agent-bench.mjs.
Block MCP is the only WordPress MCP designed from the ground up for the way agents actually edit pages: one block at a time, across multiple turns, without corrupting anything along the way. The agent-loop bench reflects that — 9 of 9 across every Claude tier, including the cheapest.
Most WordPress MCPs wrap the default REST API. That gives an agent post-level CRUD, but it stops there — to change one heading on a page, the agent has to read the entirepost_contentHTML, parse it, find the right tag, mutate it, and write the whole thing back. Block boundaries dissolve, structure breaks subtly, and there's no undo path.
Block MCP is built around the block tree itself. The agent sees a structured, addressable, well-typed view of the page — and writes through purpose-built endpoints that know what blocks are.
- Block-aware editing.Change a heading's level, swap a button's URL, reorder columns — without touching surrounding HTML. The agent works in JSON; the plugin handles parse/serialize.
- Stable block refs.Every block carries a persistent ID. An agent can fetch a page once, capture the refs of every block it intends to edit, then chain inserts/deletes/updates against those refs without re-reading. Sibling shifts don't invalidate the addresses.
- Path-based structural ops.Nine operations (update-attrs,replace-block,wrap-in-group,unwrap-group,move,duplicate,insert-child,remove-block,update-html) work on any nesting depth via integer paths or refs.
- Auto-transforms.Change a heading'slevelattribute and the<h2>/<h3>tag updates with it. Toggle a list to ordered and<ul>becomes<ol>. The plugin keeps attributes and innerHTML in sync for the common patterns so agents don't have to.
- Site policy enforcement.Per-site preference tiers reject inserts of blocks you've marked as legacy and surface suggested replacements. An agent can't write blocks your site doesn't want.
- Revision-backed undo.Every write returnsbefore_revision_idandrevision_id.revert_to_revisionrolls back to either side of any edit.
- Discovery tools.Browse registered block types with preference scoring, search patterns, query site-wide block/pattern usage, resolve URLs to post IDs. The agent can plan with knowledge of what your site actually contains.
- Static-block safety guards.Warns when an attribute change would leave rendered markup stale, so the agent knows when to also pass innerHTML.
The combination — block-aware, ref-stable, revision-tracked, policy-enforcing — is what existing REST-API-wrapping MCPs don't give you.
The WordPress MCP space is small, and Block MCP is the only one operating at the block-tree layer. The other projects work at different layers and target different workflows — they're often complementary rather than head-to-head, but the agent-loop bench above shows they don't all produce correct results when asked to edit a block.
InstaWP/mcp-wp— A REST-API-wrapping MCP that operates on whole posts, plus broad coverage of users, comments, media, plugins, and plugin-repo search. Standout feature: multi-site management from one MCP instance. Reach for it when you need post-level CRUD across many sites or general-purpose WordPress administration.Not block-aware:editing a single heading inside a long page means reading and rewriting the entire post, and the round-trip throughwp/v2'supdate_pagestrips every<!-- wp: -->block marker. In our bench it failed validation on 7 of 9 trials across Haiku/Sonnet/Opus.
AI Engine Pro— Self-hosted MCP server inside WordPress (Streamable HTTP at/wp-json/mcp/v1/http), built by Meow Apps and the most-installed WordPress AI plugin (100K+). Free tier exposes posts/comments/users/media as MCP tools; Pro adds an Editor Assistant sidebar and additional MCP plumbing. Itswp_alter_posttoolisblock-aware — block-comment markers survive — but it can desync the block's declared attributes from its innerHTML (e.g., comment marker still sayslevel: 2while the inner tag is<h3>), and the block editor flags that as broken too. Sonnet and Opus retry until consistent and pass; Haiku sometimes gives up at 7–12 tool calls. 8 of 9 in the bench.
Block MCP(this project) — Operates one layer below: inside a single post's block tree. Path- and ref-based addressing, auto-transforms that keep attributes and innerHTML in sync server-side, preference-tier enforcement, per-block revisions. None of those exist in the other three. Reach for it when an agent needs to editblocks— change a heading level, swap a column layout, insert a CTA after the third paragraph — without rewriting the surrounding content. 9 of 9 in the bench, perfect across all three Claude models, including the cheapest.
These can coexist. Block MCP could (and likely will) be exposed through the official adapter as registered abilities once that path matures — same logic, blessed plumbing. Seeissuesfor the roadmap.
- Full block tree as structured JSON: paths, names, attributes, refs,text_previewof each block's content
- Page summary in one call: block type counts, headings with paths, section markers, max nesting depth
- Outline mode for fast page structure inspection
- Search blocks by text or block name
- Render mode expands shortcodes, resolves synced patterns, marks dynamic blocks
- update_block— flat-index OR ref
- update_blocks— atomic N-update batch in ONE revision; all-or-nothing validation, max 50 items, counts as one write against the rate limit
- delete_block— top-level counter OR ref
- insert_blocks— anchor onafter_top_level/before_top_levelORafter_ref/before_ref
- edit_block_tree— 9 path-based or ref-based structural ops:
- update-attrs,update-html,replace-block,remove-block
- wrap-in-group,unwrap-group,insert-child,duplicate,move
- Auto-transform keeps innerHTML in sync when attributes change (heading level, list ordered, group tagName, button URL, image src, spacer height, etc.)
- Static block guards warn when an attribute change may leave rendered markup stale
- Configurable preference tiers: legacy blocks rejected on insert, avoid-tier blocks return warnings with suggested replacements
- Per-post rate limiting (10 writes/min, 2 full rewrites/min)
- Every write creates a WordPress revision;revert_to_revisionundoes any edit
- List block types filtered by namespace, category, or preference tier
- Browse patterns (synced + registered) scored by recency, reference count, and legacy content
- Site-wide block/pattern usage analytics (cached)
- Resolve any URL or slug to its post ID, type, and edit link
AI Agent ←stdio→ MCP server (your machine) ←HTTPS→ WordPress plugin (your site)
WordPress plugin(wordpress-plugin/gk-block-mcp/) — REST API atgk-block-api/v1. Handles block parsing, serialization, safety checks, preference scoring, rate limiting, revisions. Works with any post type that stores Gutenberg blocks inpost_content.
MCP server(src/) — TypeScript stdio server that exposes the REST API as MCP tools. Authenticates as a normal WordPress user via Application Password. No special privileges, no direct DB access from the MCP side.
Easiest — download the latest ZIP:gk-block-mcp.zip(auto-built frommainon every push).
Then in WordPress:Plugins → Add New → Upload Pluginand pick the ZIP.
Or copywordpress-plugin/gk-block-mcp/to your site'swp-content/plugins/and activate manually. Or via WP-CLI:
wp plugin install https://github.com/GravityKit/block-mcp/releases/download/latest/gk-block-mcp.zip --activate
The fastest path provisions everything for you — a dedicatedblock-mcpservice account, a minimal-capability role, and an Application Password — from inside WordPress. Go toSettings → Block MCP → Connectand pick your client.
Claude Desktop (one-click).Download the generated.mcpbfile and open it; Claude Desktop installs the server and stores the credential in your OS keychain. The.mcpbis self-contained — it bundles the server, so there's nothing else to install.
Cursor, Claude Code, ChatGPT Desktop (browser approve).Run the connector and clickApprovein the browser that opens:
npx -y @gravitykit/block-mcp connect --site https://example.com
It writes your client's MCP config for you (owner-only, mode0600), so the site-wide password never lands in your shell history or a hand-edited file. Add--client cursor|claude-code|claude-desktop|printto target a specific client. Each site you connect gets its own server entry, so one assistant can point at several sites.
Runtime:the common path runs the server withnpx -y @gravitykit/block-mcp— nothing to clone or build. The Claude Desktop.mcpbembeds the same bundle.
Prefer to wire it up by hand? Create an Application Password and register the server yourself.
In WordPress admin:Users → Profile → Application Passwords. Or via CLI:
wp user application-password create <username> "Block MCP" --porcelain
Read endpoints require theedit_postscapability; write endpoints requireedit_poston the specific post being changed. Then build and register the server:
git clone https://github.com/GravityKit/block-mcp cd block-mcp npm install # auto-builds dist/index.cjs via the prepare script
Register the server in your MCP client. Example for Claude Code's~/.claude.json:
{ "mcpServers": { "block-mcp": { "command": "node", "args": ["/absolute/path/to/block-mcp/dist/index.cjs"], "env": { "WORDPRESS_URL": "https://example.com", "WORDPRESS_USER": "your-wp-username", "WORDPRESS_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx" } } } }
Restart your MCP client. Runnpm run inspectto test the tools interactively.
When the plugin is active, an admin page appears atSettings → Block MCP. The defaults work out of the box, but it's worth a look — this is where you decide which blocks AI agents are allowed to write, what to suggest as replacements, and which post typescreate_postcan target.
See theConfigurationsection below for the full breakdown.
list_templates/get_templateare read-only tools for browsing a block theme's templates (page layouts likesingle,archive) and template parts (reusable regions likeheader,footer), the same content the Site Editor's template list shows.
Each row'swp_idtells you whether a database override currently shadows the theme file:nullmeans the id resolves to the theme file itself; a number means a customization exists and that post ID is the override. On a classic (non-block) theme,list_templatesreturns an empty list with anoteexplaining why, rather than an error.
Templates are index-addressed only.get_template'sblocksfield is formatted likeget_page_blocks. Whether the per-block write tools (update_block,edit_block_treeby ref) apply depends on thewp_id: a template that still resolves to the theme file (wp_id: null) is not writable by them, while a template with a database override (a numericwp_id) is an ordinary post they edit like any other. Useupdate_template(see Editing templates below) to materialize the override for a theme-file-only template.
update_template/reset_templatewrite to templates. Both are off by default. Enable"Let the assistant edit theme templates and template parts"under Settings → Block MCP first, or every call returns a 403 with an actionable message. Turning the toggle on grants the Block MCP agent account a dedicatedgk_block_mcp_edit_templatescapability (nothing else it can do changes); a human's own "self" connection can edit templates too, since it already carriesedit_theme_options.
- update_templatereplaces a template's entire content: whole-template replacement, likerewrite_post_blocks, not a per-block edit. Provide exactly one ofcontent(raw markup) orblocks(structured; validated against the block registry and preference tiers, same as any other structured-block write). If the id currently resolves to the theme file, a database override is created automatically (override_created: true); the theme file itself is never touched. Writing again reuses the same override.
- reset_templatedeletes the override, reverting the id back to the theme file. Appearance → Editor → Reset does the same thing from the WordPress admin.
Once an override exists, itswp_idis a normal post ID —update_block,get_page_blocks, and the rest of the per-block tool surface work against it like any other post.
Every block in aget_page_blocksresponse includes areffield:
{ "index": 5, "path": [0, 2, 1], "ref": "blk_a3f2c1q9", "name": "core/heading", "attributes": { "level": 2, "content": "Hello" } }
Refs are stored inattrs.metadata.gk_refinsidepost_content, so they survive across sessions and across mutations that shift sibling positions. Passreftoupdate_block,delete_block, oredit_block_treeto address the same block reliably even after inserts or deletes elsewhere on the page.
The first read of a post lazily assigns + persists refs via a direct DB write that skips revision creation (refs are editor-only metadata, not content). Passpersist_refs: falseto read without that side effect.
Everything in this section is editable atSettings → Block MCPin WordPress admin. Defaults are sensible — none of this is required to get started.
Block preferences are stored as a WordPress option (gk_block_api_preferences) and configurable per-site. Each block namespace gets a score 0–100, which maps to a tier:
Defaults ship withcore/preferred and a starter set of known-deprecated namespaces marked legacy. Add new namespaces by typing into the bottom row — a fresh blank row appears as soon as you start typing.
When an agent attempts to insert a legacy block, the rejection error includes a suggested replacement from this map. Both columns are searchable dropdowns of every block currently registered on your site (you can also type a block name that isn't currently registered).
A few blocks (notablyyoast/faq-block) keep the same data inboth*their attributes and their innerHTML. Updating one without the other corrupts the block silently. Block MCP detects most automatically by scanning your site; list any extras here so the API forces agents to send both fields together.
Restrictcreate_postto specific post types. Leave everything unchecked to allow any public post type with REST support (the default).
The scan walks every published post and classifies each distinct block as static / dynamic / dual, replacing the filter defaults with live data from your site. Slow on large sites; the result is cached. The Reset button below it clears every option this plugin owns and restores hard-coded defaults.
Block MCP gives an AI assistant exactly the access it needs to edit content — and nothing more.
The one-click Claude Desktop installer can either include your credential or leave it out:
Developers can force paste mode with a filter, or by definingGK_BLOCK_MCP_FORCE_PASTE_SECRETastrueinwp-config.php:
add_filter( 'gk/block-mcp/credential/seal-mode', fn() => 'paste' );
"Change the H2 'Welcome' on/about/to 'About Us'."
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.



