---
name: spotify
description: Use when the user asks to control Spotify playback, search for songs/albums/artists/playlists, manage the user's queue, view currently-playing track, transfer playback to a device, or check Spotify account status. Drives the Spotify Web API via a local CLI (`spotifyctl`). Requires prior one-time OAuth setup with a Spotify Developer app.
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux, macos, windows]
metadata:
  hermes:
    tags: [spotify, music, audio, api, cli, oauth, playback-control]
    related_skills: [media/heartmula, media/songsee]
---

# Spotify

Control Spotify playback and library via the Web API. This skill provides a `spotifyctl` CLI that wraps the most-used endpoints (play, pause, next, search, queue, transfer, now-playing) so the agent can act on natural-language requests without writing raw HTTP each time.

## Overview

Spotify's Web API uses OAuth 2.0. The CLI handles token storage, refresh, and request signing. The user authorizes once via browser, the CLI saves a refresh token, and every subsequent call works in the background — no further user interaction.

Playback control requires an **active Spotify Connect device** (desktop app, mobile, or web player). The CLI cannot start music on a device that is not online.

## When to Use

- User says "play X", "pause", "skip", "next track", "previous"
- User says "queue X", "add X to queue"
- User asks "what's playing?", "currently playing"
- User says "search for X on Spotify"
- User asks to transfer playback ("play on my phone", "switch to speakers")
- User wants to know account/plan status

**Don't use for:** downloading tracks offline, playing local files, lyrics, podcast controls (limited), or anything that requires Spotify Connect Premium features beyond basic playback.

## One-Time Setup (5 minutes)

1. **Create a Spotify app**: https://developer.spotify.com/dashboard → "Create app"
   - App name: anything (e.g. "hermes-spotify")
   - Redirect URI: `http://127.0.0.1:8765/callback` (must match exactly)
   - API: Web API
2. **Copy credentials**: Settings → "Client ID" and "Client Secret"
3. **Authorize**:
   ```bash
   spotifyctl auth --client-id <ID> --client-secret <SECRET>
   ```
   A browser opens, you click "Agree", and the CLI saves the refresh token to `~/.config/spotifyctl/token.json`.
4. **Confirm a device is online**: open Spotify on phone/desktop, start any song, then:
   ```bash
   spotifyctl devices
   ```
   You should see at least one device listed.

## CLI Reference

All commands read `SPOTIFYCTL_CLIENT_ID` / `SPOTIFYCTL_CLIENT_SECRET` env vars if flags are not passed. Add `~/bin` to PATH so `spotifyctl` is callable from anywhere.

```bash
# Auth
spotifyctl auth --client-id <ID> --client-secret <SECRET>
spotifyctl status                       # shows token expiry + user plan

# Playback control (requires active device)
spotifyctl play                         # resume on last device
spotifyctl pause
spotifyctl next
spotifyctl previous
spotifyctl seek <ms>
spotifyctl volume <0-100>
spotifyctl shuffle on|off
spotifyctl repeat track|context|off

# Device management
spotifyctl devices                      # list available Connect devices
spotifyctl transfer <device_id>         # transfer playback

# Search
spotifyctl search "query" [--type track|album|artist|playlist] [--limit 10]

# Now playing
spotifyctl now                          # current track + artist + device

# Queue
spotifyctl queue <track_uri>            # add to queue
```

Output is JSON to stdout by default. Pass `--human` *before* the subcommand for a friendly summary:
```bash
spotifyctl --human status
spotifyctl --human now
```

## Natural-Language Mapping

| User says | Command |
|---|---|
| "play Bohemian Rhapsody" | `search "Bohemian Rhapsody" --type track` → `play --uri <uri>` |
| "pause" / "stop" | `pause` |
| "next song" / "skip" | `next` |
| "what's playing?" | `now` |
| "play on my phone" | `devices` → `transfer <phone_id>` → `play` |
| "add X to queue" | `search` → `queue <uri>` |
| "louder" / "quieter" | `volume` (relative: `volume +10` or `volume -10`) |

After every action, fetch `now` and report back to the user with artist + track name.

## Common Pitfalls

1. **"No active device"** — Spotify is not running anywhere. Tell the user to open Spotify and start playing something (even briefly) to register a Connect device.
2. **403 Premium required** — control endpoints (`play`, `next`, etc.) need Spotify Premium. Free accounts are read-only.
3. **Token expired** — the CLI auto-refreshes. If it fails, re-run `spotifyctl auth`.
4. **Wrong redirect URI** — must be `http://127.0.0.1:8765/callback` exactly, including scheme and port. Mismatch returns `INVALID_CLIENT: invalid redirect URI`.
5. **`play --uri` without context** — the URI alone may resume the wrong context. For "play a specific track", prefer `play --uri spotify:track:...` and call `devices` first to confirm a target.
6. **Scoping** — the default scope is `user-read-playback-state user-modify-playback-state user-read-currently-playing playlist-read-private user-library-read`. Add `user-read-email` if you need account info. Re-authorize if scope changes.
7. **Rate limit (429)** — the CLI respects `Retry-After`. If hit, back off and inform the user.

## Verification Checklist

- [ ] `spotifyctl status` shows a valid token and a Premium plan
- [ ] `spotifyctl devices` lists at least one active device
- [ ] `spotifyctl now` returns the currently playing track
- [ ] `spotifyctl play` and `spotifyctl pause` work end-to-end
- [ ] `spotifyctl search` returns results
