Lineupify

MCP serverDev tools

Spotify playlists from a festival lineup, a genre, a song, a playlist or a blend. Own client ID.

Unavailable. This server has no hosted endpoint yet, so ahel can't serve it.

Connect ahel once, and every AI you use reads what you have installed.

From the project's README

As published by shreeshman/lineupify in README.md.

Lineupify is an MCP server for Claude Desktop, Claude Code, Cursor and any other MCP host. Paste a festival poster, describe a mood, name an artist or a song you like, point at a playlist, or blend two people's playlists. Lineupify finds the artists, picks their most popular songs, matches them exactly (by ISRC) and builds a draft you can review and edit before anything is published to Spotify. Everything runs on your machine; there is no Lineupify server and no telemetry.

SpotifyDeezer mode
What you needA Spotify Premium account and a free Spotify developer app (2 minutes, no secret)Nothing. No account, no key
What you getPlaylists created in your Spotify account, plus reading and comparing your own playlists and libraryDrafts with Deezer links that you export and import anywhere (Deezer, Apple Music, YouTube Music)
Why the differenceSpotify only lets a new app serve its owner, who must have PremiumDeezer's public API is keyless, but Deezer no longer issues write credentials

Both need Node.js 20 or newer. Package: lineupify-mcp on npm.

Contents

  • Why
  • Quick start
    • Option A: let your assistant install it
    • Option B: guided setup in a terminal
    • Option C: one click for Claude Desktop
    • No Spotify, or no Premium? Deezer mode
    • Spotify without Premium: borrow a friend's app
  • What a conversation looks like
  • How it works
  • Reference — full tables in docs/reference.md
  • Privacy, data and terms
  • Limits and known issues
  • Development
  • Credits
  • License

Why

Streaming apps are good at playing music and bad at letting you say what you want.

  • The daily mixes are not what you are in the mood for. They are built from what you played, not from what you want to play next.
  • Shuffle keeps serving the same songs and the same artists. You want new songs by the artists you already love, not the same twenty again.
  • You can describe a feeling but cannot find the genre. "Rainy Sunday jazz for cooking" is not a category in any app.
  • Adding songs to a playlist takes minutes of searching when it should take one sentence.
  • A festival lineup is forty names and you know six. Preparing for it by hand takes an evening.
  • Blend only blends profiles. You want to compare two playlists, see what they share and why, and get a mix both people will actually like.
  • The algorithm cannot explain itself. You want to see which artist a song came from and why it was picked, then change it.
  • Your playlist is on Spotify but your friend is not. You want the list as a file they can use anywhere.

Lineupify answers each of these with a draft you can see, a reason for every track, and a playlist that ends up in your own account.

Quick start

Pick one of the three ways to install. All of them end with the same server registered in your host; the Spotify app is the only step nobody can automate, because it is created in your Spotify account.

Option A: let your assistant install it

If your assistant can run terminal commands (Claude Code, Cursor, and similar), paste this into a chat and follow along:

