Skip to main content
Glama

AccessBell

Multi-sensory AI door intelligence for accessibility and independent living.
Ring · Fire TV · Alexa+ (MCP) · AWS Bedrock

ci License: MIT

Most doorbell apps are built around a phone chime and a small screen. That works well for many people — and leaves others out, often without anyone intending it.

AccessBell is a companion layer on Ring, Fire TV, and Alexa+: the same door event, delivered in ways more people in the household can actually use. It is not a new camera, and it is not a caregiver surveillance product. The person who lives there stays in control.

See

Full-screen caption on Fire TV in <200 ms (rules first — no waiting on a model)

Understand

Plain-language why in EN/VI, with confidence and evidence — it will not invent who is at the door

Ask

Spoken daily brief and door history via Alexa+ MCP

Act

One tap, TV remote (D-pad), or voice

Protect

Optional escalation if nobody answers — audited, revocable, off by default

Tagline: Accessibility, not surveillance.

Situation people describe

How AccessBell can help

Hard of hearing — the hallway strobe is easy to miss from the kitchen

Large, high-contrast Fire TV caption; urgency shown as text, not color alone

Blind or low vision — hard to “scan” a timeline of thumbnails

Spoken brief and TTS-friendly captions; history answered with event citations

Limited mobility — the phone is across the room, or gestures are tiring

Reply from the TV remote or by voice; no swipes, no hurry

Living alone — a missed pharmacy drop can turn into a long worry

Expected windows + optional escalation to someone you choose, always audited

Child home after school — unsure who is at the door; parent at work

Calm, simple caption and large TV buttons; parent is contacted only when you allow it and nobody answers

Multi-generational home — one doorbell, different needs

The same event: caption for a grandparent, buttons for a child, a parent loop if wanted

Many “eldercare” tools put monitoring first

Here the resident is the user; sharing is opt-in, logged, and easy to revoke

In one sentence: AccessBell makes the front door understandable on the screens and speakers a household already has — without turning the home into a surveillance product.


Architecture at a glance

AccessBell is the door-intelligence layer in a multi-MCP home — not a monolith calendar app and not a new camera.

                    ┌──────────────────┐
   schedule intent  │  Calendar MCP    │  (household schedule — any compliant server)
        │           └────────▲─────────┘
        │    Alexa+ orchestrates tools by intent
        ▼                    │
┌───────────────┐    ┌───────┴────────┐    ┌─────────────────────┐
│  Voice / app  │◄──►│    Alexa+      │◄──►│  AccessBell MCP     │
│  (resident)   │    │  (MCP client)  │    │  door intelligence  │
└───────────────┘    └────────────────┘    └──────────▲──────────┘
                                                      │
                     Ring device signals              │
                     webhook + HMAC                   │
┌───────────────┐    Partner API v1.1                 │
│ Ring cloud    │─────────────────────────────────────┤
└───────────────┘                                     │
                           Fire TV / PWA  ◄───────────┤
                           captions + D-pad           │
                           consent SMS/share ◄────────┘

Piece

Role

Ring

Emits door/motion events (webhook). Physical device not required to develop.

AccessBell

Ingest → Tier 1 fast caption → Tier 2 grounded meaning → act / escalate / brief

AccessBell MCP

Door tools for agents (alerts, brief, expected context, replies, escalation, a11y prefs)

Calendar MCP

Holds personal/household schedule — separate from AccessBell

Alexa+

Orchestrator: can call calendar tools and AccessBell tools in one turn

Fire TV / PWA

Largest-screen captions and one-tap / remote replies

How schedule joins the door

Pattern

What happens

Orchestrator join (primary)

“Expect pharmacy ~10” → Alexa writes calendar (if connected) and add_expected_context on AccessBell

Pipeline join (optional)

AccessBell may call a Calendar MCP list_events during enrichment — off by default

