{"slug": "i-gave-claude-code-a-realtime-voice-mode-on-my-macbook", "title": "I Gave Claude Code a Realtime Voice Mode on My MacBook", "summary": "Developer John Robinson released macvoice, an open-source tool that gives Claude Code a hands-free voice mode running entirely on a MacBook, with listening, voice-activity detection, transcription and speech synthesis taking about 1.4 GB and requiring no PyTorch or cloud speech service. The tool drives Claude Code over the Agent Client Protocol (ACP) and speaks permission requests aloud, declining on any negative or unclear answer and defaulting to a decline after 20 seconds of silence; it hands off to the agent about 350 ms after the user stops talking. Robinson's setup downloads about 0.85 GB of models once and installs the @agentclientprotocol/claude-agent-acp package, and the same flags work with any ACP agent, with modes including default, acceptEdits, plan, auto and bypassPermissions.", "body_md": "[voice](https://www.storminthecastle.com/tags/voice/)\n\n[agents](https://www.storminthecastle.com/tags/agents/)\n\n[claude code](https://www.storminthecastle.com/tags/claude-code/)\n\n[acp](https://www.storminthecastle.com/tags/acp/)\n\n[apple-silicon](https://www.storminthecastle.com/tags/apple-silicon/)\n\n# I Gave Claude Code a Realtime Voice Mode on My MacBook\n\nby John Robinson\n[@johnrobinsn](https://twitter.com/johnrobinsn)\n\nThat's me building a small web page with Claude Code without touching the keyboard. I ask for the page, it asks out loud before running a command, I say \"yes\", and when I change my mind halfway through its answer I just talk over it and it stops.\n\nThe voice part runs entirely on the laptop: listening, working out when I've finished, transcribing and speaking take about 1.4 GB, with no PyTorch and no cloud speech service. Claude Code is the same Claude Code I use every day, on my normal subscription, driven over [ACP](https://agentclientprotocol.com) (the Agent Client Protocol).\n\nLast week's post, [A Local Voice Agent on a MacBook in Under 2 GB](https://www.storminthecastle.com/posts/mac_voice/), built the voice loop. This one points it at a coding agent, which needed three more things: a project to work in, a way to say yes or no to the agent's permission requests, and something to fill the silence while it thinks.\n\n## Try it [#](#try-it)\n\n```\ngit clone https://github.com/johnrobinsn/macvoice && cd macvoiceuv sync && uv run macvoice download              # about 0.85 GB of models, oncenpm i -g @agentclientprotocol/claude-agent-acp   # Claude Code over ACPuv run macvoice run --llm acp --cwd ~/demo-site\n```\n\n`--cwd` is the folder the agent works in, created if it doesn't exist. Use laptop speakers if you like: echo cancellation is on by default, so you can interrupt it without headphones.\n\n## Asking permission out loud [#](#asking-permission-out-loud)\n\nCoding agents ask before they do anything risky, and a voice mode has to handle that, or you end up reaching for the keyboard every thirty seconds. When Claude Code wants to run a command, macvoice says something like:\n\n\"Claude wants to create site folder with an index page. Allow?\"\n\nand prints the exact command:\n\n```\n? Claude wants to run: mkdir site && echo hi > site/index.html\n    (say yes or no, or press y / n / a (always))\n```\n\nThe spoken version uses the agent's own plain-English description of the command where it gives one. Reading `mkdir site && echo hi > site/index.html` aloud sounds terrible, so the details stay on screen.\n\nThen it listens for the answer. The rules are deliberately cautious:\n\n- **\"Yes\", \"sure\", \"go ahead\"** allow it once.**\"Always\"** allows it for the rest of the session.**\"No\", \"don't\", \"stop\", \"wait\"** decline.\n- **Anything negative wins.** \"No, yes\" is a no. A misheard answer can only ever decline.\n- **Unclear answers are asked once more** , then declined. So is 20 seconds of silence.\n- **The question can't answer itself.** Echo cancellation should keep the agent's voice out of the mic anyway, but nothing heard while the question is playing counts as an answer.\n- **You can also press `y`, `n` or `a`.** Keys typed before the question are thrown away, so nothing you pressed earlier can approve it.\n\nTo approve fewer things, use the agent's own modes. Claude Code's, as it reports them over ACP:\n\n``` bash\n$ uv run macvoice modes\n * default  (Manual)  Always ask before making changes\n   acceptEdits  (Accept edits)  Automatically accept all file edits\n   plan  (Plan)  Create a plan before making changes\n   auto  (Auto)  Claude handles permission decisions\n   bypassPermissions  (Bypass permissions)  Accepts all permissions\n```\n\n`--mode acceptEdits` is a nice middle ground for voice: file edits go through, and shell commands still ask. Nothing here is specific to Claude. Modes and permission requests are part of ACP, so the same flags work with any ACP agent, and the prompt uses the agent's own name (\"Gemini wants to...\").\n\n## Filling the silence [#](#filling-the-silence)\n\nThe voice pipeline hands off to the brain about 350 ms after you stop talking. With a small local model, the first word of the answer arrives 0.6–0.8 s after you stop. Claude Code is a different animal. In my tests it took **3 to 4.5 seconds** to start answering simple requests, and longer once it's reading files or running commands.\n\nFour seconds of silence in a conversation feels like the other side hung up. So when a reply hasn't started after 1.2 seconds, macvoice plays a soft blip once a second until the first word arrives, then cuts it off mid-blip. It plays through the same output as speech, so echo cancellation removes it from the mic, and you can still talk over it. `--no-thinking-tone` turns it off.\n\nTo be clear about where the time goes: the voice pipeline is fast, and most of the wait is the agent thinking and working. The tone doesn't make Claude faster. It makes the wait feel like the agent is working, not broken.\n\n## Short answers, not code [#](#short-answers-not-code)\n\nA coding agent's natural output is markdown and code blocks, which are miserable to listen to. ACP has no system prompt, so macvoice sends a short brief with the first message: replies are spoken, keep them to one to three short sentences, and when you change files or run commands, say briefly what you did instead of showing the code. The result sounds like a colleague reporting back, while the code lands on disk where you can read it.\n\n## Interrupting [#](#interrupting)\n\nThis is the part that makes it feel real-time. While Claude is talking, start speaking and it goes quiet within a fraction of a second. It needs a quarter second of continuous speech, so a cough doesn't count, and it ignores the first half second of a reply, while the echo canceller is still learning the room.\n\nGoing quiet isn't the same as stopping. Talking over someone usually means \"I get the idea, let's move on\", not \"undo what you're doing\", so Claude keeps working. Its full reply still lands on screen, and what you said goes to it as the next prompt once its turn ends. Two soft blips tell you when it's free, if you haven't already moved on. When you really do want it to stop, say just \"stop\" (or press Ctrl+C), and macvoice cancels its turn over ACP (`session/cancel`). Permission questions are the exception to going quiet: those are always spoken.\n\n## Type or talk [#](#type-or-talk)\n\nSome things are easier to type: a file path, a variable name, a stack trace. So the terminal has an input box under the conversation, and typed and spoken prompts go to the same Claude Code session. It works like you'd expect from Claude Code itself: Enter sends, Shift+Enter adds a line, the up arrow brings back earlier prompts, Ctrl+C stops the reply. Tool calls scroll past as one-liners (`▸ Edit index.html`, `✓`), and replies are rendered as markdown on screen while the voice skips the code blocks.\n\n## Why ACP [#](#why-acp)\n\nmacvoice doesn't screen-scrape a terminal or wrap a CLI. It speaks the same JSON-RPC protocol that editors use to host coding agents: start a session in a folder, send a prompt, stream the reply, answer permission requests, cancel. That's about 300 lines of standard-library Python, and it works with Claude Code, Gemini CLI, Codex, OpenCode and the rest. I wrote more about why that shared surface matters in [ACP: the shared surface for coding agents](https://www.storminthecastle.com/posts/acp_shared_surface_for_coding_agents/).\n\n## Caveats [#](#caveats)\n\n- **Permissions are yours to manage.**`--permissions allow` approves everything without asking. Only use it in a folder you don't mind losing.\n- **One-word answers are short.** \"Yes\" is right at the edge of what the endpointer keeps (250 ms of speech). If a quick \"no\" gets missed, you'll be asked again, and silence declines anyway.\n- **It's a Mac project.** The voice stack uses MLX and Apple's voice processing. The ACP side is portable; the audio side isn't, yet.\n\n## Beyond one agent: vibr8 [#](#beyond-one-agent:-vibr8)\n\nmacvoice is a tech project on GitHub: one agent in one terminal, small enough to read in an afternoon, and that's as far as I want it to go. [vibr8](https://www.storminthecastle.com/posts/ring_zero_the_meta_agent/) is the product, the thing I actually use every day, and I'm getting it ready for other people to install. It runs on Linux today with a GPU doing the voice work; the first installable release is coming to the Mac, with a full voice pipeline that runs locally on your Mac (the same Apple Silicon stack as this post, no GPU server and no cloud speech service), and other platforms follow.\n\nThe difference is what sits between your voice and the agents. In vibr8 you talk to **Ring Zero**, a meta-agent that runs several coding sessions at once: it starts them, sends them work, relays their permission requests, and tells you when one finishes or gets stuck. Because it can see all of those sessions, it can answer \"what did the API session just do?\" with a sentence that knows the context, instead of reading you a transcript. [Ring Zero: The Meta-Agent for Coding Agents](https://www.storminthecastle.com/posts/ring_zero_the_meta_agent/) explains the idea, and [Anatomy of a Ring Zero Session](https://www.storminthecastle.com/posts/anatomy_of_a_ring_zero_session/) walks through a real one.\n\nThe voice side goes further too. A guard word means it only acts when you address it (\"vibr8, ...\"), so it's comfortable to leave listening all day ([Towards an always-listening voice agent](https://www.storminthecastle.com/posts/towards_always_listening_voice_agent/)). **Note mode** is for thinking out loud: say \"vibr8 note\", ramble for as long as you like while it stays quiet, say \"vibr8 done\", and Ring Zero gets the whole thing as one voice note to act on. And you can just ask vibr8 to put something **on your clipboard**, a command, a snippet or an image, ready to paste wherever you're working.\n\nBring your own coding agent: the sessions underneath are ACP, so Claude Code, OpenCode and the rest plug in the same way ([ACP: the shared surface for coding agents](https://www.storminthecastle.com/posts/acp_shared_surface_for_coding_agents/)). I recommend Claude Code for now. Why one person ends up running a fleet of agents at all is in [Software Factories](https://www.storminthecastle.com/posts/software_factories/).\n\nIf macvoice is talking to one agent, vibr8 is talking to the team. More soon, starting with the Mac.\n\nThe code for this post is at [github.com/johnrobinsn/macvoice](https://github.com/johnrobinsn/macvoice). The first post has the details of the voice pipeline: why Smart Turn ends turns in under 300 ms where a silence timer takes 1.5 seconds, and how echo cancellation makes barge-in work on laptop speakers.\n\nIf you try it, let me know how it goes, especially which agent you pointed it at.\n\n**Interested in being a beta tester when Ring Zero (vibr8) is released?** Sign up for the mailing list now.\n\nFollow along at [storminthecastle.com](https://www.storminthecastle.com) — or reply if you're building in this space.\n\n[Share on Twitter](<https://twitter.com/intent/tweet?text=I Gave Claude Code a Realtime Voice Mode on My MacBook&url=https://www.storminthecastle.com/posts/claude-voice/&via=johnrobinsn>)|\n\n[Discuss on Twitter](https://twitter.com/search?q=https://www.storminthecastle.com/posts/claude-voice/)\n\nJohn Robinson © 2022-2026", "url": "https://wpnews.pro/news/i-gave-claude-code-a-realtime-voice-mode-on-my-macbook", "canonical_source": "https://www.storminthecastle.com/posts/claude-voice/", "published_at": "2026-11-05 15:06:12+00:00", "updated_at": "2026-11-05 15:26:01.283325+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-tools", "developer-tools", "artificial-intelligence"], "entities": ["Claude Code", "John Robinson", "macvoice", "Agent Client Protocol", "Anthropic", "Gemini", "MacBook"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/i-gave-claude-code-a-realtime-voice-mode-on-my-macbook", "markdown": "https://wpnews.pro/news/i-gave-claude-code-a-realtime-voice-mode-on-my-macbook.md", "text": "https://wpnews.pro/news/i-gave-claude-code-a-realtime-voice-mode-on-my-macbook.txt", "jsonld": "https://wpnews.pro/news/i-gave-claude-code-a-realtime-voice-mode-on-my-macbook.jsonld"}}