Install the Lineupify MCP server for me and guide me through it. It is the npm package lineupify-mcp (https://www.npmjs.com/package/lineupify-mcp); read its README at https://github.com/SHREESHMAN/lineupify first. Ask me whether I have a Spotify Premium account. If yes, walk me through creating a Spotify app at https://developer.spotify.com/dashboard with the Redirect URI http://127.0.0.1:8765/callback, ask me for the Client ID, then run npx -y lineupify-mcp setup --client-id <id> and npx -y lineupify-mcp auth, and tell me when to approve the login in my browser. If no, skip Spotify: Deezer mode needs nothing. Then run npx -y lineupify-mcp install --claude-code (or --cursor / --claude-desktop, whichever host you are running in), then npx -y lineupify-mcp doctor, show me the result, and tell me what to say next. On Windows run npx through cmd /c.

If Lineupify is already registered but Spotify is not connected (the one-click route, or a hand-written config), paste this instead:

Call Lineupify's status tool. If Spotify is not connected, call connect with my Client ID PASTE_CLIENT_ID_HERE, tell me to approve the login in the browser, then call status again to confirm.

Option B: guided setup in a terminal

  1. Create a Spotify app (2 minutes; skip for Deezer mode). Go to https://developer.spotify.com/dashboard, click Create app, tick Web API, set the Redirect URI to exactly http://127.0.0.1:8765/callback, save, then copy the Client ID from the app's Settings page. No client secret is needed. Full walkthrough with every field: docs/setup-spotify.md.

  2. Run the guided setup:

    npx -y lineupify-mcp init
    

    It takes the Client ID, logs you in through your browser, adds Lineupify to Claude Desktop, Claude Code or Cursor (whichever it finds), and runs a health check. Every step can be skipped. Restart your host afterwards.

  3. Ask for a playlist. Any of these work:

    • "Make me a playlist for this lineup" (paste the poster text or attach the image)
    • "Rainy Sunday jazz for cooking, about an hour, nothing explicit"
    • "Artists like Khruangbin, two songs each"
    • "Songs like Ritviz – Udd Gaye, other artists only"
    • "New songs from my favourite artists that I have not liked yet"
    • "What does my friend's playlist have in common with mine? Then make us a mix."

Option C: one click for Claude Desktop

Download lineupify-<version>.mcpb from the releases page and double-click it (or drag it onto Claude Desktop). Paste your Client ID into the form, or leave it empty for Deezer mode. Node.js 20 or newer must still be installed. Then say "connect Lineupify to Spotify" in a chat.

Other hosts, the config-file route, and running two hosts at once: docs/hosts.md.

No Spotify, or no Premium? Deezer mode

Skip the Spotify app entirely: add Lineupify to your host and ask for a playlist. With no Spotify login, drafts build on Deezer automatically (or say "use Deezer"; the option is provider: "deezer"). Deezer's public API is keyless, so there is nothing to create, paste or approve.

What works in Deezer mode: every seed except your own Spotify taste, every filter, reading, analysing, comparing and merging Deezer playlists and drafts, editing, and all exports. What does not: publishing into an account. Deezer stopped issuing API credentials to new apps in 2025, so no tool can write to a Deezer account today. If Deezer reopens its API, publishing will be added.

Getting a Deezer draft into your Deezer (or Apple Music, YouTube Music) account takes one paste:

  1. Ask for the export: "export this draft as links" (export_draft, format: "links"; "text" gives "Artist - Title" lines instead).
  2. Open TuneMyMusic or Soundiiz, choose import from text (TuneMyMusic: Let's start → Upload text; Soundiiz: Import playlist → From text), and paste the list.
  3. Pick the destination service and confirm. The transfer tool logs into your account itself; nothing about your account ever passes through Lineupify.

Both tools have free tiers that cover a normal playlist.

Spotify without Premium: borrow a friend's app

Spotify's Premium rule applies to the person who owns the developer app, not to everyone who uses it. An owner can add up to four other people by email under User Management in the dashboard (five users per app in total), and those people log in with their own accounts, free ones included. So if someone you know has Premium:

  1. They create the app as in Option B step 1 and add your Spotify account email under User Management.
  2. They give you the Client ID (it is not a secret; the secret is never used).
  3. You run npx -y lineupify-mcp init with that Client ID and log in as yourself. Your tokens stay on your machine; the owner never sees your account.

Two limits: an app serves five people at most, and the owner's daily API quota is shared across all of them and all of the owner's apps. Handing the Client ID to someone who is not on the User Management list does nothing; their login fails with a 403. Fine for friends and family; not a way to serve strangers, which Spotify's terms also rule out. Details: docs/setup-spotify.md.

What a conversation looks like

A festival

You: Make me a playlist for this lineup.

SUNFALL FESTIVAL 2026 · 14-16 AUGUST
FRED AGAIN..   CHARLI XCX
Jamie xx · Four Tet · Overmono
Yaeji  Nia Archives  Barry Can't Swim  DJ Fluffhead
TICKETS ON SALE NOW

The assistant calls parse_lineup, which returns nine artists with tiers and drops the dates and ticket line, then create_draft with lineup: "Sunfall 2026". The draft comes back within about 15 seconds; a big lineup keeps building in the background:

Draft d_7k2mq "Sunfall 2026 · Lineupify"  rev 1  status ready  provider spotify  spotify: Alex
Artists 9 (resolved 8 · unresolved 1)
Tracks 27 · 1h42m · explicit 6 · via isrc 25 / text 2 · sources dz 27 / lfm 0 / sp 0
Tiers headliner 2×5 · sub 3×3 · undercard 4×2 · order interleave · private
Not found on Deezer or Spotify (1): DJ Fluffhead
Next: get_draft view=tracks to review, get_draft view=unresolved for misses, edit_draft to change, create_playlist with confirm: true to publish.

You: Show me the tracks.

t_4k2p  #1   Fred again.. – Marea (we've lost dancing)  4:52  dz/isrc  2021
t_c81z  #2   Charli xcx – Von dutch  2:44  dz/isrc [E]  2024
t_m0r3  #3   Jamie xx – Gosh  4:50  dz/isrc  2015
t_9x1c  #4   Four Tet – Baby  3:47  dz/isrc  2020
…

You: Drop the Four Tet track "Baby", forget DJ Fluffhead, and publish it.

edit_draft removes the track and excludes the artist; create_playlist returns the link:

Created playlist "Sunfall 2026 · Lineupify" with 26 tracks (1h38m).
URL: https://open.spotify.com/playlist/3cEYpjA9oz9GiPac4AsH4n

Later edits go through edit_draft followed by update_playlist, which replaces the playlist contents in place.

A mood

You: Rainy Sunday jazz for cooking, about an hour, nothing explicit.

The assistant proposes fitting artists itself, adds a genre seed with the same words so the list is not only its own guess, and calls create_draft with maxDurationMin: 60 and excludeExplicit: true:

Draft d_r47h8 "Rainy Sunday jazz · Lineupify"  rev 1  status ready
Seed genre "rainy sunday jazz" → 7 artists (Deezer playlists: Jazz for a Rainy Sunday Morning, a jazz Sunday in the rain, …)
Filters: clean only
Artists 10 (resolved 10 · unresolved 0)
Tracks 10 · 52:10 · explicit 0 · via isrc 10 / text 0

Two people

You: Compare my "6626" playlist with my listening history, then make a mix we would both like without anything that is already on it.

compare_playlists explains the overlap in numbers the assistant turns into words:

Compared 2 sides: 6626 (64 tracks, 52 artists) · your listening history (0 tracks, 210 artists)
Shared by all — artists (18): Mitski, My Chemical Romance, Linkin Park, Olivia Rodrigo, …
6626 vs your listening history: artist overlap 7% (18 shared, 0 identical tracks)
Only in 6626 (34): Camila Cabello, Sara Kays, Prelow, …

Then create_draft with seeds: [{ type: "blend", sources: ["6626", "me"] }] and excludeTracksFrom: ["6626"]:

Seed blend 6626 + me → 10 artists (99 artists on 2+ sides, 10 of the 10 picked on every side)
Excluded tracks from: 6626 (64 tracks)
Tracks 10 · 33:57 · explicit 1

How it works

Every request becomes an artist list, and every artist list goes through the same pipeline. Nothing touches Spotify until you publish.

flowchart LR
    subgraph give[What you give]
        A[Festival poster or lineup text]
        B[A description or a mood]
        C[An artist or a song you like]
        D[A country or the charts]
        E[A playlist link or your library]
        F[Two or more people's playlists]
    end
    subgraph engine[Lineupify]
        G[Artists]
        H[Most popular songs per artist]
        I[Matched by ISRC]
        J[Filters, dedupe, order]
        K[Draft you can read and edit]
    end
    L[(Your Spotify account)]
    M[CSV / M3U / links / text]
    A --> G
    B --> G
    C --> G
    D --> G
    E --> G
    F --> G
    G --> H --> I --> J --> K
    K -->|create_playlist| L
    K -->|export_draft| M
flowchart TD
    A[artists and/or seeds] --> B[Expand seeds in the background<br/>genre · similar_to · similar_songs · chart · country · playlist · taste · blend]
    B --> C[Resolve each artist<br/>Deezer → Last.fm → Spotify]
    C --> D[Ranked candidate songs<br/>lead tracks first, featured next, live/remix last]
    D --> E[Match by ISRC<br/>text search as fallback]
    E --> F{Filters}
    F -->|yearRange · bpmRange · explicit · excludeTracksFrom| G[Dedupe by URI, ISRC and title+artist]
    G --> H[Per-tier counts and maxTracks cap]
    H --> I[skipCovers · maxDurationMin · order]
    I --> J[(Draft on disk<br/>revisions, undo)]
    J -->|get_draft / edit_draft| J
    J -->|create_playlist| K[Spotify playlist]
    J -->|export_draft| L[CSV · M3U · links · text · Markdown]

Why Deezer and Last.fm for ranking? Spotify no longer exposes top tracks, recommendations, related artists, genres or audio features to new apps. Deezer's public API is keyless and gives popularity, related artists, tempo and playlists; Last.fm (optional key) adds tags, similar artists, similar songs and per-country charts; ListenBrainz (open data) adds song-level neighbours. Spotify is where the playlist ends up, and ISRC codes make the match exact.

A draft is a small state machine, checkpointed to disk after every artist, so a killed process resumes where it stopped:

stateDiagram-v2
    [*] --> building: create_draft
    building --> ready: all artists fetched
    building --> paused: quota / token / network
    building --> failed: nothing to build
    paused --> building: get_draft
    ready --> building: edit_draft asks for more tracks
    ready --> published: create_playlist
    published --> published: edit_draft + update_playlist

Reference

Every tool, every edit_draft op, every seed, every create_draft option, the CLI and config.json live in docs/reference.md rather than here, so this page stays a page you can actually read top to bottom. Five tools cover most of what you will ask for:

ToolWhat it does
statusCall first: connection state, setup steps, drafts in progress.
create_draftBuilds a draft from artists and/or seeds (genre, mood, similar artist, a playlist, a blend).
get_draftShows a draft: summary, tracks, artists, or what could not be found.
edit_draftSwap a track, drop an artist, reorder, undo.
create_playlistPublishes a reviewed draft and returns its URL.
set_playlist_imageSets the playlist cover from a JPEG saved on your machine.

Full reference →

Privacy, data and terms

Lineupify runs on your machine with a Spotify app you created. It has no server of its own, no telemetry, and no access to your account beyond the token on your disk. SECURITY.md lists what it can and cannot do and how to report a problem.

What is stored, all under ~/.lineupify/ (or LINEUPIFY_HOME):

FileContentsLifetime
config.jsonClient ID, defaults, optional Last.fm keyuntil you change it
tokens.jsonSpotify access and refresh tokensuntil disconnect / logout; refresh tokens die after 6 months anyway
cache/artists.json, spotify-tracks.json, deezer-tracks.json, artist-genres.json, covers.jsonartist matches, track lookups, tempo, genres30-90 days
cache/playlists.jsonthe track lists of playlists you read, including your liked songs when you use library12 hours
drafts/one JSON file per draft plus up to 10 undo revisionsunpublished drafts are deleted after 30 days; published ones kept
exports/the only place export_draft writes filesuntil you delete them

tokens.json is written with mode 0600 on macOS and Linux. On Windows, where that mode means nothing, its inherited permissions are replaced with an entry for your own account only (icacls /inheritance:r /grant:r); if that fails, the file keeps your user profile's default permissions, like other CLIs' credential files.

Spotify permissions requested at login, and what needs each one:

ScopeNeeded by
playlist-modify-privatecreate_playlist, update_playlist
playlist-modify-publicthe same, when public: true
user-read-privatemarket-aware search (market=from_token), i.e. every build
user-top-read, user-follow-readcompare_taste, discoveryOnly, compare_playlists with me, taste and blend seeds, refresh_taste
playlist-read-private, playlist-read-collaborativereading your own private playlists, and playlists by name
user-library-readlibrary (liked songs) in reads, exclusions and refresh_taste
ugc-image-uploadset_playlist_image, the only tool that uploads anything; it reads the local JPEG file you name and sends it to your playlist

Lineupify never deletes or unfollows a playlist, never changes your library or follows, and creates playlists private unless you ask for public. The only overwrite is update_playlist on a playlist Lineupify created, and it refuses if that playlist changed inside Spotify unless forced.

Shortened here. Read the whole README on GitHub.

Signals

GitHub stars
1
Last commit
Sep 2026
Weekly downloads
614
Advanced
Delivery
lineupify MCP server → your ahel gateway (mcp.ahel.ai) → every connected AI client.
Catalog kind
mcp-server
Gateway key
io-github-shreeshman-lineupify
Source
github.com/shreeshman/lineupify