Mullion FileMan: A Dual-Pane File Manager and a Set of Folder Tools
Mullion FileMan is a C++17 dual-pane terminal file manager. It has twenty folder_* CLI tools that compare and sync folders, and an MCP server for AI agents.
On this page
Every so often I end up with two copies of the same photo library on two drives, and no idea whether they still match. File Explorer can’t tell me which files differ, and I’m not deleting either copy until I know.
Mullion FileMan is what I built to answer that question, and it grew from there. It is a C++17 project with two parts:
- About twenty standalone
folder_*command line tools that do the actual work. - A two-pane file manager that runs in the terminal, in the style of Norton Commander, built on top of those tools.
There is also an MCP server, so an AI agent can use the same tools. This post covers how to build the project, the tools I reach for most, the two-pane UI and the MCP server.
Build the project¶
There is no installer. The build puts the binaries in the project root, and you run them from there. To build the CLI tools on Windows, use this command:
.\build.ps1
On macOS or Linux, use this command:
./build.sh
Both scripts find your compiler automatically. To run the unit tests during the build, add -Test (or --test on Unix). All you need is a C++17 compiler with a working std::filesystem. The CLI tools have no external dependencies.
The terminal UI (TUI) needs FTXUI, which CMake downloads for you. So build the TUI with CMake on every platform:
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
On Windows, a batch script builds the TUI and puts the CLI tools with it:
.\build-mullion-fileman.bat
Compare two folders¶
folder_parity was the first tool I wrote, and it is still the one I use most. It walks two folders and lists the files that differ:
folder_parity ./backup ./live -o report.csv
Each row in the CSV is one file that differs, labeled MISSING_IN_1, MISSING_IN_2 or DIFFERENT, with its sizes and modification dates. Files that match are left out. The CSV is saved in a way that lets Excel show accented and non-English filenames correctly.
By default, the tool compares files by size. That is fast, but it misses a change that leaves the size the same. To be certain, add --hash, and the tool reads every file in full and compares the contents:
folder_parity "J:\Photos" "I:\Photos" --hash --jobs -1 --ignore-system -o report.csv
--jobs -1uses all CPU cores.--ignore-systemignores.DS_Store,Thumbs.dband similar files. Without this flag, these files fill the report.
How long hashing a photo library takes depends mostly on the disk. On an SSD, using all cores makes a big difference.
Once you have read the report, the same tool can bring the two folders in line:
folder_parity ./backup ./live --sync --sync-to 1 # one-way mirror
folder_parity ./a ./b --sync --prefer newer # two-way, newest wins
--prefer accepts 1, 2, newer or larger. It decides which file wins when both sides have the same file with different contents. The exit codes are script-friendly:
0: the trees are the same.2: the tool found differences.1: an error occurred.
Sort files into a tree¶
folder_sort is my other regular. It takes one big messy folder and files everything into subfolders. By default it only shows a preview. Nothing changes until you add --apply:
folder_sort ~/Downloads ~/Sorted --by type # preview
folder_sort ~/Downloads ~/Sorted --by type --apply # do it
--by selects one of five built-in layouts:
| Layout | Result |
|---|---|
date |
{year}/{month}/{name} |
month |
{year}-{month}/{name} |
type |
{category}/{name} — images, video, audio, documents, archives, code, other |
ext |
{ext}/{name} |
letter |
{firstletter}/{name} |
If none of these layouts fit, write your own path with --template. The template accepts these fields: {name}, {stem}, {ext}, {category}, {firstletter}, {year}, {month}, {day}, {date:FMT}, {size}, and {idx} / {idx:W} for numbers with leading zeros:
folder_sort ./inbox ./archive --template "{year}/{category}/{stem}{ext}" --move --apply
By default, the tool copies the files. To move them instead, add --move. If two files have the same name, the tool adds a " (2)" suffix. To skip these files, add --skip. Each run writes a CSV index (sort-index.csv, or the name you give with -o) that records where every file went. If you run --move with the wrong template, that index is how you put everything back.
NOTE: folder_sort only looks at what the filesystem knows: modification time, extension and size. --by date uses the modification date, not the date the photo was taken, and these two dates can be years apart. For photos, use folder_photos. It reads the capture date that the camera stored in the file (the EXIF data).
The other tools¶
All the tools follow the same rules:
- They create subfolders as needed.
- They use multiple CPU cores when that helps.
- Anything that could lose data shows a preview first and does nothing until you add
--apply. - Each tool is a single executable with no shared libraries, so you can copy one file to another machine and run it.
Files and folders
| Tool | Function |
|---|---|
folder_parity |
Compare two trees, show the differences and sync them (optional) |
folder_clean |
Remove unwanted OS files (.DS_Store, Thumbs.db and similar files) |
folder_copy / folder_move / folder_delete |
Recursive file operations with many threads |
folder_find |
Find files by name, content, size or age |
folder_view |
Show a file as text or hex |
Organization
| Tool | Function |
|---|---|
folder_sort |
Move files from a flat folder into a tree from a template |
folder_rename |
Rename many files: literal, regex, case, prefix/suffix, {n:03} numbers |
folder_attr |
Timestamps, Windows attributes, POSIX chmod/owner/group |
Maintenance
| Tool | Function |
|---|---|
folder_dupes |
Find duplicate files by size, then by hash; show the space that you can recover |
folder_du |
Disk usage with bars, from largest to smallest |
folder_checksum |
Write a checksum manifest, and examine it later with --verify |
folder_shred |
Write over files before they are deleted (--passes N) |
folder_scan |
Find exposed secrets: AWS keys, private keys, JWTs and tokens |
Media
| Tool | Function |
|---|---|
folder_photos |
Sort images by EXIF capture date into a tree from a template |
folder_convert |
Convert many files with ffmpeg; the extension sets the codec |
folder_archive |
Create, extract or list tar archives |
folder_watch |
Monitor a directory and run a command when matching files change |
System
| Tool | Function |
|---|---|
folder_sysmon |
CPU, memory and GPU usage; --watch, --json, --stream |
folder_proc |
List, filter and stop processes, and change their priority |
bookmark_sync |
Sync bookmarks in two directions between Chrome, Firefox and Safari |
Some of the tools chain together. folder_watch accepts a --command, where {} stands for the file that changed. That lets you watch a folder and pass each new file to another tool:
folder_watch ./inbox --pattern "*.png" --command "folder_convert {} --to jpg --apply"
folder_scan also works well as a pre-commit hook. It reports each match as file:line and hides the secret itself.
The dual-pane UI¶
mullion-fileman is the interactive UI. Give it the two directories to open:
mullion-fileman ./backup ./live

