spotify-dj
by cikeyz
README.md
# spotify-dj MCP
<p>
<img alt="Python 3.14" src="https://img.shields.io/badge/python-3.14-3776AB.svg?logo=python&logoColor=white">
<img alt="MCP 2.1.1" src="https://img.shields.io/badge/mcp-2.1.1-blue.svg">
<img alt="Tools" src="https://img.shields.io/badge/tools-31%20%2B%203%20prompts-green.svg">
<img alt="License" src="https://img.shields.io/badge/license-MIT-yellow.svg">
</p>
A Spotify DJ MCP server: real DJ metadata plus full playlist control, in one
local server. Spotify removed `audio-features` in 2024, so pure Spotify MCPs
cannot give BPM anymore. This one rebuilds it from free sources, with
per-field provenance, and pairs it with staged playlist writes.
## What it does
- DJ metadata for any track: BPM, key plus Camelot, energy, danceability,
valence. Multi-tier free chain (cache, ReccoBeats, Deezer, AcousticBrainz,
TheAudioDB, optional local analysis), every value tagged with provider.
- Transition scoring 0-100 (harmonic plus octave-aware tempo plus energy),
next-track suggestions, energy-arc setlist planning, Rekordbox-friendly
export.
- Full Spotify control: search, playlists (list, read, create, edit, add,
remove, reorder with snapshot rollback), playback, queue, devices, library,
top items, history.
- Safety first: every stored-data mutation stages a preview with an
`operation_id`, then a single-use commit revalidates before applying.
Writes need resolved Spotify IDs, never guesses.
## Quick start
Requires Python 3.14, a Spotify account with Premium (app owner), and [`uv`](https://astral.sh/uv).
```powershell
git clone https://github.com/cikeyz/spotify-dj.git
Set-Location spotify-dj
uv venv --python 3.14
.\.venv\Scripts\Activate.ps1
uv pip install -r requirements.txt
```
Create a Spotify app (2 min, free): open the
[dashboard](https://developer.spotify.com/dashboard), Create app, add exactly
`http://127.0.0.1:8888/callback` to Redirect URIs, check Web API only, then add
yourself under User Management. Copy the Client ID, then:
```powershell
$env:SPOTIFY_DJ_HOME = "$env:LOCALAPPDATA\spotify-dj"
.\.venv\Scripts\python.exe setup\setup.py --client-id '<your-client-id>'
.\.venv\Scripts\python.exe setup\setup.py --auth-url
# open the printed URL, approve, then:
.\.venv\Scripts\python.exe setup\setup.py --auth-code '<pasted-redirect-url>'
.\.venv\Scripts\python.exe setup\tests\verify_server.py
```
Expect `RESULT: ALL CHECKS PASSED`. Full walkthrough in [`docs/SETUP.md`](docs/SETUP.md).
## MCP client config (stdio only)
```json
{
"mcpServers": {
"spotify-dj": {
"command": "C:\\path\\to\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\server.py"],
"env": { "SPOTIFY_DJ_HOME": "C:\\path\\to\\state" }
}
}
}
```
Launch the `.venv` Python directly, never through uv's runner. Tokens, cache, and
audit logs live in `SPOTIFY_DJ_HOME`, never in this repo.
## Tools (31) and prompts (3)
| Family | Tools |
|---|---|
| Search and library | `spotify_search`, `spotify_get_track`, `spotify_library_tracks`, `spotify_library_albums`, `spotify_top_items`, `spotify_history_recent` |
| Playlists | `spotify_playlists_list`, `spotify_playlist_get`, `spotify_playlist_create`, `spotify_playlist_edit`, `spotify_playlist_add`, `spotify_playlist_remove`, `spotify_playlist_reorder` |
| Playback | `spotify_devices_list`, `spotify_playback_get`, `spotify_play`, `spotify_pause`, `spotify_skip`, `spotify_queue` |
| DJ intelligence | `dj_audio_features`, `dj_compare_tracks`, `dj_score_transition`, `dj_suggest_next`, `dj_audit_playlist`, `dj_plan_set`, `dj_apply_plan`, `dj_export_setlist` |
| Infra | `spotify_auth_status`, `spotify_write_commit`, `spotify_write_cancel`, `spotify_write_list_staged` |
Prompts: `build-set` (crate to ordered setlist), `audit-crate` (drift and
duplicate report), `organize-playlist` (dedupe, sort, split).
Reads return cursor envelopes (`items`, `next_page_token`, `has_more`) capped
at 30KB. Mutations stage first, commit once. Details and live API discoveries
in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
## Optional: local analysis tier
Without it the server uses keyless catalogs only. To measure BPM and key from
audio as a last resort (proves out at ~5s per track):
```powershell
.\.venv\Scripts\python.exe -m pip install librosa
$env:SPOTIFY_DJ_LOCAL_ANALYSIS = "1"
```
## Tests
```powershell
.\.venv\Scripts\python.exe setup\tests\verify_server.py
.\.venv\Scripts\python.exe setup\tests\test_server.py
```
`verify_server.py` is offline plus static. `test_server.py` runs live against
your account with self-cleaning `SPOTIFYDJ-TEST-` playlists and must end with
`RESULT: ALL CHECKS PASSED` and zero residue.
## Layout
- `server.py`: thin shell (tools, registration, stdio entry)
- `core.py`: state, staged store, Spotify client, envelopes
- `playlists.py`, `collection.py`, `dj.py`, `prompts.py`: feature modules
- `setup/setup.py`: PKCE grant, refresh, status
- `setup/tests/`: verify plus live batteries
- `docs/`: `SETUP.md` guide, `ARCHITECTURE.md` design plus discoveries
Released under the [MIT License](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues