Inspiration
Every independent café, bakery, and corner shop has the same Sunday-night ritual: the owner sits down with a spreadsheet, drags names into cells, and then blows up the group chat trying to get coverage for next week. One wrong cell — a 17-year-old scheduled past 21:00, someone double-booked, a close with no keyholder — and it's a labour-law problem, not just an annoyed group chat.
What made this click as a WebMCP idea is that scheduling is a trust problem, not a data problem. A manager will happily let an agent read the roster. They will never let it act on it unless they can see every move and take it back. WebMCP is the first thing that makes that possible: tools that run in the user's own authenticated browser, on the live page, where every action is observable, attributable, and undoable. So we built wcrew around that exact contract.
What it does
wcrew is a shift roster co-pilot for small hourly teams (5–30 staff). It replaces the spreadsheet with a live weekly board where a manager and a browser agent fix the roster together:
- Compliance you can see — skills, availability, under-18 curfew, 11-hour rest, 10-hour daily cap, 5 consecutive days, keyholder coverage, 1.5× overtime, and a $5,200 budget are checked in real time, with the exact rule broken and a suggested fix.
- An agent that acts through 15 typed tools — the agent can check compliance, explain any assignment before making it, rank swap candidates, auto-fill open shifts with a deterministic solver (three strategies), and publish — all on the live board.
- Dry-run before mutate —
auto_fillpreviews a plan produced by the same code path as the apply, so what you see is what you get. - A trust contract — every agent action is logged
actor:agent, one-undo reversible, and destructive actions pause on a human confirmation modal. - An in-page agent console — runs the same 15 tools in any browser (no Chrome flag, no agent platform) so the demo is one click away for anyone.
How we built it
- 15 structured tools on
document.modelContext(src/webmcp.js), each with a natural-language description and JSON Schema, executing against a pure, zero-dependency scheduling engine. - Single source of truth —
evaluateAssignmentpowersexplain_assignment,assign_shift,check_compliance, and the solver, so "explain" and "do" can never disagree. - Deterministic solver — greedy, hardest-shift-first with a one-level repair pass, so the same input always yields the same plan.
- Actor-tagged store — a tiny undo/redo store where human edits and agent tool-calls go through the same commit path.
- Prompt-injection defense — staff notes are untrusted; tools surface them between
--- BEGIN UNTRUSTED ---delimiters and warn the agent not to follow instructions inside (there's a live canary in the seed data). - Origin isolation —
Origin-Agent-Cluster: ?1+Permissions-Policy: tools=(self)served bytools/serve.mjsand_headers. - Vanilla JS, no build step, no backend — runs anywhere; state lives in
localStorage.
Challenges we ran into
- WebMCP is brand new. The spec is still a draft and
document.modelContextonly exists behind Chrome 149+ with a testing flag (or ChatGPT's in-app browser). That meant the demo would silently degrade to "human-only" for most judges — so we built the in-page agent console that exercises the identical tool definitions everywhere. - Making the dry-run honest. Most demos fake a preview. We wired
auto_fill --dry_runthrough the exact solver the apply path uses, including the repair pass, so the numbers in the preview are real. - The trust contract is easy to say, hard to build. Observable, attributable, undoable required a shared store, actor tags, a confirm bridge the agent can't bypass, and locked shifts the solver respects.
- Prompt injection is a first-class concern the moment you expose user content to an agent. We had to assume staff notes are adversarial and design tool descriptions + delimiters around that.
- Origin isolation is load-bearing —
document.modelContextis gated behindOrigin-Agent-Cluster, which rules out plain static hosts like GitHub Pages and forced us to configure headers on Cloudflare Pages.
Accomplishments that we're proud of
- 15 tools sharing one engine, so answers are computed, not guessed.
- A trust contract where the agent proposes and the human decides — the thing we think makes WebMCP more than a "chat sidebar."
- An honest dry-run produced by the same code path as the apply.
- A real prompt-injection canary and untrusted-content handling.
- An agent console that makes the whole thing demo-able in any browser, no setup.
What we learned
- WebMCP's real value isn't tool-calling — it's trust: keeping the human's authenticated session, UI, and undo power in the loop.
- One engine for explain and do is the single biggest reliability win for agent-driven UIs.
- Prompt injection isn't theoretical: the moment you hand user content to an agent, you have to design for it.
- Platform details (origin isolation, permissions policy) decide whether WebMCP even works — get them right early.
What's next for wcrew
- Real teams: authentication, persistence, and multi-manager sharing so a live roster actually ships to staff (the demo is
localStorageby design). - Staff self-service: let an employee ask the agent "can I swap my Friday close?" and have the manager approve the proposed swap.
- Publish → notify: SMS/email to staff the instant the roster goes live, plus per-person ICS.
- Labour-law templates: pluggable regional rule packs (minors, rest, fair-scheduling) so the compliance engine scales beyond one jurisdiction.
- POS integrations: pull real sales demand from Square/Toast to drive the daily demand template.
Built With
- chatgpt
- chrome
- cloudflare-pages
- css
- document.modelcontext
- html
- javascript
- model-context-tool-inspector
- vanilla-js
- webmcp

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