Inspiration
I am tired of "AI everywhere" and help nowhere.
You open a support chat because a charge posted twice. You get a polite paragraph. You ask for the refund. You get another paragraph. You ask for a person. You get a form. Twenty minutes later the money still has not moved and you still cannot see who owns the case.
That is the loop I wanted to break. Not "more chatbot." A page where an agent can actually do the work, I can see every step, and I still have to approve anything that spends money or emails the customer.
What it does
Handoff is a multiplayer ops room for one live support case.
I am Jordan, the human lead. The agent is on the same board. We share CASE-1042: Maya Chen, duplicate Pro annual charge, $2,388, chargeback risk.
The agent does not scrape the UI. The page registers WebMCP tools, so it can get_case, draft_customer_reply, propose_refund, issue_refund, send_customer_reply, page_oncall, and resolve_case. Drafts show up in public. Refunds sit behind an Approve / Reject card. If I reject, that is a first-class event. Nothing irreversible happens in the dark.
Live site: https://handoffhelper.com
How I built it
Vanilla HTML, CSS, and JavaScript. No Next.js. No backend. State lives in the page.
Tools register with document.modelContext.registerTool, with navigator.modelContext as fallback. Each tool has a JSON schema. Read-only tools are marked readOnlyHint. Destructive tools open an on-page approval gate before they commit. The same store drives the UI, the timeline, and the tool results, so what the agent does is what I see.
I shipped it on Cloudflare Pages at handoffhelper.com so judges do not hit a login wall.
Challenges I faced
WebMCP was new to me. I had used the phrase "MCP" and assumed server-side Model Context Protocol. This challenge is the browser spec: the page exposes tools to the model.
That distinction ate time. I had to learn registerTool, the schemas, readOnlyHint, and what happens when modelContext is missing. Early on the public URL was a ChatGPT Site that required login. Useless for a judge. I bought handoffhelper.com and moved the static files to Cloudflare.
The other hard part was the human gate. It is easy to let the agent "just send the email." It is harder to make approve / reject visible, blocking, and logged under two identities. I wanted the kill switch to be obvious, not a hidden confirm in the model transcript.
What I learned
Agents are fast at draft and lookup. They should not be trusted with money or customer email until a person says yes.
If the tools are sloppy, the model asks extra questions and the demo dies. Tight descriptions ("do not call issue_refund until propose_refund exists") mattered more than extra features.
And a public URL with no login is part of the product. If a judge cannot open the page, the tools do not exist.
Built With
- cloudflare
- css
- html
- javascript
- pages
- webmcp
Log in or sign up for Devpost to join the conversation.