MCPcopy
hub / github.com/Nezreka/SoulSync

github.com/Nezreka/SoulSync @2.8.4 sqlite

repository ↗ · DeepWiki ↗ · release 2.8.4 ↗
21,363 symbols 87,779 edges 1,174 files 7,587 documented · 36%
README

SoulSync Logo

SoulSync - Intelligent Music Discovery & Automation Platform

Spotify-quality music discovery for self-hosted libraries. Automates downloads, curates playlists, monitors artists, and organizes your collection with zero manual effort.

IMPORTANT: Configure file sharing in slskd to avoid Soulseek bans. Set up shared folders at http://localhost:5030/shares.

Community: Discord | Website: ssync.net | Support: GitHub Issues | Donate: Ko-fi


What It Does

SoulSync bridges streaming services to your music library with automated discovery:

  1. Monitors artists → Automatically detects new releases from your watchlist
  2. Generates playlists → Release Radar, Discovery Weekly, Seasonal, Decade/Genre mixes, Cache-powered discovery
  3. Downloads missing tracks → From Soulseek, Deezer, Tidal, Qobuz, HiFi, YouTube, or any combination via Hybrid mode
  4. Verifies downloads → AcoustID fingerprinting for all download sources
  5. Enriches metadata → 10 enrichment workers (Spotify, MusicBrainz, iTunes, Deezer, Discogs, AudioDB, Last.fm, Genius, Tidal, Qobuz)
  6. Tags consistently → Picard-style MusicBrainz release preflight ensures all album tracks get the same release ID
  7. Organizes files → Custom templates for clean folder structures
  8. Manages library → Plex, Jellyfin, Navidrome, or SoulSync Standalone (no media server required)
  9. Scrobbles plays → Automatic scrobbling to Last.fm and ListenBrainz from your media server

Key Features

SoulSync Interface

Discovery Engine

Release Radar — New tracks from watchlist artists, personalized by listening history

Discovery Weekly — 50 tracks from similar artists with serendipity weighting

Seasonal Playlists — Halloween, Christmas, Valentine's, Summer, Spring, Autumn (hemisphere-aware)

Personalized Playlists (12+ types) - Recently Added, Top Tracks, Forgotten Favorites - Decade Playlists (1960s-2020s), Genre Playlists (15+ categories) - Because You Listen To, Daily Mixes, Hidden Gems, Popular Picks, Discovery Shuffle, Familiar Favorites - Custom Playlist Builder (1-5 seed artists → similar artists → random albums → shuffled tracks)

Cache-Powered Discovery (zero API calls) - Undiscovered Albums — albums by your most-played artists that aren't in your library - New In Your Genres — recently released albums matching your top genres - From Your Labels — popular albums on labels already in your library - Deep Cuts — low-popularity tracks from artists you listen to - Genre Explorer — genre landscape pills with artist counts, tap for Genre Deep Dive modal

ListenBrainz — Import recommendation and community playlists

Beatport — Full electronic music integration with genre browser (39+ genres)

Multi-Source Downloads

6 Download Sources: Soulseek, Deezer, Tidal, Qobuz, HiFi, YouTube — use any single source or Hybrid mode with drag-to-reorder priority

Deezer Downloads — ARL token authentication, FLAC lossless / MP3 320 / MP3 128 with automatic quality fallback and Blowfish decryption

Tidal Downloads — Device-flow OAuth, quality tiers from AAC 96kbps to FLAC 24-bit/96kHz Hi-Res

Qobuz Downloads — Email/password auth, quality up to Hi-Res Max (FLAC 24-bit/192kHz)

HiFi Downloads — Free lossless via public API instances, no account required

Soulseek — FLAC priority with quality profiles, peer quality scoring, source reuse for album consistency

YouTube — Audio extraction with cookie-based bot detection bypass

Hybrid Mode — Enable any combination of sources, drag to set priority order, automatic fallback chain

