spotify
Spotify: play, search, queue, manage playlists and devices.
Spotify: play, search, queue, manage playlists and devices.
Real data. Real impact.
Emerging
Developers
Per week
Excellent
Skills give you superpowers. Install in 30 seconds.
Control the user's Spotify account via the Hermes Spotify toolset (7 tools). Setup guide: https://hermes-agent.nousresearch.com/docs/user-guide/features/spotify
The user says something like "play X", "pause", "skip", "queue up X", "what's playing", "search for X", "add to my X playlist", "make a playlist", "save this to my library", etc.
spotify_playback — play, pause, next, previous, seek, set_repeat, set_shuffle, set_volume, get_state, get_currently_playing, recently_playedspotify_devices — list, transferspotify_queue — get, addspotify_search — search the catalogspotify_playlists — list, get, create, add_items, remove_items, update_detailsspotify_albums — get, tracksspotify_library — list/save/remove with kind: "tracks"|"albums"Playback-mutating actions require Spotify Premium; search/library/playlist ops work on Free.
One search, then play by URI. Do NOT loop through search results describing them unless the user asked for options.
spotify_search({"query": "miles davis kind of blue", "types": ["album"], "limit": 1}) → got album URI spotify:album:1weenld61qoidwYuZ1GESA spotify_playback({"action": "play", "context_uri": "spotify:album:1weenld61qoidwYuZ1GESA"})
For "play some
and play the artist context URI — Spotify handles smart shuffle. If the user says "the song" or "that track", search types: ["artist"]
and pass types: ["track"]
to play.uris: [track_uri]
Single call — don't chain get_state after get_currently_playing.
spotify_playback({"action": "get_currently_playing"})
If it returns 204/empty (
is_playing: false), tell the user nothing is playing. Don't retry.
Direct action, no preflight inspection needed.
spotify_playback({"action": "pause"}) spotify_playback({"action": "next"}) spotify_playback({"action": "set_volume", "volume_percent": 50})
spotify_playlists list to find the playlist ID by namespotify_playlists add_items with the playlist_id and URIsspotify_playlists({"action": "list"}) → found "Late Night Jazz" = 37i9dQZF1DX4wta20PHgwo spotify_playback({"action": "get_currently_playing"}) → current track uri = spotify:track:0DiWol3AO6WpXZgp0goxAV spotify_playlists({"action": "add_items", "playlist_id": "37i9dQZF1DX4wta20PHgwo", "uris": ["spotify:track:0DiWol3AO6WpXZgp0goxAV"]})
spotify_playback({"action": "recently_played", "limit": 3}) spotify_playlists({"action": "create", "name": "Focus 2026"}) → got playlist_id back in response spotify_playlists({"action": "add_items", "playlist_id": <id>, "uris": [<3 uris>]})
Use
spotify_library with the right kind.
spotify_library({"kind": "tracks", "action": "save", "uris": ["spotify:track:..."]}) spotify_library({"kind": "albums", "action": "list", "limit": 50})
spotify_devices({"action": "list"}) → pick the device_id by matching name/type spotify_devices({"action": "transfer", "device_id": "<id>", "play": true})
on any playback action means Spotify isn't running anywhere. Tell the user: "Open Spotify on your phone/desktop/web player first, start any track for a second, then retry." Don't retry the tool call blindly — it will fail the same way. You can call 403 Forbidden — No active device found
spotify_devices list to confirm; an empty list means no active device.
means the user is on Free and tried to mutate playback. Don't retry; tell them this action needs Premium. Reads still work (search, playlists, library, get_state).403 Forbidden — Premium required
on 204 No Content
is NOT an error — it means nothing is playing. The tool returns get_currently_playing
is_playing: false. Just report that to the user.
= rate limit. Wait and retry once. If it keeps happening, you're looping — stop.429 Too Many Requests
after a retry — refresh token revoked. Tell the user to run 401 Unauthorized
hermes auth spotify again.
Spotify uses three interchangeable ID formats. The tools accept all three and normalize:
spotify:track:0DiWol3AO6WpXZgp0goxAV (preferred)https://open.spotify.com/track/0DiWol3AO6WpXZgp0goxAV0DiWol3AO6WpXZgp0goxAVWhen in doubt, use full URIs. Search results return URIs in the
uri field — pass those directly.
Entity types:
track, album, artist, playlist, show, episode. Use the right type for the action — spotify_playback.play with a context_uri expects album/playlist/artist; uris expects an array of track URIs.
get_state before every action. Spotify accepts play/pause/skip without preflight. Only inspect state when the user asked "what's playing" or you need to reason about device/track.403 Premium required or 403 No active device. Those are permanent until user action.spotify_search to find a playlist by name — that searches the public Spotify catalog. User playlists come from spotify_playlists list.kind: "tracks" with album URIs in spotify_library (or vice versa). The tool normalizes IDs but the API endpoint differs.MIT
mkdir -p ~/.hermes/skills/media/spotify && curl -o ~/.hermes/skills/media/spotify/SKILL.md https://raw.githubusercontent.com/NousResearch/hermes-agent/main/skills/media/spotify/SKILL.md1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.