A self-contained WebMCP challenge MVP for a general-purpose human-agent change-review workspace. The demo keeps the agent useful without making the human decision invisible: inspect a page, surface priority issues, explain one, prepare a proposal, preview the before/after, stage it, approve or reject it, apply only an approved change, and generate a concise report.
https://webmcp-challenge.pages.dev/
The live deployment is a deterministic demo and does not require an account or external API.
https://github.com/rakeshr/beforeapply
The app is static, but use HTTP instead of opening index.html directly:
- Double-click
preview.baton Windows, or runpython -m http.server 4173 --bind 127.0.0.1from this folder. - Open http://127.0.0.1:4173/.
- Click through the visible workflow. The seeded data is deterministic and stored in memory only.
Recommended happy path:
- Inspect current page.
- Find priority issues.
- Click Explain on an issue.
- Click Prepare.
- Open before / after.
- Stage for approval.
- Approve.
- Apply approved change.
- Generate report.
- Click Reset demo and confirm the original snapshot returns.
The Manual fallback controls at the bottom call the same state transitions as WebMCP. Try Apply before approving to verify the approval gate blocks the action and leaves page content unchanged.
A lightweight state smoke test runs with:
node smoke-test.mjs
When document.modelContext.registerTool exists, app.mjs registers 12 tools with strict JSON schemas and explicit side-effect descriptions:
list_workspacesinspect_current_pagefind_priority_issuesexplain_issueprepare_changespreview_changesstage_for_approvalapprove_changesreject_changespublish_changesgenerate_change_reportreset_demo
Every handler returns a structured result with ok, tool, stateVersion, and either data or an error. publish_changes is hard-gated on both approval === "approved" and the proposal status being approved; it only changes the local in-memory snapshot. The UI shows whether WebMCP registered successfully and always leaves the manual fallback visible.
The live URL was independently exercised in Chrome 151 with chrome://flags/#enable-webmcp-testing enabled in an isolated profile. Native document.modelContext.getTools() discovered all 12 tools, and the full inspect → report journey passed through native executeTool() calls while preserving the human approval gate.
No authentication, secrets, external API, paid service, or WordPress dependency is required.