Music Player logo

Music Player

Community
tsirysndr
music-player

Play, queue and search music on the user's music-player daemon, and DJ for them — building a set that fits a mood, an activity or a request. Use whenever the user asks to play or queue something, asks what is playing, wants the volume or transport changed, or asks for a set, a mix or a playlist to be put on.

Overview

Publishertsirysndr
Repositorymusic-player
Skill namemusic-player
Stars
524
Forks
34
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by tsirysndr on GitHub. Read the source before you install it.

Installation

Install the Music Player AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/tsirysndr/music-player/tree/master/skills/music-player
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/tsirysndr/music-player.git /tmp/music-player
mkdir -p .claude/skills
cp -r /tmp/music-player/skills/music-player .claude/skills/music-player
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Music Player in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Music Player on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Music Player is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Playing music

You are driving a real audio player on the user's machine. Everything you do is heard immediately, by whoever is in the room. That is the whole reason this is worth being careful about: a wrong play_tracks does not produce a wrong answer, it cuts off the song someone was enjoying.

Before anything else

Check that the tools are there. If now_playing and the rest are not available, the MCP server is not connected — see Setting it up and tell the user what to run. Do not fall back to guessing.

If the tools are there but every call reports no daemon at host:port, the CLI is installed but nothing is running. Tell the user to start it:

bash
music-player          # foreground; add & to keep the shell

How to work

Find, then play. Ids are the currency. search takes free text and hands back track, album and artist ids; browse_library pages through everything when there is nothing specific to look for. Both feed play_tracks and queue_tracks.

Queue rather than replace. queue_tracks adds without touching what is playing. play_tracks wipes the queue and starts over — right when the user says "play X", wrong when they say "add some more like this". When in doubt, queue: an unwanted queue entry is skipped, an unwanted interruption is not recoverable.

Look before you change. Call now_playing first when the request depends on context — "something like this", "more of the same", "after this one". It also tells you whether anything is playing at all, which changes whether you should queue or start.

Say what you did. "Queued 8 tracks" is not an answer. Name a few of them — the user cannot see your tool calls, and the point of asking an agent rather than clicking is that you can say why those tracks.

Knowing what a track sounds like

search and browse_library only know titles. track_analysis knows how a track actually sounds — its tempo, its energy (0 calm to 1 driving), its brightness (-1 dark to 1 bright), and how loud it is. similar_tracks uses all of that to answer "what goes after this?" without needing genres or anyone else's listening history.

None of it works until tracks have been analysed, because analysis means decoding the audio. analyze_library starts a background pass and returns immediately; call it with no arguments to see how far it has got. Run it once for a library, and check it before promising a mood-based set:

  • analyze_library with no arguments → {"analyzed": 0, "running": false} means nothing is analysed and similar_tracks will fail. Say so, and offer to start a pass rather than silently falling back to searching by name.
  • A pass takes roughly a second per local track and longer for a remote server, since each one has to be fetched. Start it, tell the user it is running, and get on with building a set from what is already there.

Handing over to auto-DJ

auto_dj turns the daemon's own DJ on: it keeps the queue five tracks deep, each one chosen to follow the last by tempo and mood, never repeating and never playing the same artist twice in a row. It never interrupts what is playing.

Steer it rather than micromanaging it. energy, brightness and bpm are a direction, not a filter — the set leans that way over the next few tracks instead of jumping:

  • "wind things down" → auto_dj with enabled: true, energy: 0.25
  • "keep it going but pick it up" → energy: 0.8
  • "something more upbeat and brighter" → energy: 0.75, brightness: 0.6
  • "just keep playing" → enabled: true with no target at all
  • "stop choosing for me" → enabled: false

Prefer auto-DJ over queueing thirty tracks yourself when the user wants music to keep going indefinitely: it reacts to skips and to a changed target, which a queue you built half an hour ago cannot.

DJing

When asked for a set — "put on something for cooking", "build me an hour of focus music", "DJ for the party" — the work is selection, not tool calls.

  • Search around the request, not just inside it. A request for "something upbeat" is not a search query. Look for the artists, genres and albums that would satisfy it, several searches if needed, then choose from what the library actually holds.
  • Sequence deliberately. Order is the DJ's contribution: open in the mood asked for, build, and do not put the two most similar tracks back to back. play_tracks and queue_tracks both play in the order given.
  • Keep it to a set, not a dump. Ten to twenty well-chosen tracks beats a hundred filtered ones. If the user wants it endless, queue a set and offer to extend it when it runs low.
  • Work from their library. You can only play what is there. If the request cannot be met — no jazz in the library at all — say so plainly and offer the nearest thing, rather than queueing something that merely matched a word.
  • Use the analysis when the request is about feel. "Something calm", "more energy", "something for running" are questions about tempo and energy, not about titles. Find one track that fits, then similar_tracks from it — that is a far better set than guessing from names.

