104 lines
3.0 KiB
Markdown
104 lines
3.0 KiB
Markdown
# Voicebox MCP server
|
|
|
|
Local **Model Context Protocol** server — lets any MCP-aware agent
|
|
(Claude Code, Cursor, Windsurf, VS Code MCP extensions, etc.) speak text
|
|
in your cloned voices, transcribe audio, and browse captures.
|
|
|
|
The server runs inside the same `uvicorn` process as the rest of Voicebox
|
|
and is mounted at `/mcp` (Streamable HTTP transport).
|
|
|
|
## Install into your agent
|
|
|
|
Preferred — direct HTTP:
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"voicebox": {
|
|
"url": "http://127.0.0.1:17493/mcp",
|
|
"headers": { "X-Voicebox-Client-Id": "claude-code" }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Fallback — stdio shim (when the client doesn't speak HTTP MCP). The
|
|
`voicebox-mcp` binary ships inside the Voicebox.app bundle:
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"voicebox": {
|
|
"command": "/Applications/Voicebox.app/Contents/MacOS/voicebox-mcp",
|
|
"env": { "VOICEBOX_CLIENT_ID": "claude-code" }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Claude Code one-liner:
|
|
|
|
```
|
|
claude mcp add voicebox \
|
|
--transport http \
|
|
--url http://127.0.0.1:17493/mcp \
|
|
--header "X-Voicebox-Client-Id: claude-code"
|
|
```
|
|
|
|
## Tools
|
|
|
|
| Name | Purpose |
|
|
|---|---|
|
|
| `voicebox.speak` | Speak text in a voice profile. Returns a generation id you can poll. |
|
|
| `voicebox.transcribe` | Whisper transcription of a base64 blob or an absolute local path. |
|
|
| `voicebox.list_captures` | Recent captures (dictation / recording / file) with transcripts. |
|
|
| `voicebox.list_profiles` | Available voice profiles (cloned + preset). |
|
|
|
|
All tools resolve voice profiles in this precedence:
|
|
|
|
1. Explicit `profile` arg (name or id — case-insensitive)
|
|
2. Per-client binding keyed by `X-Voicebox-Client-Id`
|
|
3. `capture_settings.default_playback_voice_id` (global default)
|
|
|
|
Bindings are managed via `GET|PUT /mcp/bindings` or in the app under
|
|
Settings → MCP.
|
|
|
|
## Debug with MCP Inspector
|
|
|
|
```
|
|
npx @modelcontextprotocol/inspector http://127.0.0.1:17493/mcp
|
|
```
|
|
|
|
Point it at the URL, hit "List tools," call `voicebox.list_profiles`
|
|
first to confirm wiring, then `voicebox.speak` for end-to-end.
|
|
|
|
## Non-MCP REST surface
|
|
|
|
`POST /speak` is a thin wrapper on the same code path for callers that
|
|
don't speak MCP (shell scripts, ACP, A2A):
|
|
|
|
```
|
|
curl -X POST http://127.0.0.1:17493/speak \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'X-Voicebox-Client-Id: claude-code' \
|
|
-d '{"text":"Build complete.","profile":"Morgan"}'
|
|
```
|
|
|
|
## Code layout
|
|
|
|
```
|
|
backend/mcp_server/
|
|
├── __init__.py # re-export mount_into
|
|
├── server.py # build_mcp_server() + mount_into(app)
|
|
├── tools.py # @mcp.tool() implementations
|
|
├── context.py # ClientIdMiddleware + current_client_id ContextVar
|
|
├── resolve.py # profile resolution precedence
|
|
├── events.py # pub/sub queue for /events/speak pill SSE
|
|
└── README.md # you are here
|
|
|
|
backend/mcp_shim/ # stdio ↔ Streamable-HTTP proxy (see its README)
|
|
```
|
|
|
|
The package is **`mcp_server`**, not `mcp`, to avoid shadowing the
|
|
installed `mcp` PyPI package that FastMCP imports internally.
|