MCP server
@paxalabs/mcp gives any MCP client the Paxa API as tools: speech through the machine's speakers, speech to file, translation into Thai, and document OCR. Install it for Claude Code, Claude Desktop, Cursor, or VS Code, and turn Claude Code into a voice mode with the paxa say hook.
@paxalabs/mcp is the official Model Context Protocol server for the Paxa API. An agent connected to it can speak through the machine's speakers, read long content aloud as a managed playback queue, and save speech to audio files. It can also translate any language into Thai and read PDFs and images with OCR. Each tool bills the same credits as the API endpoint behind it. The source is on GitHub.
Note
The server is in beta. The tool set is complete and tested end to end, and tool names may still change before 1.0. Report problems at https://github.com/paxalabs/mcp/issues.
Install#
You need an API key. New accounts include 100 free credits.
claude mcp add paxa -e PAXA_API_KEY=pxa_your_key_here -- npx -y @paxalabs/mcp{
"mcpServers": {
"paxa": {
"command": "npx",
"args": [
"-y",
"@paxalabs/mcp"
],
"env": {
"PAXA_API_KEY": "pxa_your_key_here"
}
}
}
}The JSON entry works for Claude Desktop (claude_desktop_config.json), Cursor (~/.cursor/mcp.json), VS Code, and any other client that launches stdio servers. Replace the placeholder with your key.
Claude Desktop can also install the extension bundle from the releases page. Download the .mcpb file, open it with Claude Desktop, and enter your key in the extension settings. The bundle carries the server and its dependencies and needs no Node.js on the machine.
Tools#
| Tool | What it does | Credits |
|---|---|---|
| speak | Synthesize a short line and play it through the speakers, blocking until playback ends | 15 per 1,000 characters |
| queue_speech | Read long content aloud: splits the text, synthesizes ahead while playing, and returns at once | 15 per 1,000 characters |
| control_playback | Control the shared audio queue: status, pause, resume, skip, clear | Free |
| play_audio | Play a local audio file through the speakers | Free |
| text_to_speech | Synthesize speech to an audio file (mp3, opus, wav) without playing it | 15 per 1,000 characters |
| translate_to_thai | Translate any language into Thai, with formality, glossary, and context controls | 25 per 1,000 characters |
| ocr_document | OCR a local PDF, PNG, JPEG, or WebP into Markdown or structured blocks | 6.5 per page |
| list_voices | The voice roster with character notes | Free |
| list_models | Available models, limits, and pricing | Free |
| get_account | Credit balance, plan, and rate limits | Free |
All audio flows through one ordered queue and sounds never overlap. A speak line plays ahead of queued long-form segments, and queue_speech keeps a book or an article flowing by synthesizing the next segment while the current one plays. With a streaming-capable player installed, speech starts on the first bytes from the API; without one, it plays after the download completes.
Voice mode for Claude Code#
Three pieces let you walk away from Claude Code. It talks when it has news and calls you when it needs you. Install the server as above, tell Claude when to talk, and wire a hook for the moments the model is idle.
Tell Claude when to talk#
Add this to ~/.claude/CLAUDE.md, or to one project's CLAUDE.md:
## Voice
I have the Paxa MCP server (tools: speak, queue_speech, control_playback).
I am often away from the screen, so use voice like this:
- At the end of a turn where you did real work, call speak with a one or
two sentence summary before writing the final message: what you did,
what is next, and anything you need from me.
- When you need a decision from me, speak the question too.
- Keep it short and conversational. Never read code, file paths, logs, or
long lists aloud. Those stay in text.
- Do not speak for quick back-and-forth or trivial answers.
- If I ask to hear something long, use queue_speech.
- Speak in the language I write in.Get told when Claude needs you#
When Claude Code waits for a permission or an answer, the model is idle and cannot call speak. Claude Code fires a hook at those moments, and paxa say turns the hook into a spoken phrase such as "Permission needed." Put the command on your PATH with npm install -g @paxalabs/mcp. Then add the hook to ~/.claude/settings.json:
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt|idle_prompt|agent_needs_input",
"hooks": [
{
"type": "command",
"command": "paxa say"
}
]
}
]
}
}paxa say reads the key from PAXA_API_KEY, or from the paxa entry in ~/.claude.json when that is unset. The built-in phrases are synthesized once per voice and kept in the user cache directory. Every later notification plays from disk with no network round trip and no credits. A Stop hook configured the same way speaks "Done." at the end of every turn.
paxa say "Build finished" also works on its own, and --voice picks the voice. The README covers custom phrases, the --cache flag, and faster players on macOS.
Environment variables#
| Variable | Required | Default | Purpose |
|---|---|---|---|
| PAXA_API_KEY | Yes | Your API key. The server starts without it, and every tool that calls the API then fails with setup instructions the agent can relay. | |
| PAXA_OUTPUT_DIR | No | Working directory | Where text_to_speech saves files. |
| PAXA_DEFAULT_VOICE | No | nomyen | Voice used when a tool call does not pick one. English text usually sounds best with an English voice (donut, cookie, toast, latte). |
| PAXA_BASE_URL | No | https://api.paxalabs.com | API origin override. |
Playback support#
| Platform | File player | Streaming player | Pause and resume |
|---|---|---|---|
| macOS | afplay (built in) | ffplay, mpv, or mpg123 if installed | Yes |
| Linux | ffplay, mpv, mpg123, paplay, or aplay | ffplay, mpv, or mpg123 | Yes |
| Windows | ffplay if installed, else PowerShell (wav) | ffplay if installed | No |
Streaming needs a player that reads from stdin. On macOS, brew install ffmpeg (or mpv) enables it. If no player is found at all, the speech tools report it and text_to_speech still works.