Alexa is, for better and worse, the most widely deployed voice interface in the world. And until recently, putting anything in front of it meant building a custom skill, deploying a Lambda, and negotiating with the Amazon Developer Console — an afternoon you won't get back.
You don't have to do any of that anymore. If you have Froots running on your laptop and an Echo on your counter, you can wire them together in about ten minutes. Here's the recipe.
What we're building
"Alexa, ask my agent to brief me." Alexa hears the phrase, forwards it to Froots, where the agent-brief routine compiles a summary from your calendar + Linear + email, and speaks it back through the Echo. Same pattern works for every agent action you can think of.
The full flow, in one sentence: Alexa Routine → webhook → Froots routine → agent → text-to-speech announcement back to Alexa.
Prerequisites
- Froots installed. (Download here if you don't have it.)
- An Echo or any Alexa-enabled device on the same account as your phone.
- The Alexa app on your phone (iOS / Android).
- Five minutes of patience for Alexa's Routine editor.
Step 1 — Expose a Froots webhook
In Froots, open the command palette (⌘⇧P) and pick Routines → New routine. Name it agent-brief. Paste this into the sentence compiler and hit ⌘⇧R:
When my webhook fires, run Clem on "give me a two-sentence brief of my morning — open issues, calendar, and inbox," then announce the result on my Echo Show in the kitchen.
Froots parses it into a five-step graph:
Webhook trigger → Agent: Clem (brief) → Format (plain text, max 600 chars)
→ HomeKit announce (Echo Show, kitchen) → Log to vault
Save the routine. Froots will show you a signed webhook URL that looks like:
https://your-froots-machine/hooks/agent-brief?token=abc123…
Copy the URL. That's the one Alexa will call.
If your laptop isn't reachable from the internet, enable Settings → Routines → Expose via Tailscale (free, automatic) or Expose via Cloudflare Tunnel. Either gives you a stable public URL without opening ports on your router.
Step 2 — Build the Alexa Routine
Open the Alexa app on your phone.
- More → Routines → New routine (the
+icon). - When this happens → Voice. Type
"my agent to brief me"(Alexa prefixes that with "Alexa, ask" automatically). - Add action → Custom → Web request. Paste the Froots webhook URL. Method:
POST. Body (optional): leave blank, or paste{"source":"alexa","device":"kitchen"}if you want to route on device later. - Add action → Alexa says → Custom → "On it." This is the acknowledgement you hear after the trigger phrase; Alexa speaks it immediately while Froots works on the brief.
- From which device — pick the Echo you want the brief announced on. (Doesn't have to be the same device that heard the trigger.)
- Save.
Step 3 — Test
Say "Alexa, ask my agent to brief me."
Expected timing:
- 0.0s — you finish the phrase
- 0.3s — Alexa says "On it."
- 0.6s — Alexa hits the Froots webhook
- 2–4s — Clem compiles the brief (this depends on your model choice)
- 4–5s — the Echo Show in your kitchen announces the result
If you want faster, set the routine's model to a Haiku-class or a local 7B in Froots — Settings → Routines → agent-brief → Model. The rest is free.
Going further: custom skill path (lower latency)
If you need sub-second response times, skip the Alexa Routines path and write a trivial custom skill that also hits your Froots webhook. The latency floor is different because custom skills bypass the Routine orchestrator.
The 30-line skill is:
// index.js — AWS Lambda (Node 22)
const WEBHOOK = process.env.FROOTS_WEBHOOK;
exports.handler = async (event) => {
const utterance = event.request?.intent?.slots?.phrase?.value || '';
const res = await fetch(WEBHOOK, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ source: 'alexa-skill', utterance }),
}).then(r => r.json());
return {
version: '1.0',
response: {
outputSpeech: { type: 'PlainText', text: res.speak || 'done.' },
shouldEndSession: true,
},
};
};
Interaction model — one intent, one slot:
{
"interactionModel": {
"languageModel": {
"invocationName": "my agent",
"intents": [
{ "name": "AskIntent", "slots": [
{ "name": "phrase", "type": "AMAZON.SearchQuery" }
], "samples": ["to {phrase}", "about {phrase}"] }
]
}
}
}
With this skill, you say "Alexa, ask my agent to tell me how last night's build went" and the utterance goes straight to Froots as a slot value. Round-trip is typically 1.2–1.8s on a fast model.
Useful voice recipes
Once the pattern works for one routine, you can wire up everything:
- "Alexa, ask my agent to send it." — Clem deploys to staging, reads the commit SHA, and announces success or failure.
- "Alexa, ask my agent what I missed." — Lime collates new messages across inbox channels, reads the top three.
- "Alexa, ask my agent to remember this." — Alexa sends the utterance as text; Yuzu writes it to
Memory/context.mdwith a timestamp. Great for hands-full ideas in the kitchen. - "Alexa, ask my agent to start focus." — turns off notifications, pauses Slack, announces "focus mode — back at noon."
Troubleshooting
Alexa says "Sorry, I had trouble completing that." — The webhook didn't respond within 7 seconds. Lower your model's tier, or split the routine so Alexa's part ends quickly and the agent announcement is triggered async from a second step.
The Echo speaks the wrong response. — Your webhook returned text that Alexa spoke as-is. Fix: in your Froots routine, trim to <600 characters and strip markdown before the announce step. Add a Format node in the graph.
No sound at all. — Announcements require the Echo to have an active Spotify/Amazon Music session or be a Show device. On audio-only Echos, replace the "Alexa says → Custom" with "Alexa sends a notification" or route through a Sonos if you have one.
Why this is the Froots pitch in miniature
Most "put an AI on Alexa" tutorials are 45 minutes long because most AI tools don't come with a sentence-to-routine compiler. Froots's core trick is that the hard part — "make this call this, with a schedule and a retry and a log" — is a keyboard shortcut. The fifty lines of code above are optional; the two paragraphs of English are the whole product.