{"slug": "talking-to-claude-code-through-an-alexa", "title": "Talking to Claude Code through an Alexa", "summary": "An engineer built a system that lets them start coding tasks on Claude Code by speaking to an Amazon Alexa device. The main challenge was Alexa's eight-second response limit, which forced a design where the assistant acknowledges instantly, thinks in the background, and surfaces results on a dashboard. The system runs tasks in tmux sessions so the user can watch the work live.", "body_md": "This was an afternoon experiment, so read it in that spirit. The goal was to start real coding work by talking to a speaker: not \"set a timer\", but \"work on the board script\", and have an agent plan it with me and go and do it. No laptop open.\n\nI gave myself a few hours, which means there are shortcuts everywhere. The backend is literally my laptop. The public entry point is a free tunnel. There is exactly one user, me, and no accounts. None of that would survive contact with real users, and I will come back to what a grown-up version looks like at the end. But the core turned out to be more interesting than I expected, because the main constraint forced a better design than the obvious one.\n\nAlexa cuts off a skill's response after about eight seconds. That is the whole design problem in one sentence.\n\nA coding agent does not fit in eight seconds. Even just asking Claude to *think of a few options* for a task takes anywhere from four to twenty-plus seconds. So you cannot do the obvious thing, which is take what the person said, ask Claude about it, and speak the answer. Alexa will have hung up long before Claude replies.\n\nOnce you accept that nothing useful finishes in the window, the design falls out of it: **acknowledge instantly, think in the background, and surface the thinking somewhere the eight seconds do not apply.**\n\nHere is what actually happens when I use it.\n\n```\nme:    \"Alexa, open assistant\"\nclaude: \"Claude ready. What should I work on?\"\n\nme:    \"work on the board script\"\nclaude: \"Okay, work on the board script. I'm putting a few options on the\n         dashboard. Tell me which one or describe what you want, then say go.\"\n\nme:    \"the second one\"\nclaude: \"Here's the plan: add a --since flag to the board script. Say go to\n         start, or add more.\"\n\nme:    \"go\"\nclaude: \"Starting now: add a --since flag to the board script. Watch the\n         dashboard, and ask me for the result.\"\n```\n\nThe moment I describe a task, the server does two things at once. It replies immediately with a short acknowledgement, well inside the window, and it spawns a detached job that asks Claude to turn my vague sentence into two or three concrete, short options. Those options land on a dashboard, and the next thing I say is resolved against them. \"The second one\", \"option two\", and \"three\" all map to a choice; anything else is folded in as more detail.\n\n```\nsequenceDiagram\n  actor You\n  participant Echo as \"Echo / Alexa cloud\"\n  participant Mac as \"alexa-claude (my Mac)\"\n  participant Claude\n  You->>Echo: \"work on the board script\"\n  Echo->>Mac: signed request\n  Mac-->>Echo: ack in under a second\n  Mac->>Claude: generate options (background)\n  Claude-->>Mac: options appear on dashboard\n  You->>Echo: \"the second one\" ... \"go\"\n  Echo->>Mac: signed request\n  Mac->>Claude: run task in a tmux session\n  Mac-->>Echo: \"starting, ask me for status\"\n```\n\nSo the latency that made the naive design impossible becomes invisible: by the time I have heard the acknowledgement and decided what I want, the options are already there. The prompt gets built up across a couple of turns, and \"go\" commits it.\n\n(The skill is invoked as \"assistant\" rather than \"claude\", because Amazon will not let you claim a single well-known word as a custom invocation name. It just introduces itself as Claude.)\n\nWhen I say \"go\", the task does not run as some opaque background process. It starts in its own **tmux session**, which means it shows up in the same `sessions`\n\ntool I use for every other Claude session on the machine, and I can attach and watch it work live:\n\n```\nsessions go <pid>   # drop into the running voice-started job\n```\n\nThat mattered more than I expected. A voice command that spawns invisible work is unnerving. A voice command that spawns a session I can see, attach to, and read line by line is just a faster way to start something I already understand.\n\nVoice is a poor channel for output, so the real surface is a small web dashboard the server renders. It polls every couple of seconds and shows the prompt being built right now with its options, the jobs with running, done, and failed badges, and a log of voice turns so I can see what it heard and what it said back.\n\nThe one decision I am quietly pleased with: the dashboard is **refused on the public URL.** The tunnel that lets Amazon reach my Mac would also let anyone who found it load my activity dashboard. But tunnelled requests carry an `X-Forwarded-For`\n\nheader and direct localhost requests do not, so the server serves the dashboard only to local requests and returns a 403 to anything that arrived over the tunnel.\n\nLong work reports back through whatever channel suits. The job streams to its log and its tmux pane the whole time. When I want the result out loud, I ask:\n\n```\nme:    \"Alexa, ask assistant for the status\"\nclaude: \"Done, add a --since flag to the board script. <reads the tail of the\n         output, kept short enough to be pleasant>\"\n```\n\nIf the machine has Telegram configured it also pushes the result to my phone, but that is optional sugar now rather than the main path. Short questions are the one thing answered inline: \"ask assistant to tell me X\" runs Claude read-only with a few seconds of grace, and speaks the answer if it finishes in time.\n\nEven an afternoon toy that starts a coding agent from a public URL needs a lock, so every request has to prove itself. The server follows Amazon's verification for self-hosted endpoints: the certificate chain has to be a genuine Amazon address, the certificate has to be valid and issued for `echo-api.amazon.com`\n\n, the body has to verify against its signature, and the timestamp has to be recent so a captured request cannot be replayed. The skill id is a second lock on top. Questions run read-only; tasks run with a permission mode that edits files but still stops before risky commands.\n\nEverything above is held together with the cheapest possible parts, and that is the right call for a few hours of play. But it is worth being honest about where the shortcuts are and what you would actually build instead.\n\nThe shortcuts: the backend is my Mac, so it only works while the machine is awake with the server and tunnel running. The entry point is a personal free tunnel, not a hosted endpoint. There is one user and no authentication, so \"lock it to my skill id\" is doing a lot of heavy lifting. And the agent runs directly on my real machine with access to my real files, which is fine for me and unthinkable for anyone else.\n\nA product version inverts most of that:\n\n``` php\nflowchart LR\n  Echo[\"Echo\"] --> Alexa[\"Alexa cloud\"]\n  Alexa -->|\"account linking (OAuth)\"| GW[\"API Gateway\"]\n  GW --> Fn[\"Skill function: validate + enqueue\"]\n  Fn --> Q[\"Queue\"]\n  Fn --> DB[(\"Jobs / sessions store\")]\n  Q --> W[\"Sandboxed agent workers\"]\n  W --> DB\n  W -->|result| Push[\"Proactive notifications / companion app\"]\n  Push --> Echo\n```\n\nThe skill endpoint becomes a hosted, stateless function behind an API gateway, so there is no laptop to keep awake and no tunnel to babysit. Its only jobs are to verify the request, look up the user, and drop work on a queue, all comfortably inside the eight seconds. **Account linking** turns the single-user assumption into real multi-tenancy: each person links their own identity, and the skill id stops being the only thing standing between a stranger and a shell.\n\nThe actual agent work moves onto **sandboxed workers**, one isolated environment per user, so a task can never touch anyone else's files or the host. Job and conversation state lives in a small **database** rather than on one machine's disk, which is what lets a result reach you later, on a different device, after the voice session is long gone. And the results come back through Alexa's **proactive notifications** or a companion app, so \"ask me for the status\" becomes \"your phone buzzes when it is done.\"\n\nNone of that is exotic. It is the boring, well-trodden shape of any async job system. The interesting part, the planning-conversation-around-latency, stays exactly the same. The afternoon version just runs it on a laptop instead of a fleet.\n\nI went in thinking the hard part would be the voice. It was not; Amazon's speech to text is good and free. The hard part, and the fun part, was that the eight second wall made the naive design impossible and pushed me toward a better one: a system that never pretends to be fast, acknowledges instantly, thinks out of band, and gives you real attachable sessions and a live dashboard instead of a single hopeful reply.\n\nIt stopped being \"an agent I sit in front of\" and became \"an agent I can start a conversation with from across the room, then go and watch it work.\" For an afternoon's wiring, that is a surprisingly nice way to begin a piece of work.\n\n*Built from scratch, like everything in this newsletter. Questions about the build? Say hello.*\n\n*This was originally published on juliantellez.com. It is part of my newsletter on video, streaming, and building reliable systems from scratch: the architecture, the tradeoffs, and the occasional 3am incident.*\n\nIf it was useful, [subscribe for the next one](https://juliantellez.com/#newsletter). No spam, unsubscribe anytime. If you are building something similar and want to compare notes, [say hello](mailto:hello@juliantellez.com). I read every message.\n\nBuilt from scratch, like everything here.", "url": "https://wpnews.pro/news/talking-to-claude-code-through-an-alexa", "canonical_source": "https://dev.to/_juliantellez/talking-to-claude-code-through-an-alexa-1k71", "published_at": "2026-07-29 13:01:45+00:00", "updated_at": "2026-07-29 13:06:30.935229+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "large-language-models"], "entities": ["Alexa", "Claude Code", "Amazon", "tmux"], "alternates": {"html": "https://wpnews.pro/news/talking-to-claude-code-through-an-alexa", "markdown": "https://wpnews.pro/news/talking-to-claude-code-through-an-alexa.md", "text": "https://wpnews.pro/news/talking-to-claude-code-through-an-alexa.txt", "jsonld": "https://wpnews.pro/news/talking-to-claude-code-through-an-alexa.jsonld"}}