Honest bound: the Alexa+ MCP toolkit does not give a single add-on your Google/Outlook calendar. AccessBell stores door intent you (or the orchestrator) explicitly provide; it does not scrape private calendars in MVP.

Why multi-MCP raises the product

  • Right tool, right job — schedule stays in calendar systems; door logic stays in AccessBell

  • Alexa+ has a real role — voice orchestration across tools, not a thin remote

  • Evidence gate stays local — even with calendar context, AccessBell demotes captions that lack evidence

  • Consent stays local — escalation/share never leave AccessBell’s audit model

Schedule-aware door (product)

Households already plan pharmacy drops, packages, and school runs. When that intent is written into AccessBell, the next ring can ground to it:

You set intent

Voice or API: add_expected_context (e.g. pharmacy ~10:00)

The door uses it

In-window events get clearer captions + evidence; routine visits can be quieter

You stay in control

Opt-in memory; revoke/clear anytime; no face recognition


Related MCP server: Guardian MCP

How it works

Ring webhook (HMAC)  ──►  AccessBell  ──►  Fire TV / PWA  (Tier 1 caption <200ms)
        optional mock              │
                                   ├─►  Tier 2 (rules → Bedrock/stub) + expected_context
                                   ├─►  AccessBell MCP  ◄──►  Alexa+  ◄──►  Calendar MCP
                                   └─►  consent escalation / share (opt-in)
  1. Tier 1 (rules) — instant “Someone is at the door” (never blocked on the model).

  2. Tier 2 (LLM) — EN/VI captions with confidence + evidence; specific categories without evidence are demoted in code (grounding rule).

  3. Surfaces — Fire TV visual, Alexa+ voice via AccessBell MCP, PWA quick replies.

  4. Schedule — expected windows (door intent) improve grounding; personal calendars stay in other MCP servers if you connect them via Alexa+.

  5. Protect — unanswered high-urgency → consented contact; audit trail; revoke works.


Features (MVP)

  • Ring webhook ingest with HMAC-SHA256 (X-Signature: sha256=…), Partner API v1.1 payloads, request_id idempotency + debounce

  • Event taxonomy: MED_DELIVERY, PACKAGE_DELIVERY, FAMILY_VISITOR, UNKNOWN_VISITOR, MOTION_ANOMALY

  • Evidence-grounded triage: category, confidence, evidence[], captions EN + VI (TTS-safe)

  • Fire TV-friendly web UI: large text, urgency text + color, SSE live, D-pad navigation, why-line + grounding badge, EN/VI, child mode, escalation countdown + Stop, PWA manifest

  • Read-only advisor (GET /api/advise) suggests expected windows — never auto-writes

  • Self-hosted MCP server (Streamable HTTP, spec 2025-11-25) — 11 tools for Alexa+ / agents

  • Evidence gate made legible: triage carries grounding (grounded / generic / demoted_insufficient_evidence) + a plain-language why-line

  • Door calendar: add / list / clear expected context; optional Calendar MCP join (J2, off by default)

  • Child-safe captions and share protocol (preview → consent → apply → read-back → revoke)

  • Quick replies: leave package / coming / not now, plus child-friendly “waiting for parent”

  • Daily personal brief + consent-driven share (audit log)

  • Consent escalation (default OFF): “if nobody answers, tell Lan” — durable across restarts

  • Mock mode — full demo without Ring hardware (MOCK_MODE=true)

  • Bedrock via LangChain Converse + structured TriageResult (AWS Builder mini)

  • SQLite or Postgres; Docker / Cloud Run scripts; 271 tests (SQLite; Postgres when DSN set)


Repository layout

