Agent skill

Controlling Spotify

by oaustegard in oaustegard/claude-skills

Control Spotify playback and manage playlists via MCP server.

MITAuto-check: notesAgent Workflows

Install Controlling Spotify

skills CLI
$ npx skills add oaustegard/claude-skills --skill controlling-spotify -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install oaustegard/claude-skills controlling-spotify --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/oaustegard/claude-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/controlling-spotify .claude/skills/controlling-spotify && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
controlling-spotify
GitHub stars
150
Token cost
~2.8k tokens
SKILL.md length
705 words
Files
5 (incl. scripts, references)
Skills in repo
66
Repo updated
First seen
Licence
MIT

At a glance

Control Spotify playback and manage playlists via MCP server.

  • Works in 3 steps: Create Spotify Developer Application → Obtain Refresh Token → Configure Credentials
  • User requests playing music
  • SKILL.md covers When to Use, Prerequisites, MCP Server Installation and Available Tools, plus 6 more sections
  • Runs JavaScript and Shell scripts from its folder; calls bash; needs SPOTIFY_CLIENT_SECRET and SPOTIFY_REFRESH_TOKEN

What it does

Controlling Spotify is an agent skill from oaustegard/claude-skills. Control Spotify playback and manage playlists via MCP server. Use when user requests playing music, controlling Spotify, creating playlists, searching songs, or managing their Spotify library.

Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 6 other files, including scripts and reference files (for example `references/setup-guide.md`, `scripts/apply-patch.js` and `scripts/get-refresh-token.js`).

It sits in Agent Workflows, covering MCP servers. It works with Spotify and Model Context Protocol. The repository describes itself as: My collection of Claude skills. The licence is MIT.

When your agent uses it

  • User requests playing music
  • Controlling Spotify
  • Creating playlists
  • Searching songs

Example prompts

  • “/controlling-spotify”

Requirements

  • Python 3
  • Node.js
  • A Bash shell
  • A credential in SPOTIFY_CLIENT_SECRET
  • A credential in SPOTIFY_REFRESH_TOKEN

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. Create Spotify Developer Application
  2. Obtain Refresh Token
  3. Configure Credentials

What it can do on your machine

Read from SKILL.md and the folder at commit cf49d47. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 3 files in scripts/ (JavaScript and Shell), which the agent can run.

    Shell commands in SKILL.md call:

    • bash

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • developer.spotify.com
    • spotify.com
    • modelcontextprotocol.io

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • SPOTIFY_CLIENT_SECRET
    • SPOTIFY_REFRESH_TOKEN

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Controlling Spotify loads about 2.8k tokens when it runs, and up to ~4.8k if it reads all its reference files. Until then it costs about 53 tokens; SKILL.md has 705 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~53
When it runs · the whole SKILL.md, loaded when a task matches
~2.8k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~4.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NoteMentions a .env fileSKILL.md:53
    edge** file. Ensure the file contains a `.env` style block with the keys above.
  • NoteMentions a .env fileSKILL.md:82
    look in Project Knowledge / Context for .env style block

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from oaustegard/claude-skills at commit cf49d47, republished under its MIT licence (© oaustegard). 705 words, ~2,765 tokens.

