File13 Pro

The command-line tool requires File13 Pro. The binary ships in every install, but every subcommand except version and doctor exits with code 4 until a Pro entitlement is detected. See pricing.

Install

The binary lives at File13.app/Contents/Resources/file13. The fastest way to add it to your shell is from inside the app: Edit → Install File13 CLI…. The sheet shows the resolved path and a ln -s command you can paste into Terminal.

Why a manual link?

The Mac App Store sandbox prevents File13 from writing into /usr/local/bin on your behalf. Terminal handles that part of the install, the same way VS Code installs its code command. The binary itself is already notarized.

$ sudo ln -s \
    /Applications/File13.app/Contents/Resources/file13 \
    /usr/local/bin/file13

Verify with file13 --version. Accounts you have added in the GUI are visible to the CLI without further setup, because the two share the same keychain access group.

Automation philosophy

The CLI is held to two rules. First, every action that mutates a mailbox supports --dry-run and exits zero when the dry run is satisfied. Second, the CLI honors the same VIP and transactional protections as the GUI, and the same buffered-undo window applies — there is no “bypass safety rails” flag.

Output is line-oriented and grep-friendly. JSON output is available with --format json for downstream tooling. The CLI does not paginate, does not colorize when piped, and returns useful exit codes (see § exit codes).

Commands

file13 accounts list

List configured accounts and their connection state. Shared with the GUI.

file13 accounts add <email>

Add a new account interactively. Prompts for IMAP host, port, and password.

file13 senders [--min-count N] [--read-rate P] [--vip|--no-vip] [--format tsv|json|text]

Show one row per sender for the selected account and folder. Filter by minimum message count, read-rate threshold, or VIP status.

file13 subjects [--cluster] [--since DATE]

List subject groups. --cluster uses the same normalization the GUI uses to merge near-duplicates.

file13 fetch [--account NAME] [--folder NAME]

Refresh headers for the selected account and folder. Idempotent. Honors server rate limits.

file13 archive --from ADDR | --query EXPR [--dry-run]

Archive matching messages to the account's archive folder. Always print affected counts before committing.

file13 delete --from ADDR | --query EXPR [--dry-run]

Delete matching messages. Subject to the same VIP and transactional protections as the GUI. Refuses to run on more than 5,000 messages without an explicit --yes-bulk.

file13 move --to FOLDER --from ADDR | --query EXPR [--dry-run]

Move messages between folders.

file13 unsubscribe --from ADDR [--method http|mailto]

Perform a List-Unsubscribe action. With http, issues the one-click POST. With mailto, opens the URL in your default mail handler — File13 does not send mail.

file13 rules list

Print active rules and the order in which they evaluate.

file13 rules run [--dry-run]

Evaluate every rule against the current cache and apply the resulting actions through the buffered pipeline.

file13 export --what categories|rules|vips [--format json|tsv]

Dump local state to stdout for backup or transfer to another machine.

file13 license

Print the current license tier (free or pro) and the platform marker.

The --query expression

A small, header-only query language. Supported terms: from:, to:, subject:, list:, folder:, before:DATE, after:DATE, read:true|false, replied:true|false, size:>NB, category:NAME. Combine with AND, OR, and parentheses. Quote any term containing spaces.

file13 archive --query 'list:weekly-digest AND before:2026-01-01'

Example workflows

Quarterly cleanup, scripted

#!/usr/bin/env zsh
set -euo pipefail

# refresh, then archive any digest older than 90 days
file13 fetch --account personal
file13 archive --account personal \
  --query 'category:newsletter AND before:90d' \
  --dry-run

read "?Apply? (y/N) " confirm
[[ "$confirm" == "y" ]] || exit 0

file13 archive --account personal \
  --query 'category:newsletter AND before:90d'

Nightly digest of new high-volume senders

# crontab -e
0 6 * * * /usr/local/bin/file13 senders \
  --account work --min-count 10 --new-since 24h \
  --format tsv | mail -s "new senders" you@example.com

Review before commit

file13 rules run --dry-run --format json > /tmp/plan.json
jq '.actions | group_by(.kind) | map({kind: .[0].kind, count: length})' /tmp/plan.json

Exit codes

  • 0 — success
  • 1 — generic error
  • 2 — usage error (bad arguments)
  • 3 — IMAP connection failure
  • 4 — Pro license required
  • 5 — refused: action would affect more rows than the safety threshold
  • 6 — destructive action aborted by VIP protection
  • 7 — provider rate limit hit; retry later

Safety rails

Notice

A script that runs file13 delete in a loop can remove a large amount of mail in a short period. The CLI is the same engine the GUI uses, with the same protections, but it has no human in the loop to catch a typo in a query. Run new scripts with --dry-run first, and store backups of anything you cannot afford to lose.

  • Every destructive verb prints a count and pauses for the configured undo window before committing. The window is the same one Settings uses.
  • Operations above 5,000 messages require --yes-bulk.
  • VIPs and transactional senders are protected unless you set --allow-vip and --allow-transactional, both of which are recorded in the log.
  • The CLI refuses to run on a File13 version that is more than 90 days behind the latest, to keep IMAP behavior in sync with what the GUI ships.

License and redistribution

The CLI is part of File13 and is released under the same MIT License as the rest of the project. You are free to use, modify, and redistribute it under those terms. Build it from source, script against it, or fork it — the only condition is that the MIT copyright and permission notice travel with the code.