Inspiration

Every fitness app makes you type. Logging lunch means searching a food database with greasy fingers; logging a set means unlocking your phone between reps. Most trackers also don't know what a roti or a chicken karahi is. We wanted the opposite: say what you ate or what you lifted, and let the assistant do the bookkeeping, the maths and the shopping.

What it does

Dayform is an Alexa+ add-on. You talk to Alexa, and Alexa:

  • Logs meals in plain words, desi food included. "I had two rotis, chicken karahi and a mango lassi for lunch" logs three items (904 kcal, 48.7 g protein), says what it assumed ("1 plate of chicken karahi = 250 g"), and tells you what's left today. "Actually, make that one roti" fixes it (904 → 785 kcal). In the demo video Nova Sonic heard "chicken curry" instead of "karahi", so that take shows 721 → 602 kcal; both are real runs on the same seed.
  • Runs your gym session. "Start push day" gives today's first set (bench press 80 kg × 8); "done, eight reps" logs it, spots a new estimated-1RM PR (101.3 kg, +2.6 kg) and starts the rest timer; "my shoulder feels off, swap the overhead press" picks a shoulder-friendly alternative (landmine press 32.5 kg × 6).
  • Plans meal prep and fills your Amazon cart. "Plan my meal prep for the next four days and add what I need to my cart" builds a 4-day plan from a real grocery catalog, checks every day against your targets, turns it into packs to buy, asks you to confirm ("Add 12 items, about $112, to your Amazon cart?"), then hands off a real Amazon Add-to-Cart link. Alexa never places the order; you check out on Amazon.
  • Adapts overnight. A nightly job reviews the week. "Good morning" gives a brief: "You lost 0.3 kg this week instead of 0.4 kg, so I reduced 110 calories daily" (2,360 → 2,250 kcal), today's lead lift (squat 102.5 kg × 5), and one insight from your data (protein is 162 g on training days but 104 g on rest days).
  • Shows progress. "How's my bench going?" draws a 6-week estimated-1RM line.

Every answer comes with a 768×480 MCP Apps card: rings, meal logged, live workout with rest countdown, PR celebration, progress chart, meal-prep carousel, cart with QR code, morning brief. Without a screen, Alexa just speaks.

How I built it

The add-on is a self-hosted MCP server, exactly what an Alexa+ add-on is: MCP protocol 2025-11-25 over Streamable HTTP, stateful sessions, 18 tools (one per customer intent), 8 MCP Apps cards. TypeScript on Node with @modelcontextprotocol/sdk 1.32.1, zod contracts shared by the server, the mock, the cards and the simulator.

Architecture

