Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1081 +/- ##
=============================================
+ Coverage 81.95% 81.99% +0.04%
- Complexity 3350 3358 +8
=============================================
Files 135 136 +1
Lines 13026 13056 +30
=============================================
+ Hits 10675 10705 +30
Misses 2351 2351
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@danieliser tagging you as you had some feedback on the prior iteration in #224. |
|
@danieliser thank you, that pointer was the useful kind. I read Block MCP's surface against what this PR had and three gaps were plain: no way to place a block inside a container, no structural operations beyond remove, and no discovery of what a position allows or what attributes a block type takes. Pushed in ee48cf5, through the JS API as you said:
Two things Block MCP solves that the editor gives for free, which is worth knowing when comparing the two: What I did not carry over: atomic batches (one undo step per call seemed the honest unit inside an editor a person is watching) and path-based addressing (refs cover it once the outline is read). @zackkatz if either of those turned out to matter more than it looks from the outside, I would rather hear it now. |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @danieliser. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Thanks @dkotter, these are all fair. I'm working through them now: reverting the CHANGELOG and CREDITS edits, removing the evals files, fixing the quote blocks, the save check, locked blocks, the classic editor check and the two move cases, plus a rebase on develop. I'll reply on each thread when it's pushed. |
ee48cf5 to
40e4313
Compare
40e4313 to
f1a2157
Compare
dkotter
left a comment
There was a problem hiding this comment.
Thanks for all the work here! I think just a few more things and this will be good to go
Registers a curated, opt-in set of WordPress abilities as WebMCP tools on the page through document.modelContext, one registerTool call per tool, and executes them through a REST route that runs the ability's own permission and input checks on the server. The Abilities API stays the single registry. Two page contexts (wp-admin, front end) with separate allowlists and a per-page cap of 30 tools, because agent browsers cap what a page may register. Exposure is explicit: an ability opts in through its meta, a filter allows it, or the site owner lists it in the experiment settings. Tool names carry the ability name with __ in place of /, since a URL-encoded slash never reaches WordPress on stock Apache. Two tokens travel with each execution: the wp_rest nonce core requires in X-WP-Nonce and the experiment's own token in X-WPAI-WebMCP-Nonce. See WordPress#448. Keeps WordPress#224 as prior art. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
phpstan-wordpress infers the filter's return type from its default and WP_Ability::get_input_schema() is typed array, so the two is_array() guards read as always true; one is dropped, the other kept with an ignore, because a filter callback can return anything at runtime. The enqueue tests now assert on the real handle (the loader prefixes ai_, not ai-), register their own ability because core's are absent in the PHPUnit context, and cover the positive paths on wp-admin and the front end, which CI can run because it builds the scripts first. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The maintainers' reading of WebMCP is that an agent drives the UI on the current page and the person watches it happen, and that a site already connected over MCP gains nothing from the same server-side abilities registered again in the browser (WordPress#448). This commit changes what the experiment is accordingly. The Abilities API path is gone: no REST routes, no allowlists, no tokens. What stays is what is the same either way: registration on document.modelContext one tool at a time, the per-page cap, and a screen filter. The bridge now carries a JavaScript registry (wpai.webmcp.registerTool, the wpai.webmcp.tools filter) and ships nine editor tools that dispatch into core/editor and core/block-editor: read the document outline, set the title, insert a block, replace a block's text, change attributes, remove, select, save, publish. Every change is visible immediately and lands in the post's undo history. An e2e spec installs a document.modelContext shim before the editor loads, calls the tools the way a browser would, and asserts that the title field and the canvas change. An eval set with a small runner judges the tool descriptions by whether a model picks the right tool. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Following the pointer to Block MCP in review: an agent editing blocks needs stable references, structural operations and a way to discover what a position allows. Inside the editor those come from its own stores. Adds editor-move-block, editor-duplicate-block, editor-transform-block (through the editor's transforms), editor-get-block-types (what a position allows, or one type's attribute schema) and editor-undo (one step per tool call). editor-insert-block can now place a block inside a container, and asks canInsertBlockType first, so a locked template, an allowed-blocks list or a parent restriction refuses the insert instead of being bypassed. The e2e spec covers move, undo, duplicate, transform, discovery, nesting and a refused insert. Seven eval cases added for the new tools. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- editor-publish checks the post can be saved before setting the status, and puts the previous status back if the save fails. - editor-transform-block refuses blocks locked against removal and transforms the block does not offer. - editor-duplicate-block throws when nothing was created. - editor-update-block-attributes refuses changes to the lock attribute. - The screens filter falls back to the defaults when it returns a non-array. - Bridge data goes through localize_script; the bridge reads maxTools as a number.
…al saves - Saving and publishing are refused while the post is locked by another user (isPostLocked) or saving is locked (isPostSavingLocked). - editor-update-block-attributes rejects templateLock as well as lock. - A save that reports no failure but leaves the post dirty is reported as a failure (isEditedPostDirty).
f1a2157 to
da009a7
Compare
…or duplicating blocks, ensure that actually worked before we send a success response. Don't rollback the post status if save worked but still threw an error
|
@swissspidy @gziolo @jorgefilipecosta would appreciate a parallel review from one of you on this one, will ideally ship in the 1.5.0 release either way though if you're swamped with work elsewhere (aka not the most urgent/important item) |
What?
Adds an opt-in WebMCP experiment for the block editor, following #448. Fourteen tools let an agent browser read the current post, set its title, insert and edit blocks, move, duplicate and transform blocks, undo, save and publish. Changes happen through the editor's data stores and remain visible on the page.
Why?
WebMCP lets an agent work in the UI the person is looking at. The experiment does not mirror Abilities API tools; server-side abilities remain available through MCP.
How?
develop'sAbstract_Feature, feature registry and loader. The bridge loads on post editor screens, offers a JavaScript registry and filter for additional page tools, and registers each tool separately with a default cap of 30.contentattribute. Quote text is edited through its inner paragraphs; pullquote text uses itsvalueattribute through the attribute tool.savePost(), check that saving has settled, and reportdidPostSaveRequestFail()as an error.CHANGELOG.mdandCREDITS.mdmatchdevelop; the changelog entry is below.Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code, Codex
Model(s): Claude Fable 5.1, GPT-6
Used for: drafting the implementation, addressing review feedback, and adding regression tests. I reviewed and take responsibility for the result.
Testing Instructions
npm run build, then enable WebMCP under Settings, AI.npm run test:php -- --filter WebMCPandnpm run test:e2e -- tests/e2e/specs/experiments/webmcp.spec.js. The nine browser tests cover visible editing, structural tools, locked operations, self/descendant moves, quote attributes, failed saves/publishes, classic editor availability and non-editor screens.Validation
~/wp-aimount alias was removed using an ignored override, and pretty permalinks were restored before the full browser run.Screenshots or screencast
No separate UI; the effect is the editor changing.
Changelog Entry
document.modelContext, with tools that set the title, insert and edit blocks, save and publish, every change visible on the page as it happens.