Library Commands

The library branch provides commands for managing music libraries, processing media, and maintaining metadata.

Overview

mcli library [COMMAND] [OPTIONS]

Available Commands:

Command Alias Description
album-report ar Show report of albums found in library
clean c Clean library and delete folders without media files
find-duplicate-dirs fdd Find duplicate album directories and resolve using metadata
list ls List all libraries with their details
move-ok m Move ‘Ok’ status albums to another library
process p Process media from inbound to staging (step 1 only)
purge   Purge library data from database
rebuild r Rebuild melodee metadata albums in library
scan s Full scan workflow - process inbound → staging → storage → database
stats ss Show statistics for a specific library
validate v Validate library integrity (DB vs disk consistency)

library list

Lists all libraries configured in the database with their details.

Usage

mcli library list [OPTIONS]

Options

Option Default Description
--raw false Output in JSON format for scripting
--verbose false Include verbose debug output

Examples

# List all libraries
./mcli library list

# JSON output for scripting
./mcli library list --raw

Output

╭──────────┬─────────┬──────────────────────────────┬─────────┬────────┬───────┬─────────────────┬───────────╮
│ Name     │ Type    │ Path                         │ Artists │ Albums │ Songs │    Last Scan    │   Status  │
├──────────┼─────────┼──────────────────────────────┼─────────┼────────┼───────┼─────────────────┼───────────┤
│ Inbound  │ Inbound │ /mnt/music/inbound           │       0 │      0 │     0 │       N/A       │    ✓ OK   │
│ Staging  │ Staging │ /mnt/music/staging           │      42 │    156 │  1892 │ 20241230T130000 │ ⚠ Needs   │
│ Storage  │ Storage │ /mnt/music/library           │   1,234 │ 15,678 │187234 │ 20241230T130500 │    ✓ OK   │
╰──────────┴─────────┴──────────────────────────────┴─────────┴────────┴───────┴─────────────────┴───────────╯

Total libraries: 3
⚠ 1 library(ies) need scanning

Library Types

Type Description Scanning
Inbound New files to be processed N/A
Staging Processed files awaiting review Yes
Storage Final destination for approved albums Yes
UserImages User-uploaded images N/A
Playlist Playlist files N/A

library stats

Shows detailed statistics for a specific library.

Usage

mcli library stats --library <NAME> [OPTIONS]

Options

Option Alias Default Description
--borked   false Show only issues, skip informational stats
--library -l Required Name of the library to analyze
--raw   false Output in JSON format
--verbose   false Include verbose debug output

Examples

# Show all statistics
./mcli library stats --library "Storage"

# Show only problems
./mcli library stats -l "Staging" --borked

# JSON output
./mcli library stats -l "Storage" --raw

Output

╭─────────────────────────────────────────────╮
│ Library: Storage                            │
│ Path: /mnt/music/library                    │
│ Type: Storage                               │
╰─────────────────────────────────────────────╯

                Artist Statistics                 
╭─────────────────────┬───────────┬───────╮
│ Metric              │     Count │     % │
├─────────────────────┼───────────┼───────┤
│ Total Artists       │     1,234 │  100% │
│ With Images         │     1,200 │ 97.2% │
│ Locked              │        12 │  1.0% │
╰─────────────────────┴───────────┴───────╯

                Album Statistics                  
╭─────────────────────┬───────────┬───────╮
│ Metric              │     Count │     % │
├─────────────────────┼───────────┼───────┤
│ Total Albums        │    15,678 │  100% │
│ Ok Status           │    15,500 │ 98.9% │
│ Needs Attention     │       120 │  0.8% │
│ Missing Images      │        58 │  0.4% │
╰─────────────────────┴───────────┴───────╯

library album-report

Generates a report of albums grouped by status.

Usage

mcli library album-report --library <NAME> [OPTIONS]

Options

Option Alias Default Description
--full   false Show detailed list instead of summary
--library -l Required Name of the library
--raw   false Output in JSON format
--verbose   false Include verbose debug output

Examples

# Summary report
./mcli library album-report --library "Staging"

# Full detailed report
./mcli library album-report -l "Staging" --full

Summary Output

