Skip to main content

Spotify

Hermes can control Spotify — playback, queue, search, playlists, saved tracks/albums, and listening history — through the official spotify plugin from the plugin catalog. It uses Spotify's Web API with PKCE OAuth. The plugin is maintained by Nous Research in NousResearch/hermes-official-plugins and is not part of Hermes core. Tokens are stored in ~/.hermes/auth.json and refreshed automatically on 401; you only log in once per machine (refresh tokens expire after ~6 months; re-run hermes spotify login when they do).

Unlike Hermes' built-in OAuth integrations, Spotify requires every user to register their own lightweight developer app. Spotify does not let third parties ship a public OAuth app that anyone can use. It takes about two minutes and hermes spotify login walks you through it.

Install​

hermes plugins install spotify

Plugins are installed per profile. To use Spotify in another profile, install it there too (hermes -p <profile> plugins install spotify).

Upgrading from a release that bundled Spotify

Nothing to do. Every profile that was already using Spotify (a Spotify login in its auth.json, or the spotify toolset listed in platform_toolsets) gets the plugin installed automatically from the catalog by hermes update, or the first time the profile starts if that step could not run (this honours security.allow_lazy_installs). Your login, the spotify toolset and the tool names carry over unchanged. The one visible change: hermes auth spotify is now hermes spotify login (and hermes auth status spotify / hermes auth logout spotify are hermes spotify status / hermes spotify logout); the old spelling prints the new one. If you later remove the plugin (hermes plugins remove spotify), it stays removed.

Prerequisites​

  • A Spotify account. Free works for search, playlist, library, and activity tools. Premium is required for playback control (play, pause, skip, seek, volume, queue add, transfer).
  • Hermes Agent installed and running, with the spotify plugin installed.
  • For playback tools: an active Spotify Connect device — the Spotify app must be open on at least one device (phone, desktop, web player, speaker) so the Web API has something to control. If nothing is active you'll get a 403 Forbidden with a "no active device" message; open Spotify on any device and retry.

Setup​

1. Enable the toolset​

The plugin's spotify toolset is opt-in, so users who don't want it don't ship extra tool schemas on every API call. Turn it on in hermes tools (toggle 🔌 Spotify, then save) or with:

hermes tools enable spotify

2. Log in​

hermes spotify login

The 7 Spotify tools only reach the agent once you're logged in.

If no HERMES_SPOTIFY_CLIENT_ID is set, Hermes walks you through the app registration inline:

  1. Opens https://developer.spotify.com/dashboard in your browser
  2. Prints the exact values to paste into Spotify's "Create app" form
  3. Prompts you for the Client ID you get back
  4. Saves it to ~/.hermes/.env so future runs skip this step
  5. Continues straight into the OAuth consent flow

After you approve, tokens are written under providers.spotify in ~/.hermes/auth.json. The active inference provider is NOT changed — Spotify auth is independent of your LLM provider.

Creating the Spotify app (what the wizard asks for)​

When the dashboard opens, click Create app and fill in:

FieldValue
App nameanything (e.g. hermes-agent)
App descriptionanything (e.g. personal Hermes integration)
Websiteleave blank
Redirect URIhttp://127.0.0.1:43827/spotify/callback
Which API/SDKs?check Web API

Agree to the terms and click Save. On the next page click Settings → copy the Client ID and paste it into the Hermes prompt. That's the only value Hermes needs — PKCE doesn't use a client secret.

Running over SSH / in a headless environment​

If SSH_CLIENT or SSH_TTY is set, Hermes skips the automatic browser open during both the wizard and the OAuth step. Copy the dashboard URL and the authorization URL Hermes prints, open them in a browser on your local machine, and proceed normally — the local HTTP listener still runs on the remote host on port 43827. Your laptop's browser can't reach the remote loopback without an SSH local-forward:

ssh -N -L 43827:127.0.0.1:43827 user@remote-host

For jump-box / bastion setups and other gotchas (mosh, tmux, port conflicts), see OAuth over SSH / Remote Hosts.

Verify​

hermes spotify status

