Skip to main content
Glama

loudness-check-mcp

CI License: MIT MCP

"Is my mix too quiet for YouTube?" — answered with real LUFS numbers, then fixed.

loudness-check-mcp is a Model Context Protocol server that measures audio loudness the way platforms and broadcasters do (EBU R128 / ITU-R BS.1770 via ffmpeg), explains what YouTube, Spotify, Apple, podcast apps and broadcasters will do with your file, and writes a corrected copy — an exact gain change when that's enough, two-pass loudnorm when it isn't. It also finds dead air, clipping and sudden loudness jumps — with timestamps.

Works on audio files and on the audio track of videos. Everything runs locally.

You:    Check ep42_final.wav for podcast and YouTube.
Claude: Integrated -11.2 LUFS, true peak +0.4 dBTP.
        ⚠️ Podcast: 4.8 LU louder than -16. ⚠️ YouTube will turn it down ~2.8 dB,
        and the true peak above 0 dBTP will distort after AAC encoding.
        Want a -16 LUFS / -1 dBTP version?
You:    Yes, as MP3.
Claude: A plain -4.8 dB gain gets there, so that's all I applied (dynamics untouched).
        Saved ep42_final_podcast.mp3 — now -16.0 LUFS, -4.4 dBTP.

Tools

Tool

What it does

measure_loudness

Integrated loudness (LUFS), true peak (dBTP), loudness range (LRA), max momentary / short-term, sample peak, RMS, noise floor, DC offset. Optional target comparison.

check_loudness_targets

Compares against YouTube, Spotify, Apple Music, Tidal, social, podcast, EBU R128 and ATSC A/85 and explains what each platform will do. Optional ACX audiobook check (RMS, peak, noise floor).

normalize_loudness

