mcp-home
Integrates with Alexa+ and Amazon Bedrock to provide voice-driven household logistics management, including shopping lists, bills, chores, and pantry tracking, with natural language sentence parsing via Bedrock.
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., "@mcp-homeadd oat milk and eggs to the shopping list"
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.
mcp-home
A self-hosted MCP server that lets Alexa+ run a household's shared logistics: the shopping list, bills, chores and the food about to expire.
"Alexa, add oat milk to the shopping list." "Alexa, whose turn is it to take out the trash?" "Alexa, what do we need to deal with this week?"
Families already talk to Alexa in the kitchen. What they lack is one shared memory for the boring stuff: who paid the gas bill, who did the dishes last, what is going off in the fridge. mcp-home is that memory, exposed as an MCP server over Streamable HTTP so Alexa+ (or any MCP client) can read and update it. A web dashboard on the same server shows the family what Alexa sees, on the kitchen tablet or a phone.

Tools
Tool | What it does |
| Adds to the shared list, grouped by supermarket aisle, ignores duplicates |
| The list in the order you walk the store (read only) |
| Marks an item as bought |
| Records a bill; due date as |
| Pays the oldest open bill from that provider; a recurring bill gets its next one scheduled. Reads the bill back first and pays only on |
| Unpaid bills in the next N days, overdue ones flagged, with the total (read only) |
| "Anna took out the trash" (today by default, or |
| Fair rotation: whoever did that chore least recently, or never (read only) |
| Who is in the chore rotation (listing is read only; removing reads back first) |
| Tracks food with expiry dates |
| What to eat before it goes off (read only) |
| One sentence Alexa can read aloud: bills due, food to use, list size (read only) |
| "We're out of milk and the gas bill of 80 euro is due Friday" → plans both actions with Amazon Bedrock, reads the plan back, and runs exactly that plan on |
| The answer to "Alexa, what can you do?"; for a new household it also says how to start (read only) |
| English or Italian replies for this household |
Resource: home://briefing (same content as weekly_briefing). Prompts: set_up_household (guided first run: language, members, recurring bills, chores) and weekly_review.
Every tool has a title and explicit annotations. Read-only tools carry readOnlyHint. The spec treats any other tool as destructive unless it says otherwise, so the additive ones say destructiveHint: false and only mark_bill_paid and remove_household_member say true.
Related MCP server: HomeKeeper
Built for voice
What the Alexa+ documentation asks of an add-on, and how mcp-home answers it:
Alexa+ asks (functional requirements, quick start) | mcp-home |
"Require explicit confirmation with key details before any high-consequence action (payment, cancellation, deletion)"; on screenless devices "read back all key details and require explicit 'yes'" | Paying a bill, removing a member and free-form sentences answer |
"Surface no API codes, tool names, JSON, or internal IDs in any customer-facing response" | Every result has a |
"Provide actionable next step for every error" | "I couldn't find an open Enel bill. Want to hear what's due?"; "Tell me who lives here first, for example: add Anna to the household." |
"Return a useful, contextually relevant summary when the customer asks 'What can you do?'" |
|
"A round-trip query response latency of less than 500 ms" |
|
Why a confirm argument and not MCP elicitation. The Alexa+ client lifecycle example initialize declares only roots, not elicitation, and the server runs stateless (json_response, no SSE stream to carry a server-to-client request). A read-back plus a confirming call works with any MCP client, Alexa+ included.
English and Italian. set_language switches a household's spoken replies, the weekly briefing and the dashboard's "What Alexa will say" to Italian ("Tocca a Giulia portare fuori la spazzatura."). Dates are already understood in both ("tomorrow", "tra 3 giorni").
Dashboard
Open http://localhost:8000/ (or your deployed URL) and enter a household token once. The page keeps it in that browser's local storage, sends it only as an Authorization: Bearer header, and never puts it in a URL.
What Alexa will say: the exact
weekly_briefingsentence, large, with a Read aloud button (browser speech).Shopping list grouped by aisle in walking order, with check-off and add.
Bills for the next 31 days: overdue ones in red, recurring ones tagged, Paid and add.
Chores: whose turn it is for each chore, one-tap Done, a log form, and the members of the rotation.
Pantry and fridge with expiry badges (expired, today, tomorrow, within 3 days, later) and Used.
Connect: the MCP endpoint URL (
PUBLIC_URL, or the address the page was opened from), theAuthorizationheader with the token hidden until you click Reveal, the list of tools with read-only ones marked, and MCP Inspector steps.
It refreshes every 30 seconds, so what someone tells Alexa shows up on the tablet. Light and dark mode follow the system setting; the layout works down to phone width.
The page is one self-contained file (mcp_home/static/index.html, no CDNs, strict Content-Security-Policy). It talks to a small JSON API on the same server, protected by the same household tokens as /mcp. Every handler calls the same functions in mcp_home/logic.py as the MCP tools, so the dashboard and Alexa can never disagree.
Method and path | Does |
| Everything on the page: briefing, list, bills, chores, members, pantry, connect info |
| Add an item · check one off ( |
| Add a bill ( |
| Log a chore ( |
| Add or remove a member of the rotation |
| Track food ( |
Each write returns {"result": ..., "state": ...} so the page re-renders in one round trip. Requests without a valid token get 401; ids from another household answer not_found.
MCP client demo
Open http://localhost:8000/demo (linked from the dashboard header and its Connect panel). The page is a real MCP client running in the browser. It sends initialize (protocol 2025-11-25), notifications/initialized, tools/list and tools/call to /mcp over Streamable HTTP, with the household bearer token. This is the kind of client the Devpost FAQ accepts for the Alexa+ track demo.

Say it like you would to Alexa. "Add oat milk to the shopping list", "The gas bill of 80 euro is due Friday", "Whose turn is it to take out the trash?", "What do we need to deal with this week?". A small deterministic router in the page maps these phrasings to one tool and its arguments. Anything it does not recognise goes to
do_from_sentence, which needs Amazon Bedrock; withoutBEDROCK_MODEL_IDthe page says so.What you see for each call.
The reply as the sentence Alexa would speak, with Read aloud (browser speech).
The tool that was called.
The round-trip time, green under the 500 ms Alexa+ asks for.
The JSON-RPC request and response, collapsed.
Read-back, then yes. "We paid the gas bill" gets the server's read-back and a waiting for yes tag; "yes" sends the same call with
confirm=true, "no" sends nothing.Session panel. The negotiated protocol version, the server info, the handshake timings, and the
initialize/tools/listexchange. Next to it, the 18 tools with their read-only badges.Run demo script plays eight requests with pauses (the last two pay the gas bill after a spoken read-back and a "yes"), typing each sentence first; tick Speak replies to hear them. Good for recording the video. Add
?speakto the URL to start with speech on.
It uses the same strict Content-Security-Policy as the dashboard (connect-src 'self', no inline event handlers) and the same token storage.
How it works
flowchart LR
A[Alexa+] -- OAuth account linking, then MCP Streamable HTTP + Bearer token --> S[mcp-home]
W[Web dashboard] -- /api JSON + same Bearer token --> S
S --> L[household logic<br/>rotation, aisles, dates]
L --> D[(SQLite per household)]
S -- do_from_sentence --> B[Amazon Bedrock<br/>Converse API, forced tool use]Transport: MCP Streamable HTTP at
/mcp, stateless JSON responses, built on the official Python SDK (mcp2.x). Tested to negotiate protocol version 2025-11-25, the minimum the Alexa+ track asks for.Households: every bearer token maps to one household, either a static one (
HOUSEHOLD_TOKENS="token:household,...") or an OAuth access token issued by the built-in authorization server when someone links an app, such as Alexa+, with that household's token. Every query filters by household; tokens are compared in constant time. A request without a valid token gets401, on/mcpand on/api/*alike.OAuth 2.1: authorization code + PKCE S256, refresh tokens,
client_credentials, RFC 9728 and RFC 8414 metadata, all inmcp_home/oauth.py(see Connect to Alexa+).Host check: the SDK's DNS-rebinding protection accepts localhost plus the host in
PUBLIC_URL(and any extraALLOWED_HOSTS), so a deployed/mcpanswers instead of returning421.Bedrock:
do_from_sentencecalls the Bedrock Converse API with a single forced tool (plan_actions) whose JSON schema only allows the four write actions, and passes today's date so "Friday" resolves to a real date. The actions are then validated and executed by the same code the individual tools use, so the model can never write anything the tools could not.
Run locally
pip install -r requirements.txt
export HOUSEHOLD_TOKENS="$(openssl rand -hex 24):rossi"
python -m mcp_home.server # dashboard at http://localhost:8000/, MCP at /mcpTry it with the MCP Inspector (npx @modelcontextprotocol/inspector), transport "Streamable HTTP", URL http://localhost:8000/mcp, header Authorization: Bearer <your token>.
Deploy on AWS
infra/deploy-apprunner.sh builds the Docker image, pushes it to ECR and creates an App Runner service, then prints the MCP endpoint. You need:
an ECR access role for App Runner (
APPRUNNER_ECR_ROLE_ARN),for
do_from_sentence:BEDROCK_MODEL_ID(any Bedrock model that supports tool use) and an App Runner instance role allowed to callbedrock:InvokeModel,PUBLIC_URLset to the service URL, so the OAuth metadata, the token audience and the host check all use it. For account linking also passOAUTH_CLIENT_ID,OAUTH_CLIENT_SECRET,OAUTH_REDIRECT_URISandALEXA_COMPAT=1(see below).
Data lives in SQLite inside the container: fine for a demo, it resets on redeploy. Mount a volume or swap mcp_home/db.py for DynamoDB for real use.
Public demo on Render
render.yaml deploys the same image on Render's free plan as a public demo. Render generates a random DEMO_TOKEN, which opens a made-up "demo" household: the dashboard and /demo show a Use the public demo household button, and GET /api/demo-token returns the token for MCP Inspector, so anyone can try the server without asking for credentials. Never put real data in the demo household. Real households keep their own secret tokens in HOUSEHOLD_TOKENS, which stays optional. The public URL comes from Render's RENDER_EXTERNAL_URL, so OAuth metadata and the host check work without setting PUBLIC_URL. Free-text commands need the optional Bedrock variables. The database is in /tmp, so a restart empties the demo household, and a free instance sleeps after 15 minutes, so the first visit after that takes about a minute.
Connect to Alexa+
Hackathon reality first. The Devpost FAQ says Amazon's Alexa+ add-on tools (Category SDK, MCP Toolkit, alexa-ai CLI, Web Simulator) "are in preview" for select partners, that participants cannot get access, and that "there's no way for any participant to connect a self-hosted MCP server to a real Alexa+ device". For the demo, any real MCP client speaking Streamable HTTP is accepted (MCP Inspector with a household token, or the dashboard). The server still implements what the Alexa+ MCP Toolkit asks for, so it can be linked as soon as access opens.
What Amazon requires, and where it lives here:
Alexa+ MCP Toolkit requirement | mcp-home |
Streamable HTTP, MCP 2025-11-25 |
|
Protected Resource Metadata (RFC 9728) at | served at that path (and at |
Auth server metadata at | built in, same origin |
Authorization code grant with PKCE S256, |
|
Static client registration, DCR not supported |
|
A refresh token with every access token | yes; rotated on each use, 90 days |
Service-level | yes: that token can |
401 for unauthenticated requests, without a |
|
Bearer token in the | the only place tokens are read |
Steps, once you have Alexa+ add-on access:
Deploy behind HTTPS (
infra/deploy-apprunner.sh, or a tunnel such ascloudflaredfor testing) and setPUBLIC_URL=https://<host>. Checkhttps://<host>/.well-known/oauth-protected-resourceshows"resource": "https://<host>/mcp".Create the OAuth client the add-on will use:
OAUTH_CLIENT_ID=alexa-home,OAUTH_CLIENT_SECRET=$(openssl rand -hex 32), andOAUTH_REDIRECT_URIS= every redirect URL the Alexa+ Developer Hub lists for your add-on, comma separated (they look likehttps://alexa.amazon.com/api/skill/link/<id>). SetALEXA_COMPAT=1. Restart.Authenticate the CLI and scaffold the add-on:
alexa-ai configure, thenalexa-ai new mcp --name "Home" --locale en-US --mcp-server-url "https://<host>/mcp", and answer yes when it asks whether the add-on needs account linking.Give it the client:
alexa-ai configure-account-linking --addon-id <id> --stage development --client-id alexa-home, and type the secret at the masked prompt (or exportALEXA_CLIENT_SECRET). Alexa reads the endpoints, scopes (household) and PKCE support from the metadata above.Fill in
addon-package/addon.json(descriptions, 3 to 4 example phrases, privacy and terms URLs, icons) and runalexa-ai deploy. Run it again whenever the tools change: Alexa+ only refreshes tool information on deployment.In the Alexa app, enable the add-on and link the account. The mcp-home consent page shows where the code will be sent, and asks for the household token. Entering it proves you belong to that household. From then on Alexa sends an access token that maps to that household only.
To unlink a household from every app at once, remove or change its entry in HOUSEHOLD_TOKENS: its OAuth tokens stop working on the next request. Apps can also revoke a grant at /revoke (RFC 7009).
OAuth for other MCP clients
The same authorization server works for any MCP client that follows the 2025-11-25 authorization spec. Clients that register themselves (RFC 7591) need OAUTH_DYNAMIC_REGISTRATION=1. It is off by default because Alexa does not use it, and an open registration endpoint lets anyone create a client. Registered redirect URIs must be HTTPS or loopback. Static household tokens keep working for MCP Inspector and the dashboard, with no OAuth needed.
Variable | Default | Meaning |
| unset | The pre-registered client. Without a secret it is a public client (PKCE only, no |
| unset | Exact redirect URIs for that client, comma separated |
|
| Name shown on the consent page |
| 3600 / 7776000 | Lifetimes in seconds |
| off | Enables |
| off | Drops |
Security details: codes, access and refresh tokens are 256-bit random values and only their SHA-256 is stored in SQLite, with expiry. Codes last 5 minutes and work once: a second redemption revokes everything the code issued, and so does replaying an old refresh token. Redirect URIs are matched exactly, and an unknown one is never redirected to. Client secrets and household tokens are compared in constant time. Ten wrong household tokens from one address within 10 minutes lock the consent page for that address. The consent page has a strict CSP (frame-ancestors 'none', form-action limited to the redirect origin). Access tokens are bound to this server's resource (RFC 8707) and checked on every request. Authorization responses carry iss (RFC 9207).
Tests
pip install -r requirements-dev.txt
pytesttests/test_demo.py loads /demo in headless Chromium, signs in, and checks the handshake, the 18 tools, a spoken reply produced by a real tools/call, and a bill paid only after the read-back and a typed "yes". tests/test_voice.py covers the spoken replies (no ids or tool names, English and Italian), every confirmation path (read-back first, single use, expiry, no cross-household confirm, a sentence plan confirmed without a second model call), the annotations, the prompts, "what can you do", and the 500 ms budget. The suite also covers aisle grouping, walking order and duplicates, household isolation, spoken dates, bills, overdue detection and recurring bills, fair chore rotation and members, pantry expiry and the spoken briefing, the Bedrock request shape (with a fake client), the database migration, and end-to-end runs over HTTP: on both /mcp and the dashboard API, unauthenticated requests get 401 and two households see only their own data. tests/test_oauth.py runs the whole account-linking flow over HTTP: metadata documents, the consent page, code + PKCE with Basic and POST client authentication, wrong or missing verifiers, code replay, expired codes and tokens, refresh rotation and replay detection, revocation, unlinking a household, client_credentials, opt-in dynamic registration, and household isolation with OAuth tokens.
The browser test needs Playwright (pip install playwright && playwright install chromium, or point PLAYWRIGHT_CHROMIUM at an existing Chrome) and is skipped without it.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Household-aware cooking brain: pantry, meal suggestions, dietary safety, recipes, shopping lists.
- ManiloOAuthapp.manilo
Log, query, and edit expenses, budgets, and accounts in Manilo from any MCP-compatible AI assistant.
Your kitchen in chat: pantry stock, shopping lists, recipes and scanned grocery receipts.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI-powered household management including inventory tracking, restock predictions, meal planning from available ingredients, and baby supply monitoring through natural language commands.Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables households to manage appliance inventories, manuals, warranties, and maintenance through natural-language voice interactions, with grounded troubleshooting and consumable reordering.MIT
- AlicenseNot gradedqualityCmaintenanceGives Alexa+ persistent, structured memory of a household kitchen: tracking purchased groceries, flagging items at risk of spoiling, proposing rescue meals from expiring ingredients, and maintaining shopping lists, receipt ingestion, and waste reports through MCP tool calls. Storage, tool logic, and safety controls (consent gates, two-step deletion, rate limiting) are exposed over Streamable HTTP for any MCP client.MIT
- AlicenseAqualityFmaintenanceEnables household management through natural language, covering bills, chores, shopping, reminders, budget, and smart-home devices, with every mutating action dry-run, confirmed, and audited.31MIT