-
-
Human authorization at R4: ChatGPT prepares the exact plan but cannot approve it.
-
Durable outcome at R6: exactly-once execution returns a recoverable receipt.
-
Shared decision surface at R1: one live plan for the human and ChatGPT.
-
Protocol evidence: revision-bound capabilities, stale rejection, and zero bypasses.
Inspiration
Browser agents can move quickly, but consequential workflows become unsafe when the person and the agent are acting on different versions of the truth. A stale suggestion can overwrite a newer decision. A broad approval can outlive the plan it was meant to authorize. A retried action can execute twice.
Captain's Table helps a chief of staff or offsite organizer coordinate eight teammates' arrivals, agenda, meals, and reservations. The demonstration begins with a schedule conflict, but the product thesis is broader: people and browser agents need one shared, inspectable decision surface with explicit authority boundaries.
What it does
Captain's Table is a workflow-first WebMCP application where a human and ChatGPT operate one live plan together.
ChatGPT can:
inspect the active decision; diagnose the schedule conflict; compare repairs; select the arrival-safe repair; prepare the exact plan for review; and execute the plan after authorization.
Only the human can authorize the exact server-computed plan hash. There is deliberately no authorize_plan WebMCP tool.
The demo makes causality explicit. Each activity separates the named ChatGPT action from the authoritative Server result. For example, diagnose_plan() is the agent action; Conflict found · R1 → R2 is the authoritative outcome and revision transition.
The tool surface changes as the workflow advances from Inspect to Repair to Review to Reserve. Each tool set belongs to a capability epoch bound to one server revision and a deterministic fingerprint. If the page changes, a retained old callback cannot acquire authority over the new state. Execution is idempotent and returns the original receipt on replay.
Why WebMCP
This use case is a strong fit for WebMCP because the human and the agent must work on the same visible state, not exchange brittle descriptions of a UI.
The page exposes six imperative workflow tools through document.modelContext.registerTool():
inspect_decision diagnose_plan compare_repairs select_repair prepare_authorization execute_authorized_plan
A seventh diagnostic tool, report_observed_capabilities, lets ChatGPT report the tool set it actually sees. The page's Protocol Lab compares that agent-reported set with the expected registration set. This keeps page registration, host discovery, and host invocation as separate claims.
In the verified ChatGPT built-in-browser run, ChatGPT observed all six capability epochs. R1–R6 are the six successive server revisions in the demonstrated workflow, from initial inspection through completed reservation. ChatGPT performed state-changing invocations, respected page-only authorization, executed exactly once, recovered the same receipt after reload, and rejected a retained stale handle.
Chrome 151 separately proved page-level WebMCP enablement through the Origin Trial. We do not present that as native host-discovery evidence.
How we built it
The server is authoritative. Every mutation carries an expected revision. Each visible tool set belongs to a capability epoch bound to that revision and a deterministic fingerprint.
If the workflow advances from R5 to R6 while the host still retains an old R5 execution callback, that callback continues to identify itself as R5. The server compares its issuing revision with current state and rejects it before any mutation. An outdated tool may remain callable in the agent's memory, but it cannot reuse the organizer's approval, create a second reservation, or act on a newer plan.
FastAPI and Pydantic provide the API. Firestore transactions persist production state. SQLite with BEGIN IMMEDIATE provides the local adapter. Semantic HTML, CSS, and plain JavaScript implement the interface. One shared controller handles both human actions and WebMCP invocations. Google Cloud Run hosts the public deployment with a least-privilege service identity.
There is no embedded OpenAI Agents SDK, Gemini or Google ADK runtime, or standalone MCP server. ChatGPT is the external agent, and WebMCP is the page-scoped bridge.
Challenges we ran into
The hardest problem was proving the right thing. A page can accept registrations while the host still cannot discover them, so we added explicit agent-reported capability evidence and kept Chrome page enablement separate from ChatGPT native-host discovery.
Dynamic tools created a second challenge: removal propagation is not acknowledged to the page. A resolved registerTool() call does not prove host discovery, and the page receives no reliable confirmation that an obsolete tool was removed from the host. Client-side removal therefore cannot be the safety boundary.
We solved that with server-enforced capability epochs. We deliberately retained an execution tool issued during the final review state (revision R5). After the authorized plan executed and the workflow advanced to its completed state (revision R6), we invoked that old tool again. Its R5 issuing revision traveled with the call, so the R6 server rejected it as stale before changing Firestore. The visible result is intentionally a non-event: no plan mutation and no second reservation. This is the central safety proof: an outdated tool cannot reuse the organizer's approval.
Production introduced practical edge cases too. Cached HTML briefly loaded incompatible JavaScript, and a completed session originally had no supported way to begin again. We added versioned assets, a backward-compatible listener, and a scoped new-session control, then verified the corrected behavior on Cloud Run.
Accomplishments that we're proud of
Completed a real native ChatGPT host journey through R1–R6. Matched every agent-observed tool set with zero missing or unexpected names. Kept exact-plan authorization exclusively on the page. Executed once and recovered receipt CT-79ECA1 after reload. Rejected a retained stale R5 handle after the workflow advanced. Recorded zero stale mutations, zero authorization bypasses, and zero duplicate executions in safety probes. Shipped a complete workflow-first production experience, not only a protocol proof. Passed 20 Python 3.13 tests, including 13 Playwright browser cases. Reached 40/40 in the final independent Impeccable static design review.
What we learned
WebMCP's value is not only that agents can call tools more reliably than they can click through an interface. Its deeper value is that a website can define a shared contract between the user, the agent, and the server.
We learned to treat four facts separately: the page requested registration, the page received a resolved registration promise, the host actually discovered the tool, and the host invoked it. That distinction shaped the Protocol Lab and prevented us from making a stronger claim than the evidence supports.
We also learned that client-side tool removal is not a sufficient safety boundary. Revision-calibrated server validation ensures that an outdated tool cannot reuse the organizer's approval.
What's next
Package the revision-bound capability pattern as a reusable WebMCP reference for other consequential workflows. Add server-backed authorization-expiry and storage-fault browser cases. Add explicit 200% zoom assertions to the accessibility regression suite. Explore protocol-level discovery and removal acknowledgments if WebMCP exposes them in a future revision.
Testing
The public demo requires no account. In ChatGPT's WebMCP-enabled in-app browser, ask:
Find the most important conflict in this offsite plan, compare repairs, and select the arrival-safe option.
Review the repaired plan on the page, authorize the exact plan using the page-only control, then ask ChatGPT to create the reservation. Reload and confirm the same receipt returns.
If WebMCP is unavailable, the page enters Manual mode and the same workflow remains usable through visible controls.
The production revision is captains-table-webmcp-00011-cf4. The Python 3.13 suite passes 20 tests, including 13 Playwright cases covering the R1–R6 journey, dynamic replacement, page-only authorization, receipt recovery, stale-handle rejection, fallback modes, visible error recovery, two-tab races, navigation during mutation, and narrow reduced-motion layout.
Challenge provenance
Captain's Table was created in this dedicated repository during The WebMCP Challenge. The concept and implementation are new. General domain experience from an earlier Offsite Captain project informed the scenario, but no prior application code or interface was copied. The public Git history and CHALLENGE_WORK.md record the challenge-specific work.
Built With
- css
- fastapi
- firestore
- google-cloud-run
- html
- javascript
- openai-chatgpt
- playwright
- pydantic
- sqlite
- webmcp