Inspiration
Small local businesses, barbershops, physio clinics, pet groomers, hotel desks, corner grocery stores, run on a phone line and a paper book. They can't justify building or maintaining an app, so after-hours calls go to voicemail and bookings get lost. Alexa+'s new mid-conversation tool-calling made it possible for a customer to just ask their Echo to book a haircut the way they'd ask a human receptionist, no app for the customer, no app for the owner to build. That gap is what OpenDesk fills.
What it does
OpenDesk is an Alexa+ MCP server that turns any small local business into something a customer can book entirely by voice. A customer asks, "Alexa, ask OpenDesk to book a haircut for tomorrow after work," and OpenDesk finds the business, checks real availability against staff schedules and buffer times, holds the slot, reads it back for confirmation, books it, and spells the confirmation code aloud. It also handles rescheduling, cancellations with late-fee warnings, waitlists that automatically re-offer a freed slot, and stock-tracked product orders (groceries, hotel rooms, retail items) for businesses that sell things instead of, or alongside, appointments.
On the business side, owners get a real dashboard: a per-staff timeline with a live "now" line, a waitlist panel, analytics (bookings, revenue, channel split), and a live activity feed of every voice booking as it happens. Accounts are DynamoDB-backed with owner/manager/employee roles, so staff can get dashboard access without pricing control. Owners onboard their whole catalog, services, prices, staff, hours, by typing a plain-English description and letting Amazon Bedrock (Nova Lite) turn it into a structured, bookable business in one tool call.
How we built it
It's a stateless Streamable HTTP MCP server (MCP spec 2025-11-25) in TypeScript/Express: every request spins up a fresh McpServer and transport, so there's no session state to manage and nothing in the hot path but synchronous, JSON/DynamoDB-backed logic, keeping every tool call comfortably under Alexa+'s 500ms budget (sub-10ms p50, measured live on the dashboard). Account linking is a from-scratch OAuth 2.1 + PKCE implementation with its own /oauth/authorize page, since Alexa+ doesn't support dynamic client registration and requires a pre-registered client. Amazon Bedrock's Converse API is used only on the owner-facing side (never in the customer voice path): business onboarding forces the model to call a save_business tool whose JSON schema is generated directly from the same Zod schema used to validate the result, so the contract can't drift, plus a daily-briefing summarizer. The 9 MCP tools (find_businesses, hold_appointment, confirm_appointment, cancel_appointment, join_waitlist, etc.) and the booking/availability engine are covered by 177 automated tests, including a real end-to-end run that spawns the server as a child process.
Challenges we ran into
- Alexa+ requires a 401 response with no WWW-Authenticate header, but the MCP SDK's built-in bearer middleware adds one by default, which meant writing custom auth middleware instead of trusting the SDK's.
- Alexa+ pins to MCP spec 2025-11-25, not the SDK's LATEST_PROTOCOL_VERSION (which tracks the newer 2026-07-28 revision), so we had to check the SDK's SUPPORTED_PROTOCOL_VERSIONS list directly rather than trusting "latest."
- No dynamic client registration meant every dev loop needed a pre-registered OAuth client up front instead of just hitting an authorize endpoint.
- Keeping every tool call deterministic and under 500ms meant banning network/LLM calls from the entire customer-facing path, which shaped the whole architecture around synchronous, file/DynamoDB-backed state.
- A real Alexa+ add-on console sandbox wasn't available during the hackathon, so the demo had to simulate the Alexa+ conversation through an MCP client (Claude Desktop via mcp-remote) talking to the real, running server instead.
- A Bedrock account-level quota restriction (this was confirmed by Amazon, no escalation path before the deadline) blocked a live on-camera demo of the onboarding flow, even though it's fully built and tested.
Accomplishments that I was proud of
- Sub-10ms p50 latency on real tool calls, backed by 177 automated tests.
- A real OAuth 2.1 + PKCE account-linking flow built from scratch, including a custom login page and .well-known metadata endpoints.
- One server, five very different business types (barber, physio, pet groomer, hotel, grocery store) running off the same tools and code, because the catalog is just data.
- A waitlist that automatically re-offers a freed slot the instant a cancellation lands, visible live on the dashboard.
- Role-based (owner/manager/employee) DynamoDB-backed accounts that let staff use the dashboard without handing over pricing control.
- Bedrock-powered onboarding where the model's output schema is generated from, and re-validated against, the exact same Zod schema, so there's no drift between what's asked for and what's accepted.
What we learned
- Getting the auth story right is most of what makes a voice tool trustworthy enough to actually book something on someone's behalf, it's not a bolt-on.
- "Stateless by request" is a genuinely good fit for a 500ms voice budget: no session to manage beats optimizing a session.
- LLMs belong in the parts of the system that can tolerate latency and ambiguity (owner onboarding, summaries), and nowhere near the parts that can't (the live voice booking path).
- Platform-specific spec quirks (exact protocol version, exact 401 shape) matter more than "the SDK defaults," so cross-checking the actual platform docs against SDK behavior early saves a late debugging session.
What's next for OpenDesk
- Real testing against the live Alexa+ add-on console once sandbox access opens up beyond the hackathon.
- Finishing the on-camera Bedrock onboarding demo once the account-level quota restriction is lifted.
- Durable persistence beyond a single JSON file/App Runner's ephemeral filesystem (DynamoDB migration is already underway for accounts).
- Payments/deposits at booking time, multi-location businesses, and an SMS/notification channel for waitlist offers and reminders.
- More verticals validated end-to-end beyond barber/physio/groomer/hotel/grocery, to stress-test that "catalog is just data" claim further.
Built With
- ai
- alexa
- amazon-web-services
- bedrock
- chartjs
- docker
- dynamodb
- mcp
- node.js
- typescript
Log in or sign up for Devpost to join the conversation.