voix
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., "@voixread me the build results out loud"
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.
voix
Local voice output for AI agents. One executable, one MCP tool, no cloud.
Agent ──MCP──▶ voix ──▶ Kokoro (local ONNX) ──▶ your speakersAn agent gathers whatever it needs with its other tools, writes a spoken summary, and calls speak. voix synthesizes it with Kokoro-82M on the CPU and plays it. First audio starts in about a second; nothing leaves the machine.
Supported platforms: macOS on Apple Silicon and Linux x64 (glibc). See docs/SPEC.md for every design decision.
Install
One line (installs to ~/.local/bin/voix; set VOIX_INSTALL_DIR to change that):
curl -fsSL https://github.com/osmelmora/voix-mcp/releases/latest/download/install.sh | shThe installer selects the matching release asset:
Platform | Asset | Audio player |
macOS Apple Silicon |
| built-in |
Linux x64 (glibc) |
| tries |
Linux playback needs a working PipeWire, PulseAudio, or ALSA session. Install its client tools if necessary (for example, pipewire-bin, pulseaudio-utils, or alsa-utils on Ubuntu). Headless use with voix say --out hello.wav "Hello" needs no audio player or device. Alpine/musl, Linux arm64, Intel Macs, and Windows do not have supported binaries yet.
Or download the executable from the latest release and put it on your PATH. For macOS Apple Silicon:
curl -fsSL -o voix https://github.com/osmelmora/voix-mcp/releases/latest/download/voix-darwin-arm64
chmod +x voix && mv voix ~/.local/bin/voixFor Linux x64, use voix-linux-x64 in the download URL instead.
Or build it yourself (needs Bun 1.4.2 (pinned in mise.toml)):
git clone https://github.com/osmelmora/voix-mcp && cd voix-mcp
bun install
bun run build # → dist/voix-<platform>-<arch> for the current supported host
# Cross-compile explicitly: bun run build bun-linux-x64
# Releases add --minify: bun run build --minify
# Copy the matching executable from dist/ to ~/.local/bin/voixThe macOS binary is not code-signed. curl downloads run as-is; if you downloaded it with a browser run xattr -d com.apple.quarantine ~/.local/bin/voix once.
Related MCP server: mcp-ai-voice
First run
voix say "Hello"On first use voix downloads the Kokoro model (326 MB, fp32, Apache-2.0) into ~/.cache/voix and verifies its SHA-256. After that everything is offline. To do the download ahead of time:
voix setupConnect an agent
Add voix to your MCP client configuration (Claude Code, Claude Desktop, Cursor, ...):
{
"mcpServers": {
"voix": { "command": "voix", "args": ["mcp"] }
}
}If voix is not on the client's PATH, use the absolute path, for example "/Users/you/.local/bin/voix".
The agent gets two tools:
tool | what it does |
| Speak text. By default it returns when the player has started for the first audio batch, or at once with |
| Stop immediately and drop the queue. |
Errors come back as typed tool errors (EmptyText, TextTooLong, InvalidVoice, InvalidSpeed, ModelDownloading, DownloadFailed, ChecksumMismatch, PlayerNotFound, PlaybackFailed, SynthFailed). The server also publishes short usage instructions and the resource skill://voix/SKILL.md, which is the same text as skills/voix/SKILL.md. Copy that folder into your agent's skills directory if it supports skills.
Then try:
Give me my daily update out loud.
CLI
voix say "Build finished." # speak
echo "Deploy done." | voix say # from stdin
voix say --voice bm_george --speed 1.1 "Good evening."
voix say --out hello.wav "Hello" # write a WAV instead of playing
voix voices # 28 English voices, * marks the default (af_heart)
voix status # model, cache, player, runtime
voix setup # download the model now
voix mcp # MCP server over stdioConfiguration
There is no config file. Defaults: voice af_heart, speed 1.0.
variable | effect |
| where models are stored (default |
| download the model from a mirror; its pinned SHA-256 still applies |
| disable audio output (tests, CI) |
How it works
Runtime: TypeScript on Bun, compiled with
bun build --compile. Effect 4 for services, typed errors, the queue, interruption, and the MCP and CLI layers.Inference:
onnxruntime-nodeon the CPU with about 150 lines of Kokoro glue and the eSpeak NG phonemizer in WebAssembly. No Python, no transformers.js. voix forcesORT_DISABLE_TELEMETRY=1before loading the native runtime, disabling its bundled telemetry.Pipelining: text is split into sentences; the first plays while the rest synthesize, and each later playback chunk is everything that finished in the meantime.
Playback: a temp WAV played by
/usr/bin/afplayon macOS, orpw-play/paplay/aplayon Linux, as a scoped child process killed onstop, on request cancellation, and on exit. Linux plays one silent sample to check the sound server/device before reporting startup, trying the next installed backend on failure. Each check has a five-second deadline. Every utterance is checked before its first batch is acknowledged; later batches are not. The backend that last played successfully is tried first. Cancellation never retries. If a player fails after partially playing, fallback may replay that batch.voix saywaits for completion and exits nonzero if synthesis or every available player fails, or if no audio starts within 45 seconds.What is inside the binary: Bun runtime, the ONNX Runtime library, 28 voice files, the tokenizer, the code. Only the model is downloaded.
Development
Use mise to install and activate the Bun, Node.js, hk, Pkl, and cocogitto versions pinned in mise.toml. Node runs the lint and format tooling. mise also puts node_modules/.bin on PATH. CI uses the same mise configuration.
Linting and formatting use Ultracite with Oxlint and Oxfmt. Run bun run check to check both, or bun run fix to apply automatic fixes. The CI workflow checks commit messages, linting, formatting, types, and tests on every push to main and every pull request.
Dillon Mulroy's anti-slop rules run alongside Ultracite: all 18 generic rules, all five Effect rules, and oxc/no-accumulating-spread are errors. See the vendoring record for provenance, licenses, and update guidance. Keep oxlint and @oxlint/plugins pinned to the same version when upgrading.
Cyclomatic complexity is capped at 15 per function, overriding Ultracite's default limit of 20.
Git hooks run through hk, configured in hk.pkl. The pre-commit hook runs Oxlint, Oxfmt, and tsc on staged files and stages automatic fixes. The commit-msg hook requires Conventional Commits subjects such as feat(mcp): add stop tool. The pre-push hook runs the same checks and the tests. Run hk check --all to check everything at once, or hk fix --all to apply fixes. Set HK=0 to skip the hooks once.
Releases run in CI with cocogitto, configured in cog.toml. When the commits since the last tag call for a bump (feat → minor; fix or perf → patch; a breaking change → minor while the version is 0.x, so 1.0.0 is a manual release), a push to main builds and tests both binaries with the next version. Once both pass, CI commits that version to package.json and CHANGELOG.md as github-actions[bot], tags it, and publishes a GitHub release with the binaries, the installer, and that version's changelog entry as notes. Other pushes are plain CI runs, and commits pushed with [skip ci] are released by the next run on main. CI is the only thing that tags: don't run cog bump or push tags yourself, and pull after a release to get the bump commit. If the release job fails, re-run it; when its tag was already pushed, it publishes without bumping again. If main moves on during a release, the job leaves the release to the CI run for the newer commit, or stops when a published release already contains its commit; when neither covers it, the job fails and its error says which run to start or re-run. A release always covers every commit since the last tag, so if the newer run fails or is cancelled, re-running it (or the next green run on main) releases the commits it took over.
To release by hand, run the ci workflow on main from the Actions tab. It takes a bump (auto, patch, minor, or major), an exact X.Y.Z version that overrides the bump, and a dry run that builds and tests the release without publishing it. ci, chore, style, and test commits stay out of the changelog. Keep GitHub's default merge title ("Merge pull request #N from …") when merging a pull request: cog 7.0.0 lists a merge commit with a conventional title in the changelog next to the commit it merges, so the change appears twice. Run cog changelog to preview unreleased changes.
mise install
bun install
hk install --mise # install the git hooks
hk check --all # lint, format, and type check
VOIX_PLAYER=none bun test # synthesis and MCP tests run only if the model is cached
bun run src/main.ts say "dev mode"
bun run build
bun run scripts/smoke.ts ./dist/voix-darwin-arm64 # use voix-linux-x64 on Linux
VOIX_BIN=./dist/voix-darwin-arm64 VOIX_PLAYER=none bun test tests/mcp.test.tsKnown limitations
Supported binaries are darwin-arm64 and linux-x64 (glibc). Linux arm64, Windows, Intel Macs, and musl are not supported yet.
English voices only. Kokoro's other languages need a different grapheme-to-phoneme stack.
The embedded eSpeak NG build is GPL-3; see NOTICE.
License
MIT for voix. Third-party components are listed in NOTICE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Audio for your agent: transcribe, speak, translate, summarise, plus sound effects and music.
Let cloud agents talk to you: progress updates spoken on your Mac, and replies you send back.
Command your AI agents by voice: PTT rooms, channels, direct messages, agent email, memory (mRAG).
Text to speech for your AI. Your AI can send text to Doc Player to read it aloud. You will see a reader window with the text and you can control the playback sentence by sentence. Find an example here: https://documentplayer.com/connect-ai/
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to speak and listen in real-time with interruption handling, using local ML models and hot-swappable adapters.8 npmMIT
- AlicenseAqualityDmaintenanceEnables AI agents to synthesize natural speech using either platform system voices or premium OpenAI TTS, with automatic engine selection and graceful fallback.112 npmMIT
- AlicenseAqualityAmaintenanceEnables AI agents to speak using MacOS native text-to-speech, with support for blocking and non-blocking speech and a sequential queue.215MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to speak aloud by generating and playing audio through the system output. Supports multiple TTS providers, playback queue management, and configurable voice profiles.8 npm1MIT