Voice Coach MCP
Claude cannot process audio. This server records from your microphone, analyzes the audio on your computer, and returns compact measurements that Claude turns into concrete coaching:
Mode | What it measures |
🎤 Singing | Pitch accuracy per note (cents), flat/sharp tendency, drift, stability and vibrato. Compares against equal temperament, a key, or a MIDI melody, including wrong, missed and late notes. |
🗣️ English pronunciation | Phoneme-level comparison of what you said against what you meant to read, with per-word scores and frequent confusions (θ → s, v → b, iː → ɪ…). |
🎙️ Public speaking | Words per minute, long pauses, filler words (English and Spanish), pitch monotony and volume variation, with a timestamped transcript. |
A bundled skill turns Claude into a coach: it runs warm-up → exercise → analysis → feedback sessions, gives one concrete focus per take, and keeps a progress log across sessions. Claude replies in your language.
Local and private: audio never leaves your computer (unless you opt into the Azure backend).
Free: open-source models (faster-whisper, wav2vec2) and no API keys.
Tools measure, Claude interprets: every response is compact JSON (≤ 2 KB) with
confidenceandwarnings, so Claude never coaches on bad audio.
Install
You need uv and, for pronunciation, espeak-ng:
brew install uv espeak-ng ffmpeg # macOS (ffmpeg is optional: m4a/aac input)On Linux: install uv, then sudo apt install espeak-ng ffmpeg libportaudio2. Pronunciation
analysis on macOS needs Apple Silicon and macOS 14 or later (a PyTorch requirement).
Claude Code (plugin: server + skill)
claude plugin marketplace add FabianIMV/voice-coach-mcp
claude plugin install voice-coach@voice-coachOr, inside a session: /plugin install voice-coach --marketplace FabianIMV/voice-coach-mcp.
The first start installs the Python dependencies with uv, which can take a minute or two (the
models download later, on first use). If /mcp shows voice-coach as failed right after
installing, reconnect it from /mcp once the installation finishes.
Claude Desktop (extension)
Download voice-coach.mcpb from the latest release
and double-click it (or drag it into Claude Desktop). For the coaching skill, also download
voice-coach-skill.zip and upload it in Settings → Capabilities → Skills.
Any MCP client (manual)
claude mcp add voice-coach --scope user -- uvx --from "voice-coach-mcp[speech,pronunciation]" voice-coach-mcpFor Claude Desktop's claude_desktop_config.json, use absolute paths (Desktop does not inherit
your shell PATH; which uvx prints it):
{
"mcpServers": {
"voice-coach": {
"command": "/opt/homebrew/bin/uvx",
"args": ["--from", "voice-coach-mcp[speech,pronunciation]", "voice-coach-mcp"]
}
}
}Optional: run uvx --from "voice-coach-mcp[speech,pronunciation]" voice-coach-mcp download-models
once, so the first call does not wait for the models (~480 MB Whisper, ~1.3 GB phoneme model).
Microphone permission (macOS)
macOS grants the microphone to the app that launches the server: Claude Desktop, or the
terminal running Claude Code (Terminal, iTerm, Ghostty, VS Code…). If permission is denied,
macOS returns silence instead of an error and record_audio reports
no_microphone_permission. Fix it in System Settings → Privacy & Security → Microphone and
restart that app.
Related MCP server: claude-voice-input
Use it
Just talk to Claude:
"I want to practice singing in tune. I'm a beginner."
"Record 30 seconds of me presenting my project and tell me how many filler words I use."
"Help me pronounce 'th'. Give me sentences to read and score them."
"Analyze this voice memo against melody.mid" (any wav/mp3/m4a path works).
"How am I doing?" (Claude reads your progress log).
Real sessions in Claude Code: a 60-second talk about work, and a singing baseline on one held note.