aws-access-bell/
├── README.md
├── LICENSE
├── policy.yaml             # machine-readable privacy/guardrail policy
├── .env.example
├── Dockerfile / docker-compose.yml   # container + local demo stack
├── requirements.txt        # core (stub runs offline) + requirements-llm.txt / requirements-postgres.txt / requirements-dev.txt
├── .github/workflows/ci.yml          # pytest (sqlite + postgres) + docker build + container smoke
├── backend/
│   ├── main.py             # FastAPI app: API routes, SSE stream, MCP endpoint
│   ├── config.py           # env-based Settings (typed)
│   ├── db.py               # repository facade (SQLite/Postgres via storage dialects)
│   ├── storage/            # sqlite.py + postgres.py dialects + make_dialect()
│   ├── schema.sqlite.sql / schema.postgres.sql   # DDL per dialect
│   ├── webhook.py          # Ring Partner API webhook + HMAC-SHA256 + v1.1 parse + debounce
│   ├── ring_client.py      # Ring Partner API client (api.amazonvision.com; optional live)
│   ├── captions.py         # EN/VI presentation strings (single source; TTS-safe)
│   ├── triage.py           # Tier 1 rules + Tier 2 pipeline; pydantic TriageResult
│   ├── escalation.py       # EscalationManager: durable pending + acknowledge/audit
│   ├── brief.py            # Daily personal brief
│   ├── mcp_server.py       # MCP tools over Streamable HTTP (JSON-RPC 2.0)
│   ├── calendar_mcp.py     # optional Calendar MCP client join (J2, off by default)
│   ├── policy.py           # policy.yaml version + SHA (audit / metrics)
│   ├── oauth.py            # OAuth 2.1 resource-server verification (JWKS, scopes, CF header)
│   ├── notifier.py         # Pluggable announce / SMS (no-op in mock)
│   ├── util.py             # RateLimiter, ISO timestamps
│   ── llm/
│       ├── base.py         # TriageLLM protocol
│       ├── stub.py         # deterministic offline provider (no deps)
│       ├── langchain_provider.py  # one ChatModel + with_structured_output(TriageResult) for all live LLMs
│       └── __init__.py     # build_llm(settings) provider factory
├── web/                    # Fire TV + PWA UI (index.html / app.js / style.css, manifest + icon, SSE, D-pad, EN/VI)
├── mock/events/            # 6 fixture stories (Ring Partner API v1.1 envelopes)
├── mock/calendar_mcp/      # optional Calendar MCP stub (J2 demo)
├── prompts/triage.txt      # LLM system prompt: TriageResult contract + guardrails
├── scripts/                # demo_story.py (guided demo), demo_local.py, reset_db.py, ablation_evidence.py, check_docs_consistency.py, deploy_cloudrun.sh, smoke_docker.sh
├── docs/
│   ├── ARCHITECTURE.md     # technical design: flows, API, auth, data model, tests traceability
│   ├── DEPLOYMENT.md       # system shape, deploy targets, scaling, secrets, go-live checklist
│   ── internal/           # strategy + planning notes — local only, not published (gitignored)
└── tests/                  # pytest: triage, captions/a11y, Ring Partner API v1.1 (webhook/hmac/idempotency), db (sqlite+postgres), mcp, api, escalation, oauth, llm factory

Quick start

Prerequisites

  • Python 3.11+

  • AWS account with Bedrock model access (or set LLM_PROVIDER=stub for offline)

  • Optional: Ring developer credentials, Alexa+ / MCP client

Run with mock data (no Ring required)

git clone <this-repo>
cd aws-access-bell
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env

# Offline demo without Bedrock
export MOCK_MODE=true
export LLM_PROVIDER=stub

python -m uvicorn backend.main:app --reload --port 8080

Open:

No AWS account? Everything still works

Piece

AWS-typical

No-AWS path (already wired)

LLM

Bedrock

LLM_PROVIDER=stub (offline) or ollama (local) or openai / anthropic / google (free-tier keys)

MCP auth

Cognito

Leave OAUTH_ISSUER empty → MCP_HTTP_TOKEN local mode; or Okta Free Developer org (see .env.example)

Ring

live webhook

MOCK_MODE=true fixtures

