mcspeak gains a `transcribe` MCP tool that accepts an audio file path
and returns text. Hits the Whisper-API-shaped Parakeet endpoint at
mcspeak.gpu.supported.systems/v1/audio/transcriptions with the shared
bearer key from TTS_PARAKEET_KEY. The mcspeak.* subdomain flows
through to Langfuse as user=mcspeak for tenant attribution.
Input audio_path validates against /output/ and /tmp/mcspeak/ —
symmetric with generate_audio's _resolve_output_path discipline. That
covers the primary round-trip use case (transcribing audio mcspeak
just generated) without extra mounts. Path canonicalization rejects
both absolute paths outside the allowlist and ../-traversal escapes.
The tool exposes forward-compat params (timestamp_granularities,
diarize, num_speakers, vad, punctuation, min_confidence) that the
current phonescribe gateway silently ignores. When the gpu-stack
agent lands word-level alignment or speaker diarization, the same
calls start producing richer responses with no client change. The
shaped-now-instead-of-later approach saves a breaking change later.
response_format dispatch: json/verbose_json parse as JSON dict
directly; text/srt/vtt wrap as {"text": <body>, "format": <fmt>}.
The gateway today rejects srt/vtt with HTTP 400 "use json | text |
verbose_json" — that's a clean error users see, not silent garbage.
transcribe.py: shared httpx.AsyncClient mirrored from orpheus.py's
pattern (explicit timeouts, ConnectError/ReadError/TimeoutException
catches). Closed via lifespan finalizer.
httpx 0.28 gotcha: passing `data=` as list-of-tuples silently routes
the value to `content=`, which wraps as SyncByteStream and crashes
the AsyncClient with "Attempted to send a sync request." `data` must
be a Mapping; list values inside the dict become repeated form
fields automatically.
33 lines
1.7 KiB
Plaintext
33 lines
1.7 KiB
Plaintext
# Compose project namespace -- prevents collisions with other stacks
|
|
COMPOSE_PROJECT=mcspeak
|
|
|
|
# Host directory for generate_audio output (output_path / format params).
|
|
# Mounted as /output inside the container. Defaults to ~/mcspeak-out when unset.
|
|
# TTS_OUTPUT_HOST_DIR=/home/you/audio-out
|
|
|
|
# Default Piper voice to pre-warm at piper-tts container start. Other voices
|
|
# requested via the speak() voice= param are downloaded on demand. Full list:
|
|
# https://github.com/rhasspy/piper/blob/master/VOICES.md
|
|
# TTS_PIPER_VOICE=es_MX-ald-medium
|
|
|
|
# Parakeet speech-to-text via the gpu.supported.systems gateway.
|
|
# Without TTS_PARAKEET_KEY set, the transcribe() tool returns
|
|
# "Parakeet not configured". The shared bearer is documented in
|
|
# ~/.claude/rules/gpu.md. The mcspeak.* subdomain flows through to
|
|
# Langfuse as user=mcspeak for tenant attribution.
|
|
# TTS_PARAKEET_URL=https://mcspeak.gpu.supported.systems/v1/audio/transcriptions
|
|
# TTS_PARAKEET_KEY=sk-gpu-lb-master-key-2026
|
|
|
|
# Path to Orpheus GGUF model file (required by llama-server service)
|
|
# Tip: if you've already pulled it via Ollama, find the blob with:
|
|
# ollama show --modelfile orpheus | grep FROM
|
|
ORPHEUS_GGUF_PATH=/path/to/orpheus.gguf
|
|
|
|
# Optional overrides -- see README "Configuration" for the full list
|
|
# TTS_ENTRY_TONE=chirp # chirp | apollo | none | /path/to.wav
|
|
# TTS_EXIT_TONE=roger # roger | quindar-out | none | /path/to.wav
|
|
# TTS_CANCEL_TONE=scratch # scratch | reverse-roger | none | /path/to.wav
|
|
# TTS_DUCK_MEDIA=true # fade host audio while speaking
|
|
# TTS_VOICE_IDENTITY=true # auto-assign distinct voices per project
|
|
# TTS_SHUTDOWN_TIMEOUT=30 # max seconds to wait for current speech on stop
|