Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 116 additions & 21 deletions skills/minimax-music-playlist/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,21 @@ description: >
any language.
license: MIT
metadata:
version: "2.0"
version: "2.1"
category: creative
---

# MiniMax Music Playlist — Personalized Playlist Generator

Scan the user's music taste, build a taste profile, generate a personalized
Analyze the user's music taste, build a taste profile, generate a personalized
playlist, and create an album cover. This skill is designed for both agent and direct
user invocation — adapt interaction style to context.


## Prerequisites

- **mmx CLI** — music & image generation. Install: `npm install -g mmx-cli`. Auth: `mmx auth login --api-key <key>`.
- **Python 3** — for scanning scripts you write on the fly (stdlib only, no pip).
- **Python 3** — for data parsing scripts you write on the fly (stdlib only, no pip).
- **Audio player** — `mpv`, `ffplay`, or `afplay` (macOS built-in).

## Language
Expand All @@ -40,25 +41,69 @@ NOT the user's UI language.
## Workflow

```
1. Scan local music apps → 2. Build taste profile → 3. Plan playlist
1. Import user-exported data → 2. Build taste profile → 3. Plan playlist
→ 4. Generate songs (mmx music) → 5. Generate cover (mmx image) → 6. Play → 7. Save & feedback
```

---

## Step 1: Gather Music Listening Data

Collect the user's listening data from available sources.
Collect the user's listening data from **user-initiated exports only**. This tool
does NOT directly query or scrape any streaming service application.

**Important:** Before processing any data, display a consent prompt:
```
This tool will analyze your exported music listening data to build a taste
profile for playlist generation. The data stays on your machine and is not
uploaded anywhere. Only the final song generation prompts (containing no
personal data) are sent to MiniMax's API.

Proceed? (y/n)
```
Only continue if the user confirms.

**Supported sources:**

