-
-
ChatGPT's Sources panel: the agent called inspect_current_incident twice and show_change_comparison once, all tools this page registered.
-
The agent filled the Recovery Plan and stopped. The operator removed healthy payment from scope, so the plan is marked HUMAN EDITED.
-
RECOVERED only after a real Cloudflare rollback returned the same fixed request to 200. Three permanent-fix paths follow, the human picks.
-
PLAN_STALE: someone deployed while the plan was open, so the server refused and wrote no rollback. The plan is refreshed, not restarted.
The problem
Checkout starts returning 500 right after a deployment. An agent can inspect the incident and prepare a rollback plan, but a person still has to decide which production services get touched and when that plan becomes a real write.
In the workflow I wanted to improve, that decision lived in a chat window. The agent described a plan, the person typed "yes", and production changed before the person had reviewed the operation on screen. The approval was real. The review was not.
Incident Room puts that decision on the page. The agent fills one Recovery Plan, the person edits it, and the person presses Submit.
What the model cannot do
The WebMCP form has no toolautosubmit. The agent can fill the fields, but its tool call stays pending until a person submits the form.
The Controller also checks the Worker name, target version, scope, and observedDeploymentId against a server-side allowlist. Those values are not open parameters, so the agent can't widen the operation. The page waits for server verification before showing RECOVERED.
Why WebMCP fits
The Recovery Plan is page state shared by the agent and the person looking at it. A remote MCP server may read the same incident data, but it does not automatically know what this tab currently contains, what the person just edited, or which deployment ID was visible when the plan was drafted.
WebMCP lets both parties work on that object in place. I also checked the human gate directly: three seconds after the agent filled the form, the fields were populated and the tool promise had not settled.
What changes for the operator
The reviewer reads a form, not a paragraph. It shows the Worker, target version, included and excluded services, and the evidence required for success.
In the demo, the agent initially includes checkout and payment. Payment is healthy, so the operator removes it with one click before submitting. That correction is visible on the same screen instead of being buried in a chat log.
What people and agents can do together
A plan can survive a refusal. If another deployment happens while the form is open, the Controller returns PLAN_STALE and performs zero writes. The agent reads the new page state and refreshes the existing plan instead of starting over.
After recovery, the agent can call propose_remediation_options with a diagnosis and one of three paths: fix forward through a reviewed pull request, keep investigating on the rollback, or prepare an emergency hotfix. The person still chooses.
How I implemented WebMCP
Three imperative tools are registered with document.modelContext.registerTool() inside a React effect. An AbortController removes them when the page goes away.
inspect_current_incidentreads live health and deployment IDs, then focuses the affected service.show_change_comparisonopens a diff only for a change already listed in the incident.propose_remediation_optionsplaces a diagnosis and repair options on the recovered page.
These tools update page state but do not write to an external system. They carry readOnlyHint and untrustedContentHint, while the real authorization boundary remains in the Controller.
The Recovery Plan is the declarative tool. It has toolname and tooldescription, but no toolautosubmit. Its submit handler uses SubmitEvent.respondWith() so the page and the agent receive the same result.
What is real
The lab uses three dedicated Cloudflare Workers, not mocks. A deployed checkout version returns 500. The Controller calls the Workers Deployments API to roll back, then replays the same cart request. RECOVERED appears only when that request returns 200. Cloudflare supplies the deployment IDs shown as evidence.
I ran the full path in ChatGPT's built-in browser on GPT-5.6 Sol. I also ran it in Chrome 152 with chrome://flags/#enable-webmcp-testing, including the stale-plan case where the deployment list contained the competing deployment and no rollback.
Boundaries
There is no remote MCP server, generic connector, or multi-user platform. The public site shares one lab, so another rehearsal can make an open plan stale. Workers Logs are secondary evidence.
The permanent-fix step produces a simulated issue draft and labels it as such. It does not call GitHub or claim that a pull request exists.
Built With
- chatgpt
- cloudflare-service-bindings
- cloudflare-workers
- react
- typescript
- vite
- webmcp
Log in or sign up for Devpost to join the conversation.