╭────────────────────┬───────╮
│ Status             │ Count │
├────────────────────┼───────┤
│ ✓ Ok               │ 1,204 │
│ ⚠ Ok (Invalid)     │     3 │
│ ✗ HasNoImages      │    15 │
│ ✗ HasNoTracks      │     2 │
╰────────────────────┴───────╯

Use --full to see detailed list.

library clean

⚠️ DESTRUCTIVE OPERATION

Removes directories without media files from a library.

Usage

mcli library clean --library <NAME> [OPTIONS]

Options

Option Alias Default Description
--library -l Required Name of the library to clean
--verbose   false Include verbose debug output

What It Does

  1. Scans library for all directories
  2. Identifies directories without media files
  3. Preserves image-only directories if parent has media
  4. Permanently deletes empty/non-media directories

Safety

  • ❌ Won’t run on locked libraries
  • ✅ Safe for Staging and Storage libraries
  • ⚠️ Use caution with Inbound libraries

Example

./mcli library clean --library "Staging"

library rebuild

Regenerates Melodee metadata files by reading music files.

Usage

mcli library rebuild --library <NAME> [PATH] [OPTIONS]

Arguments

Argument Description
[PATH] Optional. Rebuild only this specific album path

Options

Option Alias Default Description
--library -l Required Name of the library
--limit -n   Maximum number of albums to process and then quit
--only-missing   true Only create missing metadata files
--skip-images   false Skip searching for, downloading and processing images. Existing images are kept unless invalid.
--verbose   false Include verbose debug output

Examples

# Create only missing metadata
./mcli library rebuild --library "Storage"

# Full rebuild (recreate all)
./mcli library rebuild -l "Storage" --only-missing false

# Rebuild specific album
./mcli library rebuild -l "Storage" "The Beatles/Abbey Road"

# Rebuild without processing images (faster, keeps existing images)
./mcli library rebuild -l "Storage" --skip-images

# Process only first 100 albums
./mcli library rebuild -l "Storage" --limit 100

Safety

  • ✅ Non-destructive: Only creates/updates metadata files
  • ❌ Won’t run on Inbound or locked libraries

library scan

Performs a full library scan workflow - the complete media ingestion pipeline.

Usage

mcli library scan [OPTIONS]

Options

Option Alias Default Description
--force   false Force processing even if recently scanned
--json   false Output results as JSON (implies –silent for progress)
--silent   false Suppress all output (silent mode)
--verbose   false Include verbose debug output

What It Does

This command orchestrates the entire media ingestion pipeline in sequence:

Step Job Description
1 LibraryInboundProcessJob Processes raw files from inbound → staging
2 StagingAlbumRevalidationJob Re-validates albums with invalid artists
3 StagingAutoMoveJob Moves approved albums from staging → storage
4 LibraryInsertJob Inserts albums from storage into database

This is the recommended way to add new music - a single command that handles everything.

Examples

# Standard scan - process everything end-to-end
./mcli library scan

# Force full reprocessing
./mcli library scan --force

# Silent mode for cron jobs (no output, exit code only)
./mcli library scan --silent

# JSON output for scripting and automation
./mcli library scan --json

# Check exit code in scripts
./mcli library scan --silent && echo "Scan successful" || echo "Scan failed"

JSON Output Example

When using --json, the command outputs structured JSON:

{
  "success": true,
  "durationSeconds": 145.23,
  "duration": "00:02:25",
  "steps": [
    { "name": "Processing inbound files", "success": true, "durationSeconds": 83.5 },
    { "name": "Revalidating staging albums", "success": true, "durationSeconds": 5.1 },
    { "name": "Moving approved albums to storage", "success": true, "durationSeconds": 12.3 },
    { "name": "Inserting albums into database", "success": true, "durationSeconds": 44.3 }
  ],
  "summary": {
    "inboundProcessing": { "newArtists": 5, "newAlbums": 12, "newSongs": 145 },
    "stagingRevalidation": { "albumsRevalidated": 3, "albumsNowValid": 2 },
    "storageTransfer": { "albumsMoved": 14 },
    "databaseInsert": { "artistsInserted": 5, "albumsInserted": 14, "songsInserted": 168 }
  },
  "errors": []
}

Interactive Output

╭─────────────────────────────────────╮
│     Library Scan Configuration      │
├─────────────────────────────────────┤
│ Force Mode    No                    │
│ Verbose       No                    │
╰─────────────────────────────────────╯