Playlist Sources: Spotify, Tidal, YouTube, Deezer, Beatport charts, ListenBrainz, Spotify Link (no API needed)

Post-Download - Lossy copy creation: MP3, Opus, AAC with configurable bitrate (Opus capped at 256kbps) - Hi-Res FLAC downsampling to 16-bit/44.1kHz CD quality - Blasphemy Mode — delete original FLAC after conversion - Synchronized lyrics (LRC) via LRClib - ReplayGain analysis — optional track-level loudness tagging via ffmpeg, runs before lossy copy so both files get tagged - Picard-style album consistency — pre-flight MusicBrainz release lookup ensures all tracks get the same release ID

Listening Stats & Scrobbling

Listening Stats Page — Full dashboard with Chart.js visualizations - Overview cards: total plays, listening time, unique artists/albums/tracks - Timeline bar chart, genre breakdown donut with legend - Top artists visual bubbles, top albums and tracks with play buttons and cover art - Library health: format breakdown bar, enrichment coverage rings, database storage chart - Time range filters: 7 days, 30 days, 12 months, all time

Scrobbling — Automatic Last.fm and ListenBrainz scrobbling from Plex, Jellyfin, or Navidrome

Audio Verification

AcoustID Fingerprinting (optional) — Verifies downloaded files match expected tracks - Runs for all download sources (Soulseek, Tidal, Qobuz, HiFi, Deezer, YouTube) - Catches wrong versions (live, remix, cover) even from streaming API sources - Fail-open design: verification errors never block downloads

AcoustID API key

AcoustID verification is opt-in. To enable it, request a free API key at https://acoustid.org/new-application and paste it into Settings → AcoustID. Without a key, downloads still complete but the verification step is skipped silently.

If a track was previously tagged by AcoustID but the retag action in the AcoustID Scanner no longer changes anything, see issue #704 — the most common cause is that the file already carries a MUSICBRAINZ_TRACKID tag, which the retag step uses as a short-circuit and therefore never overwrites. Removing the cached MUSICBRAINZ_TRACKID (and the ACOUSTID_ID if present) from the file restores the retag.

Metadata & Enrichment

10 Background Enrichment Workers: Spotify, MusicBrainz, iTunes, Deezer, Discogs, AudioDB, Last.fm, Genius, Tidal, Qobuz - Each worker independently processes artists, albums, and tracks - Pause/resume controls on dashboard, auto-pause during database scans - Error items don't auto-retry in infinite loops (fixed in v2.1)

Multi-Source Metadata - Primary source selectable: Spotify, iTunes/Apple Music, Deezer, or Discogs - Spotify no longer auto-overrides — user chooses their preferred source in Settings - Spotify auth still enables playlists, followed artists, and enrichment - MusicBrainz enrichment with Picard-style album consistency

Hydrabase (optional P2P metadata network) — replaces iTunes as the metadata source when connected. Federated lookup with community-matched results, falls back automatically if disconnected. Dev-mode feature, enable in Settings → Connections.

Genre Whitelist — filter junk genre tags (artist names, radio show names, playlist names) from all 10 enrichment sources. 272 curated default genres, fully customizable. Off by default for backward compatibility.

Post-Processing Tag Embedding - Granular per-service tag toggles (18+ MusicBrainz tags, Spotify/iTunes/Deezer IDs, AudioDB mood/style, Tidal/Qobuz ISRCs, Last.fm tags, Genius URLs) - Multi-artist tagging options: configurable separator (comma/semicolon/slash), multi-value ARTISTS tag for Navidrome/Jellyfin multi-artist linking, optional "move featured artists to title" mode - Album art embedding, cover.jpg download - Spotify rate limit protection across all API calls

