-
-
Rosa’s absence triggers two releases and Nadia’s proposed 4-hour prep cover.
-
Cancelled derby and private booking produce a 910-cover order preview before adoption.
-
The agent records chicken at 30 kg on hand with 6 kg expiring.
-
Manager actions and agent tool calls appear in one filterable service-day record.
-
One desk connects Order, Stock, Labor, and Shift log through shared browser state.
Inspiration
Restaurant orders often lock at a supplier cutoff. The forecast may have been correct yesterday, but the shift changes in real time. A nearby event gets cancelled, a private booking arrives, a shelf count changes, or a staff member calls out.
Those facts affect the order and roster together, yet they often live in separate notes or in the manager's head. I built Cutoff so a manager can state a change once and work through its effects with a browser agent on the same page.
What it does
Cutoff is a shift operations desk for a fictional restaurant. Order, Stock, Labor, and Shift log share one revisioned state inside the browser.
The Saturday scenario starts with 1,140 covers, 95 required labor hours, and a 3,629-unit supplier order. An 80-person booking and a cancelled derby produce a preview of 910 covers, 76 hours, and a 2,767-unit order. Every changed line explains its reason before the manager adopts anything.
Once the manager adopts the order, Labor reads the approved 910-cover plan. The agent can record an absence and propose releases or on-call cover without changing the roster until the manager approves it.
A corrected stock count feeds the same state. Recording chicken at 30 kg on hand with 6 kg expiring changes the recommendation from 15 to 16 cases and raises the proposed order cost to 2,835 units.
The agent can also save a bounded handoff for the next manager. Shift log joins the manager's actions and the agent's tool calls into one filterable record that can be downloaded as JSON.
Why WebMCP
The state that matters is not fully visible in the page. It includes local signals, shelf counts, quantity pins, roster absences, preview identifiers, and the current shared revision. An agent cannot recover that state reliably by reading pixels.
Cutoff exposes this information through WebMCP. The manager gives the agent the task in plain language. The agent discovers the tools available on the current page, reads the latest revision, and uses the tools it needs. The manager never has to name a tool or copy values between systems.
The result appears in the same interface the manager is already using. Proposed changes stay visible and reversible, while final approval remains with the manager.
How I built it
Cutoff is a static React and TypeScript application with no backend, account system, or application keys.
It registers 16 hand-built tools through document.modelContext.registerTool. Each page exposes only the tools relevant to that section. Order has 6 tools at rest and 7 while a preview can be adopted. Labor follows the same pattern with 4 and 5 tools. Stock exposes 4 tools, and Shift log exposes 3.
The two adoption tools exist only while their preview is current. Route changes replace the previous page's tools before navigation finishes.
Every write requires expectedRevision. If another action has changed the state, the tool returns a structured stale-write error with the current revision instead of overwriting newer work. Human-entered text is marked as untrusted when it appears in tool results.
Small deterministic engines calculate order quantities, labor demand, waste, and roster proposals. The visible controls and WebMCP tools call the same store methods, so the manager and agent cannot drift into separate versions of the plan.
Challenges
The hardest part was keeping previews, adoption, invalidation, undo, navigation, and tool registration consistent under one revision.
A stock count must make an old order preview stale without invalidating an unrelated labor preview. Adopting an order must update labor demand. Changing pages must remove the previous tools before the agent continues. Undo must restore the saved plan without printing a breakdown that no longer matches it.
The interface also had to remain readable as the product expanded from one order page into a four-section desk. I tested the final layouts on laptop and mobile widths and added direct links from agent-change notifications to the affected row or receipt.
What I learned
WebMCP works best when the page and its tools share the same product model. The tools should expose state and calculations that an agent cannot obtain reliably from the rendered interface. The page should still show every result and keep consequential decisions under human control.
Tool availability can also communicate state. An adoption tool appearing only when a valid preview exists is clearer and safer than exposing an action that may fail or apply to an old proposal.
Accomplishments
- 16 contextual WebMCP tools across 4 decision pages
- Dynamic preview and adoption tool lifecycles
- One shared revision with structured stale-write recovery
- Reversible local order and labor adoption
- Agent-driven navigation between sections
- Local handoff and Shift-log JSON exports
- 111 deterministic tests and a clean production build
- Direct production testing in ChatGPT's in-app browser and Google Chrome with WebMCP enabled
Nothing sends an order, updates a rota, contacts a supplier, or writes restaurant data to a server. All names, events, inventory, quantities, and costs are fictional.
Built With
- html
- react
- typescript
- vercel
- vite
- vitest
- webmcp
Log in or sign up for Devpost to join the conversation.