About oma-voice
oma-voice is a skill for generating and transcribing speech through the local Voicebox app, and processing existing audio with FFmpeg. It supports agent notifications, narration, and local-file transcription without cloud services.
Key features
- 01Generate speech through Voicebox
- 02Transcribe local audio files
- 03Process audio with FFmpeg
- 04Write outputs with manifests
- 05Use local services without cloud calls
Use cases
- 01Creating narration or voiceover files
- 02Transcribing audio into Markdown
- 03Generating task-completion notifications
- 04Converting or adjusting existing audio
MCP support
It connects to the local Voicebox MCP server for speech generation, transcription, and profile listing. Existing-audio processing uses local FFmpeg and ffprobe instead.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ first-fluke/ oh-my-agent --skill oma-voiceAfter installing, type/oma-voicein Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
config/voice-config.yamlreferences/_shared/conditional/experiment-ledger.mdexploration-loop.mdquality-score.mdreferences/_shared/core/clarification-protocol.mdcommon-checklist.mdcontext-budget.mdcontext-loading.mddifficulty-guide.mdexecution-policy.mdlessons-learned.mdprompt-structure.mdquality-principles.mdsession-metrics.mdskill-routing.mdtest-approach.mdvendor-detection.mdreferences/_shared/core/api-contracts/README.mdtemplate.mdreferences/_shared/runtime/memory-protocol.mdresult-contract.mdresources/audio-processing.mdchecklist.mdexecution-protocol.mdprompt-tips.mdvoice-matrix.mdDetails
From the project READMEVoice Skill - Speech and Local Audio Processing
Scheduling
Goal
Generate and transcribe speech through the local Voicebox app, and process existing audio with local media tools. Voicebox owns synthesis engines and profiles; FFmpeg owns file conversion, duration adjustment, and loudness processing.
Intent signature
- User asks to generate speech, narrate text, produce a voiceover, create an mp3 or wav from text.
- User wants an audio file transcribed into text, meeting notes, or a transcript.
- User asks for a voice notification when a long task completes or a workflow step is blocked.
- Another skill needs local audio generation infrastructure.
- User needs existing speech fitted to a time window, resampled, converted, or loudness-normalized.
When to use
- Generating short notification audio for agent task completion or blockers.
- Producing voiceover, narration, or audio assets (mp3 or wav) for apps and content.
- Transcribing local audio files (mp3, wav, m4a, webm, flac) to Markdown.
- Comparing voice profiles by re-running the same text against different profile ids.
- Processing an existing audio asset, including speech used in an
oma-videodubbing job.
When NOT to use
- Cloud TTS or high-fidelity multilingual cloud voices -> out of scope; future multi-vendor extension.
- Real-time microphone dictation loop in the terminal -> use Voicebox app's built-in hotkey dictation.
- Voice cloning sample upload and profile creation -> done in the Voicebox desktop app UI.
- Video editing and audio/video placement ->
oma-video; music and sound design are out of scope. - Stories Editor multi-voice timeline composition -> use the Voicebox app UI.
Expected inputs
- TTS: text (<= 5000 chars per call), optional profile id, optional engine, optional language, optional output path.
- STT: audio file path (absolute or relative to
$CWD), optional language hint. - Notification: short message (<= 240 chars), profile id resolved from config.
- Processing: existing audio path, requested operations, and any stated duration, sample rate, channel layout, loudness, or format constraints. Derive targets from the brief, not a universal mastering preset.
Expected outputs
- TTS: audio file (
wav— Voicebox's native TTS output format;mp3optional via a local ffmpeg transcode) at.agents/results/voice/{timestamp}-{shortid}/output.{wav|mp3}plusmanifest.json. - STT:
transcript.mdat.agents/results/voice/transcripts/{timestamp}-{shortid}/plusmanifest.json. - Notification: ephemeral playback through Voicebox; no disk write by default.
- Processing: a separate processed audio file plus
manifest.jsoncontaining source/output paths, operations, and measured audio properties. Keep the source intact. A generation id is present only when Voicebox actually generated the audio.
Dependencies
- Processing only: installed
ffmpegandffprobe; no Voicebox app or voice profile is required. - Generation/transcription: Voicebox desktop app installed and running locally.
- Generation/transcription only: Voicebox MCP registered (
claude mcp add --transport http voicebox http://127.0.0.1:17493/mcp). - TTS only: at least one voice profile created in the Voicebox app UI.
- TTS only: optionally pre-downloaded engine models for the selected profile.
Control-flow features
- Branches by mode (notify, asset, transcribe), language, and profile availability.
- Calls voicebox via MCP tools, with REST
GET /healthas the handshake probe. - Reads input audio files and writes generated audio plus manifests.
- Caches discovered MCP tool names after the first successful
tools/list.
Structural Flow
Entry
- Detect the requested mode: notification, asset TTS, transcription, or existing-audio processing. For processing, follow
resources/audio-processing.mddirectly, before any Voicebox health, profile, or model lookup. - Verify Voicebox is reachable via MCP handshake or
GET /health. - On the first run only, call MCP
tools/listand cache the resolved tool names. - For notification or asset TTS, resolve the target voice profile id. For transcription, validate the audio input and continue without a profile.
Scenes
- PREPARE: Resolve the operation and its inputs. Voicebox modes use text/audio and language; TTS additionally needs a profile. File processing uses the source and requested media properties.
- ACQUIRE: If a required signal is missing, run the clarification protocol once.
- ACT: Invoke the appropriate MCP tool (TTS or STT), or process the existing asset with local FFmpeg commands.
- VERIFY: Confirm the response carries audio output or transcript content. Validate manifest fields.
- FINALIZE: Write
manifest.jsonalongside the output. Report the path or transcript to the user.
Transitions
- For generation/transcription, if Voicebox is unreachable, surface the install or launch hint and exit. Do not attempt auto-relaunch. Existing-file processing continues without it.
- Loopback addresses refer to the process's own host or container. Invoke a host Voicebox service from the host, then transfer the resulting file to the task container; a container's
127.0.0.1does not probe the host app. - For timed narration, keep the raw generation. Select a language-capable available profile, measure the raw duration, and use
resources/audio-processing.mdfor fitting. A neural engine or correct loudness does not establish natural pronunciation or prosody. - If a TTS request has no usable profile, point the user at the Voicebox app UI to create a profile, then exit. A transcription request never needs a profile.
- If a TTS request exceeds 5000 chars, ask whether to truncate or split. Do not auto-chunk in v1.
- If an STT input exceeds 30 minutes, ask whether to proceed. Do not auto-split.
- If the selected engine model is not loaded, ask the user before triggering a download.
Failure and recovery
| Failure | Recovery |
|---|---|
| Voicebox app not running | Print install/launch hint, exit code 5 |
| No voice profile for TTS | Print "create a profile in Voicebox" hint, exit code 3 |
| Engine model missing | Ask before triggering download |
Output path outside $PWD | Use an explicitly requested path; ask only if the destination is ambiguous or overwrites unrelated data |
| TTS over 5000 chars | Ask the user to split or truncate |
| STT over 30 minutes | Confirm only if the requested duration or resource cost is unresolved |
| MCP tool name drift | Re-run tools/list and update the cache |
| SIGINT | Abort the MCP call, write no partial output |
| Local media executable missing | Report the missing tool for the requested operation; do not start Voicebox or replace audio with a placeholder |
| Speech cannot fit naturally | Retain the raw audio; adjust generation pacing when synthesis is available and authorized, or report the unresolved timing constraint instead of clipping words |
Exit
- Success: audio file or transcript exists with a complete manifest, and the path is reported.
- Partial success: output exists but a guardrail warning is surfaced (length, disk, model fallback).
- Failure: no output, the blocker (auth, profile, engine, network) is explicit.
Logical Operations
Actions
| Action | SSL primitive | Evidence |
|---|---|---|
| Validate mode and inputs | VALIDATE | Clarification protocol in execution-protocol.md |
| Resolve TTS voice profile | SELECT | voicebox_list_profiles + config defaults |
| Health check | READ | MCP handshake or GET /health |
| Generate speech | CALL_TOOL | MCP voicebox_speak |
| Transcribe audio | CALL_TOOL | MCP voicebox_transcribe |
| Write output and manifest | WRITE | Audio or transcript plus manifest.json |
| Inspect result | VALIDATE | Output presence, duration, manifest fields |
| Report result | NOTIFY | Final user-facing summary |
Tools and instruments
- Voicebox MCP server at
http://127.0.0.1:17493/mcpfor generation/transcription; local FFmpeg and ffprobe for existing audio. - REST surface for health and audio retrieval (
GET /health,GET /audio/{generation_id}). - Resource references: voice matrix, prompt tips, execution protocol, checklist.
Canonical command path
Dispatch existing-audio work to resources/audio-processing.md. The path below
is for Voicebox generation/transcription only; timed TTS follows the processing
reference after fetching the raw WAV.
# 1. MCP handshake or REST health
GET http://127.0.0.1:17493/health -> 200 OK
# 2. Discover tool names on first run
MCP tools/list -> cache real names
# 3. TTS only: resolve profile
MCP voicebox_list_profiles -> pick profile by name or config default
# 4. Generate or transcribe (STT skips profile lookup and model-status check)
MCP voicebox_speak { text, profile, language?, engine?, personality? }
MCP voicebox_transcribe { audio_path | audio_base64, language?, model? }
# 5. Fetch the generated audio (MCP has no save-to-disk; TTS output is wav)
GET http://127.0.0.1:17493/audio/{generation_id} -> wav bytes
# 6. Persist output + manifest
.agents/results/voice/<timestamp>-<shortid>/output.wav + manifest.json
.agents/results/voice/transcripts/<timestamp>-<shortid>/transcript.md + manifest.json
MCP tool mapping (verified against Voicebox 0.5.0)
| Use case | MCP tool | REST backing |
|---|---|---|
| TTS generation | voicebox_speak | POST /speak |
| STT transcription | voicebox_transcribe | POST /transcribe |
| Profile listing | voicebox_list_profiles | GET /profiles |
| Captures listing | voicebox_list_captures | GET /history (captures view) |
Tools not exposed via MCP (REST only): model status (GET /models/status), audio file serving (GET /audio/{generation_id}), per-version audio (GET /audio/version/{version_id}). The skill calls those over loopback HTTP when needed.
Notes on voicebox_speak:
- Required:
text. Optional:profile,engine,language,personality(bool). - Audio plays on the user speakers and is saved to the Captures / History panel automatically. There is no
save_to_disktoggle on the MCP tool itself; to persist a local copy, fetchGET /audio/{generation_id}(Voicebox TTS always storeswav). - Without a default profile set in Voicebox Settings,
profile=is required.
Notes on voicebox_transcribe:
- Accepts exactly one of
audio_base64oraudio_path(loopback only). Optionallanguage,model.
Resource scope
| Scope | Resource target |
|---|---|
LOCAL_FS | Input audio, generated audio, transcripts, manifests |
PROCESS | Local Voicebox app (managed by the user), FFmpeg/ffprobe processing |
NETWORK | Loopback HTTP to 127.0.0.1:17493 only |
MEMORY | Cached MCP tool names, resolved profile metadata |
CREDENTIALS | None. Voicebox is local and key-free. |
Preconditions
- Processing: local
ffmpegandffprobecan read the source asset. - Generation/transcription: Voicebox app is running and the MCP handshake succeeds.
- TTS only: at least one voice profile exists.
- TTS only: the selected engine model is loaded or the user approves a download.
- Output directory is inside
$PWDunless explicitly allowed.
Effects and side effects
- Creates audio files, transcripts, and manifests under
.agents/results/voice/. - Existing-audio processing runs local media subprocesses and preserves the input file.
- Triggers local Voicebox generation, which consumes CPU or GPU.
- May trigger an engine model download when the user approves.
- Does not call any cloud service. No external network traffic.
Guardrails
- Voicebox modes: generation/transcription requires the MCP handshake or
GET /health. On failure, exit with a one-shot install or launch hint; do not retry or auto-relaunch. Local processing does not require Voicebox. - Profile required for TTS only: resolve a profile and check the TTS engine only for notification or asset mode. Transcription proceeds with a valid audio input and optional STT model even when no profile exists.
- Tool-name discovery: on the first Voicebox invocation, call MCP
tools/listand cache the resolved names. Reuse the cache for subsequent calls in the same session. - Length limits: TTS calls cap at 5000 chars per call; warn at 2000. STT inputs cap at 30 minutes. v1 does not auto-chunk or auto-split.
- Auto-invocation transparency: notifications fire automatically only when the active task exceeds
auto_notify_after_sec(default 60s). This threshold is agent-enforced guidance — no hook measures task duration — so apply it by judgment when a long task completes or blocks. Always announce intent in one short line before generating audio. - Path safety: an explicitly requested output path authorizes writing there. Resolve ambiguity or unrelated-data replacement before the dependent write; preserve required CLI path flags.
- Cancellation: SIGINT aborts the MCP call and writes no partial output.
- Manifest required for persisted output: asset TTS and transcription modes write
manifest.jsonwith at minimum:skill,mode,voicebox_generation_id,text(ortranscript_preview),profile,engine,language,format(TTS only),created_at. Processing records the source, operations, and measured output properties as specified inresources/audio-processing.md; it never invents Voicebox provenance. Notification mode is exempt because Voicebox Captures is its system of record and no disk output is written by default. - Out of scope: voice cloning UI, captures archive, stories editor, microphone dictation loop, and cloud vendors are intentionally not exposed.
- No cost guard: Voicebox is free. The cost guardrail from
oma-imagedoes not apply.
Clarification protocol
Before invoking a TTS or STT call, the agent checks the following. If any required signal is missing, clarify with the user first.
TTS (asset mode) required:
- Text content provided?
- Voice profile id or tone description provided?
TTS strongly recommended:
- Language explicit or detectable from the text?
- Output format (wav default; mp3 requires a local ffmpeg transcode)?
STT required:
- Audio path provided and the file exists?
- Duration within 30 minutes, or user approves splitting?
Notification mode skips clarification. It uses notification_profile from config and language is auto-detected from the message.
Invocation
Standalone
/oma-voice "build succeeded, 4 minor warnings"
/oma-voice transcribe ~/Downloads/standup.m4a
/oma-voice --profile prof_warm_korean "다음 단계 진행 준비됐어요"
Shared infrastructure (other skills)
Other skills can request audio output by calling the same MCP tools directly, or by invoking /oma-voice with their text. There is no separate CLI; the skill is MCP-native.
References
- Voice engine matrix:
resources/voice-matrix.md(TTS profile/engine selection) - Prompt writing rules:
resources/prompt-tips.md(TTS text) - Execution protocol:
resources/execution-protocol.md(Voicebox generation/transcription) - Existing audio and timed narration:
resources/audio-processing.md(processing, duration fitting, or requested loudness conversion) - Pre-flight checklist:
resources/checklist.md(Voicebox calls) - Configuration: read the
voice:section of.agents/oma-config.yamlfirst, then fall back toconfig/voice-config.yamlfor any key it does not set. Both profiles ship asnulland must be set per machine — write them to.agents/oma-config.yaml, sinceoma updateoverwrites the skill config. - Context loading:
references/_shared/core/context-loading.md - Quality principles:
references/_shared/core/quality-principles.md - Design reference:
../../../docs/plans/designs/012-oma-voice.md(source repo only; absent in global-mode installs)