mtag-cli
Music Tag Organizer for self-built media libraries such as Plex, Emby, and Jellyfin.
mtag scans a source music folder, reads audio tag metadata, and writes a clean
artist/album folder layout. It is conservative by default: files are copied, existing
destinations cause an error, and --dry-run lets you inspect the plan first.
Install
Requires Rust 1.95 or newer.
Quick Start
Preview the organization plan:
Copy files into the target library:
Keep existing files and write duplicates as song (1).mp3, song (2).mp3, and so on:
Usage
Usage: mtag [OPTIONS] <MUSIC_FOLDER> [TARGET_FOLDER]
Arguments:
<MUSIC_FOLDER> Folder that contains source music files
[TARGET_FOLDER] Folder where organized files will be written [default: Music]
Options:
--dry-run Print planned file operations without writing files
--move Move files instead of copying them
--on-conflict <ON_CONFLICT> How to handle existing destination files [default: fail] [possible values: fail, skip, overwrite, rename]
--template <TEMPLATE> Organization template [default: {album_artist}/{album}/{file_name}]
-h, --help Print help
-V, --version Print version
Example Layout
Before:
Inbox/
compilation/
01 - Hooked On A Feeling.mp3
02 - Go All The Way.mp3
pink-floyd/
101 - In the Flesh.mp3
101 - In the Flesh.lrc
102 - The Thin Ice.mp3
sanitize/
01 - Thunder Test.mp3
After:
Music/
AC_DC/
Live_ 2026_/
01 - Thunder Test.mp3
Pink Floyd/
The Wall/
101 - In the Flesh.mp3
101 - In the Flesh.lrc
102 - The Thin Ice.mp3
Various Artists/
Awesome Mix Vol. 1/
01 - Hooked On A Feeling.mp3
02 - Go All The Way.mp3
Organization Rules
album_artistis preferred for the top-level folder when the tag provides it.- If
album_artistis missing, mtag uses the track artist. - If multiple artists share the same album in the same source folder, mtag places that album under
Various Artists. - Same-named albums from different source folders are not merged into
Various Artists. - A same-stem
.lrcfile next to an audio file is copied or moved with that audio file. - Unsafe path characters such as
/,\,:,?, and..are sanitized before folders are created.
Conflict Policies
Use --on-conflict to choose how existing destination files are handled:
fail Stop with an error. This is the default.
skip Keep the existing destination and skip the new file.
overwrite Replace the existing destination.
rename Keep both files by writing to the next "name (N).ext" path.
Templates
The default template is:
{album_artist}/{album}/{file_name}
Supported variables:
{album_artist}
{album}
{artist}
{disc}
{track}
{title}
{file_name}
Example:
Each slash-separated template segment is rendered and sanitized as one path component.
Library API
The crate exposes the CLI pipeline as small Rust modules:
use Path;
use ;
#
Generate local Rust documentation:
For stricter documentation checks:
RUSTDOCFLAGS="-D warnings"
Development
Run the same checks used before publishing:
See RELEASE.md for the release flow and crates.io publishing requirements.