Skip to content

AudioLoopMcp

Local stdio MCP server for Windows audio round-trip testing. It verifies screen-reader output by recording actual system audio with WASAPI loopback, transcribing locally with Whisper.net, and scoring spoken text against heard text. No cloud calls are made during transcription. First use may download the Whisper ggml model from Hugging Face if it is missing.

Requirements

  • Windows 11
  • .NET 10 SDK
  • Render audio device enabled
  • SAPI voice installed
  • Visual C++ runtime required by Whisper.net native runtime

Whisper Model

Default model path:

models\ggml-base.en.bin

The model file is gitignored. On first transcription, the server downloads ggml-base.en.bin from:

https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin

Override model path:

$env:AUDIO_LOOP_WHISPER_MODEL = "C:\models\ggml-base.en.bin"

MCP Registration

Development command:

claude mcp add audio-loop -- dotnet run --project C:\Users\fives\source\repos\audio-loop-mcp\src\AudioLoopMcp.Server

Published executable:

dotnet publish .\src\AudioLoopMcp.Server\AudioLoopMcp.Server.csproj -c Release -o .\publish\audio-loop-mcp
claude mcp add audio-loop -- C:\Users\fives\source\repos\audio-loop-mcp\publish\audio-loop-mcp\AudioLoopMcp.Server.exe

Tools

  • speak(text, voiceName?) returns { durationMs, voice }.
  • record_loopback(seconds, devicePartialName?) records system output to %TEMP%\audio-loop-mcp\ and returns { wavPath, seconds, device }. seconds is capped at 120.
  • transcribe(wavPath, language="en") returns { text, avgLogProb }.
  • list_audio_devices() returns render devices as { name, isDefault }.
  • round_trip_test(text, voiceName?, paddingSeconds=2) records while SAPI speaks, transcribes, and returns { spoken, heard, similarityPct, wavPath }.
  • listen_and_transcribe(seconds) records current system output, then transcribes it. Use this for NVDA when another caller triggers speech externally.

Tool errors return structured objects like { error, type } instead of crashing the server.

Testing

dotnet build AudioLoopMcp.sln -warnaserror
dotnet test .\tests\AudioLoopMcp.Tests\AudioLoopMcp.Tests.csproj --filter "Category!=Hardware"

Core coverage is gated at 80% in CI. WasapiCapture, SapiSpeech, and WhisperTranscriber are marked [ExcludeFromCodeCoverage] because they are thin hardware/native integration shells. Hardware smoke tests are marked [Trait("Category","Hardware")] and are excluded from CI.