Advanced Matching Engine

  • Version-aware matching: strictly rejects remixes when you want the original (and vice versa)
  • Unicode and accent handling (KoЯn, Bjork, A$AP Rocky)
  • Fuzzy matching with weighted confidence scoring (title, artist, duration)
  • Album variation detection (Deluxe, Remastered, Taylor's Version, etc.)
  • Streaming source match validation: same confidence scoring applied to Tidal/Qobuz/HiFi/Deezer results as Soulseek
  • Short title protection: prevents "Love" from matching "Loveless"

Automation

Automation Engine — Visual drag-and-drop builder for custom workflows - Triggers: Schedule, Daily/Weekly Time, Track Downloaded, Batch Complete, Playlist Changed, Discovery Complete, Signal Received, Library Scan Complete, Watchlist Match, Wishlist Item Added, and more - Actions: Process Wishlist, Scan Watchlist, Refresh Mirrored, Discover Playlist, Sync Playlist, Scan Library, Database Update, Quality Scan, Full Cleanup, and 10+ more - Then Actions (up to 3 per automation): Fire Signal (chain to other automations), Discord/Telegram/Pushbullet notifications, audible chimes - Signal Chains — One automation fires signal:foo, another listens for it. Cycle detection + chain depth limit + cooldown prevent runaway chains. - Playlist Pipeline — Single automation for full playlist lifecycle: refresh → discover → sync → download missing. No manual signal wiring. - Pipelines — Pre-built one-click deployments (New Music, Nightly Operations, Full Library Maintenance, etc.) that install a linked group of automations at once - Automation Groups — Drag-and-drop organization, bulk enable/disable, rename, right-click context menus

Watchlist — Monitor unlimited artists with per-artist configuration - Release type filters: Albums, EPs, Singles - Content filters: Live, Remixes, Acoustic, Compilations - Auto-discover similar artists, periodic scanning

Wishlist — Failed downloads automatically queued for retry with auto-processing

Mirrored Playlists — Mirror from Spotify, Tidal, YouTube, Deezer and keep synced - Auto-refresh detects source changes via URL/ID tracking in playlist metadata - Discovery pipeline matches source tracks to user's primary metadata source (Spotify/iTunes/Deezer/Discogs) - Auto Wing It fallback — tracks that fail all metadata APIs get stub metadata from the raw source title and flow through the normal download pipeline anyway - Followed Spotify playlists that hit 403 errors fall back to public embed scraper - Unmatch button on found tracks with DB persistence for mirrored playlists

Local Profiles — Multiple configuration profiles with isolated settings, watchlists, and playlists

Library Management

Dashboard — Service status, system stats, activity feed, enrichment worker controls - Unified glass UI design across all tool cards, service cards, and stat cards

Library Page — Artist grid with staggered card animations, per-artist enrichment coverage rings - Artist Radio button — play random track with auto-queue radio mode - Play buttons on Last.fm top tracks sidebar

Enhanced Library Manager — Toggle between Standard and Enhanced views - Inline metadata editing, per-service manual matching - Write Tags to File (MP3/FLAC/OGG/M4A), tag preview with diff - Server sync after tag writes (Plex, Jellyfin, Navidrome) - Bulk operations, sortable columns, multi-disc support

Library Maintenance — 10+ automated repair jobs - Track Number, Dead Files, Duplicates, Metadata Gaps, Album Completeness, Missing Cover Art, AcoustID Scanner, Orphan Files, Fake Lossless, Library Reorganize, Lossy Converter, MBID Mismatch, Album Tag Consistency, Live/Commentary Cleaner - Enrichment workers auto-pause during database scans - One-click Fix All with findings dashboard

Database Storage Visualization — Donut chart showing per-table storage breakdown

Live Log Viewer — Real-time terminal-style log viewer on Settings → Logs. Color-coded levels (DEBUG/INFO/WARNING/ERROR), live filter + search, switch between log files (app, post-processing, AcoustID, source reuse). Auto-scroll, copy, clear. Updates via WebSocket every 0.5s.

Import System — Tag-first matching, auto-grouped album cards, staging folder workflow - Auto-Import worker: recursive scan, single file support, AcoustID fingerprinting fallback - Confidence-gated: 90%+ auto-imports, 70-90% queued for review

SoulSync Standalone Mode — Use SoulSync without Plex, Jellyfin, or Navidrome - Downloads and imports write directly to the library database - Filesystem scanner for incremental and deep scan of Transfer folder - Pre-populated enrichment IDs from download context (Spotify, Deezer, MusicBrainz) - Select in Settings → Connections → Standalone

Template Organization$albumartist/$album/$track - $title and 10+ variables

Built-in Media Player

  • Stream tracks from your library with queue system
  • Now Playing modal with album art ambient glow and Web Audio visualizer
  • Smart Radio mode — auto-queue similar tracks by genre, mood, and style
  • Repeat modes, shuffle, keyboard shortcuts, Media Session API

Mobile Responsive

  • Comprehensive mobile layouts for Stats, Automations, Hydrabase, Issues, Help pages
  • Artist hero section, enhanced library track table with bottom sheet action popover
  • Enrichment rings, filter bars, and discover cards all adapt to narrow screens

Installation

Docker (Recommended)

curl -O https://raw.githubusercontent.com/Nezreka/SoulSync/main/docker-compose.yml
docker-compose up -d
# Access at http://localhost:8008

Release Channels

SoulSync publishes two Docker image tracks so you can choose your level of stability.

Stable — :latest (recommended for most users). Hand-promoted from the dev branch to main when a batch of changes is ready for release. Published to Docker Hub. Your docker-compose.yml pulls this by default — no changes needed.

docker pull boulderbadgedad/soulsync:latest

Nightly — :dev. Rebuilt every night from the dev branch (and on every push to dev). Published to GitHub Container Registry. Gets new features and bug fixes before they reach :latest, at the cost of occasional instability as changes settl

Extension points exported contracts — how you extend this code

FileRoutesByFullPath (Interface)
(no doc)
webui/src/routeTree.gen.ts
FileRoutesByTo (Interface)
(no doc)
webui/src/routeTree.gen.ts
FileRoutesById (Interface)
(no doc)
webui/src/routeTree.gen.ts
FileRouteTypes (Interface)
(no doc)
webui/src/routeTree.gen.ts
RootRouteChildren (Interface)
(no doc)
webui/src/routeTree.gen.ts

Core symbols most depended-on inside this repo

get
called by 4069
core/image_cache.py
get
called by 2595
core/imports/paths.py
get
called by 1303
core/download_plugins/registry.py
showToast
called by 1274
webui/static/downloads.js
json
called by 1031
tools/t2tunes_probe.py
get
called by 869
core/metadata/common.py
remove
called by 764
core/torrent_clients/aria2.py
replace
called by 689
core/streaming/state.py

Shape

Function 13,047
Method 6,048
Class 1,341
Route 849
Interface 78

Languages

Python85%
TypeScript15%

Modules by API surface

web_server.py1,863 symbols
database/music_database.py452 symbols
webui/static/discover.js379 symbols
webui/static/library.js239 symbols
webui/static/settings.js216 symbols
webui/static/wishlist-tools.js208 symbols
webui/static/sync-services.js200 symbols
webui/static/downloads.js153 symbols
webui/static/stats-automations.js145 symbols
webui/static/pages-extra.js132 symbols
webui/static/init.js121 symbols
webui/static/media-player.js120 symbols

Dependencies from manifests, versioned

@base-ui/react1.4.1 · 1×
@playwright/test1.59.1 · 1×
@tanstack/react-form1.29.1 · 1×
@tanstack/react-query5.100.5 · 1×
@tanstack/react-router1.168.24 · 1×
@tanstack/router-plugin1.167.27 · 1×
@testing-library/react16.3.2 · 1×
@types/node25.6.0 · 1×
@types/react19.2.14 · 1×
@types/react-dom19.2.3 · 1×
@vitejs/plugin-react6.0.1 · 1×

For agents

$ claude mcp add SoulSync \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact