Best for
- Playing, pausing, or skipping music on Spotify
- Searching for songs, albums, artists, or playlists
- Creating or modifying playlists
oaustegard/claude-skills/controlling-spotify/SKILL.md
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.
Decision brief
Control Spotify playback, search for music, and manage playlists using the Spotify MCP Server with full user account access.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/oaustegard/claude-skills --skill "controlling-spotify"Inspect the Agent Skill "controlling-spotify" from https://github.com/oaustegard/claude-skills/blob/4043d027cb302cc269c135a310be4191327a53ad/controlling-spotify/SKILL.md at commit 4043d027cb302cc269c135a310be4191327a53ad. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
1. Create Spotify Developer Application - Go to https://developer.spotify.com/dashboard/ - Create an app and note the Client ID and Client Secret - Add redirect URI: http://127.0.0.1:8888/callback
Review the “Workflow Examples” section in the pinned source before continuing.
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, albu…
CRITICAL: This skill requires user-provided credentials. The user must complete a one-time setup:
The Spotify MCP Server must be installed in the compute environment. Use the provided installation script which handles cloning, patching, and building the server.
Permission review
The documentation asks the agent to run terminal commands or scripts.
User must run the helper script locally (see `references/setup-guide.md`)The documentation asks the agent to run terminal commands or scripts.
# Run the installation scriptEvidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 95/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 147 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Control Spotify playback, search for music, and manage playlists using the Spotify MCP Server with full user account access.
Invoke this skill when users request:
CRITICAL: This skill requires user-provided credentials. The user must complete a one-time setup:
Create Spotify Developer Application
http://127.0.0.1:8888/callbackObtain Refresh Token
references/setup-guide.md)Configure Credentials
SPOTIFY_CLIENT_ID: From Spotify Developer DashboardSPOTIFY_CLIENT_SECRET: From Spotify Developer DashboardSPOTIFY_REFRESH_TOKEN: From helper script outputAlternative: 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.
The Spotify MCP Server must be installed in the compute environment. Use the provided installation script which handles cloning, patching, and building the server.
# Run the installation script
bash scripts/install-mcp-server.sh
Configure the MCP client to connect to the Spotify MCP server. Note the logic to support credentials from Project Knowledge.
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
searchSpotify - Search for tracks, albums, artists, or playlists
result = await client.call_tool("searchSpotify", {
"query": "bohemian rhapsody",
"type": "track",
"limit": 10
})
getNowPlaying - Get currently playing track information
result = await client.call_tool("getNowPlaying", {})
getMyPlaylists - List user's playlists
result = await client.call_tool("getMyPlaylists", {
"limit": 20,
"offset": 0
})
getPlaylistTracks - Get tracks from a playlist
result = await client.call_tool("getPlaylistTracks", {
"playlistId": "37i9dQZEVXcJZyENOWUFo7"
})
getRecentlyPlayed - Get recently played tracks
result = await client.call_tool("getRecentlyPlayed", {
"limit": 10
})
getUsersSavedTracks - Get user's liked songs
result = await client.call_tool("getUsersSavedTracks", {
"limit": 50,
"offset": 0
})
playMusic - Start playing track/album/artist/playlist
# 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"
})
pausePlayback - Pause current playback
result = await client.call_tool("pausePlayback", {})
skipToNext - Skip to next track
result = await client.call_tool("skipToNext", {})
skipToPrevious - Skip to previous track
result = await client.call_tool("skipToPrevious", {})
addToQueue - Add track/album to playback queue
result = await client.call_tool("addToQueue", {
"uri": "spotify:track:6rqhFgbbKwnb9MLmUQDhG6"
})
createPlaylist - Create new playlist
result = await client.call_tool("createPlaylist", {
"name": "My Workout Mix",
"description": "High energy tracks",
"public": False
})
addTracksToPlaylist - Add tracks to existing playlist
result = await client.call_tool("addTracksToPlaylist", {
"playlistId": "3cEYpjA9oz9GiPac4AsH4n",
"trackUris": [
"spotify:track:4iV5W9uYEdYUVa79Axb7Rh",
"spotify:track:6rqhFgbbKwnb9MLmUQDhG6"
]
})
getAlbums - Get album details
result = await client.call_tool("getAlbums", {
"albumIds": ["4aawyAB9vmqN3uQ7FjRGTy"]
})
getAlbumTracks - Get tracks from album
result = await client.call_tool("getAlbumTracks", {
"albumId": "4aawyAB9vmqN3uQ7FjRGTy"
})
saveOrRemoveAlbumForUser - Save/remove albums
result = await client.call_tool("saveOrRemoveAlbumForUser", {
"albumIds": ["4aawyAB9vmqN3uQ7FjRGTy"],
"action": "save"
})
# 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
})
# 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
})
# 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")
Playback control operations (play, pause, skip, queue) require Spotify Premium. Read operations (search, get playlists, view tracks) work with free accounts.
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.
Spotify API has rate limits (typically 180 requests per minute). For bulk operations, implement appropriate delays or batching.
Spotify uses URIs in the format:
spotify:track:IDspotify:album:IDspotify:artist:IDspotify:playlist:IDMost tools accept either URIs or separate type + id parameters.
Cause: Missing environment variables
Solution: Verify credentials are properly configured:
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
Cause: No Spotify client is currently running/active
Solution: Guide user to:
Cause: User has Spotify Free account
Solution: Playback control requires Spotify Premium. Only search and read operations available for free accounts.
Cause: Missing dependencies or incorrect installation
Solution:
# Re-run installation script
bash scripts/install-mcp-server.sh
getNowPlaying to verify device availabilityreferences/setup-guide.mdThis skill requires sensitive credentials. Ensure:
See references/setup-guide.md for detailed security best practices.
Frequently asked questions
Control Spotify playback, search for music, and manage playlists using the Spotify MCP Server with full user account access.
The source record exposes this install command: npx skills add https://github.com/oaustegard/claude-skills --skill "controlling-spotify". Inspect the command and pinned source before running it.
Static rules flagged exec-script in the source; the page lists the matching lines and excerpts.
Alternatives
garrytan/gbrain
End-to-end discipline for turning any large data source (audio libraries, email takeouts, document corpora, chat exports, API dumps) into brain pages at scale. The lifecycle spine: SCHEMA → ACCESS → TRIAL → EVALUATE → IMPROVE → CODIFY → TEST → SKILLIFY → BULK → MONITOR. State is tracked in a durable JSON manifest (see MANIFEST-PATTERN.md) so any crash, session boundary, or subagent fan-out resumes from ground truth instead of memory.
alirezarezvani/claude-skills
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
dotnet/skills
Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions EnableMSTestRunner, EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner. USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE); centralizing
oaustegard/claude-skills
Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre