-
-
The invoice checked line by line: $1,050 proven by photos from the visit is ready to pay. $370 waits for the homeowner.
-
Pros whose license number isn't in Florida's license registry are left out before you choose, with the source and as-of date.
-
Booking: every scope item says what proves it, and the pro agreed the door camera logs only arrival and departure.
-
Payment belongs to Alexa+ (simulated): only the proven items, voice code, card on file. The $370 is not in the order.
-
Simulator (a real MCP client) with a developer view: each tool call, each source marked live, fixture, sandbox or simulated.
-
A month later, in a new session: warranty, scope, photos and visit log are still there, and a $0.00 return visit is booked.
-
Architecture: simulator and Alexa skill call one MCP server. Registry live or recorded; camera and checkout simulated; partner sandboxed.
Proof Before Pay is an Alexa+ add-on: a self-hosted MCP server (spec 2025-11-25 over Streamable HTTP, plus 2026-07-28 on the same endpoint) with MCP Apps cards for Echo Show. Add-on tools are open to select partners only, so the Alexa+ side runs in an Echo Show 8 simulator that ships in the repo and is a real MCP client (official SDK client plus the MCP Apps bridge). A classic Alexa skill calls the same server.
Inspiration
Since we closed on our house in July, I've been in touch with 118 contractors and home-service companies and booked 13 jobs. Five went wrong. Two were marked done when the work wasn't finished, an install crew damaged the dryer duct, and two missed the arrival window they had agreed to. In two of those jobs I had already paid before I could check the work.
It isn't only my house. Florida received 4,847 unlicensed-activity complaints in fiscal year 2024-25 (DBPR ULA Report, p.13) and paid $4.35 million in 2025 to homeowners harmed by licensed contractors (DBPR 2025 Accomplishments). The FTC logged 81,925 reports in its home improvement, repair and solar category in 2024 (Consumer Sentinel Data Book 2024).
Finding a pro is easy now. Knowing what you are paying for is the hard part.
What it does
You say: "Alexa, I need a licensed electrician to replace outlets and smoke detectors in the master bath."
- It checks each pro's license number in Florida's license registry and leaves out the pro whose number isn't on record. Alexa says so and names the registry as the source.
- "Book Bright Current." It reads the booking back (six items, $1,120, paid per proven item) and books only after "yes". Every scope item says what proves it: a photo taken during the visit. The pro agrees that the front door camera logs only arrival and departure for this job, and the door code is labelled as simulated.
- After the visit: "He sent the invoice. Pay him." It checks the invoice line by line against the scope, the visit window and the photos, with fixed rules and no model. Five of six items are proven. The hallway smoke detector has no photo, and a $300 inspection wasn't in the scope. The card shows "Pay now $1,050.00" and "Waits $370.00", and every row names its source.
- A tap on "Pay $1,050.00" hands off to Alexa+ checkout. The add-on only stages a checkout session with the five proven items. Alexa+ (simulated in my host) reads the order back, asks for the voice code, charges the card on file and confirms. The add-on never receives the voice code or any card data, and the $370 is not in the order.
- Later, in a new session: "What's left with the electrician?" It remembers the job, names the two open items and drafts a note that the homeowner sends from their own messages.
- A month later, in another new session: "The master bath outlet stopped working again." It finds the 90-day labor warranty, attaches the scope, the photos and the visit log, reads the return visit back and books it at $0.00.
You can cancel a booking at any time, also in a later session; it reads back the booking and the pro's cancellation policy first.
This is the Alexa+ pattern the track calls creative: one request orchestrates several services on its own (a state license registry, a marketplace, front door camera events, job photos, checkout), the add-on maintains state across sessions and a server restart, it prepares a purchase that Alexa+ completes, and it answers with MCP Apps cards.
How I built it
- MCP server on the official TypeScript SDK v2 (
@modelcontextprotocol/server2.0.0) with 8 tools. The 2025-11-25 endpoint is strict: sessions withMcp-Session-Id, an old or unknownMCP-Protocol-Versionheader gets HTTP 400, a foreign Origin gets 403. The same/mcpURL also serves 2026-07-28 through the SDK's own era routing (isLegacyRequest+createMcpHandler), with no hand-written protocol code. I checked both eras independently with MCP Inspector CLI 2.8.0--strict: 8 tools, 0 schema problems. - MCP Apps (
@modelcontextprotocol/ext-apps2.0.0): six cards (ui://proofpay/*.html: pros, scope, payment, status, draft note, warranty). Seven of the eight tools link a card;prepare_checkouthas none on purpose, because the checkout screen belongs to Alexa+. The host renders each card in a sandboxed iframe on a second origin throughAppBridge. The pay button sends an MCP Appsui/message, nevertools/call. - Design. I designed the screens image-first: generated reference screens first, then HTML matched to them. The cards follow the Alexa+ add-on design guide (768×480 base canvas, ×1.667 on Echo Show 8, dark first, light from the same tokens). Voice comes first: every Alexa line is under 20 seconds (the longest is 11.2 s), and beats 1 to 4 take 43.6 s at 2.5 words per second. Tool names, ids and source badges live only in a separate developer view next to the device, never on the cards or in Alexa's lines. No third-party logos.
- Invoice check (
reconcile-v1): deterministic rules, no model. The same input gives the same output, and every conclusion carries its source. - License registry: a lookup against Florida DBPR's public license search (three HTTP requests with a session cookie), with the registry's "current as of" date on the card. A network error or an unexpected page is never turned into "verified": the lookup returns "unavailable", and the app falls back only to a recorded page it already has, labelled as recorded. The two licensed pros in the demo are fictional, so their "Verified" comes from recorded registry pages with fictional names and numbers; in the hosted demo and the video the unlicensed pro's number is looked up live (
REGISTRY_LIVE_NUMBERS). Run locally, everything is recorded by default;REGISTRY_MODE=livesends every lookup to the registry. - Front door camera events in the Ring Partner API webhook v1.1 format, verified with HMAC-SHA256 over the raw bytes (a bad signature gets 401 and nothing is stored). Only arrive and leave timestamps inside a consented booking window are kept; anything else is dropped. The events come from my simulator, built to the documented payloads. The door code is simulated because the Partner API has no lock control.
- Marketplace and checkout are a sandbox: Home Services SPI shapes (ListProfessionals, CreateBooking ESTIMATE → CONFIRMATION, CancelBooking) and checkout sessions in the Alexa+ checkout (UCP) shape, with
Idempotency-Keyreplay and 409 on a changed body, a decline returned as HTTP 200incomplete+payment_failed, and a session that refuses to complete when its total no longer matches the plan it was prepared from. No real money moves. - State per user in a file store with atomic rename. It survives a new MCP session and a server process restart.
- Classic Alexa skill (
ask-sdk-core2.14.0, APL 2024.3, request signature and timestamp verification): an MCP client of the same server (23 tests, including the full dialog against a real proofpay server and Amazon request-signature checks). It runs end to end in the Alexa Developer Console simulator: a custom skill in the development stage, a seven-turn dialog (the sandbox clock is advanced by a script between booking and invoice) with APL cards on the Echo Show 8 display profile. It also runs on a real Echo Show 8 at the development stage (2:22 in the video). With Alexa+ on the device, the first reply of a session is Alexa+'s own line ("Here's Proof Before Pay. Say 'Alexa exit' to get back to Alexa plus."), and then the skill speaks. npm run verifyruns 75 checks with no keys: both MCP eras, every tool, state across sessions and a restart, negative controls (404, 403, 401, 400), signed webhooks, checkout idempotency, the core unit tests, the skill tests, the backtest, and every demo beat in headless Chromium with a screenshot per beat. 75 of 75 pass on a fresh clone.
Challenges I ran into
- Serving 2025-11-25 sessions and 2026-07-28 on one endpoint is in the SDK, but I found it only in the
.d.mtstype comments. The default (legacy: "stateless") would have silently dropped my sessions. - Each MCP Apps card is about 610 KB, and about 450 KB of that is zod pulled in by the
Appclass. My own view code is about 10 KB. - The Alexa+ guide says Alexa scales the card to fit, but MCP Apps gives the view no scale signal. At ×1.667 the payment card's "not confirmed" rows and the pay button fell off the display, so each card now reduces its own zoom just enough to fit, and a verify check fails on any clipped card.
registerAppToolfor a tool without a card throws a bare TypeError at registration; my server is built per session, so it showed up as-32603oninitialize. Tools without a card now useregisterTool.- The Home Services SPI documents ListProfessionals and CreateBooking for different booking patterns. I use them together and label it as my combination.
- Alexa+ checkout has no partial capture, so "pay the proven part" is one checkout session that holds only the proven items. A second session for an item the homeowner approves later is my design inference, not something the docs confirm. Each of these is in the friction log with the command and what I saw.
Accomplishments that I'm proud of
- A backtest on my own history, run by code over an anonymized ledger of 141 engagements in the repo: all 5 jobs that went wrong since the closing would have hit at least one gate, and 3 of the 5 would have had every problem caught. What no gate catches is named too: slow, phone-only communication, and one problem I couldn't classify.
- The payment hand-off is clean. During the demo the add-on gets 13 MCP requests and none of them carries a voice code or card data. A deliberate breakage turns that check red.
- 75 of 75 verify checks on a fresh clone, two commands to run the demo, no accounts or keys.
What I learned
Payment belongs to the platform. Once I stopped building a payment screen, the add-on got simpler: its job is to get the amount right and explain every line with a source.
My bad jobs were mostly about time and proof, not licenses. On my history the visit log would have flagged 4 of the 5, proof-before-payment 3, and the license check 1.
What's next
Recurring services (lawn, pool, pest control), where billed time can be checked against time at the door. License registries in more states. A view for the pro. Real camera events once partner access is open, and a partial-capture concept in Alexa+ checkout (feature request R1).
Beyond the hackathon
The gates live in the server, not in the host, so they carry over to a real Alexa+ add-on unchanged. A verified-credential field on the SPI's Professional (license number, registry, status, as-of date; feature request R3) would let any home-services partner show a checked license instead of a badge string.
What is live and what is simulated: in the hosted demo and the video, the unlicensed pro's license number is looked up live in Florida's registry; the two "Verified" pros come from recorded registry pages with fictional values; the marketplace, photos, saved card and checkout sessions are a sandbox; the Alexa+ host, the camera events, the clock jumps and the door code are simulated. All businesses, people and places in the app demo are fictional. The dryer vent documents at 0:37 are real, from my own house, with the company, the technician and personal details left out.
In the video, the narration is my own voice, AI-cloned from my recording. Alexa's voice in the simulator is a synthetic stock voice. From 2:22 to 2:43 you see and hear the real Echo Show 8 and a real person talking to it.
For judges: where to look
| Criterion | Where to see it | Video |
|---|---|---|
| Tech Implementation | MCP 2025-11-25 strict + 2026-07-28 on one endpoint, MCP Apps cards, signed webhooks, platform checkout hand-off; npm run verify (75 checks); architecture in gallery image 7 |
1:57 under the hood; 2:22 the Alexa skill live on an Echo Show 8 |
| Design | Six beats on an Echo Show 8 frame, every Alexa line under 20 s, customer cards separate from the developer view; gallery images 1 to 6 | 0:51 to 1:57 and 2:09 to 2:22 |
| Potential Impact | Backtest on my own 141 contractor engagements; Florida and FTC numbers with sources (Inspiration) | 0:13 my own jobs; 0:37 a real job from my house: quote, proof, matching invoice; 2:44 the backtest and Florida's numbers |
| Quality of the Idea | Pay only for proven work: registry, scope, consented visit log and photos lead to a partial checkout that Alexa+ completes; state across sessions (status, warranty callback) | 0:02 the result; 0:59 license gate; 1:30 proof gate; 1:44 checkout hand-off; 2:09 memory and warranty; 2:22 the same on a real Echo Show 8 |
Built With
- alexa-presentation-language
- alexa-skills-kit
- ask-sdk-core
- esbuild
- mcp-apps
- mcp-inspector
- model-context-protocol
- node.js
- playwright
- streamable-http
- typescript
- zod
Log in or sign up for Devpost to join the conversation.