| Source | Method | Data format |
|--------|--------|-------------|
| Apple Music | `osascript` to query Music.app (official AppleScript interface) | Track name, artist, album, genre, play count |
| Spotify | User exports their own data via [Spotify Privacy Settings](https://www.spotify.com/account/privacy/) | JSON files in ZIP (`Streaming_History_Audio_*.json`) |
| Apple Music | User exports via [Apple Privacy Portal](https://privacy.apple.com/) | CSV/JSON files in ZIP |
| Spotify | User exports via [Spotify Privacy Settings](https://www.spotify.com/account/privacy/) | JSON files in ZIP (`Streaming_History_Audio_*.json`) |
| Local music library | Read local `.mp3`/`.flac` files' ID3 metadata (user's own files) | ID3 tags |
| Manual input | User describes their taste directly | Free text |

**Spotify data export flow:**
### Apple Music data export flow

Apple provides an official data export through its privacy portal. This is the
**only** supported method for Apple Music data — do NOT use `osascript`, Music.app
AppleScript, or any other programmatic querying of Apple's applications or services.

1. Search for existing exports: `find ~ -maxdepth 4 -name "Apple_Media_Services.zip" -o -name "Apple Music - Play History.csv" -o -name "Apple Music Play Activity.csv" 2>/dev/null`
2. If found, ask the user if they want to use it
3. If not found, open Apple's privacy page: `open https://privacy.apple.com/`
4. Tell the user to:
- Log in with their Apple Account
- Select "Request a copy of your data"
- Check "Apple Media Services information" (this includes Apple Music history)
- Submit the request
5. Apple typically delivers the export within 1–7 days
6. Skip Apple Music for now and continue with other sources — tell the user they
can re-run the playlist skill after the export arrives

**Apple Music data format:**
The export typically contains CSV files such as `Apple Music - Play History.csv`
or `Apple Music Play Activity.csv`. Key fields to extract:
- `Track Description` or `Song Name` — track name
- `Artist Name` — artist
- `Container Description` or `Album` — album name
- `Genre` — genre (if available)
- `Play Duration Milliseconds` or `Media Duration In Milliseconds` — playback duration
- `Event Start Timestamp` or `Activity date (UTC)` — timestamp

Filter out entries with very short play durations (< 30 seconds, likely skipped).

### Spotify data export flow

Spotify does not store useful data locally. To include Spotify listening history,
first check if the user already has a Spotify data export:

Expand All @@ -80,26 +125,45 @@ is a JSON array of listening events. Key fields to extract:
- `ts` — timestamp

Filter out entries where `ms_played < 30000` (less than 30 seconds, likely skipped).
Do NOT use or store `ip_addr` or other sensitive fields.

**PII stripping (mandatory):** Before any processing or caching of Spotify data,
explicitly remove the following fields from each record: `ip_addr`,
`conn_country`, `user_agent_decrypted`, `platform`, `incognito_mode`.
Use a whitelist approach — only keep the five fields listed above, discard
everything else.

### Local music library

As a fallback, read the user's local music files (`~/Music/` or user-specified
directory) and read ID3 tags (artist, title, album, genre) using Python's stdlib.
This only reads the user's own files and does not interact with any streaming service.

### Manual input

If no exports are available, ask the user to describe their taste: favorite
artists, genres, moods, and any recent songs they enjoyed.

**What to extract from each source:**
- Track names + artist names (primary signal)
- Playlist names and membership (e.g., a playlist named "Chinese Traditional" tells you genre preference)
- Genre tags if available
- Play counts or streaming duration if available (weight frequently played tracks higher)
- Scene/mood tags if available

**Approach:**
1. Check if Apple Music is available (try `osascript` query)
2. Ask if the user has a Spotify data export ZIP to provide
3. If no sources available, ask the user to describe their taste manually
1. Ask which sources the user has available (Apple export, Spotify export, local files)
2. For each available source, locate and parse the exported data
3. If no sources available, fall back to manual input

**Privacy rule:** Never show raw track lists to the user. Only show aggregated stats.
**Privacy rules:**
- Never show raw track lists to the user — only show aggregated stats
- Never cache or log raw export file paths that may contain usernames
- All cached profiles must be deletable via `--purge` (see Step 7)

---

## Step 2: Build Taste Profile

From the scanned data, build a taste profile covering:
From the imported data, build a taste profile covering:

- **Genre distribution** — what styles the user listens to (e.g., J-pop 20%, R&B 15%, Classical 10%)
- **Mood tendencies** — emotional tone preferences (melancholic, energetic, calm, romantic, etc.)
Expand All @@ -112,21 +176,43 @@ From the scanned data, build a taste profile covering:
Most raw data only has artist + track names without genre tags. To enrich this:
1. Look up artists in the local mapping table at `<SKILL_DIR>/data/artist_genre_map.json`
— this table covers 20,000 popular artists with pre-mapped genres, vocal type, and language
2. For artists not in the mapping table, query the MusicBrainz API:
`https://musicbrainz.org/ws/2/artist/?query=artist:<name>&fmt=json`
2. If an artist is not found in the mapping table, skip it and continue

**Optional: MusicBrainz enrichment (opt-in only)**

After the local lookup is complete, if some artists could not be matched,
prompt the user:

```
Some artists in your library could not be identified using the local database.
You can enable MusicBrainz lookup to fill in the missing genre information.
MusicBrainz is a third-party open music database. Its API is free for
non-commercial use. Commercial use is subject to their license terms:
https://musicbrainz.org/doc/About/Data_License
Enable MusicBrainz lookup? (y/n)
```

Only if the user confirms, query the MusicBrainz API for unmatched artists:
`https://musicbrainz.org/ws/2/artist/?query=artist:<n>&fmt=json`
— extract genre tags from the response; respect rate limit (1 req/sec)
— **must** set a descriptive User-Agent header per MusicBrainz API policy,
e.g., `User-Agent: minimax-music-playlist/2.1 (https://github.com/your-org/repo)`
— cache results to `<SKILL_DIR>/data/artist_cache.json` to avoid re-querying
3. If MusicBrainz returns no results, skip the artist
— if MusicBrainz returns no results for an artist, skip it

Do NOT call the MusicBrainz API without explicit user consent. The skill
must function fully without MusicBrainz — it is a supplementary data source,
not a required dependency.

**Profile caching:**
- Save profile to `<SKILL_DIR>/data/taste_profile.json`
- If a profile less than 7 days old exists, reuse it (offer rescan option)
- If a profile less than 7 days old exists, reuse it (offer rebuild option)
- If older or missing, rebuild

**Show user a summary:**
```
Your Music Profile:
Sources: Apple Music 230 | Spotify 140
Sources: Apple Music export (230 tracks) | Spotify export (140 tracks)
Genres: J-pop 20% | R&B 15% | Classical 10% | Indie Pop 9%
Moods: Melancholic 25% | Calm 20% | Romantic 18%
Vocals: Female 65% | Male 35%
Expand Down Expand Up @@ -304,6 +390,11 @@ If the user is present, ask for feedback (per-song or overall). Update the
taste profile's feedback section with liked/disliked genres and prompts to
improve future playlists.

**Data management:**
- `--purge-profile` — delete only the taste profile: `rm <SKILL_DIR>/data/taste_profile.json`
- Cached data is stored only in `<SKILL_DIR>/data/` — no data is written elsewhere
- No raw export data is ever cached — only aggregated profiles and artist metadata

---

## Replaying Playlists
Expand All @@ -318,8 +409,12 @@ available ones, and play the selected one.
- **Agent vs user invocation**: The theme/scene question (Step 3) is the single
interactive touchpoint. If the theme is already provided in the invocation,
skip the question. Everything else runs autonomously.
- **No hardcoded scripts**: Write scanning/analysis scripts on the fly as needed.
- **No hardcoded scripts**: Write parsing and analysis scripts on the fly as needed.
Use Python stdlib only. Cache results to avoid redundant work.
- **Skill directory**: `<SKILL_DIR>` = the directory containing this SKILL.md file.
Data/cache files go in `<SKILL_DIR>/data/`.
- **All mmx prompts in English** for best generation quality.
- **No osascript / no direct app querying**: This tool does not use `osascript`,
AppleScript, or any programmatic interface to query Music.app, Spotify.app, or
any other streaming service application. All data come from user-initiated
exports or local file metadata.