Shows whether tokens are present and when the access token expires. Refresh is automatic: when any Spotify API call returns 401, the client exchanges the refresh token and retries once. Refresh tokens persist across Hermes restarts, so you only re-auth if you revoke the app in your Spotify account settings or run hermes spotify logout.

Using it​

Once logged in, the agent has access to 7 Spotify tools. You talk to the agent naturally — it picks the right tool and action. For the best behavior, the agent loads a companion skill that teaches canonical usage patterns (single-search-then-play, when not to preflight get_state, etc.).

> play some miles davis
> what am I listening to
> add this track to my Late Night Jazz playlist
> skip to the next song
> make a new playlist called "Focus 2026" and add the last three songs I played
> which of my saved albums are by Radiohead
> search for acoustic covers of Blackbird
> transfer playback to my kitchen speaker

Tool reference​

All playback-mutating actions accept an optional device_id to target a specific device. If omitted, Spotify uses the currently active device.

spotify_playback​

Control and inspect playback, plus fetch recently played history.

ActionPurposePremium?
get_stateFull playback state (track, device, progress, shuffle/repeat)No
get_currently_playingJust the current track (returns empty on 204 — see below)No
playStart/resume playback. Optional: context_uri, uris, offset, position_msYes
pausePause playbackYes
next / previousSkip trackYes
seekJump to position_msYes
set_repeatstate = track / context / offYes
set_shufflestate = true / falseYes
set_volumevolume_percent = 0-100Yes
recently_playedLast played tracks. Optional limit, before, after (Unix ms)No

spotify_devices​

ActionPurpose
listEvery Spotify Connect device visible to your account
transferMove playback to device_id. Optional play: true starts playback on transfer

Home Assistant-managed speakers​

If Home Assistant manages speakers that already support Spotify Connect (for example Sonos, Echo, Nest, or other Connect-capable speakers), they appear in spotify_devices list automatically whenever Spotify can see them. Hermes does not need a Home Assistant ↔ Spotify bridge for this path — Spotify handles the device routing natively.

Ask Hermes to transfer playback by the speaker's display name (for example, “transfer Spotify to the kitchen speaker”), or call spotify_devices list and pass the exact device_id to spotify_devices transfer when scripting. If the speaker is missing, open the Spotify app or the speaker's Spotify integration once so Spotify registers it as an active Connect target.

spotify_queue​

ActionPurposePremium?
getCurrently queued tracksNo
addAppend uri to the queueYes

Search the catalog. query is required. Optional: types (array of track / album / artist / playlist / show / episode), limit, offset, market.

spotify_playlists​

ActionPurposeRequired args
listUser's playlists—
getOne playlist + tracksplaylist_id
createNew playlistname (+ optional description, public, collaborative)
add_itemsAdd tracksplaylist_id, uris (optional position)
remove_itemsRemove tracksplaylist_id, uris (+ optional snapshot_id)
update_detailsRename / editplaylist_id + any of name, description, public, collaborative

spotify_albums​

ActionPurposeRequired args
getAlbum metadataalbum_id
tracksAlbum track listalbum_id

spotify_library​

Unified access to saved tracks and saved albums. Pick the collection with the kind arg.

ActionPurpose
listPaginated library listing
saveAdd ids / uris to library
removeRemove ids / uris from library

Required: kind = tracks or albums, plus action.

Feature matrix: Free vs Premium​

Read-only tools work on Free accounts. Anything that mutates playback or the queue requires Premium.

Works on FreePremium required
spotify_search (all)spotify_playback — play, pause, next, previous, seek, set_repeat, set_shuffle, set_volume
spotify_playback — get_state, get_currently_playing, recently_playedspotify_queue — add
spotify_devices — listspotify_devices — transfer
spotify_queue — get
spotify_playlists (all)
spotify_albums (all)
spotify_library (all)

Scheduling: Spotify + cron​

Because Spotify tools are regular Hermes tools, a cron job running in a Hermes session can trigger playback on any schedule. No new code needed.

Morning wake-up playlist​

hermes cron add \
--name "morning-commute" \
"0 7 * * 1-5" \
"Transfer playback to my kitchen speaker and start my 'Morning Commute' playlist. Volume to 40. Shuffle on."

