CLI, REST API, and MCP server for audio transcription on Apple Silicon, powered by parakeet-mlx.
The default model (parakeet-tdt-0.6b-v3) achieves 6.34% average WER across 8 English benchmarks and supports 25 languages. Runs ~30x faster than Whisper on Apple Silicon via MLX.
- macOS with Apple Silicon (M1/M2/M3/M4)
- Python 3.11+
- ~2 GB memory for the default model
Transcribe audio files directly:
uvx paratran recording.wavOr start the REST API server and transcribe via client mode (no model reload per file):
uvx paratran serve
uvx paratran -s http://localhost:8000 recording.wavuv tool install paratranpip install paratrangit clone https://github.com/briansunter/paratran.git
cd paratran
uv sync
uv run paratran# Transcribe a single file
paratran recording.wav
# Transcribe multiple files with verbose output
paratran -v file1.wav file2.mp3 file3.m4a
# Output as SRT subtitles
paratran --output-format srt recording.wav
# Output all formats (txt, json, srt, vtt)
paratran --output-format all --output-dir ./output recording.wav
# Use beam search decoding
paratran --decoding beam recording.wav
# Custom model and cache directory
paratran --model mlx-community/parakeet-tdt-1.1b-v2 --cache-dir /Volumes/Storage/models recording.wavUse --server / -s to send files to a running paratran server instead of transcribing locally. This avoids model loading time on every invocation — start the server once, then transcribe instantly.
# Start the server (loads model once)
paratran serve
# Transcribe via the server
paratran -s http://localhost:8000 recording.wav
# Output and transcription options work in client mode
paratran -s http://localhost:8000 --output-format all --output-dir ./output -v recording.wav
# Set the server URL via environment variable
export PARATRAN_SERVER=http://localhost:8000
paratran recording.wav # automatically uses the server| Flag | Default | Description |
|---|---|---|
-s, --server |
URL of a running paratran server | |
--api-key |
Bearer token for an authenticated server | |
--timeout |
60 |
Server request timeout in seconds |
--model |
mlx-community/parakeet-tdt-0.6b-v3 |
HF model ID or local path |
--cache-dir |
HuggingFace default | Model cache directory |
--output-dir |
. |
Output directory |
--output-format |
txt |
txt, json, srt, vtt, or all |
--decoding |
greedy |
greedy or beam |
--chunk-duration |
120 |
Chunk duration in seconds (0 to disable) |
--overlap-duration |
15 |
Overlap between chunks |
--beam-size |
5 |
Beam size (beam decoding) |
--length-penalty |
0.013 |
Length penalty (beam decoding) |
--patience |
3.5 |
Patience (beam decoding) |
--duration-reward |
0.67 |
Duration reward (beam decoding) |
--max-words |
Max words per sentence | |
--silence-gap |
Split at silence gaps (seconds) | |
--max-duration |
Max sentence duration (seconds) | |
--fp32 |
Use FP32 precision instead of BF16 | |
-v |
Verbose output |
Environment variables: PARATRAN_MODEL, PARATRAN_MODEL_DIR, PARATRAN_SERVER, PARATRAN_API_KEY.
When using client mode, configure --model and --cache-dir on the running server; those options do not change a remote server.
# Start server with local-only defaults
paratran serve
# Custom host, port, and model cache
paratran serve --host 127.0.0.1 --port 9000 --cache-dir /Volumes/Storage/models
# Expose the server only with an API key
paratran serve --host 0.0.0.0 --api-key "$PARATRAN_API_KEY"The server defaults to 127.0.0.1, limits uploads to 512 MB, and processes one transcription at a time. Non-loopback hosts require --api-key.
The REST API is compatible with the OpenAI Audio Transcription API.
curl http://localhost:8000/health{
"status": "ok",
"model": "mlx-community/parakeet-tdt-0.6b-v3",
"model_dir": "/Volumes/Storage/models"
}Upload an audio file (wav, mp3, flac, m4a, ogg, webm):
curl http://localhost:8000/v1/audio/transcriptions \
-F "[email protected]" \
-F "model=parakeet"| Parameter | Default | Description |
|---|---|---|
file |
(required) | Audio file to transcribe |
model |
Accepted for compatibility; uses the configured model | |
response_format |
json |
json, text, srt, vtt, or verbose_json |
language |
Accepted for compatibility; language is auto-detected | |
prompt |
Accepted for compatibility; prompts are not applied | |
temperature |
Accepted for compatibility; temperature is not applied |
| Parameter | Default | Description |
|---|---|---|
decoding |
greedy |
greedy or beam |
beam_size |
5 |
Beam size (beam decoding) |
length_penalty |
0.013 |
Length penalty (beam decoding) |
patience |
3.5 |
Patience (beam decoding) |
duration_reward |
0.67 |
Duration reward (beam decoding) |
max_words |
Max words per sentence | |
silence_gap |
Split at silence gaps (seconds) | |
max_duration |
Max sentence duration (seconds) | |
chunk_duration |
120 |
Chunk duration for long audio (seconds); 0 disables chunking |
overlap_duration |
15.0 |
Overlap between chunks (seconds) |
fp32 |
false |
Use FP32 instead of BF16 |
json (default):
{"text": "Hello world, this is a test."}verbose_json (also includes processing_time):
{
"task": "transcribe",
"duration": 3.52,
"processing_time": 0.176,
"text": "Hello world, this is a test.",
"segments": [
{"id": 0, "start": 0.0, "end": 3.52, "text": "Hello world, this is a test."}
],
"words": [
{"word": "Hello", "start": 0.0, "end": 0.48},
{"word": " world", "start": 0.48, "end": 0.8}
]
}text: Returns plain text. srt / vtt: Returns subtitles.
Interactive API docs are available at http://localhost:8000/docs.
Paratran includes an MCP server so Claude Code, Claude Desktop, or any MCP client can transcribe audio files directly. Supports both stdio and streamable HTTP transports.
Add to .claude/settings.json:
{
"mcpServers": {
"paratran": {
"command": "uvx",
"args": ["--from", "paratran", "paratran-mcp"]
}
}
}Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"paratran": {
"command": "uvx",
"args": ["--from", "paratran", "paratran-mcp"]
}
}
}Optionally set PARATRAN_MODEL_DIR in the env block to customize the model cache location.
Run the MCP server over HTTP for local or multi-client access:
paratran-mcp --transport streamable-http --host 127.0.0.1 --port 8000The MCP endpoint is available at http://localhost:8000/mcp. For HTTP MCP on a non-loopback host, pass both --allowed-root and --api-key; the key is accepted as an Authorization: Bearer token. Loopback HTTP can also be protected with --api-key when multiple local clients share the server.
The transcribe tool accepts an absolute file path and all the same transcription options as the REST interface. --allowed-root restricts paths to a directory, which is recommended for HTTP MCP.
MIT