Care that asks before it alerts. Hearthbeat is a privacy-first care companion for older adults who live alone. It learns the usual rhythm of a home from Ring motion, door-contact and doorbell events (never video or audio), notices when a day looks different, has Alexa+ gently check in with the resident first, and tells family only when there is no answer or the answer means trouble, always with the reasons.
Built for Build, Ship, Shape: Amazon Developer Hackathon (Alexa+ track; Ring data as the signal source;
Open Source mini challenge for the dayrhythm library).
Demo video (under 3 minutes): https://youtu.be/axVTrTiKaog
| Alexa speaks first (simulated proactive check-in) | Family asks on the phone; the MCP App card renders |
|---|---|
![]() |
![]() |
- In the US about 28% of people aged 65+ living in the community live alone (ACL, 2023 Profile of Older Americans).
- One in four older adults reports a fall every year, and falls are the leading cause of injury-related death among adults 65+ (CDC). Worldwide, falls kill about 684,000 people a year, and adults over 60 suffer the most fatal falls (WHO).
- Lying on the floor for an hour or more after a fall was strongly associated with serious injury, hospital admission and moves into long-term care, and call alarms were usually not used in those cases (Fleming & Brayne, BMJ 2008; a small cohort of people over 90).
- Amazon's Alexa Together caregiving subscription (activity feed, "no activity by a set time" alerts) is no longer available; Amazon's page, updated 21 May 2025, points customers to Alexa Emergency Assist (Amazon). Emergency Assist helps the person who can ask for help. Hearthbeat is for the morning they can't.
- By 2030 one in six people worldwide will be 60 or over (WHO).
- Signals, not surveillance. Ring webhooks (motion, door contact opened/closed, doorbell press) arrive signed (HMAC-SHA256 over the raw body) and are stored as device, room, kind, time. Nothing else. Doorbell motion counts as outside; animal and vehicle motion is ignored; video is never requested.
- A per-home rhythm. The open-source
dayrhythmlibrary turns events into daily markers (morning movement, first kitchen activity, front-door trip, night-time trips, longest quiet spell, evening) and learns a robust baseline (median and MAD-based spread). Every deviation is explained: "No kitchen activity yet by 11:05 AM (usually 7:53 AM, give or take 20 min)." - Ask first. A
concernstarts a spoken check-in through Alexa+. "I'm fine, I just slept in" closes it. No answer: Alexa asks once more after 15 minutes, then family gets an alert with the reasons. "I fell" or "I need help" alerts family at once and tells the resident to call 911 or say "Alexa, call for help" (Emergency Assist). Quiet hours hold routine check-ins; a door open in the middle of the night skips them. An offline sensor never raises an alarm. - The resident owns it. Three sharing levels (essentials, rhythm, detailed), quiet hours, pause while away, "what does my family see?", an audit log of every family view and alert, and erase-on-request. Family cannot change any of it.
flowchart LR
subgraph Home["Resident's home"]
M[Ring Alarm motion detectors]
C[Ring contact sensors]
D[Ring Video Doorbell]
end
M --> RC
C --> RC
D --> RC
RC[(Ring cloud, or the local Ring sandbox)] -->|webhook v1.1 + X-Signature| WH["POST /ring/webhook"]
WH --> DB[(SQLite: events, check-ins, alerts, audit)]
DB --> DR["dayrhythm: markers, baseline, explanations"]
DR --> CARE["Care loop: check-in, re-ask, alert"]
CARE --> MCP["MCP server /mcp<br/>Streamable HTTP, protocol 2025-11-25<br/>12 tools + ui:// MCP App card"]
MCP <-->|initialize, tools/list, tools/call, resources/read| AX["Alexa+ (real add-on) or simulated Alexa+ host"]
AX --- ECHO[Resident's Echo Show]
AX --- APP[Family's Alexa app]
CARE --> API["/api JSON"]
API --> WEB["React caregiver app + landing page"]
OAUTH["OAuth 2.1: client_credentials + auth code/PKCE"] -.-> MCP
| Part | Where | Notes |
|---|---|---|
| MCP server | hearthbeat/server.py |
Official MCP Python SDK 2.3 (MCPServer), Streamable HTTP, Pydantic output schemas, tool annotations, MCP Apps extension |
| Care loop | hearthbeat/care.py |
assessment, door and offline-sensor rules, check-ins, escalation, answer understanding |
| Roles and privacy | hearthbeat/service.py |
resident-only controls, share-level filtering, audit log |
| Ring | hearthbeat/ring/ |
webhook verify/parse, REST client (/v1/devices, /v1/history/...), sandbox with documented shapes |
| Routine library | packages/dayrhythm |
MIT, zero dependencies, its own tests |
| Account linking | hearthbeat/auth.py |
follows the Alexa+ MCP Authentication and Account Linking pages |
| Simulated Alexa+ | hearthbeat/host/ |
real MCP client sessions; Nebius Token Factory model or deterministic router |
| Web | web/ |
React 18, Vite, Tailwind v4, Motion; built from the shared design kit |
| MCP App card | hearthbeat/widget/care_card.html |
ui://hearthbeat/care-card-<hash>.html, MCP Apps postMessage protocol, no external requests |
| Tool | Who | What |
|---|---|---|
get_wellbeing_status |
both | today vs usual, level, reasons, open check-in prompt, alerts (MCP App card) |
get_daily_rhythm |
both | a day's markers vs usual (MCP App card) |
get_recent_alerts |
both | alerts with their reasons (MCP App card) |
start_checkin |
both | start or return the open check-in; returns what Alexa should say |
log_response |
resident | record the answer: ok, unwell, help, unclear |
notify_caregiver |
resident | message family (fyi, soon, urgent) |
acknowledge_alert |
caregiver | "I've called her, she's fine" |
set_quiet_hours |
resident | no routine check-ins in this window |
pause_monitoring |
resident | pause or resume |
get_sharing_summary |
resident | who sees what, recent views, what is never collected (MCP App card) |
set_sharing_level |
resident | essentials, rhythm or detailed |
erase_my_data |
resident | destructive, needs confirmation |
Requirements: Python 3.11+ and Node 22+ (for the web build). No API keys are needed.
python -m venv .venv && . .venv/Scripts/activate # Windows; on macOS/Linux: . .venv/bin/activate
pip install ./packages/dayrhythm -e ".[dev]"
cd web && npm ci && npm run build && cd ..
python -m hearthbeat --port 8000Open http://127.0.0.1:8000 for the landing page, #today for the caregiver app and #alexa for the simulated Alexa+
conversation. The MCP endpoint is http://127.0.0.1:8000/mcp. On first start a demo household is created on the Ring
sandbox with 21 days of simulated history (Margaret, 79; caregivers James and Priya). The Try a day panel rebuilds
today as one of five scenarios and delivers it as signed Ring webhooks to the real receiver.
Optional: copy .env.example to .env. NEBIUS_API_KEY makes the simulated Alexa+ use an open model on Nebius Token
Factory for tool choice and phrasing; without it a deterministic router is used. RING_ACCESS_TOKEN and
RING_API_BASE_URL point the Ring client at a real Ring API (see KEYS_NEEDED.md).
npx -y @modelcontextprotocol/[email protected] --cli http://127.0.0.1:8000/mcp --transport http --method tools/list
npx -y @modelcontextprotocol/[email protected] --cli http://127.0.0.1:8000/mcp --transport http --method tools/call --tool-name get_wellbeing_statusWithout auth, requests act as the resident (margaret); send X-Hearth-User: priya to act as a caregiver. With
HEARTH_AUTH_MODE=oauth the server behaves as the Alexa+ docs describe: 401 (no WWW-Authenticate) without a token,
client_credentials service tokens for discovery, and authorization-code + PKCE user tokens for household tools.
pytest # 64 tests: 57 server (raw JSON-RPC Inspector-style, SDK client, Ring, care loop,
# privacy, OAuth, simulator, widget) + 7 for the dayrhythm library
python scripts/bench_latency.py http://127.0.0.1:8000/mcp
node scripts/screenshots.mjs http://127.0.0.1:8000 # Devpost screenshots via headless ChromeWhat the tests pin down, among others: the server negotiates 2025-11-25 (and 2025-03-26 and 2025-06-18, which appear
in Alexa+ doc examples, plus the stateless 2026-07-28 revision); every tool's structuredContent validates against
its outputSchema; Ring webhooks need a valid signature and are idempotent; an unanswered check-in is asked twice and
then escalated with reasons; an offline sensor never triggers a check-in; only the resident can change settings; every
family view is audited; OAuth follows the Alexa+ rules.
Measured on 13 Oct 2026 (Windows 11 laptop, loopback): warm get_wellbeing_status p50 14 ms over Streamable HTTP
(first call 400 ms while the baseline is computed). Alexa+ asks for under 500 ms.
- Docker:
docker build -t hearthbeat . && docker run -p 8000:8000 -e PUBLIC_BASE_URL=https://your.host hearthbeat(multi-stage: builds the web app with Node, runs Python 3.12). The Dockerfile was not built locally because Docker is not installed on the development machine. - Render (free):
render.yamlblueprint. Free instances sleep when idle and have an ephemeral disk: the demo household is re-seeded on start; real households would need a persistent disk or an external database. - Hugging Face Spaces (Docker, free CPU): create a Docker Space, push this repo, set
PORT=7860andPUBLIC_BASE_URL=https://<space>.hf.spaceas variables, and addapp_port: 7860to the Space README front matter. - Alexa+: see KEYS_NEEDED.md and
addon-package/addon.draft.json(icons and carousel are served from/addon/...).
- Tech implementation: a self-hosted MCP server on the official SDK, protocol 2025-11-25 over Streamable HTTP,
output schemas, annotations, an MCP App card with a content-hashed
ui://URI, OAuth that follows the Alexa+ account-linking rules (including the documentedclient_credentialstier and 401 withoutWWW-Authenticate), and a Ring integration built on the documented webhook v1.1 envelope, HMAC verification, idempotency and JSON:API devices. Validated with the official MCP Inspector CLI and 64 automated tests. - Design: voice-first, two people, two devices. Alexa asks the resident before anyone else is told; answers are short
and never say "anomaly". Screens get a card that adapts to Echo Show and phone via
hostContext.deviceClass. The caregiver app shows reasons, not raw data. - Potential impact: a specific, sourced need (people living alone, falls, the long wait), a gap Amazon's own product line left, and hardware households already own. Alexa+ add-ons and Ring's developer platform are US-first today, which is also where the 28% figure comes from.
- Quality of the idea: the judging guide's "context-aware add-on that maintains state across sessions" and "agentic workflow" in a non-security Ring use case (care-taking), with consent and explainability designed in rather than bolted on.
- All demo data is simulated on a local Ring sandbox that reproduces the documented API shapes. Real Ring access needs identity verification, a device and a US Ring Protection plan (see FRICTION_LOG.md).
- Hearthbeat has not run on a real Alexa+ device: the Alexa+ add-ons console shows "Coming Soon" for this developer account. The simulated Alexa+ host in this repo is the hackathon's documented alternative path; the MCP server is built to onboard unchanged.
- The proactive "Alexa speaks first" moment is simulated; MCP add-ons have no documented proactive-speech capability.
- Contact-sensor webhook payloads were not shown in the Ring docs; the base v1.1 envelope is assumed.
- Not a medical device and not an emergency service.
MIT (LICENSE). Fonts are OFL (Open Runde, Inter, Instrument Serif, Fragment Mono, Silkscreen) and self-hosted. Icons: Lucide (ISC). No stock photos. Statistics are cited inline above.


