Inspiration

Every small-business owner knows the night-before feeling: "I think Saturday's covered." Usually it isn't quite. One person is down for two things at once, someone was assigned but never said yes, or a helper cancelled and nobody noticed the gap. A voice assistant that cheerfully says "you're all set" makes that worse.

It's a big group of people with a real problem. The SBA Office of Advocacy's 2025 profile counts 5,720,093 US small businesses with 1 to 19 employees (https://advocacy.sba.gov/wp-content/uploads/2025/06/United%5FStates%5F2025-State-Profile.pdf). In Adobe's 2025 survey of 1,018 solopreneurs and small-business owners, nearly half said they find it hard to disconnect on time off (https://www.adobe.com/acrobat/resources/work-life-balance-trends-for-entrepreneurs.html). We wanted an Alexa+ experience that won't lie to them.

What it does

In our simulated Alexa+ experience, you ask, "I'm off Saturday. Is the flower shop covered?" The assistant calls the Open Tomorrow MCP server and answers only from real tool results:

  • It finds the exact clash ("Helper A is down for setup and delivery, and those overlap 8:30 to 9:00").
  • It separates assigned from agreed. Nothing is covered until the assigned helper accepts that exact version of the task.
  • When a helper cancels, it reopens only the affected task and rejects the old "yes" from the cancelled assignment.
  • It says "covered" only for the tasks you entered, and only after you confirm that's the whole list.
  • You can talk normally: "Helper A is swamped, let Helper B take the flowers run" becomes checked tool calls.
  • A live MCP App card (the server's own interactive board) updates beside the conversation, and its Refresh button calls the server.
  • A helper can accept from their own phone: scan the QR code, tap Accept, and the owner's screen flips to covered.

How we built it

  • MCP server: three tools (create_handover, check_coverage, change_handover) over Streamable HTTP, protocol 2025-11-25, built with the official MCP TypeScript SDK (1.30.0) and Zod schemas. Every change is revision-checked and idempotent (operation IDs), so a stale or replayed request can't silently overwrite the plan.
  • MCP Apps: all three tools declare one view, ui://open-tomorrow/board.html (@modelcontextprotocol/ext-apps 1.7.5). The judge page hosts it with the official AppBridge in a sandboxed iframe. The view has no network access of its own, and its buttons call tools through the host, so they show up in the MCP wire like any other call.
  • Workers AI language layer, where the model proposes and the rules decide: free text goes to Llama 3.3 70B on Workers AI with a JSON schema. The model may propose at most 3 {action, person, task} steps. Each id is checked against the plan, a wrong-person guard applies, and each step is rewritten as a sentence the deterministic router must classify the same way. Anything else falls back to the keyword router. The model never decides coverage: only the MCP tools do.
  • Cost guard: a global Durable Object counter caps AI calls at 250 per UTC day (about half of the free daily allocation) and 40 per session. Past the cap the page quietly uses the keyword router, so a busy day can't become a bill.
  • Agent Skill: skills/open-tomorrow/SKILL.md teaches any skills-aware agent the safe workflow: read before you write, send the current revision, treat assigned as not agreed, never reuse an old yes, and say "covered" only for entered tasks. A test checks it against the real tool names and error codes.
  • Hosting: one Cloudflare Worker serves the page and the MCP endpoint. Each visitor gets a private Durable Object session that expires after a day.
  • Simulated Alexa+ layer: the browser runs a real MCP client (initialize, tools/list, tools/call). Turns can be scripted ("Play all", with 2× speed), typed or spoken (Web Speech API where supported). Every call, including the Workers AI · interpret step, is shown live in the "MCP wire" panel.
  • Helper QR: generated locally in the page (no external services). The phone card records a simulated acceptance through the same coverage rules.
  • For judges: docs/FOR_JUDGES.md maps every claim to the file that implements it, for each judging criterion.
  • Tests: 38 Node tests (coverage rules, MCP tools and App resource, AI step parsing and fallbacks with a fake model, mic scoring, the skill). There is also an end-to-end demo script and a smoke test that runs against the live Worker.

Challenges we ran into

  • Making "covered" mean something narrow and true. Acceptance is tied to a task version, so any reassignment or retime makes old yeses invalid automatically.
  • Letting a language model help without letting it decide. We solved it by making the model's output a proposal the deterministic rules must agree with, keeping the keyword router as a fallback, and capping usage so it stays within the free tier.
  • Fitting an MCP App into a Worker: ext-apps 2.x needs SDK v2, so we pinned 1.7.5. Zod's bundled locales doubled the view's size until we trimmed them in the build.
  • Browser microphone input took three rounds of fixes.

Accomplishments that we're proud of

A judge can watch it refuse to be fooled. Press "Play all" and, after Helper B cancels, the next turn tries to reuse B's old yes. The server rejects it live, with a red STALE_OR_WRONG_ASSIGNMENT in the wire panel. Then say anything in your own words, watch Workers AI turn it into checked tool calls, see the MCP App card update, accept on a phone from the QR card, and watch the board turn green.

What we learned

Often the most useful thing an assistant can say about tomorrow is "not yet," followed by the one next step that fixes it. A language model is useful for understanding people, but the rules about what's true should stay deterministic.

What's next for Open Tomorrow

  • Connect the same MCP server to real Alexa+ once self-hosted MCP testing is open to outside developers.
  • Real helper identity on the accept card.
  • Recurring weekly templates.
  • Plans that cover more than one day.

Deliberate boundaries (honesty note)

  • The Alexa+ voice layer is simulated in the browser (the track's simulated-experience path). The MCP server, the MCP App and their tool calls are real. No Alexa device or Alexa developer console is involved.
  • Free-text understanding uses Workers AI (Llama 3.3 70B) to propose steps, which deterministic rules check. The keyword router is the fallback, and the model never decides coverage. The optional mic uses the browser's own speech recognition.
  • All acceptance is a simulated helper action, not identity-authenticated consent.
  • The result covers entered tasks only. Missing duties are unknown, not safe. This is not labor-law, staffing or safety advice.
  • All people, the shop and every acceptance are fictional.

Built With

  • agent-skills
  • cloudflare-workers
  • durable-objects
  • esbuild
  • javascript
  • llama-3.3
  • mcp-apps
  • model-context-protocol
  • modelcontextprotocol-ext-apps
  • modelcontextprotocol-sdk
  • node.js
  • typescript-sdk
  • web-speech-api
  • workers-ai
  • wrangler
  • zod
Share this project:

Updates

Submission history