Unrush MCP Server
Generates a link to each grocery item on Amazon as part of the drafted order, so the user can add products to their Amazon cart and check out themselves (checkout within Unrush is simulated and consent-gated).
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Unrush MCP Servermy 5:30 meeting ran late — what's for dinner and do I need groceries?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Unrush
An assistant that speaks first, before your evening falls apart.
Unrush is a proactive household assistant presented as a simulated Alexa+ experience. It watches your calendar, your kitchen and your groceries. When a late meeting squeezes your evening, it tells you when to leave, swaps tonight's dinner for something that fits, notices the eggs are out and the milk is about to run out, and drafts the grocery order. Nothing is bought until you say yes.
Built for Build, Ship, Shape: Amazon Developer Hackathon (Alexa+ track + AWS Builder mini challenge).

▶️ Watch the 3-minute demo with sound: codergirl73.github.io/unrush (MP4 file). The script is in DEMO_SCRIPT.md.
Both were recorded locally on real Amazon Bedrock (Nova 2 Lite) with AgentCore Memory, using the guided demo: make the meeting run late → Unrush speaks first → say yes → pick a pesto → "Yes, place the order." To try it yourself, see Setup and Run.
Self-hosted MCP server: spec 2025-11-25 over Streamable HTTP, built with the official TypeScript SDK
@modelcontextprotocol/sdk1.32.1.MCP Apps: the server ships interactive
ui://views (evening timeline, grocery order) via the official@modelcontextprotocol/ext-apps.Agent Skill:
skills/unrush-evening-rescue/SKILL.md(open Agent Skills format), loaded by the agent at runtime.Amazon Bedrock: the Converse API runs the agent loop and calls the MCP tools. Amazon Bedrock AgentCore Memory (optional) keeps the conversation and household preferences across sessions and restarts.
TypeScript everywhere, Node 20+, npm workspaces, SQLite, Vitest. MIT licensed.
What is real and what is simulated? See Real vs simulated. In short, the MCP server, the Bedrock agent, the prediction logic and the memory are real. The calendar data, the travel times and the checkout are simulated and labelled Simulated in the UI.
The hero flow
A late meeting lands. Your 5:30 Project sync now runs to 7:00, on an evening you planned to cook (
npm run demo:trigger).Unrush speaks first: "Your 5:30pm Project sync now runs to 7pm. To reach your 7:30pm Study group you'll need to leave by 7:05pm."
The dinner swap. Tonight's 45-minute chicken curry no longer fits; your longest free stretch is 40 minutes. Unrush offers a 15-minute tomato & garlic spaghetti made from what's in the pantry.
Groceries. Eggs are out (you said so this morning). Milk will run out tomorrow, predicted from six weeks of purchases.
The order. Unrush builds the order with your usual products from past orders, and asks which one for anything new ("Which pesto?"). It reads the order back and asks "Shall I place the order?" Nothing is bought without an explicit yes. On yes you get a simulated confirmation, plus a link to each product on Amazon, where you add it to your cart and check out yourself.
Memory. Reload the page, start a new session or restart the server, and Unrush still remembers everything, because the state lives in the MCP server's SQLite database.
Related MCP server: wegmans-mcp-cloudflare-workers
Architecture
flowchart LR
subgraph Browser["Browser · React (simulated Alexa+ experience)"]
UI["Voice orb · cards · agent activity panel"]
end
subgraph Web["Web backend · Express (packages/web/server)"]
API["/api/chat · /api/state<br/>/api/events (SSE)"]
Agent["Agent loop<br/>ConverseCommand ⇄ tools<br/>(≤ 8 iterations)"]
Poller["Alert poller<br/>get_alerts every 3 s"]
Skills["Agent Skill<br/>SKILL.md + load_skill"]
AppsHost["MCP Apps host<br/>AppBridge (iframe)"]
Bridge["McpBridge<br/>SDK Client +<br/>StreamableHTTPClientTransport"]
end
subgraph AWS["Amazon Bedrock"]
Converse["Converse API<br/>(BEDROCK_MODEL_ID)"]
ACMem["AgentCore Memory<br/>events + preferences<br/>(optional)"]
end
subgraph MCP["Unrush MCP server (packages/mcp-server)"]
HTTP["POST/GET/DELETE /mcp<br/>Mcp-Session-Id · spec 2025-11-25"]
Tools["17 tools · 2 resources<br/>2 MCP Apps ui:// views"]
Engine["Proactive checker<br/>every 60 s + on every write"]
Providers["CalendarProvider → SimulatedCalendar<br/>TravelProvider → SimulatedTravel<br/>Clock"]
DB[("SQLite<br/>UNRUSH_DB_PATH")]
end
UI -- "text / speech" --> API
API -- "SSE: proactive speech,<br/>tool calls, replies" --> UI
API --> Agent
Poller --> Agent
Agent <--> Converse
Agent --> Skills
API <--> ACMem
UI --> AppsHost
AppsHost --> API
Agent --> Bridge
Poller --> Bridge
Bridge <--> HTTP
HTTP --> Tools
Tools --> DB
Tools --> Providers
Engine --> DB
Trigger["npm run demo:trigger<br/>(SDK client)"] --> HTTPHow a proactive moment flows:
demo:trigger(itself an MCP SDK client) callsadd_or_update_event.The MCP server's proactive checker runs immediately and writes
leave_byandmeal_fitalerts to SQLite.The backend's poller claims them with
get_alerts {mark_delivered: true}.The poller runs the Bedrock agent with a proactive instruction ("speak first; explain, propose the fix, ask one yes/no question; don't act yet").
The agent calls MCP tools (
compute_leave_by,suggest_quick_meal).The backend streams every step to the browser over Server-Sent Events. The browser shows the banner, speaks the reply and fills the activity panel.
MCP server
packages/mcp-server is the piece to read first. It is a self-hosted MCP server.
Spec | 2025-11-25. The negotiated version is logged at each session init and checked: |
Transport | Streamable HTTP at |
SDK |
|
State | Everything is keyed by |
Logging | Every tool call is logged with its arguments and duration in ms; proactive alerts are logged when they fire |
Tools. Each tool has a zod input schema, a structured output schema and an LLM-oriented description.
Area | Tool | What it does |
Calendar |
| Events for a date (default today), with |
| Create an event, or change one by id (the "late meeting") | |
| event start − travel (TravelProvider) − buffer; also the free minutes after the previous event, and any overlap | |
Pantry & meals |
| add / remove / set. "We're out of eggs" is |
| Diets, allergies, household size, usual and latest dinner time, leave buffer | |
| One dinner per date, with | |
| Recipes ≤ | |
| Subtracts the dinner's ingredients from the pantry and logs the consumption. Idempotent | |
Groceries |
| Per staple: predicted run-out date, confidence and a one-line reasoning, from purchase and usage history |
| Missing meal ingredients + predicted run-outs + out-of-stock items, deduplicated and grouped by store section. Saved as a draft | |
| Refuses unless | |
| Sets which store product to buy for an item the household has no history for (e.g. which pesto); placed choices become "your usual" | |
| The latest order (or one by id), with its read-back | |
Proactive |
| Re-evaluates the rules and returns pending alerts. |
Resources:
unrush://households/{id}/pantryunrush://households/{id}/schedule/today
MCP Apps (@modelcontextprotocol/ext-apps 1.7.5, the release line built for MCP SDK 1.x). The server registers two interactive views with registerAppResource, served as text/html;profile=mcp-app:
View | Linked tools ( | What it shows |
|
| Tonight's events (moved meeting vs its old end), the leave-by time, and tonight's dinner before → after. It calls |
|
| Items by aisle with reasons, plus a consent-first button |
Any MCP Apps-capable chat host renders these views inline. Each view is one self-contained HTML file that inlines the official App runtime, follows the host theme and auto-resizes. The order view's button does not call place_order: it sends "Yes, place the order." as a user message, so the normal consent path decides.
The Unrush web UI includes a small MCP Apps host (the official AppBridge + PostMessageTransport, in a sandboxed iframe). Flip Cards → MCP Apps in the header to see the same cards served by the MCP server. Tool calls from inside views are proxied for read-only tools only.
Proactive checker. The checker runs every 60 s and immediately after any calendar, pantry, plan or order write. Its rules:
(a) leave_by: the departure is squeezed by the previous event (≤ 30 min of slack, or an overlap), or it is within 60 min.
(b) meal_fit: tonight's dinner
prep_minutesis longer than the longest free stretch. The stretch runs fromcook_window_starttolatest_dinner_time, minus events and travel.(c) runout: a staple is out, or is predicted to run out within 2 days.
Alerts are stored with dedupe keys and resolve themselves when the situation goes away (for example, the meeting moves back or the dinner is swapped).
Run-out prediction. For each staple bought at least 3 times:
daily usage = (total bought − on hand) ÷ days since the first purchase
days left = on hand ÷ daily usage
confidence comes from the number of purchases and how regular the intervals were (coefficient of variation)
The reasoning string is meant to be read aloud, for example: "Bought 11× in the last 6 weeks, about every 4 days (usually 2 l). Uses ~511 ml/day. 600 ml left → likely runs out tomorrow."
Providers.
CalendarProvider: the default isSimulatedCalendar(seeded events in SQLite).TravelProvider: the default isSimulatedTravel(fixed minutes per place, e.g. Library 20).Clock: real time, orUNRUSH_NOW.
A Google Calendar provider or a real maps API would implement the same interfaces. Both are on the roadmap and not built.
Checking it with MCP Inspector:
npm run dev
npx @modelcontextprotocol/inspector
# Transport: Streamable HTTP · URL: http://localhost:3001/mcp → Connect → Tools → get_alerts {household_id: "demo-household"}Agent Skill
skills/unrush-evening-rescue/SKILL.md is written in the open Agent Skills format: YAML front matter with name and description, a playbook body, and references/consent.md. It encodes the rescue order: leave-by first, then the dinner swap, then groceries, ordering only on an explicit yes.
Any skills-aware agent can use it. In Unrush it is loaded at runtime by packages/web/server/skills.ts:
Skills are discovered and their front matter validated at startup.
The skill catalog (name + description) goes into the system prompt.
A local
load_skilltool gives progressive disclosure, including referenced files (with a path-escape check).Proactive turns activate the skill directly, so its playbook is always in context when Unrush speaks first.
Where Amazon Bedrock is used
Bedrock is on the live code path for every conversation turn and every proactive moment. It is not optional decoration.
File | What it does |
Creates | |
Converts the MCP | |
Calls | |
Runs the agent for chat turns ( | |
Warm, brief voice persona anchored to the MCP server's clock: always use tools, short replies that can be spoken, never order without an explicit yes | |
Amazon Bedrock AgentCore Memory ( | |
|
AWS services used: Amazon Bedrock (Converse API) for the agent and tool use, and Amazon Bedrock AgentCore (Memory, data plane and control plane) for conversation and preference memory.
The model is never hard-coded: set BEDROCK_MODEL_ID to a model or inference profile enabled in your account. Tool use is required. Amazon Nova 2 Lite (us.amazon.nova-2-lite-v1:0) is the recommended small, cheap default. In our live tests it chained the 5 tool calls of the hero flow in one turn and kept replies speakable; Nova Lite (us.amazon.nova-lite-v1:0) also works but tends to answer in bullet lists.
Two locks on "nothing is bought without your yes":
The MCP
place_ordertool refuses unlessconfirmed === true.The backend blocks any
place_order {confirmed: true}unless the assistant's previous turn asked about placing the order and the user's reply is an unambiguous yes (consent.ts). Proactive turns can never place orders.
Real vs simulated
Piece | Status |
MCP server, tools, Streamable HTTP sessions, SQLite memory | Real |
Amazon Bedrock Converse agent loop with tool use | Real (needs your AWS account) |
Leave-by math, free-time windows, quick-meal ranking, run-out prediction, order building | Real logic |
Speech recognition and speech output | Real browser Web Speech APIs |
Calendar events | Simulated: seeded demo data ( |
Travel times | Simulated: fixed estimates per place ( |
Grocery checkout, confirmation number, ETA | Simulated: Unrush never places a real order and no money moves. The UI labels it "Simulated checkout" |
Store products and Amazon links | Real: Amazon's own grocery brands with real ASINs ( |
Six weeks of purchase history | Simulated: seeded so the prediction has data to learn from |
AgentCore Memory | Real when |
MCP Apps views | Real MCP Apps resources; the in-app host is a minimal reference host |
"Offline rehearsal" mode ( | A scripted stand-in, not Bedrock, for rehearsing the UI without AWS. Its MCP calls are real. The UI shows an orange "Offline rehearsal (not Bedrock)" badge whenever it is on |
This is a simulated Alexa+ experience in a web browser. It is not an Alexa skill and does not use any Amazon device or Alexa service.
Privacy
Data stays local. All household state is in a SQLite file on your machine. The only data that leaves it is the conversation and tool results sent to Amazon Bedrock and, if you turn it on, conversation turns stored in AgentCore Memory, both in your own AWS account.
Nothing is bought without explicit consent. Two independent checks enforce this (see above). Checkout is simulated anyway.
No card data. There are no payment fields or payment APIs anywhere, and nothing that stores card data. The simulated checkout only produces an order summary and a fake confirmation number.
.envand*.dbare gitignored. Credentials are never written by the app.
Setup
Prerequisites: Node.js 20.6+ (developed on Node 24) and an AWS account.
Enable a Bedrock model. In the Amazon Bedrock console, pick your region (e.g.
us-east-1), open Model access and enable a model that supports tool use. Amazon Nova Lite is cheap and fast. Many models must be called through a cross-region inference profile (IDs likeus.amazon.nova-lite-v1:0); check Cross-region inference in the console for the exact ID available to you.Credentials come from the default AWS credential chain. The simplest is
aws login(AWS CLI 2.32+, browser sign-in, short-lived credentials);aws configure,aws sso login,AWS_PROFILE, environment variables or an IAM role also work. The identity needsbedrock:InvokeModelfor that model or profile.Install and configure:
git clone <this repo> && cd amazon-developer-hackathon
npm install
cp .env.example .env # set AWS_REGION and BEDROCK_MODEL_ID; optionally UNRUSH_NOW=15:00
npm run seed # create / reset the demo household
npm run agentcore:setup # optional: create the AgentCore memory, then add AGENTCORE_MEMORY_ID to .envAgentCore Memory needs bedrock-agentcore:CreateMemory, GetMemory and ListMemories for the setup script, and CreateEvent, ListEvents and RetrieveMemoryRecords at runtime. Without it, Unrush uses in-process conversation memory; household state is always kept in the MCP server.
Run
npm run dev # MCP server :3001 + API :3000 + UI http://localhost:5173
npm run demo:trigger # in another terminal: the late meeting lands → Unrush speaks first
npm run seed # reset everything for another take (also clears today's AgentCore conversation if enabled)npm run chatis a terminal REPL against Bedrock + MCP, useful to check your model before opening the UI.npm run dev:offlinerehearses the UI without AWS, using the scripted stand-in (not Bedrock).Recording tip: the demo evening runs 5:30 to 9:30pm. If you record later in the day, set
UNRUSH_NOW=15:00in.env, then reseed and restart, so the Unrush clock starts at 3pm and keeps ticking.Voice: hold the orb (or Space) to talk; Chrome has the best Web Speech support. Use the speaker toggle to mute spoken replies.
Guided demo: the step bar under the header follows the story from the live state. Make the meeting run late does what
npm run demo:triggerdoes, and Start over re-seeds the day at 3pm (noUNRUSH_NOWneeded).
Host it
deploy/deploy.sh puts a public demo on one EC2 t4g.micro in your account. It runs the MCP server, the web backend and Caddy, which gives it automatic HTTPS on an <ip>.sslip.io hostname.
./deploy/deploy.sh # reads AWS_REGION, BEDROCK_MODEL_ID and AGENTCORE_MEMORY_ID from .env; prints the URL
./deploy/update.sh # pull the latest main onto the instance and restart
./deploy/teardown.sh # delete everything it createdA household per visitor. With
UNRUSH_PUBLIC=1, each browser gets its own household by cookie, seeded so its day starts at 3pm whenever the visitor arrives. Each household has its own alerts, conversation and AgentCore actor, and is deleted after 24 hours.Capped Bedrock use. Visitors get 40 messages an hour, an address can start 10 sessions an hour, and the whole site gets 1,500 Bedrock turns a day. Set these with
UNRUSH_TURNS_PER_HOUR,UNRUSH_HOUSEHOLDS_PER_IP_PER_HOURandUNRUSH_TURNS_PER_DAY. Past the daily cap, Unrush still speaks first using the alert text.Least privilege, no keys. The instance's IAM role allows only Converse with the configured model and the four AgentCore Memory calls (deploy/iam-policy.json). Only ports 80 and 443 are open, with no SSH; use Session Manager for a shell. The MCP server listens on localhost only.
Cost: about $10 a month (t4g.micro, public IPv4 address, 8 GB disk) plus Bedrock usage.
Test
npm test # 104 Vitest tests across both workspaces
npm run typecheckWhat the tests cover:
Every tool: leave-by math and overlaps, free-time windows, quick-meal ranking with diet and allergy filters, run-out prediction (dates, confidence, reasoning), order building and dedupe, and
place_orderrefusing without confirmation.Proactive rules, dedupe and self-resolution.
MCP integration: the real HTTP server driven by the SDK client, checking that the negotiated protocol is
2025-11-25, the tool and resource listing, the hero flow with the agent scripted, reconnect, and a server restart.Agent loop: a fake Converse client against the real MCP server, including the order-consent gate and the 8-iteration cap.
MCP Apps: tool
_metalinks, resource MIME type and HTML, and host routes (views may call read-only tools only).Agent Skill: front-matter validation,
load_skill(including path escapes), and activation on proactive turns.AgentCore Memory: command shapes against a fake data plane, continuity across a backend restart, recall in the prompt, and turns that still succeed when AgentCore fails.
Phase 3 end to end: late meeting → SSE proactive speech → swap → read-back → explicit yes → simulated confirmation, plus the fallback that still speaks first when the model is unavailable.
Hosted demo: separate households per browser, a 3pm clock whatever the real time, the late-meeting and reset endpoints, and the turn and session caps.
Cost
A full hero run is about 6–8 Converse calls of a few thousand input tokens each (mostly the 16 tool schemas). With Amazon Nova Lite that is a fraction of a cent per run; check current Bedrock pricing for your model and region. BEDROCK_MAX_TOKENS caps output per call, and token usage is shown per turn in the agent activity panel. AgentCore Memory, if enabled, adds a small per-event and per-retrieval charge (two or three calls per turn); check current AgentCore pricing. Nothing else in the stack costs money.
Project layout
packages/mcp-server MCP server: transport, tools, proactive engine, providers, seed, demo trigger, tests
packages/web/server Express backend: MCP client bridge, Bedrock agent loop, consent gate, SSE, CLI
packages/web/src React UI: voice panel, cards, MCP Apps host, agent activity panel
skills/ Agent Skills (SKILL.md) loaded at runtime
docs/ALEXA_PLUS.md Alexa+ MCP Toolkit readiness and path to a live add-on
DEMO_SCRIPT.md 2:45 video script
FRICTION_LOG.md Friction hit with the MCP SDK, Streamable HTTP and Bedrock
FEEDBACK_NOTES.md What worked well / what needs workAlexa+ readiness
Alexa+ add-ons connect through the Alexa+ MCP Toolkit, which requires an MCP server on spec 2025-11-25 over Streamable HTTP, and supports MCP Apps. Those are exactly what Unrush's server implements. What a live add-on still needs:
a public HTTPS URL;
OAuth 2.1 with PKCE for account linking;
Amazon Wallet checkout endpoints in place of the simulated checkout;
Private Preview access.
See docs/ALEXA_PLUS.md for a requirement-by-requirement comparison with Amazon's docs, the exact path (alexa-ai new mcp … && alexa-ai deploy), and draft add-on metadata.
Coming next
Out of scope for the hackathon build and not implemented:
Live on Alexa+: connect this MCP server through the Alexa+ MCP Toolkit (public hosting + OAuth 2.1), and move checkout to Amazon Wallet so Alexa+ handles payment and confirmation. See docs/ALEXA_PLUS.md
Real integrations: Google Calendar (
CalendarProvider) and live travel times (TravelProvider), behind env flagsFitness and workouts
Body tracking
Habit and goal coaching
Restaurant suggestions when there's no time to cook at all
Ride booking when the leave-by time is too tight
License
This server cannot be deployed
Maintenance
Related MCP Connectors
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
Discover, plan and run tools across your connected business systems through one OAuth MCP endpoint
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Set up and run an in-product AI assistant: widgets, knowledge, MCP connections, usage.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to read current pantry inventory and low-stock shopping needs, export a shopping queue, and perform idempotent inventory adjustments and catalog link management through remote MCP tools.MIT
- AlicenseNot gradedqualityCmaintenanceEnables users to search grocery products and stores, manage a cart, sync purchase history, and predict needed items through MCP tools. It also stores food preferences as server instructions so connected agents can respect them automatically.1MIT

Pantry Buddy MCPofficial
AlicenseNot gradedqualityCmaintenanceEnables managing a personal pantry, shopping lists, cookbook recipes, and saved receipts remotely through MCP tools using natural language or API calls.MIT- AlicenseNot gradedqualityBmaintenanceEnables Alexa+ and other MCP clients to manage a household's shared shopping list, bills, chores, and pantry expiry through natural-language voice interactions. It provides read-only briefings and confirmation-gated updates for recurring household logistics.MIT