| name | music |
| description | Apple Music in your terminal. Play tracks, route to AirPlay speakers and AirPods, search 100 million songs, build playlists, discover new music, favorite tracks, seek within a song, browse your listening history. This is the plugin's only entry point — there are no separate slash commands, so EVERY music request comes here: transport, playback routing, search, library, playlists, discovery, eq, equalizer, bass, treble, 'sound like'. Trigger on anything music-related: playing a song, pausing, skipping, switching speakers, adjusting volume, seeking within a track, searching the catalog, adding tracks to the library, building or managing playlists, finding similar music, checking what's playing, favoriting a song, recalling recently played music, adjusting the equalizer. Covers casual requests too: 'put on some house music', 'pause the music', 'next track', 'find me something like this', 'switch to my AirPods', 'add the bedroom to the group', 'turn down the kitchen', 'search for Gypsy Woman', 'add that track to my library', 'make a playlist from those results', 'add this to my workout playlist', 'play Kid A in the kitchen and living room at 60%', 'love this track', 'skip ahead 30 seconds', 'what was that song I played earlier', 'more bass', 'make it sound like a nightclub', 'turn off the EQ'. Handles Apple Music, AirPlay, HomePod, AirPods, Bluetooth audio, albums, artists, playlists, recommendations, new releases, listening history, heavy rotation, equalizer presets, and any audio routing on macOS. |
Apple Music Controller
Control Apple Music from the terminal via the music CLI. All commands run as bash — use music for structured operations, with --json for machine-readable output.
If the CLI is not installed
If command -v music fails, do NOT improvise AppleScript fallbacks. Tell the user the CLI needs a one-time build and point them at the install script, then retry after they run it:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/install.sh"
Fast path: play requests
For any request shaped like "play X [on/in speakers] [at volume%] [shuffle]", forward the user's words to music play in ONE bash call — strip only the leading "play" and any % sign. The CLI's parser deterministically extracts speaker names (including several at once), volume, filler words ("in", "the", "and", "at", "on"), and a trailing "shuffle":
music play kid a in the kitchen and living room at 60
music play jazz for cooking kitchen 40 shuffle
Naming speakers routes playback to exactly those speakers (it deselects the rest). Don't pre-chain music speaker + music volume for simple play requests — music play does all three. If the query itself contains a speaker-like word, use the explicit flags (--song, --album, --playlist) instead. Named-speaker plays are verified automatically once playback starts (✓ <speaker> verified (…)); an unestablished route triggers an automatic heal before an honest failure message.
Architecture
The music CLI has two backends:
- AppleScript — playback, speakers, volume, now playing (no auth needed)
- REST API — catalog search, library writes, playlists via API, discovery (needs auth)
Playback (no auth)
music play
music play "Working Vibes"
music play "Working Vibes" shuffle
music play 3
music play "Working Vibes" kitchen 20
music play "Working Vibes" kitchen 20 shuffle
music play kid a in the kitchen and living room at 60
music play deck and pool
music play "Gypsy Woman" "Tom Misch"
music play "https://music.apple.com/...?...i=1581424482"
music play --playlist "Working Vibes"
music play "Gypsy Woman (Quarantine Sessions)"
music play --album "Kid A" --artist "Radiohead"
music play --song "Get It Done" --artist "Fouk"
music play --verbose
music pause
music skip
music back
music stop
music now
music now --json
music seek +30|-30|90|1:30
music shuffle
music repeat off|one|all
music love
music unlove
Speakers (no auth)
music speaker list
music speaker list --json
music speaker kitchen
music speaker kitchen 40
music speaker kitchen stop
music speaker airpods only
music speaker 1 2 5
music speaker wake
music speaker wake kitchen
music speaker verify
music speaker verify kitchen
music speaker set "Kitchen"
music speaker add "Bedroom"
music speaker remove "Bedroom"
music speaker <name> (add), set, and only verify the route automatically while playing — output gains a ✓ <speaker> verified (…) line, and an unverified route triggers an automatic heal (away-and-back reroute, then a transport-cycle reset) before falling back to an honest failure naming the manual fix. While paused, routing can't be network-verified — it prints Route set; will verify on next play. and re-checks when playback starts. Scripting's own claims (selected, active) are shown as advisory only, not trusted, because they can lie. Routing to the Mac's own output is never "verified" — local output has no AirPlay session.
Volume (no auth)
music volume
music volume 60
music volume up
music volume down
music volume kitchen 80
Equalizer (no auth)
Real Music.app EQ control. Venue presets are created on first selection and
persist as real presets (visible in Music's own EQ window). Live EQ control
drives the Equalizer window via UI scripting (Music's scripting API for live
EQ state is broken): it needs Accessibility permission for the terminal and
opens the Equalizer window. On a permission error, relay the command's hint —
it names the exact System Settings toggle.
| Request | Command |
|---|
| "make it sound like a dungeon" / "nightclub mode" | music eq dungeon / music eq nightclub |
| "more bass" | music eq "Bass Booster" |
| "flat" / "turn off the EQ" | music eq flat / music eq off |
| "what's the EQ?" | music eq |
| "remove the venue presets" | music eq remove-pack |
Venue pack: Nightclub, Dungeon, Open Air, Concert Hall, Jazz Club, Stadium,
Cathedral, Late Night. Any other name forwards verbatim — Music's built-in
presets (Acoustic, Hip-Hop, Loudness, …) all resolve. Unknown names print
near-matches.
Visualizer (no auth)
music visualizer [on|off] toggles Music's on-screen visualizer (the Cmd-T
visuals). Same UI-scripting + Accessibility requirement as the equalizer.
GUI-only: the visuals render in the Music window on the Mac's display (not on
AirPlay outputs), and turning it on brings Music to the front.
Search (catalog: developer token · library: + user token)
music search "Bohemian Rhapsody Queen"
music search "Fouk" --limit 20
music search "house" --types songs,albums,artists,playlists
music search "The Smiths" --library
music search "kid a" --library --types playlists
music search --artist "Radiohead"
music search --album "OK Computer"
music search "query" --json
--types accepts any of songs,albums,artists,playlists (default songs). Only songs are numbered/cached for index-based add/quick-pick; albums, artists, and playlists print with their catalog/library ids.
Add to Library (requires user token)
music add "Get It Done" "Fouk"
music add 3
music add --id 1844648631
music add --to "House"
music add --to "House" --to "Chill"
music add 3 --to "House"
Remove from Playlist (requires user token)
music remove
music remove "House"
music remove all
Playlists (requires user token for API, AppleScript fallback for local)
music playlist list
music playlist tracks "Working Vibes"
music playlist create "New Playlist"
music playlist create "New Playlist" 1 3 5
music playlist add "House" 1 3 5
music playlist add "Working Vibes" "Song" "Artist"
music playlist delete "Old Playlist"
music playlist remove "Playlist" "Song"
music playlist share "Playlist" --imessage "+1234567890"
music playlist share "Playlist" --email "a@b.com"
music playlist temp "Song1" "Artist1" "Song2" "Artist2"
music playlist create-from "Song1" "Artist1" "Song2" "Artist2" --name "My Mix"
music playlist cleanup
Discovery (requires user token)
music similar
music similar Hotel California
music recent
music rotation
music suggest
music suggest 10 --from "Working Vibes"
music new-releases --like-current
music new-releases --artist "Fouk"
music mix --artists "Fouk,Floating Points" --count 20 --name "Friday Mix"
Interactive TUI (requires real terminal, not Claude Code)
music
Bare music is the main interactive surface — a tabbed shell with Now, Playlists, and Speakers tabs. (music now / music now --json and music playlist <subcommand> are non-interactive CLI commands, documented above.) Four one-shot quick pickers also exist for terminal/slash-command use: bare music speaker (AirPlay picker), bare music volume (mixer), and the music similar / music suggest result pickers.
TUI behavior: the Now tab shows the current album context; selecting a playlist on the Playlists tab pins it on the Now tab. Cursor movement is local and fast. On the Speakers tab, toggling a speaker on while playing verifies the route and toasts if it couldn't be verified.
TUI controls: 1/2/3 switch tabs (Now / Playlists / Speakers), Tab/Shift-Tab cycle tabs, ↑↓ navigate (PgUp/PgDn/Home/End for long lists), Enter play/open selected, ←→ seek (Now) or volume (Speakers), Space pause, </> previous/next track (full up/down through the playlist), z/r shuffle, l favorite, +/- volume, n next-up options (Now), / filter playlists (arrows navigate while typing), Esc back, q quit. Playlist track-play requires Music's Autoplay (∞) turned OFF — it drives playback track-by-track and needs each track to stop at its end.
Result Cache
Search, similar, suggest, new-releases, and playlist tracks write results to ~/.config/music/last-songs.json. Speaker list writes to last-speakers.json. Follow-up commands reference results by index:
music search "house"
music play 3
music add 3
music add 3 --to "House"
music playlist create "House" 1 3 5
Auth Management
music auth status
music auth setup
music auth
music auth set-token <TOKEN>
Auth Tiers
| Tier | What works | What doesn't |
|---|
| No auth | play, pause, skip, back, stop, now, shuffle, repeat, speaker, volume | search, add, playlist (API), similar, suggest, new-releases, mix |
| Developer token only | Above + search | add, playlist (API), similar, suggest, new-releases, mix |
| Both tokens | Everything | — |
Workflow: Complex Requests
Minimize tool calls. Chain independent commands with && in a SINGLE bash call where possible.
"Play X on speaker Y at volume Z" is NOT a multi-step request — music play handles routing and volume natively (see Fast path above):
music play Working Vibes in the kitchen at 60 shuffle
For "find house tracks and make a playlist":
music search "house Fouk Chris Lake FISHER" --limit 20 --json
music playlist create "House Vibes" 1 3 5 7 9
music play "House Vibes" shuffle
For bulk operations where you have title/artist pairs, use create-from (ONE command for all tracks):
music playlist create-from "Losing It" "FISHER" "Coconuts" "Fouk" "Stay With Me" "Chris Lake" --name "House Vibes"
Rules:
- Use result indices (
music playlist create "Name" 1 3 5) when building from search results
- Use
create-from when you have title/artist pairs from other sources
- Never chain
music speaker + music volume + music play for a play request — one music play call does all three
- Use
--json on search to get structured results for parsing
- Both
create-from and index-based create handle errors gracefully
Output Modes
- Default: Human-readable text for terminal
--json: Structured JSON for scripting and Claude
Always use --json when you need to parse the output programmatically.
Error Handling
- "Config not found" — Run
music auth setup
- "User token required" — Run
music auth
- "API request failed with status 401/403" — Token expired, run
music auth again
- "No tracks found" — Try a broader search query
- Speaker commands fail — Check exact speaker name with
music speaker list