The tools

ToolFor
now_playingCurrent track, position, volume, how much is queued
playback_controlplay, pause, next, previous, stop
seekJump to a position in the current track
set_volume0–100
searchTracks, albums and artists matching free text
browse_libraryPage through albums, artists or tracks
get_albumAn album with its tracks, in order
get_artistAn artist with their albums and tracks
list_playlists / get_playlistThe user's saved playlists
play_tracksReplace the queue and start — interrupts
queue_tracksAdd to the queue, next or end — does not interrupt
view_queueWhat has played, what is coming
clear_queueEmpty it and stop
set_playback_modeShuffle on/off, repeat off/queue/track
list_servers / connect_serverSwitch which library is being read
track_analysisTempo, energy, brightness, loudness of one track
similar_tracksWhat sounds good after a given track
analyze_libraryAnalyse tracks in the background, and check progress
auto_djHand the queue over to the daemon, and steer it

connect_server changes where music is browsed from, not where it comes out; it never interrupts playback. Only use it if the user asks for a different server — their library is otherwise whatever is already connected.

Things to get right

  • Never clear or replace the queue without being asked. "Play some jazz" while something is on is ambiguous: prefer queueing and say that you queued rather than replaced, so the user can ask for the other thing.
  • Volume is heard by people, not read by them. Do not raise it beyond what was asked, and do not set it at all unless asked.
  • playback_control with play resumes what is loaded. It starts nothing on an empty queue — use play_tracks for that.
  • A tool that returns isError has failed and changed nothing. Read the message and tell the user; do not retry the same call.

Setting it up

Only needed once, and only if the tools are missing.

1. Install the CLI

macOS or Linux, prebuilt binary:

bash
curl -fsSL https://raw.githubusercontent.com/tsirysndr/music-player/master/install.sh | sh

Homebrew (macOS/Linux):

bash
brew install tsirysndr/tap/musicplayer

npm:

bash
npm install -g @tsiry/music-player

Debian, Ubuntu and other APT systems:

bash
echo "deb [trusted=yes] https://apt.fury.io/tsiry/ /" \
  | sudo tee /etc/apt/sources.list.d/music-player.list
sudo apt-get update && sudo apt-get install music-player

Fedora, RHEL, Rocky, AlmaLinux and other DNF systems:

bash
sudo tee /etc/yum.repos.d/music-player.repo <<'EOF'
[music-player]
name=Music Player
baseurl=https://yum.fury.io/tsiry/
enabled=1
gpgcheck=0
EOF
sudo dnf install music-player

Check it worked with music-player --version.

2. Point it at some music

The daemon reads ~/Music by default; set music_directory in ~/.config/music-player/settings.toml for anywhere else. Then:

bash
music-player scan     # index the library
music-player          # start the daemon

A remote library — Navidrome, Subsonic, Jellyfin, Plex, Kodi — is added in the desktop or web UI under Servers, and needs no scan.

3. Register the MCP server

Claude Code:

bash
claude mcp add music-player -- music-player mcp

Codex (~/.codex/config.toml):

toml
[mcp_servers.music-player]
command = "music-player"
args = ["mcp"]

Claude Desktop, and other hosts that use the same file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):

json
{
  "mcpServers": {
    "music-player": {
      "command": "music-player",
      "args": ["mcp"]
    }
  }
}

Restart the host afterwards. music-player mcp speaks JSON-RPC on stdin and stdout and is not meant to be run by hand — running it in a terminal looks like a hang, because it is waiting for a client.

Frequently asked questions

What does the Music Player AI skill do?

Play, queue and search music on the user's music-player daemon, and DJ for them — building a set that fits a mood, an activity or a request. Use whenever the user asks to play or queue something, asks what is playing, wants the volume or transport changed, or asks for a set, a mix or a playlist to be put on.

Why use Music Player on TypingMind?

Because you install it once and use it with any model. Music Player is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Music Player in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/tsirysndr/music-player/tree/master/skills/music-player. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Music Player?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Music Player?

As many as you like. As long as a model supports skills, you can use Music Player with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Music Player AI skill free?

Yes. It is published on GitHub by tsirysndr under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