Guided sessions are also available as MCP prompts: singing_session, pronunciation_session
and speaking_session (in Claude Code: /mcp__voice-coach__singing_session).
Tools
Tool | Purpose |
| Records a 16 kHz mono WAV to |
| Pitch accuracy per note against equal temperament, a key ("A minor", "G major"…) or a MIDI melody. |
| Local transcription with segment and word timestamps. |
| Pace, long pauses, filler words, pitch monotony and volume variation. |
| Phoneme-level English pronunciation scores and errors. |
| Read and append sessions in |
Audio can be a path or the name returned by record_audio. When a result is too long, the most
relevant items are returned and everything else is saved next to the audio (full_details).
{"audio":"examples/audio/c_major_scale.wav","duration_s":7.36,"mode":"equal_temperament",
"summary":{"notes":8,"range":"C4–C5","pct_within_25_cents":75.0,"mean_deviation_cents":-7.8,
"mean_abs_deviation_cents":13.6,"tendency":"centered","drift_cents":-1.0,
"stability":{"stable":7,"vibrato":1,"unstable":0}},
"notes":[{"t":0.4,"dur":0.62,"note":"C4","cents":0,"stability":"stable"},
{"t":1.84,"dur":0.62,"note":"E4","cents":-30,"stability":"stable"},
{"t":4.72,"dur":0.62,"note":"B4","cents":-42,"stability":"stable"},
{"t":5.44,"dur":1.43,"note":"C5","cents":-2,"stability":"vibrato","vibrato_hz":5.5,"vibrato_pp_cents":84}, "…"],
"confidence":{"value":1.0,"level":"high"},"warnings":[]}With a MIDI reference, the server detects
that the melody was sung an octave lower (octave_shift: -1), started 1 s late
(start_offset_ms: 1003), and that one note came in 134 ms late.
{"backend":"wav2vec2-local",
"summary":{"overall_score":90,"words":10,"words_with_errors":3,
"errors":{"substitution":3,"deletion":0,"insertion":0},
"frequent_confusions":[{"expected":"θ","detected":"s","count":2},{"expected":"v","detected":"b","count":1}]},
"words":[{"word":"think","score":75,"t":0.56,"expected":"θ ɪ ŋ k","detected":"s ɪ ŋ k",
"errors":[{"type":"substitution","expected":"θ","detected":"s"}]},
{"word":"very","score":75,"t":0.96,"expected":"v ɛ ɹ i","detected":"b ɛ ɹ i",
"errors":[{"type":"substitution","expected":"v","detected":"b"}]}, "…"],
"confidence":{"value":1.0,"level":"high"},"warnings":[]}{"language":"en",
"pace":{"words":36,"speaking_time_s":14.9,"words_per_minute":145,"wpm_excluding_long_pauses":165},
"pauses":{"threshold_s":0.7,"count":2,"total_s":1.9,"max_s":1.03,"per_minute":8.1,
"items":[{"t":4.42,"dur":1.03,"after":"speaking"},{"t":12.1,"dur":0.83,"after":"normal"}]},
"fillers":{"total":6,"per_minute":24.2,"by_type":{"um":1,"so":1,"uh":1,"you know":1,"like":1,"i mean":1}},
"pitch":{"median_f0_hz":101,"std_semitones":1.53,"monotone":true,"monotone_stretches":[{"t":0.0,"end":12.0}]},
"volume":{"mean_dbfs":-21.2,"std_between_words_db":2.4,"low_variation":true},
"confidence":{"value":1.0,"level":"high"},"warnings":[]}The synthetic voice is very flat, hence monotone: true. A Spanish example is also included.
All example outputs are real responses from the server over stdio, regenerated by
examples/generate_examples.py on synthetic audio; see
examples/outputs/.
How it works
Pitch: pYIN (librosa) finds voiced frames; each frame is refined from its harmonic peaks with parabolic interpolation (~1 cent accuracy from C2 to C6). Notes are split at silences, energy dips and sustained pitch changes; vibrato does not split notes. With a MIDI reference, the octave and offset are found by cross-correlation, notes are aligned with Needleman–Wunsch, and a tempo line
t_sung = a·t_ref + bis fitted to judge each onset.Speech: faster-whisper transcribes with word timestamps (an initial prompt keeps fillers). Pauses are measured from the audio energy, because Whisper stretches word endings into silence. Ambiguous fillers ("like", "so") only count when isolated by a comma or a pause.
Pronunciation: phonemizer + espeak-ng give the expected IPA phonemes; the
facebook/wav2vec2-lv-60-espeak-cv-ftphoneme model gives what was said; both are aligned by edit distance. Normal American English variants (flap, schwa, linking r, glottal stop) are not counted as errors.Quality first: clipping, background noise, silence and missing microphone permission are reported as warnings and lower the confidence.
Known limitations: one voice at a time (accompaniment degrades pitch detection); two identical notes sung in perfect legato count as one; the phoneme model uses sentence context and may occasionally "correct" a mispronounced word; pronunciation assessment is English-only.
Privacy and network access
Everything the plugin runs, writes and downloads:
Runs:
uvstarts the server from the plugin folder (uv run --frozen, pinned byuv.lock); the server usesespeak-ngfor expected phonemes andffmpegonly to read m4a/aac files.Microphone: only while
record_audioruns, for the number of seconds Claude asks for.Writes: recordings and
progress.mdin~/VoiceCoach(orVOICE_COACH_DIR), and an analysis detail file<audio>.<tool>.jsonnext to each analyzed audio (or in~/VoiceCoach/analysisif that folder is read-only). Analyzing the same audio again replaces its detail file; nothing else is overwritten or deleted.Downloads: the Python dependencies from PyPI on first start, then the models from Hugging Face on first use: the faster-whisper model (
Systran/faster-whisper-smallby default) andfacebook/wav2vec2-lv-60-espeak-cv-ft. After that, models load from the local cache.Sends: nothing by default. No telemetry, no accounts, no API keys. Only if you set
VOICE_COACH_PRONUNCIATION_BACKEND=azurewith your ownAZURE_SPEECH_KEYandAZURE_SPEECH_REGIONdoesassess_pronunciationsend that audio and the expected text to Azure Speech in your region.
Configuration
Variable | Default | Purpose |
|
| Recordings, analysis details and |
|
| Maximum |
|
| Tuning reference |
|
| Response size budget |
|
|
|
|
| CTranslate2 settings |
| — | Your own filler-word TOML (see |
|
|
|
|
|
|
| — | Optional Azure Pronunciation Assessment backend ( |
| auto-detected | Path to |
Development
git clone https://github.com/FabianIMV/voice-coach-mcp.git && cd voice-coach-mcp
uv sync --extra speech --extra pronunciation
uv run pytest # fast suite: synthetic audio, simulated microphone
uv run pytest -m models # real Whisper and wav2vec2 models on synthetic speech
uv run ruff check . && uv run ruff format --check .See CONTRIBUTING.md for the design principles and the release process.
src/voice_coach_mcp/
server.py MCP tools and prompts (thin layer)
audio/ loading, recording and quality checks
singing/ pitch tracking, music theory, MIDI reference, pitch accuracy
speech/ transcription, speech metrics, filler lists
pronunciation/ expected phonemes, alignment, wav2vec2 and Azure backends
output.py 2 KB response budget and details file
progress.py progress log
skills/voice-coach/ coaching skill (also bundled in the Python package)
examples/ synthetic audio and real tool outputsLicense and credits
MIT © FabianIMV. Built on faster-whisper, librosa, wav2vec2 phoneme recognition and the official MCP Python SDK. The optional pronunciation extra uses phonemizer and espeak-ng, both GPL-3.0. Example voices were synthesized with espeak-ng and Piper (public-domain LJSpeech voice).
Available Tools
7 toolsanalyze_pitchAIdempotent
Measures the pitch accuracy of sung audio (solo voice, one melodic line).
Args:
audio: audio path (wav/flac/mp3/m4a) or a name returned by record_audio.
reference_midi: optional path to a .mid with the expected melody. Tolerates singing an
octave up/down, starting at another moment and a somewhat different tempo.
key: optional when there is no MIDI, e.g. "A minor", "G major", "F#" (Spanish names such as
"La menor" also work): each note is compared with the nearest note of that scale.
Without it, with the nearest equal-tempered note.
midi_track: index of the MIDI track to use (default: the non-drum track with most notes).
Returns `summary` (notes, range, pct_within_25_cents, signed mean_deviation_cents,
tendency flat/sharp/centered, drift_cents between 1st and 2nd half, stability counts; with
MIDI also missed, extra_notes, wrong_notes, onsets on_time/late/early, octave_shift,
start_offset_ms and relative_tempo >1 = slower) and `notes`: t (s), dur, note or
expected/sung, cents (+ = sharp), stability (stable | vibrato with vibrato_hz and
vibrato_pp_cents | unstable with std_cents), drift_cents within the note and, with MIDI,
onset_ms/onset; reference notes not sung have status=missed and unmatched sung notes
status=extra. If the list does not fit, the most problematic notes are shown and the rest
is in `full_details`.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | ||
| audio | Yes | ||
| midi_track | No | ||
| reference_midi | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (non-destructive, idempotent, closed-world), so the description correctly spends its words on tolerance behaviour an agent could not infer: octave-up/down singing, late starting points, tempo variance, and the fallback comparison path. It does not mention failure modes (polyphonic input, unreadable files) or processing cost.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and parameter block are front-loaded and efficient, but the Returns paragraph is a dense run-on enumeration of summary and note fields that largely duplicates the output schema. An agent must parse a long comma-spliced sentence to extract the few novel semantics (cents sign, tempo ratio direction).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-param analysis tool with an output schema, the description covers input formats, matching modes and result interpretation; the return-value detail is a bonus rather than a gap. Only edge-case behaviour and the constraint enforcement on polyphonic audio are unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, yet all four parameters are documented with real semantics: accepted audio formats and the link to record_audio names, the .mid expectation, key syntax with examples in two languages, and midi_track's default resolution rule. This fully compensates for the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Measures the pitch accuracy of sung audio') plus the scope constraint 'solo voice, one melodic line', which tells an agent immediately what input is valid. This is clearly distinguishable from recording, transcription or pronunciation siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives conditional guidance on the two analysis modes: reference_midi when a score exists, key when there is no MIDI, and plain nearest-note comparison when neither is supplied. It stops short of explicitly naming alternatives (e.g. 'use transcribe for text output') or stating when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assess_pronunciationAIdempotent
Compares the pronounced phonemes with the expected ones for a text read aloud (English).
Args:
audio: audio path or a name returned by record_audio (up to 60 s; short sentences work best).
expected_text: the exact text that was read.
language: "en-US" (default) or "en-GB".
Returns `summary` (overall_score 0–100, words_with_errors, error counts by type,
frequent_confusions expected→detected) and `words`: word, score, t (s) and, when there are
errors, expected/detected in IPA and errors [{type: substitution|deletion|insertion,
expected, detected}]; `missing` when the word was not said. `phonemes` holds both full
sequences. Word score = 100·(1 − (S + D + 0.5·I)/expected phonemes). Allophonic variants
(flap, schwa, linking r) do not count as errors. The text_mismatch warning means a
different text was probably read. Backend: local wav2vec2, or Azure when
VOICE_COACH_PRONUNCIATION_BACKEND=azure (then the audio is sent to Azure).
| Name | Required | Description | Default |
|---|---|---|---|
| audio | Yes | ||
| language | No | en-US | |
| expected_text | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses important behavior: audio is sent to Azure only when the backend environment variable is set, the scoring formula is given, allophonic variants are excluded from errors, and text_mismatch indicates a likely wrong text. These are substantial operational and privacy-relevant details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and well organized, with arguments first, then return details and behavioral notes. It is somewhat dense and explains return fields despite an output schema existing, but the information largely earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema, annotations, and three-parameter schema with no descriptions, the description is complete enough to call the tool correctly. It covers inputs, output structure, scoring behavior, warnings, and backend-dependent privacy implications.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning. It fully documents all three parameters: audio source and duration, exact expected text, and language values en-US and en-GB.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it compares pronounced phonemes with expected phonemes for English text read aloud. The scope and purpose are clear, but it does not explicitly distinguish itself from siblings such as transcribe or speech_metrics.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage context: audio can be a path or a name returned by record_audio, recordings up to 60 seconds work, and short sentences work best. It also explains the text_mismatch warning, though it does not explicitly say when to prefer this tool over transcribe or speech_metrics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
log_progressA
Appends a session to the progress log (~/VoiceCoach/progress.md).
Args:
entry: markdown of the session. It should start with "## YYYY-MM-DD · mode · exercise";
if it does not start with "## ", the date and time are added as the title.
| Name | Required | Description | Default |
|---|---|---|---|
| entry | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a non-read, non-idempotent, non-destructive write to a closed world. The description adds genuine value beyond them: the exact file path, the append semantics, and the conditional behavior where a missing '## ' prefix causes the date and time to be generated as the title.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in one sentence, and the Args block adds only the format detail an agent actually needs. The docstring indentation and stray line break make it slightly less clean than it could be, but nothing is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the one-parameter schema is fully explained in prose. Remaining gaps are secondary: behavior if the file or directory is missing, and confirmation that repeated calls create duplicate entries (consistent with idempotentHint=false but unstated).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% for the single `entry` parameter, so the description must carry the load and largely does: it specifies the markdown format, the required header pattern ('## YYYY-MM-DD · mode · exercise'), and the fallback title auto-generation. It omits whether trailing newlines are added or whether mode must match an enum-like value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with the concrete target ('Appends a session to the progress log (~/VoiceCoach/progress.md)'), which implicitly distinguishes it from read_progress. It stops short of explicitly naming the sibling for contrast, but the append-vs-read distinction is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is for recording a completed session, and the sibling list contains read_progress. There is no explicit when-to-use statement, no mention of prerequisites (does the file need to exist?), and no exclusion of alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_progressARead-onlyIdempotent
Reads the latest sessions from the progress log (~/VoiceCoach/progress.md).
Use it at the start of a session to pick up the previous focus. Returns `file`,
`total_entries` and `entries` (markdown of each session, oldest to newest).
| Name | Required | Description | Default |
|---|---|---|---|
| entries | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and closed-world, so the safety profile is covered. The description adds real context beyond that: the file location and the ordering of returned session markdown (oldest to newest), which is a behavioral detail an agent would otherwise have to guess.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences: purpose and location first, the usage trigger second, the return shape last. Nothing is redundant and every sentence carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not enumerate return values, yet it helpfully sketches them. The one real hole is the undocumented 'entries' parameter; otherwise an agent has everything needed to call this simple read tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the single parameter 'entries' (default 5) is never explained — the reader cannot tell whether it controls how many sessions are returned or how many markdown lines. Worse, the name collides with the returned 'entries' field, so the description actively muddies rather than clarifies the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Reads the latest sessions from the progress log') and even names the backing file path (~/VoiceCoach/progress.md). It is implicitly distinguishable from the sibling log_progress by the read/write naming pair, but it never explicitly contrasts with it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use it at the start of a session to pick up the previous focus' gives a clear triggering context, which is more than most read tools offer. It stops short of naming log_progress as the counterpart to use when writing, so the when-not guidance is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_audioA
Records from the computer's microphone and saves a 16 kHz mono .wav.
Args:
seconds: recording length (max 120 by default). Tell the user before calling.
name: optional file name (without extension); defaults to date and time.
Returns `audio` (path of the .wav), levels (peak/RMS in dBFS, estimated SNR, % clipping),
`confidence` and `warnings`. The `no_microphone_permission` warning means macOS delivered no
audio: the user must enable the microphone for the app in System Settings.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| seconds | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover mutation/idempotency/destructiveness, so the description is free to add real value — the 120-second cap and the meaning of the no_microphone_permission warning (macOS gave no audio; user must enable mic in System Settings). That is exactly the kind of recovery context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded purpose sentence, then Args, then Returns — clean structure. The Returns paragraph restates some of what the output schema already exposes, but the warning explanation earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter capture tool with annotations and an output schema, the description covers the cap, naming behavior, and the one failure mode an agent cannot infer. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it does: seconds is the recording length bounded at 120, name is an optional filename without extension that defaults to date/time. The 'max 120 by default' phrasing is slightly ambiguous about whether 120 is a default or a hard ceiling.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+output format: records from the computer's microphone and saves a 16 kHz mono .wav. No sibling in the list captures audio, so the boundary is immediately obvious.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States an explicit operational rule — 'Tell the user before calling' — and implies the when (capture live audio). It stops short of naming when-not or pointing to transcribe/analyze_pitch as downstream steps, so a 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
speech_metricsAIdempotent
Measures pace, pauses, filler words and pitch/volume variation of a speech.
Args:
audio: audio path or a name returned by record_audio.
language: language of the speech ("en" or "es"; filler lists exist for both).
pause_threshold_s: minimum silence between words to count as a long pause.
Returns:
- `pace`: words, speaking_time_s, words_per_minute, wpm_excluding_long_pauses.
- `pauses`: count, total_s, max_s, per_minute and items [{t, dur, after: previous word}].
- `fillers`: total, per_minute, by_type and occurrences [{t, text}]. Ambiguous words
("like", "so") only count when isolated by a comma or a pause.
- `pitch`: median_f0_hz, std_semitones, range_p10_p90_semitones, monotone (std < 2 st) and
monotone_stretches [{t, end}] over 8 s windows.
- `volume`: mean_dbfs, std_between_words_db, range_p10_p90_db, low_variation (std < 3 dB).
- `segments` of the transcript [{t, end, text}].
| Name | Required | Description | Default |
|---|---|---|---|
| audio | Yes | ||
| language | Yes | ||
| pause_threshold_s | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare idempotent, non-destructive, closed-world, but the description adds genuinely non-structured behavior: filler words like 'like'/'so' only count when isolated by a comma or a pause, and monotone/low-variation are defined by numeric thresholds. It also clarifies that audio may be a name returned by record_audio, which explains the cross-tool dependency. It omits any note on cost/runtime for audio processing, which is the one behavioral trait still missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The one-line purpose is properly front-loaded and the Args block is tight. The Returns block, however, is a long enumeration of output fields that an output schema already covers, so a substantial fraction of the text does not earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
All three parameters are documented, the input source ambiguity is resolved, and threshold semantics are disclosed; annotations plus the output schema carry the safety and return-shape burden. The remaining gap is operational: no indication of processing expectations or audio-format constraints for what is likely a heavy analysis call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description fully compensates: audio is 'path or a name returned by record_audio', language is constrained to 'en' or 'es' with the note that filler lists exist for both (an enum the schema lacks), and pause_threshold_s is defined as the minimum silence between words to count as a long pause. Each parameter gains meaning beyond its bare title.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb plus the exact measured dimensions (pace, pauses, fillers, pitch/volume variation), which is far stronger than a generic 'analyze speech'. It does not, however, name the overlapping siblings analyze_pitch and transcribe, so an agent must infer that this tool subsumes rather than replaces them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the purpose sentence – an agent can guess you call this when you want delivery metrics rather than a raw transcript. There is no explicit when-to-use/when-not, no mention of prerequisites (recording must exist first), and no routing to analyze_pitch or transcribe despite clear functional overlap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transcribeAIdempotent
Transcribes audio with timestamps (faster-whisper, local).
Args:
audio: audio path or a name returned by record_audio.
language: "en", "es", "en-US", "Spanish"…; auto-detected when omitted.
Returns `language`, `language_prob`, `text`, `segments` [{t, end, text}] and `words`
[{w, t, end}]. If it does not fit, words are dropped first and then segments (everything
stays in `full_details`). The first call downloads the model (VOICE_COACH_WHISPER_MODEL).
| Name | Required | Description | Default |
|---|---|---|---|
| audio | Yes | ||
| language | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds genuinely useful context beyond annotations: the first call downloads a model (cost/latency, env var VOICE_COACH_WHISPER_MODEL), and output degradation policy (words dropped first, then segments, with everything preserved in full_details). Annotations already cover idempotency and safety, so this is a solid supplement; missing are rough latency/blocking expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, followed by Args and Returns sections; every line carries information. The embedded docstring formatting (indentation, 'Args:') is slightly noisy but does not obscure content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the critical operational facts an agent needs: parameter forms, auto-detection default, model download on first use, and truncation behavior that the output schema alone would not reveal. A note on supported audio formats or expected duration limits would close the remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the load and largely does: audio is either a path or a name from record_audio, and language accepts codes or names (en, en-US, Spanish) with auto-detect on omission. The exact accepted format set for language remains loose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Transcribes audio') plus differentiating scope details: timestamps, engine (faster-whisper), and local execution. An agent can distinguish this from siblings like assess_pronunciation or speech_metrics, which analyze rather than transcribe.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The audio parameter note ('a name returned by record_audio') implies the natural pipeline with that sibling, but no explicit when-to-use/when-not guidance versus speech_metrics or assess_pronunciation is given, and nothing says when to prefer this over another tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.1.0- First observed
analyze_pitch - First observed
assess_pronunciation - First observed
log_progress - First observed
read_progress - First observed
record_audio - First observed
speech_metrics - First observed
transcribe
TDQS
Scored across 7 tools
The tools target clearly different tasks: recording, sung pitch analysis, transcription, speech delivery metrics, pronunciation scoring, and progress log read/write. The only mild overlap is pitch measurement appearing in both analyze_pitch (singing, melodic line) and speech_metrics (speech variation), but the descriptions clearly separate singing from speech and read-aloud pronunciation assessment.
Five of the seven tools follow a clear verb_noun pattern (record_audio, analyze_pitch, read_progress, assess_pronunciation, log_progress). The bare verb 'transcribe' and the noun phrase 'speech_metrics' are minor deviations but still readable and unambiguous.
Seven tools is well within the sweet spot for this domain, and each one maps to a distinct stage of the coaching workflow (record, analyze, log, review). Nothing feels padded or redundant.
The surface covers the full loop: capture audio, analyze singing, speech and pronunciation, then read and append progress. The progress log has read/append but no update, delete, or cross-session comparison, which are minor gaps an agent can work around.
Maintenance
Related MCP Connectors
AI voice generation: text-to-speech and voice cloning from any MCP client.
Generate AI music via the Lacuna Music API from MCP clients like Claude Desktop & Code.
- QuallaaOAuthcom.quallaa
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Use AI models for chat, image, and video generation from Claude Code and other MCP hosts.
Related MCP Servers
- AlicenseAqualityDmaintenanceThis MCP server enables Claude to speak summaries, announcements, and explanations aloud using text-to-speech — right from your terminal.4MIT
- AlicenseNot gradedqualityFmaintenanceLocal MCP server that enables voice input to Claude by transcribing microphone audio locally using faster-whisper, avoiding cloud services.MIT
- AlicenseNot gradedqualityAmaintenanceGive Claude access to your music library. MixCraft is a hosted MCP server that connects Claude to Apple Music, letting Claude search your library, build playlists, and learn your taste over time.12 npm2MIT
- FlicenseNot gradedqualityDmaintenanceExposes headless Claude Code as a remote MCP server with a voice client, enabling hands-free task execution and session management via OpenAI's Realtime API.-