JamRelay
Connects AI assistants to your own Spotify account, exposing tools for Spotify search, playlist management, library access, music discovery, and playback control.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@JamRelayadd the song currently playing on Spotify to my Liked Songs"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Provider-neutral, self-hosted music automation through MCP.
Turn high-level requests into deterministic, inspectable and reversible music operations through MCP.
Get started · Documentation · MCP tools · Latest release
What is JamRelay?
JamRelay is a self-hosted, provider-neutral music automation engine that connects MCP clients to independent music-provider connections through a stateful automation layer.
JamRelay can persist local state, resolve canonical tracks and provider mappings, analyze playlists, plan mutations, preview them, snapshot state, execute bounded changes, verify the result, resume jobs after restarts, transfer playlists across providers, import/export provider-neutral playlists, and derive local personalization signals from events it actually observed.
Supported adapters are Spotify, SoundCloud, Apple Music, and YouTube Data API. They do not have identical capabilities. JamRelay also supports a valid zero-provider installation; provider connectivity is not server health.
The goal is not to make an AI client manually coordinate hundreds of Spotify API requests.
The goal is:
request
↓
analyze state
↓
build deterministic plan
↓
preview / dry run
↓
snapshot
↓
execute bounded provider operations
↓
verify
↓
record stateJamRelay handles the automation layer in between.
Related MCP server: Spotify MCP Server
Why JamRelay?
Music automation instead of API plumbing
High-level behavior lives in JamRelay rather than in an AI client's conversation context.
Examples include:
smart playlist reordering,
artist balancing and spacing,
semantic deduplication,
playlist merge/split/clone/sync,
reusable rules and recipes,
playlist personalization,
session queue planning,
recurring rotations,
durable bulk operations.
Plan before changing
Complex playlist mutations are designed around:
ANALYZE → PLAN → DRY RUN → SNAPSHOT → EXECUTE → VERIFY → RECORDSmart mutations use dry-run-first behavior where supported. JamRelay can preserve ordered playlist snapshots before a change and verify the resulting playlist afterwards.
Database-first track resolution
JamRelay does not immediately call Spotify Search for every metadata lookup.
metadata query
↓
normalize
↓
local canonical / alias lookup
├── hit → return local result
└── miss → Spotify Search → validate → persistKnown tracks can resolve locally. Ambiguous or low-confidence matches are not blindly cached.
Persistent local state
JamRelay stores durable application state in SQLite, including:
canonical tracks and aliases,
resolver attempts,
API errors and rate limits,
durable jobs,
playlist snapshots and operations,
playlist recipes,
locally observed listening events,
playlist rotations.
This is application state, not temporary chat memory.
Explainable personalization
JamRelay does not claim to know Spotify's private recommendation model or a user's complete listening history.
Personalization is derived from evidence JamRelay actually has, with observed facts kept separate from derived scores.
Core capabilities
Area | Examples |
Spotify access | Search, tracks, artists, albums, playlists, library, playback, devices |
Track resolution | DB-first lookup, aliases, ambiguity handling, alternate resolver fallback |
Playlist analysis | Health reports, duration, concentration, duplicates, repetition |
Playlist layout | Smart shuffle, artist balancing, artist/album gaps, smart insertion |
Playlist cleanup | Exact/semantic dedupe, filters, artist limits |
Playlist composition | Merge, split, clone, sync, extract, move, replace |
Safety | Dry runs, plans, snapshots, verification, restore, undo |
Automation | Rules, recipes, bulk operations, optimization |
State | SQLite persistence, migrations, diagnostics, error history |
Jobs | Durable execution, retry state, resume, cancel, commit |
History | Locally observed listening events with provenance |
Personalization | Affinity ranking, recent-play avoidance, rediscovery, deep cuts |
Sessions | Session queues, duration targets, artist spacing, smart next |
Rotations | Daily mixes, weekly rotations, persistent schedules |
The exact MCP surface is generated from the runtime registry.
See docs/tools-reference.md for the canonical tool reference.
Example: improve a playlist safely
A request such as:
Improve this playlist without changing which songs are in it. Spread artists and albums out, preview the changes first, then verify the result.
can become:
playlist health report
↓
deterministic optimization plan
↓
dry run
↓
safety snapshot
↓
apply ordering changes
↓
capture resulting state
↓
verify ordered playlist contentsThe playlist engine can preserve the original track set while changing only the layout.
Playlist automation
JamRelay's playlist engine works on normalized tracks and serializable operation plans.
Analysis
health reports
duration
artist/album concentration
adjacent-artist repetition
exact duplicate detection
conservative semantic duplicate detection
unavailable-item detection
Layout
deterministic seeded shuffle
artist and album spacing
artist balancing
artist-share limits
smart insertion
affinity ordering
Cleanup and composition
exact/semantic deduplication
typed filtering
artist removal/replacement
merge/split/clone/sync
extract and move artist tracks
duration-based trimming/extension
Automation
reusable typed rules
persistent recipes
optimization plans
bulk editing
recurring rotations
daily and weekly playlist workflows
Read more in Playlist automation.
Safety model
Spotify writes are external network operations, not one cross-request ACID transaction.
JamRelay does not pretend otherwise.
Before supported complex mutations it can preserve ordered URIs, playlist metadata, Spotify snapshot identifiers when available and operation metadata. After writes, it can verify the actual resulting playlist.
If a multi-request operation partially fails, that partial state is surfaced explicitly.
Undo applies only to supported JamRelay-managed reversible operations.
See Playlist safety, snapshots and undo.
Database-first resolution
flowchart LR
A[Metadata query] --> B[Normalize]
B --> C[Canonical track + alias lookup]
C -->|Hit| D[Return local result]
C -->|Miss| E[Spotify Search]
E --> F[Validate candidate]
F --> G[Persist canonical track + alias]
G --> DSpotify responses can passively warm canonical state. When Spotify Search is rate-limited, cached matches remain available.
An optional alternate resolver may provide candidate Spotify IDs or URLs, but JamRelay validates accepted candidates against Spotify before treating them as canonical.
See Database-first track resolution.
State database
JamRelay uses SQLite for durable local application state.
Forward-only SQL migrations are applied automatically at startup. Applied migrations are recorded with version, SHA-256 checksum, provenance and application timestamp, and are verified on future startups.
JamRelay rejects inconsistent migration histories instead of silently continuing.
The health endpoint exposes schema state:
{
"database": {
"status": "ok",
"schemaVersion": "0004_personalization_history.sql",
"expectedVersion": "0004_personalization_history.sql",
"schemaState": "current"
}
}See State Database.
Quick start
Requirements
Node.js 22.13+ or Docker
Spotify Developer application
Spotify account
callback URL you control
Some playback operations may require Spotify Premium and an active compatible device.
Clone and install
git clone https://github.com/makkiattooo/JamRelay.git
cd JamRelay
npm ciCreate .env:
cp .env.example .envPowerShell:
Copy-Item .env.example .envGenerate an encryption key:
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"Configure at minimum:
SPOTIFY_CLIENT_ID=
SPOTIFY_CLIENT_SECRET=
TOKEN_ENCRYPTION_KEY=
PUBLIC_BASE_URL=http://127.0.0.1:5267Start:
npm run devAuthorize Spotify:
http://127.0.0.1:5267/auth/providers/spotify/startCheck:
http://127.0.0.1:5267/auth/status
http://127.0.0.1:5267/healthLocal MCP endpoint:
http://127.0.0.1:5267/mcpFor remote deployments, expose the MCP endpoint through HTTPS and configure Bearer auth or MCP OAuth.
MCP clients
JamRelay uses MCP Streamable HTTP and includes setup notes for:
ChatGPT
Claude
Gemini CLI
Cursor
VS Code / Copilot
Windsurf
MCP Inspector
Automated MCP protocol tests cover the server surface. Live third-party client verification remains a manual release-owner check for each target client.
See Connect clients and MCP OAuth registration.
Authentication
JamRelay has two separate authorization boundaries:
Spotify authorization
Spotify OAuth grants JamRelay permission to operate on the connected Spotify account.
MCP client authorization
MCP auth controls which clients may access JamRelay.
Supported mechanisms include:
OAuth 2.0 Authorization Code
PKCE
static OAuth clients
multiple OAuth clients
RFC 7591 Dynamic Client Registration
public and confidential clients
optional static Bearer auth
Docker and deployment
JamRelay supports Docker and Docker Compose.
Persistent state lives under:
/dataProduction Compose deployments use the external jamrelay_data volume so recreating the application container does not destroy state.
The production container is designed around:
non-root execution,
read-only root filesystem,
dropped Linux capabilities,
no-new-privileges,writable
/tmp,explicit internal networking.
The VPS deployment workflow includes local checks, build verification, tarball upload, Compose validation, image build, controlled replacement, schema verification, health-gated rollout, public endpoint checks and rollback support.
See:
Development
npm ci
npm run devUseful checks:
npm run format
npm run format:check
npm run lint
npm run typecheck
npm test
npm run build
npm run docs:generate
npm run docs:check
npm run docs:buildFull verification:
npm run checkRelease gate:
npm run release:checkDocumentation
The VitePress documentation is the primary technical documentation.
English — canonical
Polski — high priority
Deutsch — best effort
Français — best effort
Español — best effort
Fast-changing references are generated from project sources with:
npm run docs:generateArchitecture
flowchart LR
A[MCP client] --> B[Transport + auth]
B --> C[MCP tool layer]
C --> D[Domain services]
D --> E[Playlist engine]
D --> F[Track resolver]
D --> G[Jobs]
D --> H[History + personalization]
E --> I[(SQLite State DB)]
F --> I
G --> I
H --> I
E --> J[ProviderRegistry]
F --> J
G --> J
J --> K[Provider adapters and APIs]JamRelay's MCP tools are an interface to this architecture, not the architecture itself.
See Architecture.
The multi-provider execution, synchronization and release audit is documented in Release audit.
Privacy and security
JamRelay is self-hosted. By default, state such as OAuth data, canonical track mappings, playlist snapshots, job state, local history and derived personalization signals stays inside your deployment.
Do not expose JamRelay publicly without authentication.
Keep .env, client secrets, token stores, MCP secrets, /data and database backups outside version control and public web roots.
Use HTTPS for remote deployments.
See SECURITY.md and Security documentation.
Contributing
Contributions are welcome.
Before submitting changes:
npm run checkRead:
Releases
Latest release:
JamRelay v1.3.0 — Production Hardening & Admin Console
Release notes:
See CHANGELOG.md for the complete release history.
License
JamRelay is licensed under the GNU Affero General Public License v3.0 only (AGPL-3.0-only).
See LICENSE and LICENSING.md.
Disclaimer
JamRelay is an independent open-source project.
It is not affiliated with, endorsed by, sponsored by, or an official product of Spotify, OpenAI, Anthropic, Google, Microsoft, Cursor, Windsurf, or any other platform or vendor referenced by the project.
Spotify and other product names and trademarks belong to their respective owners.
Music automation you can run yourself.
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server for progressive tool usage at any scale (see https://klavis.ai)
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables remote interaction with Spotify through the Model Context Protocol, allowing users to search tracks, control playback, and manage playlists with per-user OAuth authentication. It is hosted on Cloudflare Workers and supports remote MCP over HTTP for compatible clients.2-
- AlicenseAqualityBmaintenanceMCP server for the Spotify Web API — gives Claude and other AI assistants tools to search music, control playback, manage playlists, library, and podcasts.47MIT
- FlicenseNot gradedqualityDmaintenanceA FastMCP server that exposes Spotify's catalog and user context as tools for Claude, enabling track search, audio features, artist discography, recommendations, currently playing, and playlist creation.-
- AlicenseNot gradedqualityDmaintenanceA robust MCP server that connects Spotify playback, search, and library management to LLM agents via tools, with dual authentication and reliable token handling.2MIT