Local-first music discovery CLI inspired by Prawo Mamonia.
Project description
Mamonia
A music discovery CLI tool with an intuitive interface that keeps it local. Inspired by Engineer Mamoń's Principle / Prawo inżyniera Mamonia.
It starts from playlists and libraries you already like, builds a reusable profile of your taste, then explores artist networks and music databases to find fresh releases you might dig. It remembers what it's already recommended so you don't get the same suggestions twice. Never ever.
Think of it as an extension of Spotify's algorithm - instead of a black box, influenced by $, doing its thing, Mamonia walks you through the connections between artists and pulls recommendations from MusicBrainz, Last.fm, ListenBrainz, and Deezer when useful. Spotify's just there acting as a catalog and to help fill in metadata gaps.
Current Features
- Guided interactive menu: run
mamonia --helpto see all commands, or run baremamoniafor the guided interactive menu. - Guided localization with English and Polish locale files, plus a saved language preference for the menu flow.
- Guided profile reuse decisions based on real playlist delta and enrichment completeness.
- Durable SQLite artist/track enrichment reused across runs and saved profiles.
- Guided library maintenance for heard releases, cache management, saved profile backup/export/import, and Spotify enrichment refresh.
- Supported inputs:
- preferred: Spotify playlist URL / ID or TuneMyMusic-style
.csv, - also viable: Tidal playlist URL/ID or a simple
.txt.
- preferred: Spotify playlist URL / ID or TuneMyMusic-style
- Outputs: TuneMyMusic-style
.csv, plain.txt, and JSON. - Private Spotify playlist creation as the default guided output, with a local CSV backup always written alongside it. Spotify open-URL link-back included in exports when Spotify data is present.
- Reusable source profiles keyed by playlist ID or order-independent text/CSV track-set hash.
- Delta updates for changed playlists: Mamonia detects additions/removals, asks before updating, and reuses existing data.
- Global memory mode to exclude known tracks from every saved profile, not only the active source.
- Input playlist releases are automatically marked as heard before discovery begins, preventing recommendations from the user's existing collection.
- Permanent release-level heard list; successful exports automatically mark releases as heard.
- Mandatory discovery progress with one updating Rich/ASCII block in interactive terminals and compact fallback lines in redirected output.
- Dry-run previews that do not write exports, mark heard releases, or create playlists.
- Provider-aware rate-limit warnings and
mamonia diagnosefor local state, cache stats, provider TTLs, and credential checks. - SQLite API cache for provider data, including normalized cache keys, provider-specific TTLs,
--force-refresh, Spotify artist/album/tracklist lookups, and negative Spotify misses. - Variant-aware duplicate and heard matching for deluxe/remaster/regional/anniversary-style releases when stable IDs are missing.
- Cache-first Spotify track resolution with MusicBrainz tracklist fallback, Spotify track backfill, and conservative representative-track fallback.
- Hardened Spotify auth and request handling: PKCE for playlist read/write, client credentials for catalog lookups, scope-specific token caches, bounded retry for required playlist operations, and clearer auth/scope/market/access error messages.
- Discovery scoring improvements including serendipity weighting,
--discovery-mode, and label-affinity candidates from MusicBrainz. - JSON explainability fields that summarize candidate source, provider evidence, filter/fallback context, and tracklist derivation.
- CSV/JSON track diagnostics including
Spotify URI,Spotify URL,Spotify Attribution,Resolution source, andResolution note. - Tidal feasibility diagnostics in
mamonia diagnose, plus experimental native Tidal playlist creation (mamonia tidal-playlists,mamonia tidal-smoke).
Human Logic Proposal Pipeline
- Tier-driven discovery (Tier 1–4): seed artists → MusicBrainz collaborators → ListenBrainz similarity → Last.fm similarity.
- Structured recommendation explanations (seed connections, confidence, matching tags).
- Balanced v2 selection defaults to a high/medium/low confidence mix with diversity pressure;
top_firstremains available for strict score ordering. - Optional v2 controls can penalize artists with many recent EPs/singles and deterministically shuffle whole release recommendations.
- Scoring with multi-seed diminishing returns (100%/70%/40%/20%) and modifiers for reissues, uncertainty, and tag-only matches.
- Track enrichment pipeline (Spotify → MusicBrainz → ISRC fallback via Tidal/Deezer).
- Enrichment phase separation:
- discovery-time candidate browsing uses lightweight enrichment only (MusicBrainz + ISRC fallback),
- full enrichment (including Spotify lookup/backfill/recovery) runs only after final release candidates are selected.
- Cross-recommendation track deduplication: ISRC and Spotify ID exact matches removed automatically; borderline fuzzy matches (50–74%) presented for interactive review; the more-complete track absorbs metadata from the duplicate before discard.
Mamonia deliberately does not use Spotify Audio Features, Audio Analysis, Recommendations, or Related Artists.
How It Works: The Simple Version
Building your taste profile:
You give Mamonia a Spotify playlist, Tidal playlist, or a simple text/CSV file of songs you like. Mamonia reads all the artists and looks them up in four music databases:
- Spotify — what else are they famous for
- MusicBrainz — who do they collaborate with, which bands are related
- Last.fm — what tags do listeners use, who else listens to them
- ListenBrainz — how many listeners share taste (which ones also listen to other artists)
All this info gets stored locally in a file called a "taste profile" — essentially a map that says "you like these artists, they're connected to these other artists, they make music tagged as rock/electronic/etc., and they've worked with these collaborators."
Finding recommendations (default mode):
When you ask for recommendations, Mamonia:
-
Expands your network — starts with your seed artists and follows the connections: "if you like Massive Attack, you might like their collaborators (Ghostpoet) or the artists they're similar to (Portishead)."
-
Fetches releases — looks up new albums/EPs from all those connected artists in MusicBrainz (the most comprehensive open music database). When
--use-streaming-providersis enabled and MusicBrainz lacks results, Deezer and Tidal are queried as a fallback; independent execution ensures one provider's failure does not suppress the other, and corroborated releases are marked for higher confidence. -
Filters — removes old stuff you asked for (e.g., last 6 months), removes albums already in your heard list, removes bad matches.
-
Scores — ranks remaining albums by how many of your seed artists are connected to them. An album by Ghostpoet scores high because Ghostpoet worked with Massive Attack (one of your seeds). A random artist with the same genre scores lower.
-
Outputs — gives you the top results as a CSV/JSON/TXT file, with links to Spotify (if the tracks were found there).
Concrete example:
You have a Spotify playlist: Massive Attack, Portishead, Burial.
Mamonia learns:
- Massive Attack worked with Ghostpoet and is related to Portishead
- Portishead is similar to Burial
- All three are tagged "trip-hop" or "electronic" in Last.fm
When you ask for recommendations, Mamonia finds:
- A new Ghostpoet album (Massive Attack collaborator) → scores high
- A new album by an artist Portishead's listeners also love → scores medium
- A random trip-hop artist from ListenBrainz with no other connection → scores low and is kept to the balanced-mode wildcard quota rather than filling the list.
Result: you get the Ghostpoet album first, and the high-confidence connections, not a random artist filling space.
What makes it different from Spotify:
- Spotify's algorithm is a black box. Mamonia shows you why it picked something.
- Spotify's algorithm may prioritize what makes them money. Mamonia just walks the graph of actual artist connections.
- You keep full control — all data lives on your machine. No tracking, no streaming history leaks, no ads.
- Results are reproducible — same input, same profile, same date range = same output. No surprises due to A/B tests.
Documentation
Unified Documentation Structure
This project maintains two documentation directories with a clear hierarchy of truth:
- Source Code — The most up-to-date reference; code is canonical
docs/Documentation — Canonical documentation for all models and humans.ai/Documentation — Active compatibility mirror of canonical docs
For AI/Automation Mirrors
.ai/README.md— Entry point for Claude documentation.ai/MEMORY.md— Current project state and constraints.ai/ARCHITECTURE.md— System architecture.ai/TESTING.md— Test baseline and test file map.ai/AGENTS.md— Mirror of agent guardrails.ai/KNOWN_FAILURES.md— Recurring failure patterns
For General Users
docs/README.md— Entry point for general documentationdocs/system-context.md— Global principles and constraintsdocs/ARCHITECTURE.md— System architecture and data flowdocs/DECISIONS.md— Architecture decisionsdocs/PROJECT_MEMORY.md— Project memorydocs/ROADMAP.md— Implementation prioritiesdocs/testing.md— Testing guidedocs/TROUBLESHOOTING.md— Troubleshootingdocs/SPOTIFY_CALL_SURFACE.md— Spotify compliance referencedocs/SMOKE_TEST_NOTES.md— Manual smoke test checklistdocs/source-material/README.md— Archived historical context
Cross-Reference
See .ai/README.md and docs/README.md for full cross-reference maps between documentation directories.
Setup
PowerShell:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
Copy-Item .env.example .env
Bash/zsh:
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env
For Tidal playlist input, install the optional Tidal extra:
pip install -e ".[dev,tidal]"
Fill in .env as needed:
SPOTIPY_CLIENT_ID="your_spotify_client_id"
SPOTIPY_CLIENT_SECRET="your_spotify_client_secret"
SPOTIPY_REDIRECT_URI="http://127.0.0.1:8888/callback"
LASTFM_API_KEY="your_lastfm_api_key"
MB_CONTACT_EMAIL="you@example.com"
# Optional override. If unset, Mamonia uses a platform default:
# Windows: %LOCALAPPDATA%\Mamonia
# macOS: ~/Library/Application Support/Mamonia
# Linux: ${XDG_STATE_HOME}/mamonia or ~/.local/state/mamonia
MAMONIA_HOME="~/.local/state/mamonia"
TIDAL_CLIENT_ID=""
TIDAL_CLIENT_SECRET=""
LISTENBRAINZ_USER_TOKEN=""
Spotify credentials are required for Spotify playlist input and Spotify playlist creation. For local CLI PKCE, configure the exact http://127.0.0.1:8888/callback redirect URI from .env in the Spotify developer dashboard; non-loopback redirect URIs must use HTTPS, and localhost is intentionally rejected. Last.fm is optional but strongly recommended. ListenBrainz is optional and provides listener affinity data.
MusicBrainz contact email should be a real contact value, but Mamonia only warns if it is still the placeholder.
Running
Open the guided UI:
mamonia
Check configuration without printing secrets:
mamonia diagnose
mamonia diagnose --playlist "https://open.spotify.com/playlist/PLAYLIST_ID"
Run discovery from a Spotify/Tidal/text/CSV source:
mamonia discover --playlist "https://open.spotify.com/playlist/PLAYLIST_ID"
mamonia discover --playlist "tracks.txt" --output csv
mamonia discover --playlist "My Spotify Library.csv" --global-memory
When a playlist matches a saved profile but has changed, Mamonia compares track identity rather than order. Shuffled playlists are treated as unchanged. If tracks were added or removed, Mamonia asks whether to update the connected taste profile and only enriches newly introduced artists.
Run discovery from an existing saved profile:
mamonia discover --profile 1
mamonia discover --profile spotify-PLAYLIST_ID
Preview safely:
mamonia discover --playlist "tracks.txt" --dry-run
Tune expensive runs:
mamonia discover --playlist "tracks.txt" --months 12 --max-tracks 3 --limit 100 --max-candidates 150
mamonia discover --playlist "tracks.txt" --discovery-mode deep_diverse
mamonia discover --playlist "tracks.txt" --force-refresh
mamonia discover --playlist "tracks.txt" --penalize-frequent-artists
mamonia discover --playlist "tracks.txt" --shuffle-releases
Create a private Spotify playlist too:
mamonia discover --playlist "tracks.txt" --create-spotify-playlist --spotify-playlist-name "Mamonia Fresh Finds"
Inputs And Outputs
Text input supports:
Artist - Track
Artist | Track | Album
CSV input supports TuneMyMusic-style columns:
Track nameArtist nameAlbumPlaylist nameTypeISRCSpotify - id
CSV recommendation output uses the same importer-friendly shape, now with trailing diagnostics: Track name, Artist name, Album, Playlist name, Type, ISRC, Spotify - id, Spotify URI, Spotify URL, Resolution source, Resolution note, and Spotify Attribution. Album names are included so downstream importers have more matching context than plain artist/title text.
JSON export includes the same track-level diagnostics plus Spotify open URLs, an attribution block, and an explain block for each recommendation with candidate sources, provider evidence, filter/fallback context, and whether the final tracklist was Spotify-derived, MusicBrainz-derived, mixed, or unresolved.
Default export filenames include output type, a source hint, timestamp, and collision suffixes when needed, for example:
my-spotify-l_23_04_26.csv
Local Data
Mamonia stores local state in a stable per-user directory by default:
- Windows:
%LOCALAPPDATA%\Mamonia - macOS:
~/Library/Application Support/Mamonia - Linux:
${XDG_STATE_HOME}/mamonia(or~/.local/state/mamoniawhenXDG_STATE_HOMEis unset)
If those defaults cannot be resolved safely, Mamonia falls back to ~/.mamonia.
mamonia.sqlite- reusable taste profiles
- seed-track exclusion keys
- cached source playlist state for delta updates
- heard releases
- provider API cache rows
- recommendation run metadata
- Spotify OAuth token cache
Set MAMONIA_HOME to override this directory explicitly (for example, project-local ./.mamonia).
Heard matching is release-level and uses this precedence:
- MusicBrainz release-group ID
- Spotify album ID
- normalized artist + normalized release title + release year
Input playlist releases are automatically marked as heard before discovery begins; exported recommendations are marked as heard after successful export. See Heard Semantics for details.
Management Commands
mamonia heard list
mamonia heard add --artist "Artist" --release "Release" --release-date "2026-01-15"
mamonia heard remove --id 1
mamonia heard export-json --path heard_backup.json
mamonia heard import-json --path heard_backup.json
mamonia cache clear
mamonia profile list
mamonia profile show 1
mamonia profile refresh --playlist tracks.txt
mamonia profile delete 1
mamonia profile export --profile 1 --path profile.json
Development
python -m pytest
python -m unittest discover tests
Current Test Status (2026-04-30): python -m pytest -q -> 6 failed, 688 passed, 1 skipped, 1 warning.
Last Known Green Baseline: 661 passed, 1 skipped, 1 warning.
See docs/testing.md for canonical test status and .ai/TESTING.md for the mirror.
Known Limitations
- MusicBrainz metadata is uneven for very new, obscure, regional, or messy releases.
- Native Tidal playlist creation is implemented but still marked experimental; verify with
mamonia tidal-smokebefore relying on it for routine workflows. - Spotify playlist creation requires resolved Spotify track URIs; a local CSV backup is always written alongside the playlist. When URIs are absent, CSV export is the primary output.
- Remaining-time estimates are candidate-based; provider fan-out can make them approximate.
- The dated real-terminal smoke pass is still open documentation/product-polish work.
- Guided localization is implemented, but one real-terminal copy review pass is still worth doing.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mamonia-0.1.0.tar.gz.
File metadata
- Download URL: mamonia-0.1.0.tar.gz
- Upload date:
- Size: 290.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd49e14e5030f92473f515d776b1cbc378e206d193cb0570c5c4081e0efb4de0
|
|
| MD5 |
3db040e977d77963c81965b82b8f457c
|
|
| BLAKE2b-256 |
754f96fb5be64220edd180ac0f5790798758bea19110b8f9335e2a21c368734f
|
File details
Details for the file mamonia-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mamonia-0.1.0-py3-none-any.whl
- Upload date:
- Size: 216.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59579c6f0c5ffecfb22d49dd5bc2be7325352b47f2a222207404b53e6ff291df
|
|
| MD5 |
9018f71d812491d753bccf352a36afc4
|
|
| BLAKE2b-256 |
a621882a98b5c7023af15bcf26ba6087dbcddf6ce26696bb7abf979f756ccbb2
|