Bedrock and Cognito are optional production paths. The default is offline-friendly: "designed for Bedrock, tested with stub, flip via env."

Environment

See .env.example for all variables:

Variable

Default

Purpose

MOCK_MODE

true

Use fixtures instead of live Ring

LLM_PROVIDER

stub

stub | bedrock | openai | anthropic | google | ollama

LLM_MODEL

provider default

Optional model override (per-provider defaults below)

DB_URL

sqlite:///accessbell.db

Storage: SQLite or postgresql://user:pw@host:5432/db

DB_PATH

accessbell.db

SQLite file (used when DB_URL is empty)

PORT

8080

HTTP port (any platform; Cloud Run injects PORT)

WEB_DIR

web

Static UI directory

MOCK_EVENTS_DIR

mock/events

Fixture JSONs

*_API_KEY

OPENAI_/ANTHROPIC_/GOOGLE_API_KEY per provider

BEDROCK_MODEL_ID

us.amazon.nova-lite-v1:0

Bedrock model

OLLAMA_BASE_URL

localhost:11434

Ollama server

LLM_TIMEOUT_SECONDS

5

Model call budget (→ Tier 1 only on timeout)

RING_*

Live Ring credentials (optional)

RING_WEBHOOK_ENABLED / RING_WEBHOOK_SECRET / RING_SIGNATURE_HEADER

false / – / X-Signature

Webhook HMAC verify (Partner API)

RING_API_BASE_URL

https://api.amazonvision.com

Ring Partner API base

MCP_HTTP_TOKEN

Bearer token for MCP HTTP (demo mode; replaced by OAuth when enabled)

MCP_ORIGIN

Optional allowed Origin(s) (host or full URL), comma-separated

OAUTH_ISSUER

OAuth 2.1 issuer (Cognito / Okta) — set → /mcp requires JWT; empty → falls back to MCP_HTTP_TOKEN

OAUTH_JWKS_URL / OAUTH_AUDIENCE / MCP_RESOURCE

JWKS discovery override, expected audience, RFC 8707 canonical URI

OAUTH_REQUIRE_RESOURCE

false

Strictly enforce resource claim on tokens

CF_ACCESS_JWT_ENABLED

false

Accept Cf-Access-Jwt-Assertion as user-tier token (Cloudflare Access)

MCP_401_WWW_AUTHENTICATE

true

false for Alexa+ (401 without WWW-Authenticate)

CALENDAR_MCP_URL / CALENDAR_MCP_TOKEN

Optional Calendar MCP join (J2): Tier 2 reads list_events and cites calendar: evidence; empty = standalone

CONTEXT_BUDGET_MS

200

Calendar-context budget; slower → context_status=timeout, fail-open

ENRICH_BUDGET_MS

2000

Documented Tier 2 enrichment budget (LLM_TIMEOUT_SECONDS bounds the model call)

QUIET_HOURS_START / QUIET_HOURS_END

Quiet-hours phrasing for night motion (UX only, never evidence)

API_AUTH_DISABLED / API_TOKEN

true / –

