Inspiration
Most recipes tell you how long one dish takes. They don't tell you when to start each dish so that three of them finish together on one oven, or what to change when one of them runs late. We wanted to solve the second problem, and a kitchen speaker is the right place for it, because your hands are busy and the plan changes while you cook.
We also wanted a test with an exact answer. If the salmon needs five more minutes at 6:20 PM, only the salmon should move, dinner should move from 6:30 to 6:35 PM, and the rice and green beans should keep their times. Our scenario tests check for exactly that.
What it does
One Oven is a self-hosted MCP server for the Alexa+ track. It plans a home meal backward from dinner time, treats oven preheating and pan capacity as constraints, and repairs the schedule when one dish runs late. We show it in our own web simulator of an Alexa+ screen device and a voice-only speaker.
The server has six MCP tools:
| Tool | What it does |
|---|---|
set_kitchen |
Ovens, burners, cooks, time zone |
list_dishes |
The eight built-in recipes |
plan_meal |
Backward plan from a serving time, with preheat steps |
next_step |
What to do now; a step is done only when the cook says so |
report_delay |
Takes "the salmon needs five more minutes" and returns the new serving time and the exact changed steps |
swap_dish |
Replaces one dish and keeps the rest |
- Preheating is its own step, so nothing is scheduled into a cold oven.
- Saying the same delay twice counts once. The second call returns
deduplicated: trueand the plan version stays the same. - On a speaker with no screen the same tools answer by voice. Replies are at most two sentences and 30 words and never mention IDs, tools or screens.
- An eight-dish Thanksgiving menu fits potatoes and stuffing into the oven while the turkey rests.
How we built it
browser UI ──loopback──> simulator host ──> Strands Agent
text / mic WAV Whisper STT │ OneOvenMcpClient
speech playback <───── system TTS ▼ Streamable HTTP, MCP 2025-11-25
MCP server
deterministic engine + SQLite
The MCP server uses the official TypeScript SDK (@modelcontextprotocol/sdk 1.32.1) with Streamable HTTP and JSON responses. A smoke test asserts that protocol version 2025-11-25 is negotiated.
Scheduling is done by a deterministic reverse scheduler with a thermal model: preheat and cool-down rates, a 25°F range for dishes sharing the oven, and pan capacity. An independent verifier rechecks every plan, and the model never computes a time. Plans live in SQLite. Each change runs in one BEGIN IMMEDIATE transaction and writes a version event with the exact before and after step changes. Optional request_id keys and a 20-second implicit guard make retries safe.
The agent host is built on the Strands Agents TypeScript SDK 1.21.0. A Strands Agent and McpClient call the server over HTTP in text mode, in voice mode and from the simulator. Timers run in the host, not on the server. Speech recognition is local whisper.cpp (base.en), replies use the system TTS, and nothing is spoken until it passes a lint check.
The simulator is an Express host and a Vite page with a Now card, a Run of Show timeline and a speaker mode. The browser never calls MCP and never computes a schedule. The plan, timeline and tool calls on screen come from structuredContent of the tool results, and each take writes a sync log with monotonic timestamps and the drawn rectangle of every bar.
Out of the box the agent runs a scripted model that follows the demo conversation, so the demo needs no account or API key. Our live trials used a local OpenAI-compatible model.
Challenges we ran into
- IDs disappeared between tool calls. Strands 1.21.0 forwards only
contentand dropsstructuredContent, so the model never saw thekitchen_idit needed for the next call. We override the publicMcpClient.callTooland append the structured result as JSON (friction entry F-12). - In the first live evaluation the model filled host-owned fields such as
based_on_version: 1, andset_kitchenfailed withversion_conflictin all five trials. AlistToolsoverride now hides those fields from the model-facing schema. - Voice was too slow at first. In one 20-turn weekday flow the baseline path made 54 model requests and the median turn took 6.52 s. We now speak the tool's validated
saythrough theAfterToolsEventhook, apply timers in the host and trim the context. The same flow took 20 requests, with a 2.45 s median. - With an en-us synthetic voice,
base.enrecognized 6 of 12 clips ("burners" came out as "burgers"). An en-gb voice plus one shared list of cooking words reached 12/12. - Participants get no Alexa+ MCP Toolkit, CLI or web simulator (F-05), and we found no documented way to hand cooking timers to Alexa's built-in timers (F-09). We built our own simulator and run the timers in the host.
- The simulator log had a race. If a page finished loading after a new take had started, that take logged no clock sync at all. A browser test exposed it, and the UI now logs once per take.
Accomplishments that we're proud of
npm run checkpasses. It covers the build, recipe validation, 79 unit and integration tests, an HTTP smoke test, a scripted text E2E, and four YAML scenarios in engine, MCP and agent modes (12/12). The tests include 1,000 seeded random kitchen, delay and swap cases checked by the verifier.- With a live local model, 19 of 20 scenario trials passed (4 scenarios × 5).
- On a delay only the changed bars animate. A Playwright test reads the sync log and checks that every other bar kept its rectangle.
- The repository has three friction-log entries and six feature requests, each linked to its evidence.
What we learned
Let the engine do the math. A language model is good at picking the right tool and unreliable at adding minutes across ovens, burners and pans.
Alexa phrases its replies from the data you return, so every tool result carries a short say that can be spoken as is. Speaking it directly was also one of the changes that made voice mode faster.
Writing the expectation first paid off. The four YAML scenarios are both the regression suite and the demo script, so the scenes in the video are the same ones the tests run.
What's next for One Oven
- Cook real weeknight dinners with it and calibrate the recipe timings.
- Test it with people's voices in a real kitchen.
- Run the agent on Amazon Bedrock.
- Add OAuth and household selection, then deploy publicly.
- Hand timers to Alexa's built-in timers once a documented contract exists.
Built With
- espeak-ng
- express.js
- fast-check
- ffmpeg
- mcp-typescript-sdk
- model-context-protocol
- node.js
- playwright
- sqlite
- strands-agents
- streamable-http
- typescript
- vite
- whisper.cpp
- yaml
- zod
Log in or sign up for Devpost to join the conversation.