✓ Processing inbound files           (01:23)
✓ Revalidating staging albums        (00:05)
✓ Moving approved albums to storage  (00:12)
✓ Inserting albums into database     (00:45)

── Library scan completed in 00:02:25 ──

╭─────────────────────────────────────╮
│           Scan Summary              │
├─────────────────────────────────────┤
│ Inbound Processing                  │
│   New artists discovered        5   │
│   New albums discovered        12   │
│   New songs discovered        145   │
├─────────────────────────────────────┤
│ Database Insert                     │
│   Artists inserted              5   │
│   Albums inserted              14   │
│   Songs inserted              168   │
╰─────────────────────────────────────╯

library process

Processes media from Inbound to Staging library.

Usage

mcli library process --library <NAME> [OPTIONS]

Options

Option Alias Default Description
--copy   true Copy files instead of moving
--force   true Override existing metadata files
--inbound     Inbound path (path-based mode)
--library -l Required Name of the inbound library
--limit     Maximum albums to process
--pre-script     Script to run before processing
--staging     Staging path (path-based mode)
--verbose   false Include verbose debug output

What It Does

  1. Scans inbound library for media files
  2. Parses ID3/Vorbis tags
  3. Extracts album artwork
  4. Creates melodee.json metadata files
  5. Moves/copies to staging

Examples

# Process all from Inbound
./mcli library process --library "Inbound"

# Process 10 albums
./mcli library process -l "Inbound" --limit 10

# Path-based mode
./mcli library process --inbound "/mnt/incoming" --staging "/mnt/staging"

library move-ok

Moves albums with “Ok” status between libraries.

Usage

mcli library move-ok --library <FROM> --to-library <TO> [OPTIONS]

Options

Option Alias Default Description
--from-path     Source path (path-based mode)
--library -l Required Source library name
--to-library   Required Destination library name
--to-path     Destination path (path-based mode)
--verbose   false Include verbose debug output

Examples

# Move from Staging to Storage
./mcli library move-ok --library "Staging" --to-library "Storage"

# Path-based mode
./mcli library move-ok --from-path "/mnt/staging" --to-path "/mnt/library"

library purge

⚠️ DESTRUCTIVE OPERATION

Purges all data for a library from the database.

Usage

mcli library purge --library <NAME> [OPTIONS]

Options

Option Alias Default Description
--force   false Ignore last scan timestamp
--library -l Required Name of the library to purge
--verbose   false Include verbose debug output

What Gets Deleted

  • All artist records for this library
  • All album records
  • All song records
  • Library statistics

What Is NOT Deleted

  • Filesystem files (only database records)
  • The library configuration itself

Safety

  • ❌ Won’t run on locked libraries
  • Confirmation required

Example

./mcli library purge --library "Staging"

library validate

Validates library integrity by checking bidirectional consistency between database records and files on disk.

Usage

mcli library validate --library <NAME> [OPTIONS]

Options

Option Alias Default Description
--fix   false Remove orphaned database records
--json   false Output results as JSON
--library -l Required Name of the storage library to validate
--verbose   false Include verbose debug output

What It Validates

  1. Database → Disk: Checks that all artists, albums, and songs in the database have corresponding files/directories on disk
  2. Disk → Database: Checks that all album directories with media files on disk are registered in the database

Issues Detected

Issue Type Description Fix Option
Orphaned Artists Artist in DB but directory missing on disk --fix removes from DB
Orphaned Albums Album in DB but directory missing on disk --fix removes from DB
Missing Songs Song in DB but file missing on disk --fix removes from DB
Unregistered Directories Album directory on disk not in DB Run library scan to add

Examples

# Basic validation - check for issues
./mcli library validate --library "Storage"

# JSON output for scripting
./mcli library validate -l "Storage" --json

# Auto-fix orphaned DB records
./mcli library validate -l "Storage" --fix

# Pipe JSON to jq for processing
./mcli library validate -l "Storage" --json | jq '.issues.orphanedAlbums | length'

Example Output

╭───────────────────────────────────╮
│     Library Validation            │
├───────────────────────────────────┤
│ Library     Storage               │
│ Path        /mnt/music/library    │
│ Fix Mode    No                    │
╰───────────────────────────────────╯