Gate /api/* on public deploys (Bearer, ?token=, or cookie); UI bootstraps from /?token=…

PURGE_INTERVAL_S

86400

Scheduled retention purge cadence (startup purge always runs)

DEMO_TOKEN

Optional Bearer required by /api/simulate

RATE_LIMIT_PER_MINUTE

30

Per-IP webhook/simulate limiter

DEBOUNCE_SECONDS

10

Dedupe window (kind+device); also meta.request_id

EVENT_TTL_DAYS

30

Auto-purge events older than N days

LLM providers (LangChain abstraction)

All live providers go through one ChatModel interface + with_structured_output(TriageResult), so the LLM contract (§4.4) is enforced identically by every model. Switch providers with one env var:

LLM_PROVIDER

Package

Default model overridden by LLM_MODEL

stub (offline)

none

deterministic fixtures

bedrock

langchain-aws

us.amazon.nova-lite-v1:0

openai

langchain-openai

gpt-4o-mini

anthropic

langchain-anthropic

claude-3-5-haiku-latest

google

langchain-google-genai

gemini-2.0-flash

ollama

langchain-ollama

llama3.2

pip install -r requirements-llm.txt        # core stays langchain-free (stub works with only requirements.txt)
export LLM_PROVIDER=anthropic ANTHROPIC_API_KEY=... LLM_MODEL=claude-3-5-sonnet-latest
python -m uvicorn backend.main:app --port 8080

Tests

pip install -r requirements-dev.txt
pytest -q        # 271 tests: taxonomy, Ring Partner API v1.1 (HMAC, idempotency), grounding gate, door calendar, Calendar MCP, db (sqlite+postgres), MCP tools, API, consent-share, escalation, OAuth 2.1, captions/a11y, LLM factory
# Postgres path locally: TEST_POSTGRES_DSN=postgresql://user:pw@host/db pytest -q
# Container check:      scripts/smoke_docker.sh [image]

MCP smoke test (no Alexa needed)

curl -s -X POST localhost:8080/mcp \
  -H 'Authorization: Bearer change-me' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

curl -s -X POST localhost:8080/mcp \
  -H 'Authorization: Bearer change-me' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_daily_summary","arguments":{}}}'

Deploy & demo targets

Local + simulation (recommended for the demo video) — run all flows above, no cloud needed:

python3 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt
.venv/bin/python -m uvicorn backend.main:app --port 8080        # MOCK_MODE + stub by default
# automated demo: .venv/bin/python scripts/demo_local.py

Docker (same app, persistent volume):

docker compose up --build            # open http://localhost:8080
# try a real LLM: LLM_PROVIDER=ollama docker compose up   (Ollama runs on the host)

Fire TV on the LAN: open http://<lan-host>:8080 in the Silk browser on Fire TV (or the Fire TV Simulator); the UI runs kiosk-style and SSE updates alerts live.

GCP Cloud Run (public URL — convenient for testing MCP from a phone / sharing a link):

gcloud auth login && gcloud config set project <project-id>
./scripts/deploy_cloudrun.sh <project-id> [region]   # builds from the Dockerfile, deploys, prints URL & token

Cloud Run caveat: SQLite is ephemeral per instance — fine for a demo, lost on restart. For durability set DB_URL=postgresql://user:pw@host:5432/db (Cloud SQL / Neon / RDS all work) — the repository already ships a Postgres dialect, no code changes. Bedrock/IAM still work from Cloud Run because LLM_PROVIDER=bedrock only needs AWS credentials in the environment.

Secrets per platform (env is fine for the demo):

Platform

How to inject

Local / Docker

.env (never committed) or docker compose env

GCP Cloud Run

Secret Manager + --set-secrets KEY=secret:latest; or --set-env-vars

AWS

SSM Parameter Store / Secrets Manager; Lambda env; ECS secrets

Cloudflare Workers/Containers

wrangler secret put

Secrets to manage: OPENAI_/ANTHROPIC_/GOOGLE_API_KEY, RING_WEBHOOK_SECRET, RING_ACCOUNT_TOKEN, MCP_HTTP_TOKEN, OAUTH_*, DEMO_TOKEN.

Deploy anywhere, integrate Amazon hardware

Thesis: the stack is portable; the integration surface is Amazon. AccessBell is a software layer — run it wherever you want, keep the Ring / Fire TV / Alexa+ experience.

Layer

Portable?

Choices (wired in code, not aspirational)

Compute

✅ anywhere

local uvicorn · Docker Compose · GCP Cloud Run (scripts/deploy_cloudrun.sh) · any VM/k8s

LLM

stub · ollama · openai · anthropic · google · bedrock (AWS-native)

Identity (MCP OAuth 2.1)

Okta · Auth0 · Keycloak · Cloudflare Access · Cognito (AWS-native) · local token

Data

SQLite now; Postgres/Cloud SQL is a small repository swap, not a redesign

Device integration

❌ deliberately Amazon

Ring webhook (HMAC) · Fire TV caption surface (SSE) · Alexa+ MCP tools (spec 2025-11-25)

Defensible claim: no infrastructure lock-in, native on the Amazon device ecosystem. AWS-native pieces (Bedrock, Cognito) are options, not requirements — the same image runs on GCP or a laptop with LLM_PROVIDER=stub.

Precision when pitching:

  • Cloudflare: the Python FastAPI app does not run on Workers (JS/TS runtime) as-is — use Cloudflare Containers, or keep Cloudflare for TLS/Zero Trust in front of the app. Access Managed OAuth / Access-as-OIDC remains a valid IdP choice.

  • Bedrock needs AWS credentials regardless of where the app runs (Cloud Run included).

One-liner: "Runs anywhere — laptop, Docker, Cloud Run, any VM. Speaks natively to the hardware people already own: Ring, Fire TV, Alexa+."

Security model (implemented)

  • Ring payloads: HMAC-SHA256 hex signature in RING_SIGNATURE_HEADER (default X-Signature, optional sha256= prefix), constant-time compare on raw body; retries deduped by meta.request_id via a hashed unique index (event_hash).

  • /api/* is gated by API_TOKEN on public deploys (API_AUTH_DISABLED=false); all write endpoints are rate-limited per IP (RATE_LIMIT_PER_MINUTE).

  • /mcp uses OAuth 2.1 (JWKS-verified JWT, two-tier) when OAUTH_ISSUER is set — service tokens cannot act for users; falls back to MCP_HTTP_TOKEN for offline demo. MCP_ORIGIN allowlist enforced.

  • Events auto-purged after EVENT_TTL_DAYS (retention, no video archive).

  • LLM output is re-validated in code (pydantic TriageResult): enum category, 0–1 confidence, known evidence sources, non-empty captions, and a grounding rule — specific categories require expected_context / calendar / user_label / snapshot evidence or payload signal, else the result is demoted with grounding=demoted_insufficient_evidence.

  • Escalation and share are the only outward actions: escalation (default OFF) is durable and at-most-once, share requires explicit consent; both are audited, and escalation audit rows cite the policy.yaml version + SHA (GET /api/policy).

Latency SLO (p95) — budgets in code

Path

Target

Hard rule

Webhook in → SSE alert_raw

p95 < 200 ms

rules + DB insert only; tier1_ms histogram

Context join (local)

p95 < 50 ms

indexed DB reads; context_ms

Calendar MCP (J2)

CONTEXT_BUDGET_MS else skip

httpx timeout; fail-open context_status=timeout

Enrich → SSE alert_enriched

p95 < 2 s

ENRICH_BUDGET_MS hard wait_for; on fail keep Tier 1 (enrichment_failed) and still arm escalation

MCP tool (/mcp tools/call)

p95 < 500 ms

DB-only, no LLM inside a tool; mcp_tool_ms

Escalation fire

timeout ± 1 s after ingest

durable pending + at-most-once claim

Measured per process in /api/metrics (timers: tier1_ms, context_ms, enrich_ms, mcp_tool_ms, webhook_to_sse_ms). Aggregates are in-memory and disposable; counters are fixture-derived until live data exists. Ring→cloud network delay cannot be guaranteed in-process — an optional poll backup (internal design) mitigates missed webhooks.

Line: If we hear the door, you see it in under 200 ms; if the model or the calendar is slow, you still see the door.

How we know (fixture-derived, not production telemetry)

The grounding gate is measurable — same fixtures, three arms (scripts/ablation_evidence.py):

Arm

Signal available

Category accuracy

event_only

event type only

0.5

payload_hints

demo label hints in the payload

1.0

expected_window

user-set expected window

1.0

A specific claim (MED_DELIVERY, PACKAGE_DELIVERY, FAMILY_VISITOR) that lacks grounding is demoted in code to UNKNOWN_VISITOR with status demoted_insufficient_evidence; the why-line says so on screen. GET /api/metrics reports the same counters at runtime, clearly labelled as fixture-derived.


AWS services

Service

Role

Amazon Bedrock

Triage + accessible phrasing (Converse API, structured JSON)

AWS Lambda (optional)

Host webhook / skill

IAM

bedrock:InvokeModel for runtime

References:


Value to the Amazon ecosystem

AccessBell is designed as a layer that makes existing Amazon products usable by more people — not a competing device or camera.

Amazon product

What AccessBell adds

How it shows up

Ring

Door events become usable for deaf, blind and limited-mobility users, who today cannot act on a chime or a thumbnail

new audience for hardware + Protect, fewer "can't use it" returns

Fire TV

The largest screen in the home becomes an accessibility alert surface (large caption, urgency, bilingual)

daily habitual reason to keep the TV in the loop

Alexa+

A working MCP add-on: 11 tools covering alerts, context snapshot, daily brief, door calendar (add/list/clear expected context), replies, accessibility prefs and consent-based escalation

installs, voice sessions, tool calls

Bedrock

A repeatable, safe pattern: rules first, structured TriageResult, evidence + confidence, grounding that refuses to invent

steady, low-cost inference per household

AWS (runtime)

One container, Postgres-optional, deployable in a customer's own AWS account

Marketplace-style service delivery

Positioning: we do not ask Amazon to build accessibility; we ship it on top of what they already sell, and measure success in their metrics — attach, renewal, sessions, tool calls.


Ring integration

Capability

Use

Webhook events (button_press, motion_detected, …)

Primary trigger

HMAC-SHA256 (X-Signature: sha256=<hex>)

Verify payloads (raw body)

Device discovery

List doorbell / cameras (api.amazonvision.com)

Image snapshot (optional)

One-frame share / richer triage — no video archive

Sandbox / personal account

Test without production publish (no physical device required to develop)

Docs:


Fire TV

Fire TV supports web apps, React Native, and Android on Fire OS / Vega OS.
AccessBell ships a kiosk web UI + SSE. Try it on a physical Fire TV with the official Web App Tester loading a LAN URL, or open the same UI in any browser for development.


Alexa+ / MCP

AccessBell exposes a self-hosted MCP server at POST /mcp (JSON-RPC 2.0, Streamable HTTP, spec 2025-11-25+). It is designed to sit beside other MCP servers — e.g. a Calendar MCP — with Alexa+ as the orchestrator that calls the right tool for the job.

Tool

Description

get_door_alerts

List alerts by time / urgency

get_event_detail

One event with evidence

get_context_snapshot

Transparency: local context inputs used (expected/labels/hints)

get_daily_summary

Accessible daily brief

add_expected_context

Door intent — “expect pharmacy ~10am”

list_expected_context

Read the door calendar (active + upcoming windows)

clear_expected_context

Revoke a door-intent window by id or label

confirm_event

User ground-truth label

send_quick_reply

Leave / coming / not now

update_accessibility_prefs

Caption vs voice profile

set_escalation

“If nobody answers, tell Lan” — consent safety net

Orchestration example (multi-MCP):

User: "Alexa, I expect a pharmacy delivery around 10."
Alexa+ → Calendar MCP.create_event(...)          # if a calendar server is connected
Alexa+ → AccessBell.add_expected_context(...)    # door intent for triage evidence
... later ...
Ring webhook → AccessBell → grounded caption on Fire TV

Any MCP client can call the same server (tools/list / tools/call). For a production Alexa+ connection: HTTPS + OAuth 2.1/PKCE; set MCP_401_WWW_AUTHENTICATE=false (Alexa+ checklist: 401 without WWW-Authenticate). See MCP Toolkit.


Design principles

  1. Event-driven — no 24/7 video upload.

  2. Rules first, LLM second — low latency, lower cost, fewer hallucinations.

  3. Evidence over invention — if confidence is low, say “Someone is at the door.”

  4. User agency — briefs are for the resident household; sharing is opt-in with audit trail.

  5. No medical claims — logistics + accessibility only; not EMS, not diagnosis.

  6. Local-first demo — you can run the full experience without flaky live APIs.

  7. Same stack, many homes — elder, child-at-home, multi-gen home share one event pipeline.


Ethics & privacy

  • Do not use AccessBell to covertly monitor household members.

  • Face recognition is out of scope on purpose.

  • Snapshot frames (if enabled) are single-event and not a video archive.

  • Share / escalation are logged; the resident can revoke.

  • Child-at-home uses the same consent gate — the child still sees the TV caption (not secret monitoring); the parent is notified only per policy.


Product story (3 minutes — one door, three people)

  1. Frame: Hoa in the kitchen, An (10) in the living room, a parent at work. Most door apps assume a phone chime is enough.

  2. See: ring → Fire TV full-screen caption in &lt;200 ms.

  3. Understand: enrichment → “Possible package delivery” + confidence + evidence.

  4. Act: An uses the TV remote → “Leave at door.”

  5. Protect: “If nobody answers, tell Mom.” High-urgency, no reply → parent notified; audit row; reply in time stops it; revoke → silence.

  6. Equity: Ring AI subscription features off → the experience still works.

  7. Close: “Accessibility isn’t a skin on a door app — it’s the architecture.”

Drive the whole thing with one command (beats, waits, and the measured proof for each step):

.venv/bin/python -m uvicorn backend.main:app --port 8080      # MOCK_MODE + stub
.venv/bin/python scripts/demo_story.py --pace 3               # add --calendar http://127.0.0.1:8085/mcp for the multi-MCP cut

Who it is for

Residents who want a door they can understand — hearing, vision, mobility, language, or age

Families who want a calm safety net, not always-on cameras

Builders extending Ring / Fire TV / Alexa+ with a privacy-first accessibility layer


Roadmap

Shipped (MVP)

Ring webhook ingest (HMAC, Partner API v1.1 shape) + mock fixtures

Tier 1 fast captions + Tier 2 grounded triage (Bedrock / stub)

Fire TV / PWA web UI (SSE, D-pad, EN/VI)

AccessBell MCP (10 door tools, Streamable HTTP)

Consent escalation, audit, quick replies, daily brief

Evidence gate status + why-line; door calendar list/clear

Calendar MCP join (J2, optional); local stub for demo

Child-safe captions; share protocol (preview/apply/read-back/revoke)

Ablation script, metrics endpoint, docs-consistency check

Next (production path)

Focus

Intent

Live Ring sandbox

Real webhook credentials + end-to-end device events

Durable deploy

HTTPS + Postgres; secrets via cloud secret stores

Alexa+ connection

OAuth 2.1 / PKCE + MCP mode tuned for Alexa+ clients

One-frame share

Optional snapshot in consented messages — never a video archive

Later (opt-in)

Focus

Intent

One-frame share

Optional snapshot in consented messages — never a video archive

Richer voice history

Natural door Q&A with event citations

Speak-at-door replies

Where device APIs allow

Store readiness

Ring / Alexa+ listing assets, privacy policy, certification

Deliberately out of scope

Face recognition · location tracking of children · scraping private email/calendars · medical monitoring or EMS · 24/7 video analytics.


License

MIT — see LICENSE.


Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to interact with Ring cameras and doorbells through the official Amazon Vision API, supporting device listing, health status, event history, and live WebRTC streaming via natural language.
    7
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables context-aware home safety monitoring by exposing tools to retrieve recent Ring events, household context, deterministic activity assessments, and alert explanations over MCP.
    114,317 npm
    MIT