Skip to main content
Glama
README.md
# spotify-llm-mcp

Control Spotify and build **LLM-reasoned playlists** from any MCP client (Claude Code, Claude Desktop, Cursor, …).

It wraps the [`spotify_player`](https://github.com/aome510/spotify-player) CLI as the control plane, so it needs **no Spotify Developer app and no OAuth of its own** — it reuses the session you already logged into. The recommendation engine is the **calling LLM itself**: it reasons over your real playlist tracks and the server resolves its picks to Spotify tracks via search. (Spotify removed its `audio-features`/`recommendations` endpoints for new apps in Nov 2024 — this design sidesteps that entirely.)

## Why this design

- **Zero new credentials.** `spotify_player` already holds your session; this server just shells out to it.
- **Immune to Spotify Web-API deprecations.** Control flows through librespot, not `api.spotify.com`.
- **The LLM is the recsys.** Its music knowledge replaces Spotify's dead recommendation endpoints; the server turns song names into playable Spotify tracks.
- **Portable.** One MCP server, usable by every MCP-speaking client.

## Requirements

- [`spotify_player`](https://github.com/aome510/spotify-player) installed, authenticated once, and running as an active device. **Spotify Premium** is required for playback control.
- Python ≥ 3.10.

## Install

```bash
git clone https://github.com/rachittshah/spotify-llm-mcp
cd spotify-llm-mcp
uv pip install -e .
```

Register with Claude Code:

```bash
claude mcp add spotify -- spotify-llm-mcp
```

Or in `settings.json` / `claude_desktop_config.json`:

```jsonc
{ "mcpServers": { "spotify": { "command": "spotify-llm-mcp" } } }
```

## Tools

**Control:** `now_playing` · `control` (play/pause/next/previous/shuffle/repeat/volume/seek) · `play` · `search` · `list_devices` · `switch_device` · `get_queue`

**Recsys inputs & delivery:** `list_playlists` · `get_playlist_tracks` · `taste_profile` · `resolve_tracks` · `create_playlist_from_tracks` · `append_to_playlist`

## Features (MCP prompts / slash-commands)

- `/recommend-from-playlist <name>` — read a playlist, let the LLM extend it in-vibe, build & play the result.
- `/vibe-playlist <description>` — "late-night coding, downtempo instrumental" → a fresh playlist.
- `/more-like-this` — recommendations seeded from what's playing now.
- `/my-taste` — a summary of your listening profile.

## How the recsys works

```
LLM client ──► get_playlist_tracks("On Repeat")      # real tracks, via spotify_player
   │  (LLM reasons over them using its music knowledge)
   └─► create_playlist_from_tracks(name, [{title, artist}, ...])
          │  server resolves each name → Spotify track via search
          └─► play(new_playlist_uri)                 # on your spotify_player device
```

## Claude Code skill

This repo also ships a Claude Code **skill** (`skill/spotify-dj/`) that teaches Claude the recsys workflows on top of the MCP tools. Install it:

```bash
cp -r skill/spotify-dj ~/.claude/skills/spotify-dj
```

Then in Claude Code: "recommend music like my On Repeat playlist" or `/spotify-dj`.

## Known limitations

- **Playback control needs Spotify Premium.** Free accounts can read state but not control it.
- **`spotify_player`'s search errors on some queries** (an upstream JSON-deserialization bug — exit 0 but non-JSON output). The recsys is resilient to this: an unresolvable pick is skipped and reported under `unresolved`, never aborting the batch.
- **Delivery is a playlist, not an ephemeral queue** — `spotify_player`'s CLI has no "add to queue" verb, so recommendations are delivered as a (revisitable) playlist.

## Development

```bash
uv pip install -e ".[dev]"
.venv/bin/python -m pytest            # unit tests (no Spotify needed)
.venv/bin/python scripts/smoke_live.py  # end-to-end against a live spotify_player
.venv/bin/python scripts/smoke_mcp.py    # MCP-protocol smoke over stdio
```

## License

MIT © Rachitt Shah

TDQS

A3.6/5.0

Scored across 14 tools

Disambiguation4/5

Most tools have a clear resource+action distinction, but search, play, and resolve_tracks overlap in their underlying lookup/resolution behavior, and the playlist creation/append tools both resolve track picks. Descriptions are usually enough to pick the right one.

Naming Consistency3/5

Names are mostly readable but inconsistent: verb_noun forms like play_playlist and list_devices coexist with bare verbs like play and control, plus noun phrases like now_playing and taste_profile. The generic name control is particularly vague.

Tool Count4/5

14 tools is a reasonable size for a Spotify assistant covering playback, queue, devices, search, and playlist management. Some search/resolve and playback-control functionality could be consolidated, but the count is not excessive.

Completeness3/5

Core workflows are covered: playback control, queue, devices, search, taste profile, and creating/appending playlists. However, there is no way to remove tracks or delete/replace playlists, nor any queue editing or recommendation tool, leaving notable playlist-lifecycle gaps.

Maintenance

ActivityMaintained
ResponsivenessNo issues