Inspiration
Customer-service calls waste time in a uniquely frustrating way. Users must navigate phone menus, repeat context, wait on hold, survive transfers, and remain available for the brief moment when a representative finally answers.
Existing voice agents can speak, but speaking is only a small part of the problem. A useful calling agent must maintain state throughout a long-running call, recognize when the situation changes, and know when it must return control to the user.
That led us to build Waitless: an MCP-compatible phone-agent capability that an assistant such as Alexa can invoke. Waitless handles the waiting and routine coordination, while the user retains control of their identity and consequential decisions.
What it does
A user describes a customer-service goal conversationally—for example:
“Ask my bank about a possible duplicate charge.”
Waitless converts that request into a bounded call task. It can:
- Prepare the request using the user's saved, non-secret profile details
- Navigate phone menus conservatively
- Remain on hold and track transfers
- Display an observable activity timeline
- Detect when a representative becomes available
- Bring the user into the existing call for private identity verification
- Request explicit approval before consequential account changes
- Arrange a callback when the case cannot be completed immediately
- Preserve a structured history of the task and its outcome
Conceptually, the product divides the call into two operating modes:
$$ \text{Delegated work} \longrightarrow \text{Private user verification} \longrightarrow \text{Delegated work resumes} $$
Waitless does not treat privacy as a disclaimer. During sensitive verification, the AI leaves the media path so the user speaks directly with the representative. AI listening, recording, and transcription are disabled during that portion of the interaction.
The agent receives only the minimum state required to continue:
verification_completed = true
It does not receive the user's password, PIN, verification code, or sensitive audio.
How we built it
We designed Waitless as a capability rather than another standalone assistant.
An Alexa-style conversational interface delegates the task through MCP. Behind that interface, the phone agent operates as a closed loop:
$$ \text{Observe} \rightarrow \text{Decide} \rightarrow \text{Act} \rightarrow \text{Verify} $$
The agent observes the current call state, selects a bounded action, invokes an explicit phone tool, and verifies the resulting state before continuing.
The prototype combines:
- An MCP-compatible task and handoff layer
- A realtime voice and phone-event runtime
- Speech and keypad-action handling
- Confidence thresholds and safe fallbacks
- Policy gates for verification and account changes
- A user-facing event timeline
- Traceable task states and regression fixtures
- A responsive H5 experience designed to fit naturally inside an assistant
A simplified view of the architecture is:
Alexa-style interface
|
v
MCP capability layer
|
v
Phone-agent control loop
|
+---- Policy and authorization gates
|
+---- Voice, IVR, hold, and transfer runtime
|
+---- Human handoff bridge
|
v
Observable task events and results
For the hackathon demo, we created simulated customer-service flows so judges can experience the complete product safely without placing a real call or changing a real account. The interface clearly identifies the simulation, while the workflow demonstrates how the same state machine, tools, and handoff boundaries can apply to a production calling system.
Challenges we ran into
The hardest challenge was not generating natural speech. It was deciding when the agent should act, wait, ask, or stop.
Phone systems are unpredictable. Menus change, prompts repeat, transfers introduce silence, and the same key may have different meanings at different levels of an IVR.
We therefore avoided assuming that a fixed keypad sequence would always be correct. The agent waits until the relevant menu option has been heard completely and applies a conservative confidence threshold:
$$ a = \begin{cases} \operatorname*{arg\,max}_{k} P(k \mid x), & \max_k P(k \mid x) \geq 0.6 \ \text{no action}, & \max_k P(k \mid x) < 0.6 \end{cases} $$
Here, $x$ represents the observed prompt and call context. If the agent is not sufficiently confident, it presses nothing instead of guessing.
Identity verification created another architectural challenge. Simply instructing a language model not to remember a password or verification code is not sufficient. Sensitive audio must be removed from the AI media path itself. This requirement shaped our secure human-handoff flow.
We also learned that observability is essential. A long-running autonomous process can easily feel frozen—or like a prerecorded animation—unless the interface exposes meaningful events such as dialing, navigating the IVR, waiting, connecting, handing off, and arranging a callback.
Accomplishments that we're proud of
We are proud that Waitless is more than a voice interface layered on top of a scripted demo. We designed the call as a visible, stateful agent process in which each meaningful UI transition corresponds to an observed event, a bounded decision, or a tool result.
We are especially proud of the secure human handoff. Instead of merely asking the model to ignore sensitive information, Waitless changes the media path itself. The user can verify directly with the representative while AI listening, recording, and transcription remain outside that private portion of the call.
We are also proud that Waitless does not require users to trust an agent with unlimited authority. It automates menus, waiting, transfers, and routine context, but pauses for identity checks and consequential account decisions. That boundary made the experience safer and also made the product easier to understand.
Finally, building Waitless as an MCP-compatible capability means the work is not limited to one application or one interface. The same task, policy, calling, handoff, and observability tools can be invoked by other compatible assistants while preserving the same behavioral constraints.
What we learned
The product boundary that emerged from our work is:
Automate the waiting and coordination, not the user's authority.
Users do not need another opaque agent making irreversible decisions on their behalf. They need an agent that handles repetitive work, makes its progress visible, and returns control at exactly the right moment.
MCP was valuable because it allowed us to model Waitless as a reusable capability with explicit tools and state boundaries. The calling workflow is not tied to one screen or one assistant. It can be invoked by any compatible agent while preserving the same safety rules.
What's next for Waitless
Next, we plan to:
- Connect the prototype to a production telephony provider
- Evaluate it across more real-world IVR structures
- Improve interruption, silence, and transfer detection
- Add company-specific calling skills
- Expand call-trace evaluation and regression testing
- Support multilingual customer-service calls
- Introduce user-configurable authorization policies
Our long-term goal is simple: people should be able to delegate the frustrating parts of customer-service calls without delegating control of their identity or important decisions.
Built With
- amazon-nova-sonic
- amazon-web-services
- boto3
- css3
- fastapi
- html5
- javascript
- model-context-protocol-(mcp)
- node.js
- pipecat
- python
- uvicorn
- websockets
Log in or sign up for Devpost to join the conversation.