What happens at 7am every weekday:

  1. Cron spins up a headless Hermes session.
  2. Agent reads the prompt, calls spotify_devices list to find "kitchen speaker" by name, then spotify_devices transfer → spotify_playback set_volume → spotify_playback set_shuffle → spotify_search + spotify_playback play.
  3. Music starts on the target speaker. Total cost: one session, a few tool calls, no human input.

Wind-down at night​

hermes cron add \
--name "wind-down" \
"30 22 * * *" \
"Pause Spotify. Then set volume to 20 so it's quiet when I start it again tomorrow."

Gotchas​

  • An active device must exist when the cron fires. If no Spotify client is running (phone/desktop/Connect speaker), playback actions return 403 no active device. For morning playlists, the trick is to target a device that's always on (Sonos, Echo, a smart speaker) rather than your phone.
  • Premium required for anything that mutates playback — play, pause, skip, volume, transfer. Read-only cron jobs (scheduled "email me my recently played tracks") work fine on Free.
  • The cron agent inherits your active toolsets. Spotify must be enabled in hermes tools for the cron session to see the Spotify tools.
  • Cron jobs run with skip_memory=True so they don't write to your memory store.

Full cron reference: Cron Jobs.

Sign out​

hermes spotify logout

Removes tokens from ~/.hermes/auth.json. To also clear the app config, delete HERMES_SPOTIFY_CLIENT_ID (and HERMES_SPOTIFY_REDIRECT_URI if you set it) from ~/.hermes/.env, or run the wizard again.

To revoke the app on Spotify's side, visit Apps connected to your account and click REMOVE ACCESS.

Troubleshooting​

403 Forbidden — Player command failed: No active device found — You need Spotify running on at least one device. Open the Spotify app on your phone, desktop, or web player, start any track for a second to register it, and retry. spotify_devices list shows what's currently visible.

403 Forbidden — Premium required — You're on a Free account trying to use a playback-mutating action. See the feature matrix above.

204 No Content on get_currently_playing — nothing is currently playing on any device. This is Spotify's normal response, not an error; Hermes surfaces it as an explanatory empty result (is_playing: false).

INVALID_CLIENT: Invalid redirect URI — the redirect URI in your Spotify app settings doesn't match what Hermes is using. The default is http://127.0.0.1:43827/spotify/callback. Either add that to your app's allowed redirect URIs, or set HERMES_SPOTIFY_REDIRECT_URI in ~/.hermes/.env to whatever you registered.

429 Too Many Requests — Spotify's rate limit. Hermes returns a friendly error; wait a minute and retry. If this persists, you're probably running a tight loop in a script — Spotify's quota resets roughly every 30 seconds.

401 Unauthorized keeps coming back — Your refresh token was revoked (usually because you removed the app from your account, or the app was deleted). Run hermes spotify login again.

Wizard doesn't open the browser — If you're over SSH or in a container without a display, Hermes detects it and skips the auto-open. Copy the dashboard URL it prints and open it manually.

Advanced: custom scopes​

By default Hermes requests the scopes needed for every shipped tool. Override if you want to restrict access:

hermes spotify login --scope "user-read-playback-state user-modify-playback-state playlist-read-private"

Scope reference: Spotify Web API scopes. If you request fewer scopes than a tool needs, that tool's calls will fail with 403.

Advanced: custom client ID / redirect URI​

hermes spotify login --client-id <id> --redirect-uri http://localhost:3000/callback

Or set them permanently in ~/.hermes/.env:

HERMES_SPOTIFY_CLIENT_ID=<your_id>
HERMES_SPOTIFY_REDIRECT_URI=http://localhost:3000/callback

The redirect URI must be allow-listed in your Spotify app's settings. The default works for almost everyone — only change it if port 43827 is taken.

Where things live​

FileContents
~/.hermes/auth.json → providers.spotifyaccess token, refresh token, expiry, scope, redirect URI
~/.hermes/.envHERMES_SPOTIFY_CLIENT_ID, optional HERMES_SPOTIFY_REDIRECT_URI
Spotify appowned by you at developer.spotify.com/dashboard; contains the Client ID and the redirect URI allow-list