mac-voice-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mac-voice-mcpask me if I'm ready to deploy the app"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Claude says something through your Mac's speakers, listens to your answer the way a person would, and gets back what you said as text. Speech recognition runs on your Mac, so no audio leaves your computer.
Claude ──speak_and_listen("Tests pass. Open the PR?")──▶ 🔊 "Tests pass. Open the PR?"
🎙 you: "yes, and tag Priya"
Claude ◀──────────────── "Yes, and tag Priya." ───────── whisper.cpp on your MacIt's built for Apple Silicon Macs (M1–M4). Linux works too, with SoX and espeak-ng installed.
🤖 Vibe-coded
This project was designed and written with Claude, in conversation. A human (me) steered it, tried it on a real Mac and checked the test suite, but most of the code was written by AI. It's a proof of concept: it works and has tests, but expect rough edges, and read the code before relying on it for anything important. Issues and pull requests are welcome.
It's an independent project, not made or endorsed by Anthropic. It works with any MCP client, including Claude Desktop, Claude Code and Cursor.
How it works
The server has two tools and two prompts:
What it does | |
| Speaks a short message, listens for one conversational turn and returns the transcript. |
| Checks what's installed. After you agree, it installs only what's missing. |
| A guided setup: it checks, asks you, installs, then runs a spoken test. |
| A hands-free session where Claude checks in by voice at natural points. |
Listening works like a conversation. A soft chime plays when the mic opens. The server waits for you to start talking and hands back to Claude about a second after you stop. It adjusts to background noise, doesn't cut you off at pauses mid-sentence, and ignores coughs and clicks. If you say nothing for 8 seconds, Claude gets "no speech", which it is told never to treat as a yes.
Replies come back fast. whisper.cpp's server keeps the speech model loaded between turns, and the model starts loading while Claude is still talking. You don't wait for a model load on each reply. After 15 idle minutes the server shuts down to free memory. It is stopped automatically even if the MCP server crashes.
Claude sends text meant to be heard. The tool description gives Claude rules for writing short spoken sentences. If code, paths, links or markdown still get through, the server rewrites them before speaking and tells Claude, so the next message is cleaner. See below.
Related MCP server: Voice MCP
Install
1. Add the server to your client. You need Node.js 18.17 or newer.
Claude Code
claude mcp add voice-mcp -s user -- npx -y mac-voice-mcpOr install it as a Claude Code plugin:
/plugin marketplace add jeet0007/mac-voice-mcp
/plugin install mac-voice-mcp@mac-voice-mcpClaude Desktop. Add this to ~/Library/Application Support/Claude/claude_desktop_config.json, then quit (⌘Q) and reopen the app:
{
"mcpServers": {
"voice-mcp": {
"command": "npx",
"args": ["-y", "mac-voice-mcp"]
}
}
}If you get spawn npx ENOENT, use the full path from which npx, e.g. "command": "/opt/homebrew/bin/npx".
Cursor. Add the same mcpServers block to ~/.cursor/mcp.json, or use the one-click link:
cursor://anysphere.cursor-deeplink/mcp/install?name=voice-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1hYy12b2ljZS1tY3AiXX0=2. Run setup once. Ask Claude to "set up voice". In Claude Code you can also run /mcp__voice-mcp__setup, or from a terminal run npx -y mac-voice-mcp setup.
Setup checks what's already there before it changes anything:
Needed | Provided by | If it's missing |
Voice | macOS | Nothing to do. It's part of macOS. |
Microphone capture | SoX ( |
|
Speech-to-text | whisper.cpp ( |
|
Speech model |
| Downloaded once to |
Nothing is redone. Tools already on your PATH are used as they are. If the model is already somewhere on disk (a whisper.cpp checkout, Homebrew's share folder, another tool's cache, or anything Spotlight can find), it's symlinked, not downloaded again.
brew installruns only for the missing formulae.Nothing happens without your OK. Claude calls
voice_setupto check first, shows you the checklist, and asks before calling it withinstall=true.Slow installs don't time out. If
brew install whisper-cpptakes a while, setup reports INSTALLING. The install carries on in the background, and the next check picks up the result.
3. Allow the microphone. The first time Claude listens, macOS asks whether Claude (or Cursor, or your terminal) can use the microphone. Click Allow.
Installing from a clone
One command does everything above: it builds the project, runs setup (asking before installing anything), adds voice-mcp to Claude Desktop (backing up your config first) and to Claude Code, and offers a spoken test. It's safe to re-run, because each step checks first and skips anything already done.
git clone https://github.com/jeet0007/mac-voice-mcp && bash mac-voice-mcp/install.shUsing it
"Work on X and check in with me by voice when you need a decision." Claude works quietly and only speaks at decision points.
/mcp__voice-mcp__voice_mode fix the flaky login test. Claude reads its plan back to you, then checks in at each checkpoint. Say "stop voice mode" or "I'm back" to end it."Read me a 20-second summary of this PR and ask if I should approve it." Use this for one-off briefings.
Just talk after the chime. You don't need to hurry or fill silence. If you're still talking at the 30-second safety cap (
listen_seconds), Claude is told your reply may be cut off and asks you to continue.
Getting Claude to sound natural
Guidance reaches Claude through several channels, because each client shows different ones:
Channel | Who sees it |
Tool description (rules plus a good and a bad example) | Every client |
Server instructions (when to use voice, how to handle replies, setup) | Claude Code (it reads up to 2 KB) |
The | Claude Code (as slash commands), Claude Desktop, Cursor |
Server-side rewrite plus a | Always on |
The rules Claude is given:
- 1–3 short sentences, under ~40 words; lead with the outcome, then one question.
- Plain words only: no markdown, bullets, emoji, code, file paths, URLs, stack traces or tables.
- Describe code instead of reading it, say file names not paths, round numbers, spell out symbols.
- Ask one question at a time, answerable in a few words.
- Put the details (diffs, logs, links) in the on-screen reply, and say so out loud.The safety net turns ## Results\n- \npm test` ✅ 42/42\n- see /Users/x/repo/src/index.ts:120` into "Results. npm test 42 of 42. see index.ts."
Claude Desktop ignores server instructions. To make the rules stick there, paste examples/CLAUDE.md into Settings → Profile → personal preferences or into a Project's instructions. For Claude Code, add it to CLAUDE.md. For Cursor, copy examples/voice-mcp.mdc to .cursor/rules/.
Configuration
Everything is optional. Set these in your client config's "env": { … } block, or with -e NAME=value in claude mcp add.
Speaking
Variable | Default | |
| system voice | macOS voice, e.g. |
| system rate | Words per minute, e.g. |
|
| Longer text is cut at a sentence boundary ("the rest is on screen"). |
|
| Set to |
Listening
Variable | Default | |
|
| How long a pause ends your turn. Use |
|
| How long to wait for you to start talking. |
|
| How much louder than room noise counts as speech. Raise it in noisy rooms. |
|
| The quietest level that ever counts as speech (dBFS). |
|
|
|
Speech-to-text
Variable | Default | |
|
| Which model to use (see the table below). |
|
|
|
| — | Words to bias toward: names, product terms, jargon. |
| — | Use this exact |
| — | Extra folders to check for an existing model ( |
|
| Set to |
|
| How long the warm server stays up without use. |
| min(8, cores) | Number of whisper.cpp threads. |
|
| Where models are downloaded or symlinked. |
|
| Verbose logs with per-turn timings, written to stderr. |
Models (whisper.cpp names):
Model | Size | Good for |
| 75 MB | Yes/no answers, the lowest latency |
| 142 MB | Default. English conversation. |
| 466 MB | Noticeably more accurate English |
| 547 MB | Other languages, e.g. Thai with |
Troubleshooting
Symptom | Fix |
"voice-mcp is not set up yet" | Ask Claude to set up voice, or run |
"microphone returned pure digital silence" | macOS is blocking the mic for the host app. Go to System Settings → Privacy & Security → Microphone, enable Claude / Cursor / your terminal, then restart that app. |
No permission prompt ever appears | Run |
It cuts me off while I'm thinking | Set |
It never stops listening | The room is too noisy for the defaults. Set |
It hears its own voice | Use headphones, or turn the speaker volume down. It only listens after it finishes speaking, but echo can linger. |
"Homebrew: not installed" | Install it from brew.sh. It needs your password, so it can't run from Claude. Then run setup again. |
It garbles names or jargon | Set |
Known limitations
You can't interrupt it. It finishes speaking, then listens. Barge-in would mean listening while the speakers play, which needs headphones or echo cancellation.
It's macOS-first. Linux works with SoX and espeak-ng. Windows is untested.
Turn-taking is based on loudness, not a speech model. It adapts to background noise, but very noisy rooms, music or TV can confuse it. A headset helps, and so do the listening settings above.
One conversation at a time. There's one speaker and one microphone, so calls are queued.
Privacy and safety
Audio stays on your machine. Recordings go to a temporary file that's deleted after each turn. The only network use is the one-time model download from Hugging Face.
The warm whisper server is local only. It listens on
127.0.0.1on a random port, and stops when idle or when this server exits.Setup can only install known packages. Its install list is fixed in the code (
sox,whisper-cpp), so nothing Claude says can make it install anything else. It never uninstalls or modifies other software.
Security
Secrets: every push and pull request is scanned for leaked secrets with TruffleHog, and the whole history is scanned before the first push. GitHub secret scanning with push protection is also on.
Dependencies: Dependabot opens weekly update pull requests. CI fails on high-severity advisories (
npm audit), and dependency review blocks pull requests that add vulnerable packages.Code: CodeQL runs with the
security-extendedqueries.Releases: releases publish through npm trusted publishing, with no long-lived npm token and a signed provenance attestation for every version.
To report a vulnerability, see SECURITY.md.
Development
npm install
npm test # build + 27 tests: unit tests and end-to-end tests over MCP with stub binaries
npm run audit # known-vulnerability and signature checks on dependencies
npm run setup # check what's installed; offers to install what's missing
npm run test:voice # one real speak → listen → transcribe turn
npm run inspect # MCP InspectorModule | Responsibility |
| Environment settings, logging, the PATH fix-up for GUI apps |
| Rewriting screen text for speech, cleaning up transcripts (pure, unit-tested) |
| Turn-taking voice-activity detection (pure, unit-tested) |
| Text-to-speech, chimes, streaming mic capture |
| Finding, symlinking or downloading the model |
| The warm |
| Requirement checks and consent-based background installs |
| The round trip, the MCP tools and prompts, and the CLI |
The package installs two commands: mac-voice-mcp (the one npx -y mac-voice-mcp runs), and voice-mcp.
Releasing
First release:
bash publish.sh. It asks before each public step and uses your own GitHub and npm logins. It creates the GitHub repo, publishes to npm, and lists the server in the official MCP Registry, which Smithery, Glama, PulseMCP and mcp.so pick up from.Later releases: bump
versioninpackage.jsonandserver.json, then push av<version>tag. The Publish workflow tests the build, checks that the tag matches both versions, and publishes to npm and the MCP Registry. It needs no secrets: both logins use GitHub's OIDC identity, once you've set the package's Trusted Publisher on npmjs.com (publish.shprints the steps).
License
MIT
Available Tools
2 toolsspeak_and_listenSpeak and listenA
Say something out loud to the user and hear their spoken reply. Speaks text_to_speak through the computer's speakers, then listens like a conversation turn — it waits for the user to start talking and stops when they finish — and returns an on-device transcript of what they said.
Write text_to_speak for the ear, not the screen:
1–3 short sentences, under ~40 words; lead with the outcome, then one question.
Plain words only: no markdown, bullets, emoji, code, file paths, URLs, stack traces or tables.
Describe code instead of reading it ("I added a retry to the upload function"), say file names not paths ("in index.ts"), round numbers ("about two hundred ms"), spell out symbols.
Ask one question at a time, answerable in a few words ("Should I deploy it — yes or no?").
Put the details (diffs, logs, links) in your normal on-screen reply, and say so out loud.
Good: "The build passed and all tests are green. Want me to open the pull request?"
Bad: "## Results\n- npm test ✅ 42/42\n- see /Users/x/repo/src/index.ts:120"
Once the user is talking with you by voice, keep the conversation in voice: answer each transcript with another speak_and_listen call (not a text reply) until they say stop or start typing. A reply of "(No speech detected …)" means the user did not answer — never treat it as consent. If it reports that voice-mcp is not set up, call voice_setup.
| Name | Required | Description | Default |
|---|---|---|---|
| text_to_speak | Yes | The summary or message to read aloud to the user. Plain, conversational text. | |
| listen_seconds | No | Upper limit on how long to listen, in seconds (default 30, max 120). Listening already stops when the user finishes talking, so you rarely need this. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide no safety hints (all false), so the description carries the full burden. It discloses the listening behavior (waits for speech, stops when finished), the on-device transcript return, special handling for no speech, and a setup fallback. This is rich behavioral context beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average, but every section earns its place. It front-loads the core function, then uses bullets and examples to convey style rules without redundancy. The structure makes it scannable and actionable for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and complex interactive behavior, the description thoroughly covers the return value (transcript), edge cases (no speech), setup errors, and conversation flow. It leaves no critical gap an agent needs to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds substantial meaning to the text_to_speak parameter with a full style guide: write for the ear, 1–3 short sentences under 40 words, no markdown/code/URLs, ask one question at a time, and provide good/bad examples. It also reinforces that listen_seconds is rarely needed because listening stops automatically.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear statement of the tool's function: 'Speaks text_to_speak through the computer's speakers, then listens like a conversation turn... and returns an on-device transcript.' This is a specific verb+resource description that clearly distinguishes it from the sibling voice_setup, which is only mentioned as a fallback for setup issues.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: keep voice conversations going with repeated speak_and_listen calls until the user says stop or types, never treat '(No speech detected …)' as consent, and call voice_setup if the tool reports lack of setup. It also specifies the alternative (text reply) and when not to use it in favor of voice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
voice_setupVoice setupAIdempotent
Check whether this computer has everything speak_and_listen needs — text-to-speech, a microphone recorder (SoX),
whisper.cpp speech-to-text and the speech model — and optionally install what's missing.
Anything already installed is reused (an existing model elsewhere on disk is symlinked, not re-downloaded).
Call it with install=false (the default) first and tell the user what is missing.
Only call it with install=true after the user agrees: it runs brew install for the missing packages
and downloads the speech model once. It never uninstalls or changes anything else.
If it reports INSTALLING, the install continues in the background — wait a minute and call it again to check.
| Name | Required | Description | Default |
|---|---|---|---|
| install | No | false (default): only check. true: brew install missing packages and download the model. Ask the user first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate mutability and idempotency, but the description adds valuable specifics: existing installs are reused, an existing model is symlinked rather than re-downloaded, it uses brew install, downloads only once, never uninstalls or changes other things, and installation may continue in the background. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but every sentence carries necessary operational information: what is checked, what installation does, reuse behavior, user-consent requirement, safety constraints, and background-install handling. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with no output schema, the description covers prerequisites, side effects, safety boundaries, invocation sequence, and the background-install scenario. The only missing detail is the full set of possible return statuses, but the mention of the INSTALLING report is enough to guide the agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description enriches the single install parameter substantially: false is the default and means check-only, true means install missing packages and download the model, and true requires prior user consent. This goes well beyond the schema's brief parameter description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific purpose: check for and optionally install the dependencies that speak_and_listen needs, naming the exact components (text-to-speech, SoX, whisper.cpp, model). It clearly distinguishes itself from the sibling speak_and_listen by being the setup tool rather than the communication tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit sequencing: call with install=false first and report missing items; only call with install=true after user agreement. It also explains the background-install behavior and tells the agent to wait and re-check, which is strong operational guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.0- First observed
speak_and_listen - First observed
voice_setup
TDQS
Scored across 2 tools
The two tools are completely distinct: speak_and_listen handles interactive voice turns, while voice_setup handles environment setup and installation. There is no overlap in purpose or timing.
Both names use snake_case and are descriptive, but speak_and_listen is a verb phrase while voice_setup is a noun compound. The pattern is mostly consistent with a minor structural deviation.
Two tools is sparse but appropriate for the narrow scope of Mac voice interaction and setup. Each tool serves a clear, necessary role and there are no redundant tools.
The core voice turn-taking flow and the setup prerequisites are fully covered. Minor gaps like standalone listening or granular audio controls exist but do not affect the primary use case.
Related MCP Connectors
Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.
Claude makes real phone calls for you — in many languages, with transcript and outcome back in chat.
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
- QuallaaOAuthcom.quallaa
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables hands-free voice conversations with Claude using real-time speech recognition and text-to-speech on macOS. Creates a self-sustaining conversation loop where Claude can autonomously listen, respond, and continue the interaction without keyboard input.MIT
- AlicenseNot gradedqualityDmaintenanceEnables bidirectional voice interaction for Claude Code using local speech-to-text and text-to-speech models optimized for Apple Silicon. It provides tools to listen to user speech via microphone and speak responses aloud through system speakers.16Apache 2.0
- -licenseNot gradedqualityNot gradedmaintenanceA voice-enabled interface for Claude Desktop that supports speech-to-text input and text-to-speech output via ElevenLabs, turning Claude into a voice assistant.1-
- FlicenseNot gradedqualityDmaintenanceEnables Claude to speak text with an embedded audio player, supporting 54 voices, voice cloning, and playback controls, all running locally.2-