HomePilot AI MCP Server
README.md
# HomePilot AI
**A stateful household operations agent with a real MCP server.**
HomePilot turns a natural-language household request into a transparent, multi-step plan:
read the household profile → check pantry stock → fetch a live weather forecast → choose
dinners under diet, allergy, time, and budget constraints → calculate the true grocery gap →
propose a shopping list and task → wait for explicit confirmation → apply the changes
idempotently and keep an auditable activity trail.
Built for the **Alexa+ track** of the **Build, Ship, Shape: Amazon Developer Hackathon 2026**.
> Submission deadline used for this build: **October 23, 2026, 12:00 PM Pacific**.
> See `docs/JUDGING_SCORECARD.md` for the requirement-to-evidence map.
---
## Quick start
Requirements: **Node.js 24+** (the project uses the built-in `node:sqlite` module) and npm.
```bash
npm install
npm run build # builds the React dashboard into dist/web
npm start # serves API + MCP + UI at http://127.0.0.1:4173
```
No AWS account, API key, or external database is required for the local demo. Weather uses
Open-Meteo (keyless). If the network is unavailable, planning continues without weather and
says so.
Open <http://127.0.0.1:4173> and click **Run demo workflow**, or paste this prompt into the
agent console:
> Plan three affordable dinners for this week. Check the weather, use ingredients I already
> have, make a shopping list for the missing items, and keep everything under my budget.
The workflow proposes a plan but **does not mutate the shopping list or tasks until you press
Confirm plan**.
### Useful commands
| Command | What it does |
| --- | --- |
| `npm start` | Production server (API, MCP, built UI) on port 4173 |
| `npm run dev:web` | Vite dev server for the React UI, proxying `/api` and `/mcp` to 4173 |
| `npm run build` | Type-check-free production bundle into `dist/web` |
| `npm run typecheck` | TypeScript check of the React app |
| `npm test` | 41 automated tests (domain, tools, agent, shopping, AI fallback, end-to-end) |
| `npm run test:mcp -- --spawn` | Connects a real MCP client to a freshly spawned server and calls tools |
| `npm run verify:bedrock` | Real Amazon Bedrock connectivity check (requires env; exits 2 if unconfigured) |
---
## What the demo shows
1. **Dashboard** — live forecast, pantry coverage, budget, pending tasks, and the current plan.
2. **Agent console** — streaming execution trace with every MCP tool call, timing, and outcome.
3. **Plan studio** — three dinners with weather rationale, pantry-aware gap table, pack-level
demo prices, budget check, and an auditable 8-step timeline.
4. **Confirmation gate** — the plan is saved as `awaiting_confirmation`; shopping and task
mutations are blocked until the user confirms.
5. **Shopping / Pantry / Tasks** — persistent CRUD with optimistic-free server reconciliation.
6. **Activity** — every plan, shopping edit, pantry change, task change, and profile update.
7. **Settings** — profile editor, integration status, MCP tool inventory, JSON export, and reset.
The same server exposes the full workflow to any MCP client at `POST /mcp` using the
**Streamable HTTP** transport and protocol **2025-11-25**.
---
## Architecture at a glance
```text
Browser (React 19 + TypeScript)
│ HTTP /api + SSE
▼
Node 24 HTTP server ─────────────────────────────────────────────┐
│ in-process orchestrator (McpBridge) │
│ MCP Streamable HTTP client │
▼ │
POST /mcp ──► MCP server (official SDK, protocol 2025-11-25) │
│ 18 tools, Zod-validated │
▼ │
Domain logic (deterministic) │
SQLite via node:sqlite ◄── seed / persistence │
│ │
├── Open-Meteo (live forecast, cached 10 min) │
├── Amazon Bedrock (optional, advisory AI) │
└── Amazon DynamoDB (optional snapshot mirror)┘
```
The web app is a **real MCP client**, not a mock: the agent invokes tools through the MCP
transport, exactly as an external Alexa+ skill or MCP host would.
Full details: [`ARCHITECTURE.md`](ARCHITECTURE.md).
---
## MCP tools (18)
Core planning and state:
`get_household_profile`, `update_household_profile`, `get_pantry_inventory`,
`update_pantry_inventory`, `get_weather_forecast`, `plan_meals`,
`calculate_missing_ingredients`, `get_shopping_list`, `update_shopping_list`,
`get_household_tasks`, `manage_household_task`, `create_household_plan`,
`start_household_plan`, `record_plan_step`, `complete_household_plan`,
`get_plan_status`, `get_activity_log`, `reset_household_data`.
Schemas, annotations, and example payloads: [`docs/MCP_TOOLS.md`](docs/MCP_TOOLS.md).
Try it without the UI:
```bash
# Terminal 1
npm start
# Terminal 2
npm run test:mcp
```
---
## Real vs simulated integrations
| Capability | Status | Notes |
| --- | --- | --- |
| MCP server (Streamable HTTP, 2025-11-25) | **Real** | Official `@modelcontextprotocol/sdk`; stateful sessions; verified by `test:mcp` |
| Weather | **Real** | Open-Meteo, keyless; 10-minute cache; labelled forecast; graceful unavailable state |
| Persistence | **Real** | SQLite `node:sqlite`, durable across restarts |
| Amazon Bedrock | **Real integration, optional** | Anthropic-style invoke via AWS SDK; deterministic fallback always available; no credentials bundled |
| Amazon DynamoDB mirror | **Real integration, optional** | Full snapshot mirror + restore when `HOMEPILOT_DYNAMO_TABLE` is set |
| Grocery prices | **Demo data** | `local-demo-catalog-v1`; pack prices are illustrative, **not live retailer quotes** |
| Household, pantry, tasks | **Demo seed** | Clearly labelled demo household; editable in the UI |
| Retailer ordering / Alexa purchase | **Not implemented** | The app creates a shopping list; it never places an order |
Honesty rules used throughout:
- A plan is not "applied" until the shopping and task tools confirm it.
- Failed Bedrock calls surface a warning and fall back; they never fabricate narration.
- Failed Open-Meteo calls return `available: false`; planning continues and says so.
- Prices always carry their source and an explicit "not live retailer prices" disclaimer.
- Allergy filtering is a filter, **not a safety guarantee**.
See [`docs/DATA_SOURCES.md`](docs/DATA_SOURCES.md).
---
## AWS integration
Two genuine AWS services are wired through the official SDKs, both optional and lazy-loaded so
the local demo never needs credentials:
### Amazon Bedrock (advisory AI)
- Model: `BEDROCK_MODEL_ID` (for example an Anthropic Claude model available in your region).
- Region: `AWS_REGION` (default `us-east-1`).
- Uses the standard AWS credential chain (environment, profile, SSO, instance role).
- Intent extraction is **advisory**; the deterministic parser always runs and remains the
source of truth. Narration is fact-checked against supplied numbers.
- Verify with `npm run verify:bedrock`.
### Amazon DynamoDB (durable snapshot mirror)
- Set `HOMEPILOT_DYNAMO_TABLE` to enable.
- On startup, a fresh local database attempts to restore the latest snapshot.
- Every mutation mirrors a full snapshot item (`pk=homepilot`, `sk=household-snapshot`).
- The expected table has a string partition key `pk` and string sort key `sk`.
- Local SQLite remains the source of truth; mirror failures are logged and surfaced in status.
**Verification status in this workspace:** both integrations are implemented and covered by
fallback tests, but they were **not exercised against a live AWS account** here because no
credentials were available. `npm run verify:bedrock` correctly exited with code 2
("not configured"). No deployment or AWS success is claimed.
Suggested IAM permissions (least privilege):
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "arn:aws:bedrock:<region>:<account>:inference-profile/*"
},
{
"Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:PutItem"],
"Resource": "arn:aws:dynamodb:<region>:<account>:table/<table>"
}
]
}
```
---
## Configuration
Copy `.env.example` to `.env` if you want to override defaults. The app reads the process
environment directly (no dotenv dependency); use your shell, a process manager, or your
platform's environment settings.
| Variable | Default | Purpose |
| --- | --- | --- |
| `PORT` | `4173` | HTTP port |
| `HOST` | `127.0.0.1` | Bind address (`0.0.0.0` for containers) |
| `HOMEPILOT_DB_PATH` | `data/homepilot.db` | SQLite file |
| `HOMEPILOT_DATA_DIR` | `data/` | Data directory |
| `BEDROCK_MODEL_ID` | unset | Enables Bedrock advisory AI |
| `AWS_REGION` | `us-east-1` | AWS region |
| `HOMEPILOT_DYNAMO_TABLE` | unset | Enables DynamoDB snapshot mirror |
| `HOMEPILOT_DEMO_MODE` | `true` | Labels demo data in the UI/API |
| `LOG_LEVEL` | `info` | Reserved for log filtering |
---
## Testing
```text
npm test
ℹ tests 41
ℹ pass 41
ℹ fail 0
```
Coverage includes:
- Unit conversion, aliases, allergen and diet filters, pantry netting, pack costing, budgets.
- All 18 tools registered; Zod validation and structured error codes.
- Pantry, shopping, task, plan lifecycle, supersession, idempotency, reset guards.
- Intent parsing, confirmation gating, revision replacement, honest fallback.
- Bedrock-unconfigured behavior and narration fallback.
- End-to-end: real HTTP server + real MCP bridge + SSE + persistence + reset.
Details and the exact commands used: [`docs/TESTING.md`](docs/TESTING.md).
---
## Project structure
```text
src/
server.js process entry point
app.js HTTP API, MCP session transport, SSE, static serving
mcpServer.js MCP server + tool registration
mcpClient.js in-process MCP Streamable HTTP client
tools.js 18 tool definitions, Zod schemas, structured errors
agent.js deterministic intent parser + workflows + confirmation
domain.js meal planning, pantry netting, pack costing, budgets
db.js SQLite schema, seed, repository, snapshots
catalog.js demo ingredient/recipe/price catalog
weather.js Open-Meteo provider + cache + honest failure
ai.js Amazon Bedrock intent/narration with fallback
aws.js DynamoDB snapshot mirror/restore
config.js environment configuration
web/
src/ React 19 dashboard, views, components, design system
tests/ 41 Node test-runner tests
scripts/ verify-mcp.mjs, verify-bedrock.mjs
docs/ submission, architecture, tools, testing, strategy, friction
data/ local SQLite database (git-ignored)
dist/web/ built UI (git-ignored)
```
---
## Safety and limitations
- **Demo prices.** Groceries are estimated from a bundled catalog. Check current prices and
pack sizes in store.
- **Allergy filtering is best-effort.** Ingredient metadata and cross-contamination are not
guaranteed. Always read packaging.
- **Weather is a forecast.** Open-Meteo data is labelled with source and fetch time.
- **No purchasing.** HomePilot prepares a list and a task; it never buys anything.
- **Single-household demo.** There is no authentication or multi-tenant isolation. Do not
expose a public deployment without adding auth, rate limiting, and per-user storage.
- **Bedrock is advisory.** The deterministic engine owns every computed number and action.
---
## Submission docs
- [`docs/SUBMISSION_DESCRIPTION.md`](docs/SUBMISSION_DESCRIPTION.md) — copy-ready submission text
- [`docs/DEMO_SCRIPT.md`](docs/DEMO_SCRIPT.md) — 3-minute recording plan and narration
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — system design and data flow
- [`docs/MCP_TOOLS.md`](docs/MCP_TOOLS.md) — tool contracts
- [`docs/DATA_SOURCES.md`](docs/DATA_SOURCES.md) — provenance and honesty labels
- [`docs/TESTING.md`](docs/TESTING.md) — test strategy and evidence
- [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) — local, Docker, and AWS notes
- [`docs/HACKATHON_STRATEGY.md`](docs/HACKATHON_STRATEGY.md) — track fit and judging rationale
- [`docs/JUDGING_SCORECARD.md`](docs/JUDGING_SCORECARD.md) — requirement mapping
- [`docs/PRODUCT_FEEDBACK.md`](docs/PRODUCT_FEEDBACK.md) — Alexa+/MCP product feedback
- [`docs/FRICTION_LOG.md`](docs/FRICTION_LOG.md) — build friction log (bonus category)
---
## License
MIT — see [`LICENSE`](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues