Inspiration
Freelancers and small-biz owners who get paid in crypto receive their invoices by email. Answering "what's unpaid right now?" means 20 minutes of inbox archaeology — search, open, copy amounts into a spreadsheet, remember what you already paid. The current workaround is a spreadsheet plus memory, and memory loses.
What it does
A simulated Alexa+ voice experience in a web app. You say "Alexa, what's unpaid?" and it searches your real inbox over the Mermail MCP server, reads the invoice emails, extracts invoice IDs and amounts, reconciles them, and speaks the answer back — with invoice cards on screen. Also supported: "audit my invoices" (full audit), "is invoice INV-2044 paid?" (single-invoice check), "check for duplicate invoices" (duplicate sweep). Voice in → real data → voice out, one workflow end to end.
How we built it
The track's required technology lives in code, not the README: backend/mcp_client.py is a hand-rolled MCP Streamable-HTTP client (httpx, zero new dependencies) that performs the real initialize handshake, notifications/initialized, tools/list, and tools/call against the Mermail MCP server (12-tool least-privilege agent-inbox profile: mailbox discovery, email search, email read; no send, no wallet), authenticated with an x-api-key header. Around it: a FastAPI backend, a deterministic intent router (regex, no LLM), and a reconciliation engine that renders verdicts — UNPAID, DUPLICATE_CLAIM, MATCH, AMOUNT_MISMATCH. The frontend uses the browser's built-in Web Speech API for voice in/out; no audio leaves the device.
Challenges we ran into
Kept as a 6-entry friction log (submitted with this entry): the MCP endpoint answers only up to the auth boundary (401 on a bad key — the correct answer); pip install mcp is PEP-668-blocked, so we hand-rolled the client; the server answers notifications/initialized with HTTP 200 and an empty body per spec, which crashed our client until we handled it; the search_emails free-text field is named "query" in the live inputSchema (undocumented — our first guess was wrong); sandbox NO_PROXY IPv6 literals crash httpx's env parsing, so the client wires the proxy explicitly.
Accomplishments that we're proud of
28/28 tests pass, including a live authenticated MCP session (initialize → tools/list → tools/call against the real server). /api/ask verified live: "what's unpaid?" searches the real inbox and answers honestly. The honesty contract holds end to end — no API key means a 503 refusal, never fabricated inbox data; an empty inbox gets an honest "found none," not a guess.
What we learned
The live inputSchema is the only source of truth for tool arguments — docs examples can mislead. And a skipped key-gated test is a known-unknown, not a passing test: our two real bugs only surfaced on the first authenticated run.
What's next for Alexa+ Invoice Radar
A real self-hosted MCP server on the same Streamable-HTTP transport; invoice PDF attachment parsing; payment verification against wallet history so "paid" becomes verifiable instead of honestly-reported-as-unpaid.
Note for judges: the demo mailbox ([email protected]) currently holds no invoices, so the video shows the honest empty-state path — the same pipeline that renders spoken summaries and verdict cards when invoices are present.
Log in or sign up for Devpost to join the conversation.