Inspiration

I have run Fort Collins Junk Removal and Demo for 15 years. The calls I miss are the calls I lose, and I miss them because I am usually carrying a couch down a staircase. Most haulers are one truck and one or two people. We cannot afford an answering service, and national booking platforms do not know local rules, like which county site takes old paint. I wanted a front desk that a voice assistant could run for me, with me still in charge of the schedule.

What it does

HaulDesk is a self-hosted MCP server that gives Alexa+ (or any MCP client) a complete front desk for a small hauler, on both sides of the counter.

Customer side:

  • estimate_quote: "How much to haul a couch and a fridge, two flights of stairs?" becomes a load size and a price range, labeled sample pricing, with "final price confirmed on site". In hosts that support MCP Apps, the quote comes back as an interactive card with a trailer-fill meter and a "Request this pickup" button.
  • find_dropoff: "Where can I take old paint?" returns verified local sites with hours, fees, what they refuse, and the official source page and check date. Nothing is invented.
  • request_booking: collects name, contact, zip, and a preferred window over several turns and saves a request like HD-7K3Q as pending owner review. It never promises a time and never texts or emails anyone.
  • check_request: works from any later session or device. Once the owner decides, it says "Good news. Request HD-7K3Q is confirmed for Saturday 9 to 11 AM", reads the owner's note, and offers an Add to calendar file.

Owner side:

  • list_requests: "Any new requests?" returns a one-sentence spoken briefing and the queue.
  • review_request: "Confirm HD-7K3Q for Saturday 9 to 11" or "decline it". The customer hears the decision the next time they ask.
  • The owner page at /owner is a phone-friendly dashboard with Read it to me, Confirm, and Decline. Every button is a real MCP tools/call.

How we built it

  • Official MCP TypeScript SDK 1.32.1, protocol 2025-11-25, stateless Streamable HTTP on Node and Express. A new McpServer per request, so it scales to zero and survives reloads; state that must outlive a session (quotes, requests, owner decisions) lives in a small JSON store with atomic writes.
  • Deeper MCP than a tool wrapper: 6 tools with input schemas, output schemas, and annotations; structured content on every result; 4 resources (the pricing sheet, the service area, the verified drop-off directory, and the MCP App view); 2 prompts (front_desk and owner_briefing); and per-connection tool lists, so owner tools only appear on connections with owner access (OWNER_KEY header, or masked public demo mode).
  • MCP Apps (SEP-1865): estimate_quote links ui://hauldesk/quote-card.html. The view is one self-contained HTML file with no external scripts or network calls. Our simulated Alexa+ page is also a small MCP Apps host: it reads the ui:// resource, renders it in a sandboxed iframe with a strict CSP, and speaks the ui/initialize, tool-input, tool-result, size-changed, and ui/message protocol. The card's button sends ui/message, and the conversation continues into booking.
  • The simulated Alexa+ page is a real MCP client (the official SDK client bundled for the browser), with browser speech in and out and no paid APIs. Behind the scenes shows every JSON-RPC message and every MCP App postMessage, plus a Connect your own MCP client panel with copyable setup for Cursor, Claude Desktop, MCP Inspector, and curl.
  • An Agent Skill (skills/hauldesk-front-desk/SKILL.md) teaches any skill-aware agent the voice playbook for these tools; a test keeps it in sync with the server.
  • Business, pricing, and drop-off data are plain JSON files, so another hauler can fork it, edit three files, and have their own front desk.
  • 59 automated tests (unit, multi-session integration over real HTTP, owner key gating, MCP Apps resource checks), an SDK smoke client, MCP Inspector 2.11.0, and headless Chrome runs at phone and desktop sizes. Tool calls answer in about 3 to 9 ms locally, far under a voice latency budget.
  • Built with a Cursor cloud coding agent and Grok Bot from my written plan.

Design: why the interaction model fits voice

  • Every tool returns one or two sentences written to be spoken, plus structured data for a card. Ids use a voice alphabet with no 0/O or 1/I, and check_request accepts "hd 7k3q".
  • Booking is multi-turn: it asks for exactly the one missing thing next.
  • Safe by design: nothing is confirmed without the owner, nothing is texted or emailed, contact details never come back out of check_request, and the public demo masks phone and email on the owner side.
  • The owner side is voice-first too: the briefing is a sentence, not a table, because the owner is usually driving.

Potential impact

There are thousands of one- and two-truck haulers in the US, and each one loses jobs to missed calls. HaulDesk turns the three questions they answer all day (how much, where can I take this, can you come Saturday) into tools any assistant can call, and closes the loop with an owner approval step that respects how small crews actually schedule. The drop-off answers also keep paint, batteries, and electronics out of the landfill by pointing people to the right county site with its official source. Because the data is three JSON files, the same server works for any city.

Challenges we ran into

  • The Alexa+ MCP Toolkit, CLI, and Web Simulator are partner-only previews (the hackathon FAQ confirms this), so I built a browser client that speaks real MCP instead, and made the server work with any MCP client.
  • Spec 2026-07-28 is published while the hackathon minimum is 2025-11-25. I stayed on 2025-11-25 because the FAQ describes the initialize flow.
  • The SDK's createMcpExpressApp has no request-size option, so I swapped in a 32kb JSON parser.
  • MCP Apps helpers live in a separate package and the spec's web sandbox needs a second origin, so I wrote a minimal host and documented exactly what it does and does not do.

Accomplishments that we're proud of

  • A full loop across sessions and roles: a customer books by voice, the owner confirms by voice or tap, and the customer hears it later from any client.
  • A real MCP App rendered by our own host, with a button that drives the conversation.
  • Drop-off answers that cite official local sources with a last-verified date.

What we learned

MCP makes a tiny business's know-how reusable. The hard part was not the code, it was writing tool answers short enough to sound right out loud while still carrying enough data for a card, and deciding what the assistant must never do on its own.

What's next for HaulDesk MCP

OAuth 2.1 for the owner side when connecting to a real Alexa+ add-on, real calendar sync once the owner opts in, and shared drop-off data files so haulers in other cities can contribute.

Built With

Share this project:

Updates

Submission history