✓ Validating database records against disk
✓ Validating disk directories against database

── Validation completed in 00:02.345 ──

╭─────────────────┬─────────┬────────╮
│ Category        │ Checked │ Issues │
├─────────────────┼─────────┼────────┤
│ Artists         │   1,234 │      0 │
│ Albums          │  15,678 │      3 │
│ Songs           │ 187,234 │     12 │
│ Disk Dirs       │  15,700 │      5 │
╰─────────────────┴─────────┴────────╯

✗ Library validation failed - 20 issue(s) found.
Tip: Use --fix to remove orphaned database records.
Tip: Run 'mcli library scan' to add unregistered directories.

JSON Output Example

{
  "success": false,
  "libraryName": "Storage",
  "libraryPath": "/mnt/music/library",
  "durationSeconds": 2.345,
  "summary": {
    "artistsChecked": 1234,
    "albumsChecked": 15678,
    "songsChecked": 187234,
    "directoriesScanned": 15700
  },
  "issues": {
    "orphanedArtists": [],
    "orphanedAlbums": [
      { "id": 123, "name": "Missing Album", "directory": "M/Mi/Missing Artist/Missing Album/" }
    ],
    "missingSongs": [
      { "id": 456, "title": "Lost Track", "fileName": "01 - Lost Track.mp3", "albumName": "Some Album" }
    ],
    "unregisteredDirectories": [
      "/mnt/music/library/N/Ne/New Artist/New Album"
    ]
  },
  "fixed_": null
}

Safety

  • ✅ Read-only by default (only reports issues)
  • ⚠️ --fix modifies database (removes orphaned records)
  • ❌ Only works with Storage libraries

library find-duplicate-dirs

Finds duplicate album directories (same album name, different years) and optionally resolves them using metadata searches from MusicBrainz, Spotify, and other sources.

Usage

mcli library find-duplicate-dirs --library <NAME> [OPTIONS]

Options

Option Alias Default Description
--artist -a   Filter to specific artist name (partial match)
--delete   false Delete incorrect duplicates (requires --search)
--json   false Output results as JSON
--library -l Required Name of the storage library to scan
--limit -n   Maximum number of duplicate groups to process
--search   false Search metadata sources to determine correct year
--verbose   false Include verbose debug output

What It Does

  1. Scans the library for album directories with the same normalized name but different years
  2. Identifies potential duplicates (e.g., “Hot Pink [2019]” and “Hot Pink [2020]”)
  3. Searches metadata sources (when --search is used) to determine the correct release year
  4. Suggests which directories to keep and which to delete
  5. Deletes incorrect directories (when --delete is used)

Examples

# Find all duplicate album directories
./mcli library find-duplicate-dirs --library "Storage"

# Filter to a specific artist
./mcli library find-duplicate-dirs -l "Storage" --artist "Doja Cat"

# Search metadata to determine correct year
./mcli library find-duplicate-dirs -l "Storage" --search

# Search and auto-delete incorrect duplicates
./mcli library find-duplicate-dirs -l "Storage" --search --delete

# JSON output for scripting
./mcli library find-duplicate-dirs -l "Storage" --search --json

# Limit to first 10 groups
./mcli library find-duplicate-dirs -l "Storage" --limit 10

Example Output (Basic)

╭─────────────┬──────────────────┬──────────────────────────────┬──────┬───────╮
│ Artist      │ Album            │ Directory                    │ Year │ Files │
├─────────────┼──────────────────┼──────────────────────────────┼──────┼───────┤
│ Doja Cat    │ Hot Pink         │ Hot Pink [2019]              │ 2019 │    12 │
│             │                  │ Hot Pink [2020]              │ 2020 │    12 │
│             │                  │                              │      │       │
│ Pink Floyd  │ The Wall         │ The Wall [1979]              │ 1979 │    26 │
│             │                  │ The Wall [1980]              │ 1980 │    26 │
╰─────────────┴──────────────────┴──────────────────────────────┴──────┴───────╯

