Inspiration
Browser agents usually have to infer intent from interfaces designed for people: find the right control, interpret changing DOM structure, and guess whether an action is harmless or consequential. WebMCP changes that relationship. A website can publish an explicit capability with a typed contract instead of making an agent reverse-engineer the screen.
We wanted to explore the product-design consequence of that shift, not only the reliability benefit. If an agent can act faster through declared tools, the application should become equally explicit about where human authority begins. GhostLayer asks a simple question: what if the agent could discover and prepare structured work immediately, while the website retained validation, effect preview, approval, rejection, lifecycle, and recovery at the point of consequence?
What it does
GhostLayer is a human-authority layer for product and platform teams exposing commerce, finance, support, and administrative actions through WebMCP. It keeps consequential work behind a human-owned commit boundary instead of giving an agent unchecked authority.
The public Challenge Edition proves that product pattern in a fictional, client-only CRM sandbox with two page-owned WebMCP tools:
find_customerperforms an exact read-only lookup over three clearly fictional customer records and returns structured output.create_invoice_draftaccepts a returned customer ID, a 1–160 character description, and a fictional amount from $0.01 to $5,000. It validates the input, then keeps the tool call pending while the site shows the exact effect for human review.
Nothing is created while approval is pending. Rejecting, cancelling, expiring the two-minute window, pausing the agent surface, or resetting the sandbox creates no draft. Approval creates one tab-local demo draft. Repeating the same normalized approved request returns the existing invoice with replayed: true instead of adding another row.
The human can pause the entire agent surface, which disposes both WebMCP registrations, and resume it to publish the same bounded contract again. Reset clears all fictional state in the current tab. Visible forms provide a transparent manual path through the same lookup, validation, approval, rejection, replay, pause, and reset behavior when native WebMCP is unavailable.
The public challenge build intentionally contains no real customer data, login, application credentials, application API, D1 database, R2 bucket, external CRM, payment flow, or durable persistence. Reloading, closing, resetting, or opening a new tab starts clean. It demonstrates a governed interaction pattern; it does not claim durable or globally exactly-once execution.
From sandbox to a production app
A production team keeps its existing identity, policy, database, and business API. The request path becomes: agent request → typed WebMCP contract → GhostLayer review → authenticated, policy-checked backend commit → durable receipt returned to the agent. The public app proves the complete visible decision loop; production adopters connect server-side RBAC, durable idempotency, and audit storage at the same boundary.
How we built it
The challenge Site is a TypeScript application built with React 19 and Next.js 16 through Vinext/Vite for the OpenAI Sites runtime.
The bounded adapter schema and WebMCP bridge began in the earlier GhostLayer 0.5 private prototype and are reused transparently here. The new challenge-period work is the standalone public native WebMCP experience: its judge sandbox, page-owned registration, visible approval, rejection and expiry semantics, replay protection, Pause/Resume lifecycle, Reset behavior, deployment isolation, and verification. The private owner application, extension, control plane, and credentials are not part of this submission.
The tool contract in app/challenge-contract.ts defines the fictional records, exact-origin adapter, typed input and output schemas, and separate read and confirm risk levels. A shared WebMCP bridge feature-detects secure document.modelContext, registers the page-owned tools, validates adapter configuration and exact-origin availability, validates provider inputs and outputs, limits serialized tool results to 1,536 bytes, and uses an AbortController to dispose registrations with page or human-controlled lifecycle changes.
The React application owns the consequential boundary. create_invoice_draft returns a promise that stays unresolved while the approval panel is visible. The panel shows the customer, description, amount, and two-minute decision window. Approval resolves the call after creating one in-memory draft; rejection, cancellation, expiry, pause, reset, or teardown rejects it without a write. A stable replay key is derived from the normalized customer ID, trimmed description, and amount in cents. State and a short eight-entry activity log remain in React memory, with an eight-draft-per-tab cap.
Vitest uses deterministic fake timers to verify the exact two-minute expiry and tests schema validation, normalization, and replay-key stability. Playwright covers route isolation, absence of application API calls, tab isolation, zero-write rejection, approval, and the native WebMCP discovery/execution/replay/pause/resume chain in a compatible Chromium build.
GhostLayer had an earlier private adapter/extension prototype. This standalone public Challenge Edition was created during the submission period as a new directly testable WebMCP application. The challenge-period work comprises the client-only judge sandbox, direct page-owned native tool registration, governed approval/rejection/expiry, same-tab replay, Pause/Resume and Reset controls, deployment isolation, and the accompanying automated verification. The dated public commit history records this package; the earlier owner-only prototype is not included or required to run the submission.
Challenges we ran into
- An evolving API surface. WebMCP is experimental, and the current draft and available Chromium implementation can expose slightly different provider callback shapes. The bridge supports both without weakening validation or lifecycle cancellation.
- Waiting safely for a person. A consequential tool had to remain pending across visible review without silently committing, leaking an unresolved invocation, or writing after cancellation, expiry, pause, reset, or teardown.
- Replay without overclaiming. The demo needed to prevent duplicate rows for the same normalized request while staying honest that this is tab-local behavior, not durable cross-device idempotency.
- A genuinely safe public judge target. The experience had to be fully interactive without credentials, private routes, production data, persistent storage, or application API calls.
- Progressive availability. Native WebMCP is not available in every browser, so the manual forms needed to explain and exercise the same application-owned behavior without pretending to be an agent call.
Accomplishments we are proud of
- A real WebMCP tool invocation remains pending until the person approves or rejects the exact effect.
- The visible invoice count stays at zero during review, and rejection or expiry creates nothing.
- An approved replay returns the same tab-local invoice rather than adding a duplicate row.
- One human control removes both tools from agent availability and can restore the bounded contract.
- Input and output validation, exact-origin checks, bounded provider output, and cancellation are enforced inside the provider path.
- The judge sandbox is useful without collecting or persisting user data and includes a manual fallback for incompatible browsers.
- Browser tests exercise both the visible safety behavior and the native WebMCP chain.
What we learned
Typed tools remove UI ambiguity, but the schema is only the beginning of a trustworthy WebMCP product. The application still needs to own validation, effect previews, approval semantics, cancellation, lifecycle disposal, replay behavior, and recovery.
We also learned that human control is most convincing when it changes the capability surface itself. Pausing GhostLayer does not merely disable a button; it removes both registered tools. Finally, safe replay semantics must be described at their real scope. The current sandbox can prove same-tab duplicate prevention, while durable idempotency, authorization, and multi-tenant isolation belong in a separately reviewed server-backed system.
What's next
- Test the provider bridge against additional browser implementations as the WebMCP draft evolves.
- Extract the visible governed-approval boundary into a reusable provider component.
- Generate approval UX from policy and consequence classes while keeping the final decision application-owned.
- Add conformance and accessibility tests for descriptions, schemas, approval dialogs, focus behavior, and lifecycle controls.
- Connect an opt-in version to a fictional server backend and evaluate authorization, tenant isolation, audit retention, and durable idempotency independently.
- Explore the same pattern in support consoles, internal operations, commerce back offices, and regulated workflows.
Built With
- chromium
- cloudflare
- next.js
- openai
- playwright
- react
- typescript
- vite
- vitest
- webmcp
- zod
Log in or sign up for Devpost to join the conversation.