An Alexa+ MCP server that turns voice into dinner. KitchenSync gives an AI agent a complete, live model of one household kitchen — pantry inventory with expiry tracking, a recipe book with ingredient-level matching, a shopping list, and the meal plan — exposed through 14 MCP tools over Streamable HTTP (spec 2025-11-25).
Your fridge is a database you've never been able to query. KitchenSync fixes that: "Alexa, what can I cook tonight?" now has a real answer, backed by tool calls.
docs/demo-video/kitchensync-demo.mp4 (subtitles burned in — an .srt sits next to it)
Hackathon tracks: Primary Alexa+ (self-hosted MCP server, Streamable HTTP, spec 2025-11-25) · Mini challenge Open Source (MIT). The Fire TV–style Cook Mode view connects the living room to the same MCP server.
Every household runs a tiny supply chain — buy food, store it, cook it, throw out what spoils — and it's all tracked in nobody's head. Generic assistants guess. An agent with tools doesn't have to:
| You say | The agent does (real MCP tool calls) |
|---|---|
| "What can I cook tonight?" | pantry_list_items → recipes_match_by_ingredients → "Cacio e Pepe, 100%, 15 min…" |
| "What's expiring soon?" | pantry_expiring_soon → recipes_match_by_ingredients → "spinach in 2 days — a frittata would use it up" |
| "Let's have the chicken tinga tacos tonight" | mealplan_set → "you're missing tortillas and limes — want them on the list?" |
| "Add tortillas and limes to the shopping list" | shopping_add_items ✓ |
| "I'm back from the store!" | shopping_mark_purchased → the pantry auto-restocks, and the tacos now match at 100% |
| "Start cook mode" | recipes_get → the recipe lands on the TV screen, D-pad step-by-step |
The shopping loop closes: plan → buy → restock → cook → use — every step a tool call an agent can chain.
you (voice) any MCP client
│ (Inspector, agents, …)
▼ │ JSON-RPC
┌─────────────────────────┐ ▼ POST /mcp
│ simulated Alexa+ web │ plain fetch ┌──────────────────────────┐
│ experience (public/) │ ───────────────▶│ KitchenSync MCP server │
│ rule-based planner or │ Streamable │ (src/, TypeScript) │
│ any OpenAI-compatible │ HTTP │ 14 tools · 3 resources │
│ LLM w/ tool-calling │ │ 2 prompts · stateless │
└─────────────────────────┘ └───────────┬──────────────┘
│ JSON state
┌────────────────────────┐ ▼
│ Fire TV Cook Mode │ same MCP endpoint src/data/state.json
│ (public/tv.html) │ ◀──────────────────── (auto-seeded)
└────────────────────────┘
One process serves everything: the MCP endpoint, the simulated Alexa+ experience, and the TV view — so localhost demos "just work" with zero configuration.
npm install
npm start| URL | What |
|---|---|
http://localhost:3000/ |
Simulated Alexa+ experience (chat) |
http://localhost:3000/tv |
Fire TV-style Cook Mode |
http://localhost:3000/health |
Health + counts |
POST http://localhost:3000/mcp |
The MCP endpoint (Streamable HTTP) |
Requires Node 20+ (24 recommended). The pantry auto-seeds with a realistic 42-item kitchen (incl. items about to expire, so the demo always has something to say). npm run reset gives you a fresh one.
Try it from any MCP client — the endpoint is stateless, so a single POST is a complete conversation turn:
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"pantry_expiring_soon","arguments":{"days":3}}}'Works with MCP Inspector too: npx @modelcontextprotocol/inspector, transport = Streamable HTTP, URL = http://localhost:3000/mcp.
| Tool | What it does |
|---|---|
pantry_list_items |
Full inventory: quantities, storage location, days-to-expiry |
pantry_add_item |
Add/restock an item (merges by name) |
pantry_use_item |
Mark as used while cooking; auto-removes at zero |
pantry_remove_item |
Remove an item |
pantry_expiring_soon |
Waste-reduction lens: items inside an N-day window |
recipes_search |
By keyword / max minutes / cuisine / diet |
recipes_match_by_ingredients |
⭐ Ranks recipes by % of required ingredients you have; reports exact missing items (staples like salt/oil ignored) |
recipes_get |
Full recipe: ingredients with quantities + numbered steps |
shopping_list_items |
Read the list |
shopping_add_items |
Add items (typically the missing ones from matching) |
shopping_remove_items |
Remove items |
shopping_mark_purchased |
✅ Check off after a store run — purchased items restock the pantry automatically |
mealplan_set |
Plan a meal (fuzzy names OK: "the pad thai") |
mealplan_get |
What's for dinner (default: today) |
Every tool returns structured JSON in content[0].text, designed for agent chaining. The server also ships instructions in its initialize response describing the intended flows.
pantry://inventory · shopping://list · mealplan://today
plan_dinner (plan tonight from the pantry, waste-aware) · reduce_waste (find dishes that use up what's expiring)
The bundled web app (/) looks and feels like an Echo Show: an animated Alexa orb, typewriter replies, live tool-call cards with expandable JSON-RPC frames, and side panels (pantry / shopping list / tonight's plan) that update as the tools mutate state. The MCP wire log drawer (bottom-right) shows every real JSON-RPC request/response.
Two interchangeable planners drive it:
- Rule-based (default) — deterministic intent → tool-call chains, zero config, always works offline. The full demo runs on this.
- Real LLM (optional) — click ⚙ and point it at any OpenAI-compatible endpoint (Ollama, LM Studio, vLLM, Bedrock via proxy…). It performs genuine tool-calling against the same MCP server, same wire log.
This is the "simulated Alexa+ experience" path from the track brief — and because the server underneath is a real, spec-compliant MCP server, the same tools are ready for a hosted integration.
/tv is a 10-foot living-room UI — big type, ambient scene, readable from the couch:
- Shows tonight's plan (set by voice through MCP) with an ingredient checklist: green ✓ = in the pantry, amber ! = missing
- Cook Mode:
Enterstarts,←/→step through the recipe exactly like a Fire TV remote's D-pad,iflips the ingredient overlay - Live-syncs every 15s — set dinner from the chat, watch the TV update
npm run smoke # spawns an isolated server on :3999 and drives the full
# demo journey over real MCP Streamable HTTP (29 assertions:
# handshake, protocol version, all tool flows, edge cases)npm test aliases are kept minimal on purpose — the smoke suite is the app's contract. It covers: initialize negotiation (2025-11-25), tools/resources/prompts listings, the cook-matching chain, meal planning, shopping → pantry restock loop (with a 100%-match assertion after restock), expiry ordering, fuzzy-name resolution, and error suggestions.
src/
index.ts Express: POST /mcp (stateless Streamable HTTP) + static hosting
server.ts McpServer factory: 14 tools, 3 resources, 2 prompts
store.ts Pantry/shopping/mealplan state (JSON-persisted, seeded)
recipes.ts Recipe matching engine (loose ingredient equality, staples)
util.ts Name normalization + aliases + date math
data/recipes.json 26 original recipes, 6 cuisines, diet-tagged
public/
index.html + app.js + kitchen.js Simulated Alexa+ experience
tv.html + tv.js Fire TV-style Cook Mode
scripts/
smoke.mjs E2E journey test req-*.json curl-ready payloads
screenshot.mjs UI screenshots (optional, needs `npm i -D puppeteer`)
docs/
demo-script.md 3-minute demo video storyboard
screenshots/ Captured by scripts/screenshot.mjs
PRODUCT_FEEDBACK.md Per-tool feedback + friction log (built during the Amazon
Developer Hackathon, Oct 2026 — submission window missed,
shared publicly as a portfolio piece)
Development feedback on every tool/SDK used — plus a friction log with severity, workarounds, and suggestions — lives in PRODUCT_FEEDBACK.md.
- Multi-household + auth (API keys per family)
- Receipt scanning →
shopping_mark_purchased(photo of the grocery receipt restocks the pantry) - Dietary profiles ("grandma is visiting — gluten-free this week") constraining
recipes_match_by_ingredients - Real Alexa+ preview integration once available to outside developers
- Bedrock-native LLM planner option
MIT — see LICENSE.