Download SKILL.mdSave it as .claude/skills/controlling-spotify/SKILL.md (or your agent's skills folder). This skill also uses 4 other files; get the full folder from GitHub.
name
controlling-spotify
description
Control Spotify playback and manage playlists via MCP server. Use when user requests playing music, controlling Spotify, creating playlists, searching songs, or managing their Spotify library.
credentials
SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, SPOTIFY_REFRESH_TOKEN
domains
api.spotify.com, accounts.spotify.com, raw.githubusercontent.com, github.com
metadata.version
0.1.0

Controlling Spotify

Control Spotify playback, search for music, and manage playlists using the Spotify MCP Server with full user account access.

When to Use

Invoke this skill when users request:

  • Playing, pausing, or skipping music on Spotify
  • Searching for songs, albums, artists, or playlists
  • Creating or modifying playlists
  • Viewing currently playing track or playback status
  • Managing their Spotify library (saved tracks, albums)
  • Queuing songs or albums

Prerequisites

CRITICAL: This skill requires user-provided credentials. The user must complete a one-time setup:

One-Time User Setup
  1. Create Spotify Developer Application

  2. Obtain Refresh Token

    • User must run the helper script locally (see references/setup-guide.md)
    • Script exchanges OAuth code for a long-lived refresh token
    • Refresh token is saved as credential in skill configuration
  3. Configure Credentials

    • Add three credentials to this skill:
      • SPOTIFY_CLIENT_ID: From Spotify Developer Dashboard
      • SPOTIFY_CLIENT_SECRET: From Spotify Developer Dashboard
      • SPOTIFY_REFRESH_TOKEN: From helper script output

    Alternative: Credentials can also be provided via a Project Knowledge file. Ensure the file contains a .env style block with the keys above.

Without these credentials, the skill cannot function. If credentials are missing, guide the user through the setup process detailed in references/setup-guide.md.

MCP Server Installation

The Spotify MCP Server must be installed in the compute environment. Use the provided installation script which handles cloning, patching, and building the server.

bash
# Run the installation script
bash scripts/install-mcp-server.sh
MCP Server Configuration

Configure the MCP client to connect to the Spotify MCP server. Note the logic to support credentials from Project Knowledge.

python
from mcp import Client
import asyncio
import re

# 1. Try to get credentials from skill configuration
env_vars = {
    "SPOTIFY_CLIENT_ID": credentials.get("SPOTIFY_CLIENT_ID"),
    "SPOTIFY_CLIENT_SECRET": credentials.get("SPOTIFY_CLIENT_SECRET"),
    "SPOTIFY_REFRESH_TOKEN": credentials.get("SPOTIFY_REFRESH_TOKEN")
}

# 2. If missing, look in Project Knowledge / Context for .env style block
if not all(env_vars.values()):
    # Heuristic: Scan context/files for VAR=VALUE patterns
    # (Pseudo-code: Implement based on available context access)
    pass

# Server configuration
mcp_config = {
    "command": "node",
    "args": ["/home/claude/spotify-mcp-server/build/index.js"],
    "env": env_vars
}

# Initialize client
async def initialize_spotify_mcp():
    client = Client()
    await client.connect_stdio(
        mcp_config["command"],
        mcp_config["args"],
        mcp_config["env"]
    )
    return client

Available Tools

Read Operations
  1. searchSpotify - Search for tracks, albums, artists, or playlists

    python
    result = await client.call_tool("searchSpotify", {
        "query": "bohemian rhapsody",
        "type": "track",
        "limit": 10
    })
  2. getNowPlaying - Get currently playing track information

    python
    result = await client.call_tool("getNowPlaying", {})
  3. getMyPlaylists - List user's playlists

    python
    result = await client.call_tool("getMyPlaylists", {
        "limit": 20,
        "offset": 0
    })
  4. getPlaylistTracks - Get tracks from a playlist

    python
    result = await client.call_tool("getPlaylistTracks", {
        "playlistId": "37i9dQZEVXcJZyENOWUFo7"
    })
  5. getRecentlyPlayed - Get recently played tracks

    python
    result = await client.call_tool("getRecentlyPlayed", {
        "limit": 10
    })
  6. getUsersSavedTracks - Get user's liked songs

    python
    result = await client.call_tool("getUsersSavedTracks", {
        "limit": 50,
        "offset": 0
    })
Playback Control
  1. playMusic - Start playing track/album/artist/playlist

    python
    # Play by URI
    result = await client.call_tool("playMusic", {
        "uri": "spotify:track:6rqhFgbbKwnb9MLmUQDhG6"
    })
    
    # Or by type and ID
    result = await client.call_tool("playMusic", {
        "type": "track",
        "id": "6rqhFgbbKwnb9MLmUQDhG6"
    })
  2. pausePlayback - Pause current playback

    python
    result = await client.call_tool("pausePlayback", {})
  3. skipToNext - Skip to next track

    python
    result = await client.call_tool("skipToNext", {})
  4. skipToPrevious - Skip to previous track

    python
    result = await client.call_tool("skipToPrevious", {})
  5. addToQueue - Add track/album to playback queue

    python
    result = await client.call_tool("addToQueue", {
        "uri": "spotify:track:6rqhFgbbKwnb9MLmUQDhG6"
    })
Playlist Management
  1. createPlaylist - Create new playlist

    python
    result = await client.call_tool("createPlaylist", {
        "name": "My Workout Mix",
        "description": "High energy tracks",
        "public": False
    })
  2. addTracksToPlaylist - Add tracks to existing playlist

    python
    result = await client.call_tool("addTracksToPlaylist", {
        "playlistId": "3cEYpjA9oz9GiPac4AsH4n",
        "trackUris": [
            "spotify:track:4iV5W9uYEdYUVa79Axb7Rh",
            "spotify:track:6rqhFgbbKwnb9MLmUQDhG6"
        ]
    })
Album Operations
  1. getAlbums - Get album details

    python
    result = await client.call_tool("getAlbums", {
        "albumIds": ["4aawyAB9vmqN3uQ7FjRGTy"]
    })
  2. getAlbumTracks - Get tracks from album

    python
    result = await client.call_tool("getAlbumTracks", {
        "albumId": "4aawyAB9vmqN3uQ7FjRGTy"
    })
  3. saveOrRemoveAlbumForUser - Save/remove albums

    python
    result = await client.call_tool("saveOrRemoveAlbumForUser", {
        "albumIds": ["4aawyAB9vmqN3uQ7FjRGTy"],
        "action": "save"
    })

Workflow Examples

Example 1: Play User's Favorite Song
python
# 1. Search for the song
search_result = await client.call_tool("searchSpotify", {
    "query": "user's favorite song name",
    "type": "track",
    "limit": 1
})

# 2. Extract track URI from results
track_uri = search_result["tracks"][0]["uri"]

# 3. Play the track
await client.call_tool("playMusic", {
    "uri": track_uri
})
Example 2: Create Playlist from Genre
python
# 1. Search for tracks in genre
search_result = await client.call_tool("searchSpotify", {
    "query": "genre:rock year:2020-2024",
    "type": "track",
    "limit": 20
})

# 2. Create new playlist
playlist_result = await client.call_tool("createPlaylist", {
    "name": "Modern Rock Mix",
    "description": "Recent rock tracks",
    "public": False
})

# 3. Extract track URIs
track_uris = [track["uri"] for track in search_result["tracks"]]

# 4. Add tracks to playlist
await client.call_tool("addTracksToPlaylist", {
    "playlistId": playlist_result["id"],
    "trackUris": track_uris
})
Show full SKILL.md (330 more words)Show less
Example 3: Show What's Playing
python
# Get current playback state
now_playing = await client.call_tool("getNowPlaying", {})

# Format and display
print(f"Now Playing: {now_playing['track']['name']}")
print(f"Artist: {now_playing['track']['artists'][0]['name']}")
print(f"Album: {now_playing['track']['album']['name']}")
print(f"Progress: {now_playing['progress_ms']} / {now_playing['duration_ms']} ms")

Important Notes

Spotify Premium Required

Playback control operations (play, pause, skip, queue) require Spotify Premium. Read operations (search, get playlists, view tracks) work with free accounts.

Active Device Required

For playback commands to work, the user must have an active Spotify session (web player, desktop app, mobile app) with a device available. If no active device, playback commands will fail.

Rate Limits

Spotify API has rate limits (typically 180 requests per minute). For bulk operations, implement appropriate delays or batching.

Token Security
  • Refresh tokens grant full access to user's Spotify account
  • Never log or expose refresh tokens
  • Treat them with the same security as passwords
  • Users can revoke tokens from https://www.spotify.com/account/apps/
URI Format

Spotify uses URIs in the format:

  • Track: spotify:track:ID
  • Album: spotify:album:ID
  • Artist: spotify:artist:ID
  • Playlist: spotify:playlist:ID

Most tools accept either URIs or separate type + id parameters.

Troubleshooting

"Spotify configuration not found"

Cause: Missing environment variables

Solution: Verify credentials are properly configured:

python
import os
print(os.getenv("SPOTIFY_CLIENT_ID"))  # Should not be None
print(os.getenv("SPOTIFY_CLIENT_SECRET"))  # Should not be None
print(os.getenv("SPOTIFY_REFRESH_TOKEN"))  # Should not be None
"No active device"

Cause: No Spotify client is currently running/active

Solution: Guide user to:

  1. Open Spotify on any device (web, desktop, mobile)
  2. Start playing something (can pause immediately)
  3. Try the playback command again
"Premium required"

Cause: User has Spotify Free account

Solution: Playback control requires Spotify Premium. Only search and read operations available for free accounts.

MCP Server Won't Start

Cause: Missing dependencies or incorrect installation

Solution:

bash
# Re-run installation script
bash scripts/install-mcp-server.sh

Best Practices

  1. Always search before playing - Don't assume URIs, search for content first
  2. Check playback state - Use getNowPlaying to verify device availability
  3. Handle errors gracefully - Provide helpful messages when operations fail
  4. Batch operations - When adding multiple tracks, use single call with array
  5. Respect rate limits - Add delays for bulk operations

References

Security

This skill requires sensitive credentials. Ensure:

  • Credentials are stored securely in skill configuration
  • Never expose credentials in responses to users
  • Never log credentials
  • Users understand they can revoke access anytime

See references/setup-guide.md for detailed security best practices.

© oaustegard, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 4 other files (scripts, references) in controlling-spotify of oaustegard/claude-skills.

  • SKILL.md
  • references/setup-guide.md
  • scripts/apply-patch.js
  • scripts/get-refresh-token.js
  • scripts/install-mcp-server.sh

Open the folder on GitHubat commit cf49d47

Compare with similar skills

Controlling Spotify next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Controlling Spotify compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Controlling Spotify this skilloaustegard/claude-skills150—~2.8kAutomated safety check: NotesMIT
MCP Server Builderanthropics/skills180k63 repos~2.3kAutomated safety check: PassApache-2.0
MCP Server BuildershareAI-lab/learn-claude-code78k5 repos~1.2kAutomated safety check: PassMIT
MCP Integration for Pluginsanthropics/claude-plugins-official38k11 repos~3.1kAutomated safety check: PassApache-2.0
Crush Configurationcharmbracelet/crush29k—~3.7kAutomated safety check: PassCustom licence
Context Mode Output Sandboxmksglu/context-mode26k—~4.1kAutomated safety check: PassCustom licence

Similar skills

  • MCP Server Builder

    anthropics/skills

    Official

    Guides the design and implementation of Model Context Protocol servers in TypeScript or Python, from tool naming and error messages to evaluation.

    180k GitHub starsUsed in 63 repos~2.3k tokens
    Agent WorkflowsAuto-check passed
  • MCP Server Builder

    shareAI-lab/learn-claude-code

    Walks through building MCP servers in Python or TypeScript that expose tools, resources and prompts to Claude, with templates, registration and testing.

    78k GitHub starsUsed in 5 repos~1.2k tokens
    Agent WorkflowsAuto-check passed
  • MCP Integration for Plugins

    anthropics/claude-plugins-official

    Official

    Explains how to bundle Model Context Protocol servers in a Claude Code plugin, covering config files, stdio, SSE, HTTP and WebSocket server types, and authentication.

    38k GitHub starsUsed in 11 repos~3.1k tokens
    Agent WorkflowsAuto-check passed
  • Crush Configuration

    charmbracelet/crush

    Explains how to configure the Crush coding agent with crushrc or crush.json, covering providers, models, LSPs, MCP servers, hooks, permissions and config precedence.

    29k GitHub stars~3.7k tokensUpdated today
    Agent WorkflowsAuto-check passed
  • Context Mode Output Sandbox

    mksglu/context-mode

    Routes large command, file, API and browser output through context-mode tools so only the needed result enters the agent's context, instead of dumping it via Bash.

    26k GitHub stars~4.1k tokensUpdated today
    Agent WorkflowsAuto-check passed
  • Migrates the compatible subset of settings and global file-based MCP servers from the Warp desktop app into Warp Agent CLI without exposing credentials or state.

    65k GitHub starsUsed in 1 repo~2.1k tokens
    Agent WorkflowsAuto-check passed

More from oaustegard/claude-skills

All 66 skills in this repo
  • Vega-Lite Interactive Charts

    oaustegard/claude-skills

    Builds interactive Vega-Lite charts from uploaded data: analyzes the fields, picks five to ten fitting chart types, and produces a React artifact with the data embedded inline.

    150 GitHub stars~2.1k tokensUpdated yesterday
    Auto-check passed
  • Single-File HTML Composer

    oaustegard/claude-skills

    Builds self-contained single-file HTML pages such as reports, decks, postmortems, flowcharts and prototypes from a small spec using a bundled Python composer and templates.

    150 GitHub stars~3.2k tokensUpdated yesterday
    Auto-check passed
  • Declauding

    oaustegard/claude-skills

    Rewrites model-sounding prose into plain technical writing and checks that every claim survives, for PR text, docs, commit messages and similar drafts.

    150 GitHub stars~5.2k tokensUpdated yesterday
    Auto-check passed
  • Preact Developer

    oaustegard/claude-skills

    Guides building standards-based Preact apps with native-first choices, HTM syntax, import maps and vendored ESM, from single-file demos to larger builds.

    150 GitHub stars~4.6k tokensUpdated yesterday
    Auto-check passed
  • Bluesky Zeitgeist Sampler

    oaustegard/claude-skills

    Deprecated sampler that captures short windows of the Bluesky firehose, clusters trending terms and builds an HTML report; replaced by the browsing-bluesky skill.

    150 GitHub stars~1.4k tokensUpdated yesterday
    Auto-check passed
  • Adversarial Review Before Shipping

    oaustegard/claude-skills

    Has a fresh-context adversary attack a blog post, recommendation, analysis brief or piece of code before you ship it, using a profile suited to that kind of artifact.

    150 GitHub stars~3.4k tokensUpdated yesterday
    Auto-check passed

Categories

Questions about Controlling Spotify

What does Controlling Spotify do?

Control Spotify playback and manage playlists via MCP server. Controlling Spotify is an agent skill from oaustegard/claude-skills. Control Spotify playback and manage playlists via MCP server.

When should I use Controlling Spotify?

Controlling Spotify fits situations like: user requests playing music; controlling Spotify; creating playlists; searching songs.

How do I install Controlling Spotify in Claude Code?

Run `npx skills add oaustegard/claude-skills --skill controlling-spotify -a claude-code`. Or copy the skill folder (controlling-spotify in oaustegard/claude-skills) into .claude/skills/controlling-spotify in your project. Claude Code loads it when a task matches its description.

How do I install Controlling Spotify in Codex?

Run `npx skills add oaustegard/claude-skills --skill controlling-spotify -a codex`. Or copy the skill folder (controlling-spotify in oaustegard/claude-skills) into .agents/skills/controlling-spotify in your project. Codex loads it when a task matches its description.

Can I use Controlling Spotify in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add oaustegard/claude-skills --skill controlling-spotify -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/controlling-spotify, .gemini/skills/controlling-spotify, .github/skills/controlling-spotify and .opencode/skills/controlling-spotify in your project.

What does Controlling Spotify need to run?

Going by SKILL.md and its folder, Controlling Spotify needs JavaScript and a shell for the scripts in its folder, the command-line tools its instructions call (bash) and credentials named SPOTIFY_CLIENT_SECRET and SPOTIFY_REFRESH_TOKEN. Our summary lists: Python 3; Node.js; A Bash shell; A credential in SPOTIFY_CLIENT_SECRET; A credential in SPOTIFY_REFRESH_TOKEN.

Does Controlling Spotify access the network?

SKILL.md names 3 domains. As links in the text: developer.spotify.com, spotify.com and modelcontextprotocol.io. This is read from the text; nothing was executed.

Is Controlling Spotify safe to install?

Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Controlling Spotify use?

Controlling Spotify is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Controlling Spotify use?

About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.1k tokens, read only when the agent opens those files.

What are the alternatives to Controlling Spotify?

Skills that share tags, products or a category with Controlling Spotify: MCP Server Builder (anthropics/skills, 180k stars), MCP Server Builder (shareAI-lab/learn-claude-code, 78k stars), MCP Integration for Plugins (anthropics/claude-plugins-official, 38k stars) and Crush Configuration (charmbracelet/crush, 29k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Controlling Spotify?

oaustegard (a GitHub user) maintains it in oaustegard/claude-skills, which has 150 GitHub stars. The repository holds 66 skills in this directory. The repository was last updated on October 8, 2026.

Source: oaustegard/claude-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.