If you have used Norton Commander or Midnight Commander, you already know how this works. There are two panes side by side:
- Push Tab to go to the other pane.
- Push Enter to open a directory.
- Push Backspace to go to the parent directory.
- You can also use the Vim keys
jandk.
Each pane shows the name, date and size of each item. A status line shows the path, the number of items and the current sort.
The most important functions are:
- Tagging. Space tags the current row.
+and-tag rows by glob.*inverts the selection. Tagged rows become yellow and show an asterisk. Copy, move and delete apply to all tagged rows. - Quick filter.
/filters the pane while you type.Escremoves the filter.Enterkeeps the filtered view. - F-keys. F3 shows a file as text or hex. F5 is copy, F6 is move, F7 is mkdir and F8 is delete. F8 first shows a dry run and asks for confirmation before it removes files.
- Other keys.
topens the tree view.sopens the sort menu.xopens the Tools menu for bulk operations.:runs a shell command in the directory of the active pane.
You can also use the menu bar and the mouse. Double-click a folder to open it. Right-click to open a context menu. m opens a system monitor that shows the CPU, memory and GPU usage.
The TUI has two optional functions:
- A local AI agent (
a) that examines folders. It can only read files. - Voice input (
V) to speak to the agent.
To include them, use -DBUILD_MULLION_FILEMAN_AI=ON during the build. To run the agent on the GPU, also use -DMULLION_FILEMAN_AI_CUDA=ON. Both are off by default, which keeps the normal build small.
Use the tools from an AI agent¶
The project also has an MCP server, which is how AI agents such as Claude plug in outside tools. It is a small Python wrapper that calls the same folder_* programs, so the C++ code stays free of dependencies:
cd mcp
pip install -r requirements.txt
python server.py
The server gives eight tools: compare, sync, find, view, clean, copy, move and delete. It finds the executables through $FOLDER_TOOLS_DIR. If this variable is not set, it uses the repository root. For Claude Desktop, add an entry to claude_desktop_config.json:
{
"mcpServers": {
"folder-tools": {
"command": "python",
"args": ["path/to/server.py"],
"env": { "FOLDER_TOOLS_DIR": "path/to/repo" }
}
}
}
Now you can ask the agent in plain words to compare J:\Photos and I:\Photos by hash, or to find *.log files larger than 1 MB in D:\logs. It gets the same preview-first defaults as the command line.
Warning¶
WARNING: folder_parity --sync does not delete files. It only adds files and writes over files. A sync cannot remove a file that you forgot about. But “sync” is not the same as “mirror”: files that are only on the destination stay there. Read the CSV report before you sync important data.
Links¶
- Repo: github.com/sina5/mullion-fileman
- Docs: sinafathi.com/mullion-fileman
- Building · The TUI · MCP server
- Tool reference: folder_parity · organize · maintenance · media · system
Mullion FileMan runs on Windows, macOS and Linux. Issues and PRs are welcome.
Two related posts: Redthread is another MCP tool of mine, for agent memory. And if the photo library is what brought you here, Sabattier edits the photos once they are sorted.