The current track, live in your Claude Code statusline — ticking every second, ⌘+clickable, styleable down to the bar characters: And whatever your Mac is playing — Spotify, Apple Music, a browser tab, VLC — you can control it from the chat too: "what song is
FAQ
media is a Claude Code plugin with 16 hand-picked skills for automation work, indexed on Flowy. Install it with the command on its page. It includes verify, artwork, config. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
> /plugin marketplace add Bangs00/claude-media-control> /plugin install media@claude-media-control
The current track, live in your Claude Code statusline — ticking every second, ⌘+clickable, styleable down to the bar characters:
▶︎ Karma Police — Radiohead (Spotify) 🔉 ▄ 45%
━━━━━━━━━━━━──────── 2:13/4:24 🎧 AirPods Pro
And whatever your Mac is playing — Spotify, Apple Music, a browser tab, VLC — you can control it from the chat too: "what song is this?", "pause", "next", "play it on my AirPods". It talks to the macOS system-wide now-playing service, so there's no app lock-in, no OAuth, no API keys — and nothing to install with Homebrew.

Inside Claude Code:
/plugin marketplace add Bangs00/claude-media-control
/plugin install media@claude-media-control
/media:config display.statusline on
That last line is the statusline — wired in automatically, live on the next
tick. macOS only; the first media command builds a tiny native helper once
(~2s). /media:doctor verifies everything (healthy = verdict: PRIMARY OK).
Everything below is automatic — the full guide is docs/statusline.md:
statusLine
value is backed up and restored automatically if you ever uninstall the
plugin. No restart, no manual steps./media:statusline: digits are items —
1 track · 2 app · 3 volume · 4 bar · 5 time · 6 output — and / starts a
new line, so 123/456 stacks track/app/volume over bar/time/output.#ff8800), 36 progress-bar charsets
(from line ━━── to smooth partial blocks, a knob slider head,
whole-bar wave/pulse/eq/notes waveforms and their braille twins,
audio visualizers spectrum/mirror/cava/ripple, and a heartbeat
ECG ━━┻┳━━),
the bar length (1–60 cells), volume bar shapes, icons — or off to hide
any part. See the style gallery for all of them with
examples — or paste a whole look from the recipes.Natural language, slash commands, or an interactive menu — all work:
| Say this | …or run | What happens |
|---|---|---|
| "what song is playing?" | /media:now | title / artist / app + progress bar |
| "pause the music" | /media:pause · /media:toggle | pause / resume the active player |
| "next track" | /media:next · /media:prev | skip / go back |
| "jump to 1:30" | /media:seek 1:30 | seek to an absolute position |
| "show the album art" | /media:artwork | saves the cover and displays it |
| "turn it down" | /media:volume 30 | system output volume (0–100) |
| "what played earlier?" | /media:history | recently played tracks |
| "switch to my AirPods" | /media:output airpods | list / switch audio output devices |
| "give me a remote" | /media:menu | interactive arrow-key controller |
| "make the title cyan" | /media:statusline | arrange + style the statusline |
| "turn off the history" | /media:config | quick toggles + statusline reset |
| — | /media:doctor | diagnose build / permissions / fallbacks |
Playback history is logged passively — it piggybacks on reads that
happen anyway (statusline ticks, commands), so there's no polling and no
daemon. The log keeps the latest 500 tracks locally and never leaves your
machine (/media:config history.record off stops it, /media:history clear
wipes it). Output devices are listed and switched through the public
CoreAudio API — no extra permissions.
macOS has no public API for another app's now-playing info; since 15.4,
the private MediaRemote framework answers only Apple-signed processes.
Like ungive/mediaremote-adapter,
this plugin loads a small Objective-C helper (native/adapter.m) through
/usr/bin/perl — an Apple platform binary — which passes the entitlement
check. No Command Line Tools? Reads fall back to compile-free
osascript/JXA, and control to per-app AppleScript (Spotify / Apple
Music). /media:doctor tells you which mode you're in.
Disclaimer. This relies on a private, undocumented Apple framework. It works on macOS 26.x today and re-validates itself after every macOS update (the build cache is keyed on the OS build), but Apple could change or block it at any time — the plugin then degrades to the fallbacks and
/media:doctorreports it. No warranty — see LICENSE.
git clone, you already have them (xcode-select --install otherwise;
without them the plugin runs in fallback mode).No Homebrew, no Node, no Python, no API keys.
| Symptom | Fix |
|---|---|
DEGRADED — native helper unavailable | xcode-select --install, then /media:doctor --rebuild |
PRIMARY READ LIKELY BLOCKED after a macOS update | /media:doctor --rebuild; if it persists, open an issue |
| AppleScript control fails with error -1743 | approve your terminal under System Settings → Privacy & Security → Automation (fallback mode only) |
Nothing plays but now shows a track | stale app state; try /media:next or restart the player |
Build logs: ${CLAUDE_PLUGIN_DATA}/build.log.
/plugin uninstall media@claude-media-control
/plugin marketplace remove claude-media-control
This fully reverts your machine. Everything lives in two Claude-managed
directories (~/.claude/plugins/cache/… and …/data/…); no LaunchAgents,
no login items, no system packages. The statusline wiring undoes itself:
on the first tick after the uninstall, the wrapper restores your previous
statusLine, deletes itself and its backup, and removes the click-handler
app — your statusline is back exactly as it was, within a second
(details).
Two harmless things may remain: a macOS Automation approval if you used
the AppleScript fallback (tccutil reset AppleEvents clears it), and — only
if you wired the statusline manually — your own wrapper files, which are
yours to remove.
playerctl/MPRIS · Windows via SMTC — the dispatcher is
already structured for per-OS backends; contributions welcome.claude --plugin-dir . # load the plugin from a checkout
shellcheck scripts/*.sh # lint
npx bats tests/media.bats # unit tests (native stubbed out)
claude plugin validate . --strict
CI runs all of the above plus a strict native build on a macOS runner.
MIT. The native adapter ports BSD-3-Clause techniques from ungive/mediaremote-adapter and references CLI/JSON conventions from ungive/media-control — see native/NOTICE.
.claude/
.claude-plugin/
marketplace.json
plugin.json
skills/
verify/
SKILL.md
.github/
workflows/
ci.yml
.gitignore
CHANGELOG.md
docs/
demo.gif
demo.ja.gif
demo.ko.gif
demo.zh-CN.gif
recipes/
recipes.ja.md
recipes.ko.md
recipes.md
recipes.zh-CN.md
cassette.gif
console.gif
dial.gif
goban.gif
hardcopy.gif
lead-ii.gif
lo-fi.gif
mono.gif
neko.gif
night-drive.gif
phosphor.gif
plasma.gif
platform.gif
ripple-tank.gif
seiche.gif
service.gif
slider-wall.gif
synthwave.gif
telegraph.gif
third-octave.gif
twilight.gif
vernier.gif
vfd.gif
zen.gif
statusline.ja.md
statusline.ko.md
statusline.md
statusline.zh-CN.md
styles.gif
styles.ja.md
styles.ko.md
styles.md
styles.zh-CN.md
hooks/
hooks.json
LICENSE
native/
adapter.m
loader.pl
NOTICE
README.ja.md
README.ko.md
README.md
README.zh-CN.md
scripts/
build-click-handler.sh
build-native.sh
media.sh
read-jxa.js
skills/
artwork/
SKILL.md
config/
SKILL.md
doctor/
SKILL.md
history/
SKILL.md
menu/
SKILL.md
next/
SKILL.md
now/
SKILL.md
output/
SKILL.md
pause/
SKILL.md
play/
SKILL.md
prev/
SKILL.md
seek/
SKILL.md
statusline/
SKILL.md
toggle/
SKILL.md
volume/
SKILL.md
tests/
media.bats
stubs/
build-click-handler.sh
build-native.sh
loader.pl
read-jxa.js© 2026 Flowy · Free and open source
Built for Claude Code · Not affiliated with Anthropic