Found 2 duplicate album group(s) with 4 directories
╭─────────────┬──────────────────┬──────────────────────┬──────┬───────┬───────────────┬─────────────────┬──────────╮
│ Artist      │ Album            │ Directory            │ Year │ Files │ Metadata Year │ Source          │ Status   │
├─────────────┼──────────────────┼──────────────────────┼──────┼───────┼───────────────┼─────────────────┼──────────┤
│ Doja Cat    │ Hot Pink         │ Hot Pink [2019]      │ 2019 │    12 │ 2019          │ SearchEngine    │ ✓ Keep   │
│             │                  │ Hot Pink [2020]      │ 2020 │    12 │               │                 │ ✗ Delete │
│             │                  │                      │      │       │               │                 │          │
│ Pink Floyd  │ The Wall         │ The Wall [1979]      │ 1979 │    26 │ 1979          │ SearchEngine    │ ✓ Keep   │
│             │                  │ The Wall [1980]      │ 1980 │    26 │               │                 │ ✗ Delete │
╰─────────────┴──────────────────┴──────────────────────┴──────┴───────┴───────────────┴─────────────────┴──────────╯

Found 2 duplicate album group(s) with 4 directories
  Resolved via metadata: 2
  Directories suggested for deletion: 2

JSON Output Example

{
  "durationSeconds": 12.34,
  "totalGroups": 2,
  "totalDirectories": 4,
  "resolvedGroups": 2,
  "directoriesToDelete": 2,
  "groups": [
    {
      "artistName": "Doja Cat",
      "albumName": "Hot Pink",
      "metadataYear": 2019,
      "metadataSource": "SearchEngine",
      "musicBrainzId": "abc123-...",
      "spotifyId": "xyz789",
      "suggestedCorrectDirectory": "/mnt/music/library/D/Do/Doja Cat/Hot Pink [2019]",
      "suggestedDeleteDirectories": [
        "/mnt/music/library/D/Do/Doja Cat/Hot Pink [2020]"
      ],
      "directories": [
        {
          "path": "/mnt/music/library/D/Do/Doja Cat/Hot Pink [2019]",
          "albumName": "Hot Pink",
          "year": 2019,
          "fileCount": 12,
          "isCorrectYear": true
        },
        {
          "path": "/mnt/music/library/D/Do/Doja Cat/Hot Pink [2020]",
          "albumName": "Hot Pink",
          "year": 2020,
          "fileCount": 12,
          "isCorrectYear": false
        }
      ]
    }
  ]
}

How Year Detection Works

The command detects album years from:

  1. Directory name patterns: [2019], (2019), or 2019 prefix
  2. Melodee metadata files: melodee.json if present
  3. Metadata searches: MusicBrainz, Spotify, and other configured search engines

Safety

  • ✅ Read-only by default (only reports duplicates)
  • ⚠️ --search queries external metadata APIs
  • ⚠️ --delete permanently removes directories (requires confirmation)
  • ❌ Only works with Storage libraries

Use Cases

  1. Post-migration cleanup: After importing a large music collection, find and resolve duplicate albums with inconsistent years
  2. Quality assurance: Identify albums that may have been ripped or tagged with incorrect years
  3. Library maintenance: Periodic checks to keep your library clean and consistent

Workflow Examples

# Single command to process all new music end-to-end
./mcli library scan

This is the simplest and recommended approach. It handles:

  • Processing files from inbound
  • Validating and revalidating albums
  • Moving approved albums to storage
  • Adding them to the database

Force Full Reprocessing

# Force reprocess everything, ignoring timestamps
./mcli library scan --force

Full Library Rebuild

#!/bin/bash
# Complete library rebuild (metadata regeneration)

LIBRARY="Storage"

echo "Starting full rebuild of $LIBRARY..."

# Clean first
./mcli library clean -l "$LIBRARY"

# Full metadata rebuild
./mcli library rebuild -l "$LIBRARY" --only-missing false

# Rescan into database
./mcli library scan --force

echo "Rebuild complete"

Validate and Fix Library Integrity

#!/bin/bash
# Check and fix library integrity issues

LIBRARY="Storage"

echo "Validating library integrity..."

# First, check for issues
./mcli library validate -l "$LIBRARY"

# If issues found, fix orphaned DB records
./mcli library validate -l "$LIBRARY" --fix

# Add any unregistered directories to DB
./mcli library scan

echo "Library validation complete"

See Also