KitchenSync
README.md
# π² KitchenSync
**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.

**βΆοΈ Watch the 2:14 narrated demo:** [`docs/demo-video/kitchensync-demo.mp4`](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](#-fire-tv-cook-mode) view connects the living room to the same MCP server.
---
## Why
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.
## Architecture
```
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.
## Quickstart
```bash
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:
```bash
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`.
## The MCP API
### Tools (14)
| 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.
### Resources (3)
`pantry://inventory` Β· `shopping://list` Β· `mealplan://today`
### Prompts (2)
`plan_dinner` (plan tonight from the pantry, waste-aware) Β· `reduce_waste` (find dishes that use up what's expiring)
## The simulated Alexa+ experience
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:
1. **Rule-based (default)** β deterministic intent β tool-call chains, zero config, always works offline. The full demo runs on this.
2. **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.
## πΊ Fire TV Cook Mode
`/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**: `Enter` starts, `β`/`β` step through the recipe exactly like a Fire TV remote's D-pad, `i` flips the ingredient overlay
- Live-syncs every 15s β set dinner from the chat, watch the TV update
## Testing
```bash
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.
## Repo layout
```
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)
```
## Feedback & friction
Development feedback on every tool/SDK used β plus a friction log with severity, workarounds, and suggestions β lives in [PRODUCT_FEEDBACK.md](PRODUCT_FEEDBACK.md).
## Roadmap
- 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
## License
MIT β see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues