-
-
Reasoning and authority are separate: Gemini + ADK propose, a human approves, the gateway validates, native WebMCP executes.
-
The evidence: an order-issued invoice states the duplicate $18 charge and exact refundable balance. Document AI parses and binds it.
-
Executed via the shop's own native WebMCP tool - exactly once. One $18 refund committed; balance $14 to $32, captured $36.
-
Durable truth in Firestore: exactly one refund document - 1800 cents, duplicate_charge, demo_credit - matching lease and order.
-
The crash test, disclosed on screen: the purchase intentionally records two $18 captures to reproduce a real duplicate charge.
-
The audit trail: six Cloud Run log events for one order - purchase, invoice, Document AI evidence, lease, execution, denied replay.
-
Paired and verified: the server checks the shop's 4 native WebMCP tools before anything runs. The merchant declares the surface.
-
Replay attack on camera: the used approval is submitted again. Server rejects it - lease_replayed. Refund count stays at 1.
-
Approval mints an Evidence Lease: 120 seconds, one execution, bound to this order and invoice. Countdown live: 1:58 remaining.
-
Explicit WebMCP pairing: a one-time code pairs exactly one shop tab. The Chrome extension is only a relay - no cookies, no other tabs.
Inspiration
An AI agent that can act needs a clear boundary between a proposed action and permission to carry it out.
We built ScopeShift around one question: what exactly did the user approve, and is that approval still valid when the action executes?
Approval can become unsafe if it is reused or if the supporting evidence changes. We wanted it to behave like a single-use ticket: specific to one action, time-limited, and checked when presented.
ScopeShift: Evidence Lease connects native WebMCP execution with evidence-bound human approval.
What it does
ScopeShift turns a duplicate-charge complaint into an approved, auditable refund.
Important demo notice: We deliberately configured one USD 18 purchase to produce two USD 18 charges. This is an intentional error scenario, not an accidental checkout malfunction. All amounts are synthetic demo credits; no real payment processor is involved.
The workflow separates four roles:
| Role | Actor | Responsibility |
|---|---|---|
| Propose | Gemini 3.5 Flash + Google ADK | Analyze accepted evidence and propose a refund |
| Approve | Human | Approve the exact action and amount |
| Validate | Policy gateway on Cloud Run | Check evidence, approval, browser binding, expiry, and prior use |
| Execute | Paired shop tab through native WebMCP | Invoke the shop's refund tool; the gateway commits the authorized result |
Approval creates a 120-second, single-use Evidence Lease bound to the approved action and evidence through SHA-256 digests. The gateway rechecks those conditions at execution time and permits only one committed refund per lease.
The model cannot approve its own proposal or directly commit a refund.
Two verified flows, one system. The video demonstrates the duplicate-charge flow; the /judge reader page documents a second verified flow — evidence change wi
th automatic re-approval ($18 approved → $8 prior credit found → old approval invalidated → new $10 approval). Same lease rules, different evidence story.
Why WebMCP matters
The shop declares its own structured tools through native WebMCP. The ScopeShift Chrome extension discovers and relays those tools without DOM scraping, synthetic clicks, or cookie export.
The AI workspace and shopping site run on separate origins. Explicit pairing connects one authenticated shop tab, and the server verifies its tool catalog before purchase. The recorded demo shows four verified native tools.
WebMCP provides the execution interface. ScopeShift adds evidence-bound human approval and server-enforced replay protection.
The recorded native flow was tested on Chrome 151 with WebMCP enabled and the ScopeShift extension.
The intentional duplicate-charge scenario
We chose a scenario with a clear expected result: USD 36 captured for one USD 18 item, leaving USD 18 to refund.
- The user confirms the purchase, and the shop intentionally records two charges.
- The shop issues a PDF invoice for that order after purchase.
- Document AI reads the uploaded invoice, and the gateway checks it against the order's issued document.
- Gemini proposes a USD 18 refund. A person approves that exact amount.
- The paired shop invokes its native refund tool. The server records one refund, raising the demo balance from USD 14 to USD 32.
- We deliberately attempt to reuse the approval. The server returns
lease_replayed; the refund count remains one.
The Google Cloud Console segment reviews stored logs and Firestore records from that same order after execution. It is recorded verification, not a new live run during submission.
How we built it
- Agent: A private Python service uses Gemini 3.5 Flash through Vertex AI and Google ADK, with structured output validation.
- Evidence: Document AI extracts invoice information; the gateway validates it and stores an order-bound evidence record.
- Policy: A Node.js/TypeScript gateway on Cloud Run owns approval, evidence checks, expiry, and execution authorization.
- Persistence: Firestore transactions update the refund, balance, and lease state atomically. The lease ID also identifies its refund record.
- Audit: Cloud Logging records key events, including purchase, invoice issuance, evidence acceptance, approval, execution, and replay denial.
Challenges we ran into
Making evidence belong to the action. The invoice had to be issued after purchase and matched to the current order. We added rejection paths for documents from other orders, modified files, and stale revisions.
Getting Document AI to read the intended amounts. It initially separated invoice labels from their values. We revised the generated PDF layout to keep them together while preserving strict rejection of missing or conflicting evidence.
Enforcing single use across the browser and server. A disabled button could not enforce the policy. We placed the decisive checks and refund update in the gateway's transaction path, then demonstrated rejection of a used approval.
Accomplishments that we're proud of
- Connected human approval to native WebMCP execution across separate AI and shop interfaces.
- Recorded one USD 18 refund and visibly rejected reuse of its approval.
- Matched the demonstrated order and lease to Firestore records and Google Cloud logs.
- Made the intentional duplicate charge and synthetic-credit boundary explicit.
What we learned
- Structured output is not execution authority.
schema_validconfirms output structure; the gateway must independently validate the proposed action. - Evidence changes require renewed approval. Digests identify changes, while explicit server checks invalidate outdated authorization.
- Tool access and action authorization are separate responsibilities. A callable browser tool still needs policy checks before changing merchant state.
What's next for ScopeShift
Separate development work covers revised and conflicting invoices; the submitted video focuses on one refund and replay rejection.
Our next priorities are shared relay routing across gateway instances, broader validated invoice formats, stronger multi-merchant authentication, and extending the existing capability-grant model to additional action types.
The current demo supports allowlisted demo sites and their own order-issued PDFs. Real payment integration remains outside its scope.
Built With
- chrome
- cloud-run
- document-ai
- firestore
- gemini
- google-adk
- google-cloud
- webmcp


Log in or sign up for Devpost to join the conversation.