Hits a preset or custom target. Applies an exact gain change when that keeps true peak under the ceiling (your mix's dynamics are untouched); otherwise uses two-pass dynamic loudnorm and tells you why. Copies the video stream untouched for video files and re-measures the result.

loudness_timeline

Loudness per window (default 5 s): loudest/quietest sections and sudden jumps. CSV export.

detect_silence

Silent stretches with timestamps, totals, and padded keep segments for planning jump cuts. CSV export.

detect_clipping

Flat-topped clipping, true-peak overs, and the time ranges where peaks cross a threshold.

list_targets

All targets and how each platform behaves.

check_setup

Confirms ffmpeg and the required filters (ebur128, loudnorm, astats, silencedetect).

Targets

id

Target

Integrated

True peak

Platform behaviour

youtube

YouTube

-14 LUFS

≤ -1 dBTP

Turns louder videos down; doesn't turn quiet ones up

spotify

Spotify

-14 LUFS

≤ -1 dBTP

Normalizes both ways (up only as far as peaks allow)

apple_music

Apple Music

-16 LUFS

≤ -1 dBTP

Sound Check

tidal

Tidal

-14 LUFS

≤ -1 dBTP

Normalizes down

social

Instagram / TikTok / Shorts

-14 LUFS

≤ -1 dBTP

No published spec; common practice

podcast

Podcast (stereo)

-16 LUFS

≤ -1 dBTP

Widely used podcast target (≈ -19 for mono)

ebu_r128

EBU R128 broadcast

-23 LUFS ±0.5

≤ -1 dBTP

Delivery spec

atsc_a85

ATSC A/85 (US broadcast)

-24 LKFS ±2

≤ -2 dBTP

Delivery spec

include_acx

ACX / Audible

RMS -23 to -18 dB

peak ≤ -3 dB

Noise floor ≤ -60 dB

Streaming targets are the commonly cited reference levels. Platforms tweak their normalization over time; broadcast specs are formal standards.


Related MCP server: loudcheck

Requirements

  • Node.js 20+

  • ffmpeg with the ebur128, loudnorm, astats and silencedetect filters (all standard builds include them)

    • macOS: brew install ffmpeg · Ubuntu: sudo apt install ffmpeg · Windows: winget install ffmpeg

The server finds ffmpeg via FFMPEG_PATH, then PATH, then common folders like /opt/homebrew/bin (Claude Desktop on macOS starts servers with a minimal PATH).

Install

Claude Desktop

Settings → Developer → Edit Config:

{
  "mcpServers": {
    "loudness-check": {
      "command": "npx",
      "args": ["-y", "github:anshumanofficial2002-cpu/loudness-check-mcp"]
    }
  }
}

Claude Code

claude mcp add loudness-check -- npx -y github:anshumanofficial2002-cpu/loudness-check-mcp

Cursor / Windsurf / VS Code / other clients

{
  "loudness-check": {
    "command": "npx",
    "args": ["-y", "github:anshumanofficial2002-cpu/loudness-check-mcp"]
  }
}

From source

git clone https://github.com/anshumanofficial2002-cpu/loudness-check-mcp.git
cd loudness-check-mcp && npm install && npm run build
# point your client at: node /absolute/path/to/loudness-check-mcp/dist/index.js

Example prompts

  • "How loud is ~/Music/bounce_v7.wav? Is it ready for Spotify and YouTube?"

  • "Normalize ep12.mp3 to podcast loudness and save it as ep12_master.mp3."

  • "My reel final.mp4 sounds quiet next to other posts. Fix the audio to -14 LUFS without re-encoding the video."

  • "Where's the loud part in this interview? Give me a 10-second timeline."

  • "Find every pause longer than 0.8 s in raw_vo.wav and give me the segments to keep for jump cuts."

  • "Is voiceover.wav clipping anywhere?"

  • "Does chapter_03.wav pass ACX for Audible?"

  • "Make an EBU R128 broadcast version of promo.mov."


Tool reference

Shared params on analysis tools: path, start (seconds or HH:MM:SS), duration (seconds), audio_stream (default 0).

measure_loudness

targets (optional list of target ids).

check_loudness_targets

targets (default ["youtube","spotify","social","podcast"]), include_acx (false).

normalize_loudness

Param

Default

Notes

output_path

<name>_<target>.<ext> next to source

Extension picks the codec: .wav 24-bit PCM, .aiff, .flac, .mp3 320 kbps, .m4a AAC 256 kbps, .opus; .mp4/.mov/.mkv keep the video stream (copied) with AAC audio.

target

youtube

Any target id.

integrated_lufs

—

Custom target (overrides target).

true_peak_dbtp

target's ceiling

Custom ceiling.

lra_lu

11

Target loudness range in dynamic mode.

linear

true

Prefer an exact gain change. If that would push true peak over the ceiling, dynamic loudnorm is used and the result explains what to change to stay linear. Set false to always use dynamic loudnorm.

sample_rate

source rate

Output sample rate (loudnorm processes at 192 kHz internally; output is resampled to this).

dry_run

false

Measure, pick the mode, and return the command without writing.

overwrite

false

loudness_timeline

window_seconds (5), jump_lu (6 — flags jumps in max momentary loudness between windows), max_rows (120), csv_output_path, overwrite.

detect_silence

noise_db (-45; raise to -35 for noisy rooms), min_silence_seconds (0.6), keep_padding_seconds (0.12), include_keep_segments (true), max_rows (100), csv_output_path, overwrite.

detect_clipping

threshold_dbtp (-1), max_rows (50). Verdict fail = flat-topped samples at full scale; warn = true peak above 0 dBTP or peaks above the threshold.


How it measures

  • Integrated loudness, LRA, true peak, momentary/short-term: ffmpeg ebur128 with peak=true (ITU-R BS.1770-4 gating, 4× oversampled true peak).

  • Sample peak, RMS, noise floor, DC offset, flat factor: ffmpeg astats, in the same pass via asplit.

  • Normalization: loudnorm pass 1 measures the file. If target − measured dB of gain keeps the true peak under the ceiling, that exact gain is applied with ffmpeg's volume filter (true linear normalization, works on clips of any length). Otherwise pass 2 runs loudnorm in dynamic mode with the measured values, which is far more accurate than single-pass. Lossy encoders (MP3/AAC) can add a few tenths of a dB of true peak; the result flags it.

  • Silence: silencedetect.

Safety

  • ffmpeg runs via spawn with argument arrays — no shell.

  • Outputs are refused if they already exist unless overwrite: true, and can't overwrite the input.

  • No network access, no telemetry.

Development

npm install
npm run build
npm test          # parser unit tests + end-to-end tests that generate audio with ffmpeg
npm run inspect   # MCP Inspector

dist/ is committed so npx github:… works without a build; CI verifies it matches src/.

License

MIT © 2026 Anshuman

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Loudness compliance verdicts against formal broadcast standards (EBU R128, ATSC A/85). Measures audio/video with ffmpeg and returns a pass/fail verdict with exact deltas and remediation parameters.
      2
      47 PyPI
      1
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables local, CPU-only audio post-production through tools for denoising, LUFS loudness normalization, silence removal, format conversion, pitch shifting, and speed changes. Supports podcast and video platform loudness compliance workflows.
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Audio perception for AI agents. Measure loudness, clipping, noise and pitch; view spectrograms; split audio into events; transcribe speech; compare before/after; and clean up, edit or synthesize sound. Runs locally, no API keys.
      14
      144 PyPI
      MIT