A browser extension that adds smart cleanup suggestions to the Spotify web player. When you open a playlist on Spotify, click on the cat in the corner and we'll finds tracks that don't quite belong. Swipe through the suggestions, make your picks, and Syncopate cleans up the rest.
syncopate-demo-1787447676633.1.mp4
- macOS or Linux
- Python 3.11+ (3.12 recommended)
- Node.js 18+ and npm
- A Spotify Developer app (free — takes ~2 minutes)
- A Chromium-based browser (Chrome, Brave, Arc, etc.) for the extension
Storage is a plain tokens.json file in the project root. It holds your Spotify refresh token so you don't have to re-login every server restart. Delete the file to log out; back it up by copying it.
Backend:
python -m venv .venv
source .venv/bin/activate
cp .env.example .env # fill in Spotify client ID/secret
uvicorn main:app --reload --port 8000
Extension:
cd extension
npm install
npm run build
In Chrome: open chrome://extensions, enable Developer mode, click Load unpacked, and select extension/dist/. Copy the extension ID Chrome assigns and paste it into ALLOWED_ORIGINS in your .env, then restart uvicorn.
Log in once: visit http://127.0.0.1:8000/login, complete OAuth.
While the Spotify app is in Development Mode, only accounts you've added under User Management in the Spotify Developer dashboard can log in.
The user flow. Every time you open a playlist page, the extension injects a draggable cat mascot into Spotify's own UI . Clicking the cat triggers the backend to analyze the playlist. When the analysis returns, the cat morphs depending on how much of the playlist "fits together." A second click opens a card popup. Press ✓ to queue a removal; press ✕ to skip that suggestion. "Apply changes" commits all queued removals to Spotify in one batch via the Web API.
The detection layer. Every analysis runs two kinds of detector on the playlist's track metadata:
Deterministic heuristics (in services/suggestions.py) (straightforward statistical rules):
- Duplicates — same track ID appears more than once
- Era — release-year outliers (mean ± 1.5σ)
- Explicit — parental-advisory tracks in an otherwise clean playlist
- Artist mix — one artist dominates ≥40% of the playlist
- Style — genre outliers (requires Spotify's
/artistsendpoint; silently skipped for apps in Development Mode)
ML-based semantic detection (in services/ml_scoring.py) (catches "vibe" outliiers). For every track we build a natural-language description like:
Bohemian Rhapsody by Queen. From the album A Night at the Opera. Released in 1975.
Genre: glam rock, classic rock, symphonic rock. Clean.
Each description is embedded into a 384-dimensional vector using all-MiniLM-L6-v2, a pretrained sentence-transformer model from HuggingFace. We compute the playlist's centroid (the average vector across all tracks) and rank each track by cosine similarity to it. The bottom 15% — the tracks furthest from the playlist's overall "meaning" — surface as AI · Vibe suggestions.
This is unsupervised so no user data, no training loop, no personalization.