You (voice or text)
  -> Simulator: React "Echo Show" screen  <-WebSocket->  simulator backend
       backend <-bidirectional stream-> Amazon Nova 2.5 Sonic on Bedrock (Alexa's voice and brain)
       backend --MCP 2025-11-25, Streamable HTTP, SigV4--> Dayform MCP server on Amazon Bedrock AgentCore Runtime
                     server -> Aurora PostgreSQL Serverless v2 (17.11) via the RDS Data API
                     server -> Amazon Nova 2 Lite on Bedrock (judgment calls only)
                     server -.Add-to-Cart link.-> amazon.com cart
  EventBridge Scheduler (03:00 Asia/Karachi) -> Lambda overnight job -> Aurora + Nova 2 Lite
  • Alexa side. We don't have a way to run a private add-on on a real Alexa+ device, so a web simulator plays the Echo Show. Nova 2.5 Sonic is its voice and its brain: it hears you, picks the tool, fills the structured inputs, and speaks the reply from the facts the tool returns. Typed input works too. The simulator talks to our server through a real MCP client, so nothing in the server is simulator-specific.
  • Server side. Each tool is a contract (zod input, zod output, card) plus a handler. A registry checks every output against its contract before it leaves the server, attaches _meta.ui.resourceUri for the card, and turns any throw into an MCP error.
  • The model judges, code checks. Amazon Nova 2 Lite estimates foods the table can't match (labeled "estimated"), writes meal plans, reviews next-session targets and writes the morning brief. Code does every number: food search and nutrient maths, Mifflin-St Jeor targets, the adaptive weekly check-in with a ±250 kcal cap, double progression, Epley e1RM, PR detection, grocery packs and prices. Every model output passes a zod schema and a code check before it is stored: meal plans may use catalog ingredients only (a zod enum), code fits the grams so each day lands within ±5% of calories, and every number in the morning brief is compared with the database (a mismatch regenerates once, then falls back to a code sentence).
  • Under 500 ms. The confident path makes no model call. Slow model work runs in the overnight job or in the background (plan_meal_prep with new constraints returns {status: "preparing"} and the plan is ready a few seconds later).
  • Food data. 1,659 foods: 1,396 USDA FNDDS + 208 SR Legacy, plus 55 desi entries (from FNDDS codes or standard USDA-ingredient recipes). Search is exact alias, then pg_trgm trigram similarity, then portion resolution; vague portions log a standard portion and return the assumption.
  • Cart. A 38-item grocery catalog with real ASINs and prices read from amazon.com on 2026-10-22. Checkout asks for confirmation through MCP elicitation, then returns an https://www.amazon.com/associates/addtocart?AssociateTag=…&ASIN.n=…&Quantity.n=… link. Links go through one CartProvider interface (Add-to-Cart link, search-link fallback).
  • Hosting. [T-40] The server container (linux/arm64) runs on Amazon Bedrock AgentCore Runtime in stateful MCP mode with SigV4 inbound auth, deployed with CloudFormation; the overnight job is a Lambda function on an EventBridge Scheduler cron. The same container runs locally in Docker against local Postgres.

Measured, not claimed

  • Tool latency on the server (S1–S6 from the seed state): log_meal 13–91 ms, correct_meal 13–52 ms, live-workout tools ≤ 21 ms, the 4-tool meal-prep-to-checkout chain ≤ 60 ms per call (cached plan), get_morning_brief 11–16 ms, get_progress 3–5 ms.
  • AgentCore Runtime (smoke deployment): warm MCP ping p50 118 ms from our laptop to us-east-1; elicitation round trip 230 ms.
  • Nova 2.5 Sonic: end of speech to first audio p50 1.2 s on tool turns.
  • Food search: 100/100 top-1 on our food-word test set, p50 about 10–12 ms per item on Postgres.
  • Meal plans: 10/10 within tolerance on the bench (3.0–4.2 s each); with a 12-item grocery cap, 5/5 within tolerance and $94–108 carts.
  • Aurora: Data API p50 81 ms from the laptop; a full demo reset in 2.4–3.0 s, giving byte-identical table hashes to local Postgres.
  • Server test suite: 89/89 passing.

What's real and what's sample data

  • Real: every AWS service call (Bedrock Nova 2 Lite and Nova 2.5 Sonic, AgentCore Runtime, Aurora with the Data API, Lambda, EventBridge Scheduler); USDA nutrient data; the 38 grocery ASINs and prices (read 2026-10-22); the Amazon Add-to-Cart link, which fills a real signed-in cart; every number in the demo, which comes from a real run.
  • Sample: one demo user, "Ali", with 6 weeks of generated history (42 days, 24 workouts, 378 sets, daily weigh-ins) from a deterministic seed. The demo runs on a demo clock (demo day 2026-10-23, 13:00 Asia/Karachi), rest timers are shortened to 10 s, and the video uses cached overnight output so every take is identical (the live overnight run takes about 7 s and gives the same brief). A hidden demo panel resets the seed state and "skips to morning".
  • Simulated: the device. The simulator stands in for an Echo Show; Dayform has not been certified or published as a real Alexa+ add-on.

How it meets the Alexa+ add-on rules

  • MCP 2025-11-25 over Streamable HTTP at an HTTPS endpoint (AgentCore Runtime).
  • One tool per customer intent, no overlaps: 18 tools, each with a description that says when to call it, why, and what it returns.
  • Declare only parameters we honor; output matches the declared schema (the registry rejects a non-matching output before it leaves the server).
  • Always a result or an error: any failure becomes an MCP error with a plain message.
  • Facts, not scripts: tools return structuredContent and short fact text; Alexa writes the spoken reply.
  • Visuals: tools link their card with _meta.ui.resourceUri; cards are single-file MCP Apps at 768×480 (text/html;profile=mcp-app); voice-only still works.
  • Elicitation confirms checkout, sent on the tool call's own response stream so it works on AgentCore.
  • Under 500 ms on every confident path.
  • No purchases by voice: Alexa builds and confirms the cart; the user checks out on Amazon.
  • A second understanding mode (UNDERSTANDING=server) gives every tool one plain-text input that the server's own model parses, for clients without a strong language model (0.6–1.4 s per call by design).

Challenges we ran into

  • Elicitation silently vanished on AgentCore. The MCP SDK sent it on the standalone GET stream, which AgentCore answers with 405, and the SDK dropped it without an error. The fix is one option (relatedRequestId), but finding it took a trace of every HTTP exchange.
  • Nova Sonic called dependent tools in parallel and repeated a pending checkout, so a second confirmation popped up mid-sentence. The simulator backend now runs a turn's tool calls in order and de-duplicates them.
  • A non-JSON tool result ended the whole Sonic session.
  • The documented Add-to-Cart link opened an empty cart. We found the endpoint Amazon redirects to and verified it fills a real cart.
  • Long structured output from Nova was flaky (a 4-day plan sometimes came back with fewer days), so the planner asks for 1–2 day menus that alternate, fits grams in code, and sends misses back for up to 3 rounds.

Accomplishments that I am proud of

  • A real MCP server that follows the Alexa+ add-on rules, with 18 tools and 8 cards, running on AgentCore Runtime. [T-40]
  • Desi food that just works: "two rotis, chicken karahi and a mango lassi" resolves to the right foods and portions.
  • From "plan my meal prep" to a filled Amazon cart in one sentence and one "yes".
  • A morning brief where every number is checked against the database before Alexa says it.

What I learned

  • Let the model judge and let code count. Every place we let code own the numbers got faster and more reliable.
  • Stream-level details matter on managed runtimes: which HTTP stream a server-to-client request rides decides whether it arrives.
  • Voice models need orchestration around them: ordering tool calls, waiting out playback, renewing sessions before the 8-minute cap.

What's next for Dayform

  • Run on a real Alexa+ device once add-on publishing is open, with OAuth 2.1 (authorization code + PKCE) sign-in and multiple users.
  • A program builder and more programs, beyond the one pre-set 4-day program.
  • A pantry step for meal plans, and fresh groceries through Amazon Fresh where available.

Built With

  • alexa-plus
  • amazon-alexa
  • amazon-aurora
  • amazon-bedrock
  • amazon-bedrock-agentcore
  • amazon-cloudwatch
  • amazon-ecr
  • amazon-eventbridge-scheduler
  • amazon-nova
  • aurora-serverless
  • aws-cloudformation
  • aws-iam
  • aws-lambda
  • aws-secrets-manager
  • docker
  • drizzle-orm
  • mcp-apps
  • model-context-protocol
  • nova-2-lite
  • nova-sonic
  • pg-trgm
  • postgresql
  • rds-data-api
  • typescript
  • vitest
Share this project:

Updates

Submission history