MacnifyIt can be driven without opening its window: from Terminal with the macnifyit command, from the Shortcuts app, or by an AI agent that can run shell commands. Everything runs on your Mac, inside the MacnifyIt app. The command never renders pixels itself: it hands the job to the app, waits for the result and prints it.
This page covers photos only. Output is a new file; your original is never changed unless you ask for --if-exists overwrite.
Install
From the app
- Open MacnifyIt.
- Choose MacnifyIt ▸ Install Command-Line Tool….
- Pick one of the two buttons:
- Install System-Wide… links
/usr/local/bin/macnifyit to the tool inside the app. You are asked for your Mac password once. - Install for Me Only links
~/.local/bin/macnifyit. No password is needed. If ~/.local/bin is not on your shell's PATH, the confirmation shows the exact line to add, with a Copy PATH Line button.
The same menu has Uninstall Command-Line Tool, which removes only links that point into a MacnifyIt app. A file of the same name that is not ours is never deleted; you get a message instead. A status line in the menu shows where the tool is installed.
One line for an agent or a script
The tool lives inside the app, so a single symlink is all an agent needs:
mkdir -p ~/.local/bin && ln -s /Applications/MacnifyIt.app/Contents/Helpers/macnifyit ~/.local/bin/macnifyit
System-wide instead: sudo ln -s /Applications/MacnifyIt.app/Contents/Helpers/macnifyit /usr/local/bin/macnifyit. You can also run the tool by its full path without linking it at all. Check the result with macnifyit doctor.
Before the first run
- Finish setup once. Open MacnifyIt normally one time and complete the first-launch screen. Until then every job is refused with
onboarding_incomplete (exit code 5, "Open MacnifyIt once to finish setup."). - Preview with
--dry-run. A command-line job never shows the first-run sheet or any other window. To see what would happen, add --dry-run: it prints the plan (which files would be exported, skipped or renumbered, with their sizes and formats), exports nothing and uses none of your trial.
Commands
macnifyit <command> --help prints the full help for a command, including the exit-code and error-code tables below.
enlarge
macnifyit enlarge <path>... [size] [options]
Enlarges image files, or the images inside folders (a folder needs --out). Relative paths are made absolute before the job is sent.
Pick one size (default --scale 2):
| Flag | Meaning | Example |
|---|
--scale 2|4|8 | Enlarge by 2×, 4× or 8× | macnifyit enlarge photo.jpg --scale 4 |
--percent N | Scale to N percent of the original (above 0, up to 1000) | macnifyit enlarge photo.jpg --percent 150 |
--long-edge PX | Make the longest side PX pixels | macnifyit enlarge photo.jpg --long-edge 6000 |
--width PX | Make the width PX pixels | macnifyit enlarge photo.jpg --width 4000 |
--height PX | Make the height PX pixels | macnifyit enlarge photo.jpg --height 3000 |
--box WxH | Fit inside a W by H pixel box | macnifyit enlarge photo.jpg --box 3000x2000 |
Options:
| Flag | Meaning | Example |
|---|
--method exact|clarity|enhance | Resize method. enhance adds AI-estimated detail (see below) | macnifyit enlarge photo.jpg --method clarity |
--strength 0.1-1.0 | Enhance AI detail (the app's AI detail slider, 10–100 %); only with --method enhance. Default 0.50 (50 %). A value below 0.1 counts as 0.1 | macnifyit enlarge photo.jpg --method enhance --strength 0.7 |
--format same|png|jpeg|tiff|webp|avif|heic | Output format. Default same: the format of the source | macnifyit enlarge photo.png --format jpeg |
--quality 1-100 | Compression quality; only with --format jpeg or webp | macnifyit enlarge photo.png --format webp --quality 85 |
--out DIR | Output folder. Default: beside each source. Required if any input is a folder | macnifyit enlarge ~/Pictures/trip --out ~/Desktop/big |
--name TEMPLATE | Output file name template. Default: the app's default naming | macnifyit enlarge photo.jpg --name "{source}_big" |
--recursive | Also process the sub-folders of folder inputs | macnifyit enlarge ~/Pictures/trip --out ~/Desktop/big --recursive |
--if-exists number|skip|overwrite | When the output file exists: number it (default), skip it or overwrite it | macnifyit enlarge photo.jpg --if-exists skip |
--use-app-settings | Use the Enlarge options saved in the MacnifyIt app instead of the factory defaults. The same command then no longer gives the same file on every Mac | macnifyit enlarge photo.jpg --use-app-settings |
Each file prints one line, then a summary:
✓ photo.jpg → photo_4x.png (6240×4160)
recipe
macnifyit recipe list
macnifyit recipe run <id|name> <path>... [--out DIR] [--recursive]
recipe list prints the recipes saved in the app (id and name). recipe run runs one on files or folders. The recipe decides size, method and format, so recipe run accepts only --out and --recursive plus the global options. Folders need --out.
macnifyit recipe run "Web 2000px" ~/Pictures/trip --out ~/Desktop/web --recursive
status
macnifyit status [<job>]
Shows one job (its id is printed by --no-wait and by --timeout) or, without an id, the recent jobs. A finished job exits with its own code; a job that is still running exits 0. If MacnifyIt quit in the middle of a job, it is asked to reconcile the job first.
cancel
macnifyit cancel <job>
Cancels a running job, like the Stop button in the app. Pressing Ctrl-C while the tool is waiting cancels the job too and exits 130.
doctor
macnifyit doctor
Checks that the app is found, that its version matches the tool, that setup is finished and how much trial or licence is left. It exports nothing and uses no trial.
version
macnifyit version
Prints the version of the tool.
Global options
These work on every command (--dry-run and --progress apply to enlarge and recipe run).
| Flag | Meaning | Example |
|---|
--json | Print one JSON document on stdout (the app's result) instead of text lines | macnifyit enlarge photo.jpg --json |
--no-wait | Submit the job, print its id and exit 0 without waiting | macnifyit enlarge ~/Pictures/trip --out ~/Desktop/big --no-wait |
--timeout SEC | Stop waiting after SEC seconds and exit 6. The job keeps running and its id is printed | macnifyit enlarge ~/Pictures/trip --out ~/Desktop/big --timeout 120 |
--progress | Stream NDJSON progress events on stderr | macnifyit enlarge ~/Pictures/trip --out ~/Desktop/big --progress |
--dry-run | Show what would be exported; exports nothing and uses no trial | macnifyit enlarge photo.jpg --scale 4 --dry-run |
--quiet | Print only errors | macnifyit enlarge photo.jpg --quiet |
--no-notify | Do not post a completion notification | macnifyit enlarge photo.jpg --no-notify |
--app <bundle-id|path> | Target a specific MacnifyIt build, by bundle id or app path. Default: the app the tool ships in, else the installed MacnifyIt | macnifyit doctor --app /Applications/MacnifyIt.app |
--help, -h | Show help for a command | macnifyit enlarge --help |
The --json result
With --json the tool prints exactly one document on stdout and nothing else: the job's result. This is the example result the command-line formatter is tested against, for macnifyit enlarge a.jpg b.jpg --scale 4 --method enhance --json on two photos:
{
"app": {
"build": "202610261",
"bundle_id": "com.macnifyit.app",
"version": "1.3.2"
},
"counts": {
"completed": 2,
"failed": 0,
"skipped": 0
},
"dry_run": false,
"finished_at": "2026-10-26T03:14:19Z",
"items": [
{
"ai_detail": true,
"error": null,
"format": "jpeg",
"height": 4160,
"method": "enhance",
"output": "/Users/k/a_4x.jpeg",
"receipt": "/Users/k/Library/Application Support/MacnifyIt/Receipts/a_4x.macnifyitreceipt",
"source": "/Users/k/a.jpg",
"state": "completed",
"width": 6240
},
{
"ai_detail": true,
"error": null,
"format": "png",
"height": 4160,
"method": "enhance",
"output": "/Users/k/b_4x.png",
"receipt": "/Users/k/Library/Application Support/MacnifyIt/Receipts/b_4x.macnifyitreceipt",
"source": "/Users/k/b.jpg",
"state": "completed",
"width": 6240
}
],
"job": "6F1C2A40-3B7D-4E58-9A21-0C5D8E7F1B01",
"request": {
"command": "enlarge",
"format": "same",
"method": "enhance",
"size": {
"mode": "x4"
},
"strength": 0.5
},
"schema": "com.macnifyit.agent.result/1",
"started_at": "2026-10-26T03:14:07Z",
"state": "completed",
"trial": {
"exports_remaining": 15,
"licensed": false
},
"updated_at": "2026-10-26T03:14:19Z"
}How to read it:
state is one of completed, partial, failed, cancelled, trial_exhausted, rejected or running. A rejected job was refused before anything was exported and carries a top-level error.items[] has one entry per file with its own state (pending, running, completed, skipped, failed or cancelled), the final output path, width, height, format, method and, for a failed file, an error with a code from the table below.ai_detail is true for every item made with Enhance.counts totals completed, failed and skipped items.trial shows licensed and, while unlicensed, exports_remaining; it is null once licensed.request echoes what was resolved, so you can see the defaults that were applied.- With
--dry-run the result has dry_run: true, no items exported and a plan listing each file with the action (export, number or skip).
Progress events
--progress writes one JSON object per line (NDJSON) on stderr while the job runs, so stdout stays a single document. The events are job_started, item_started, item_progress, item_completed, item_failed, item_skipped and job_finished. A job with one failure looks like this:
{"event":"job_started","job":"6F1C2A40-3B7D-4E58-9A21-0C5D8E7F1B02","schema":"com.macnifyit.agent.progress/1","total":2,"ts":"2026-10-26T03:14:07Z"}
{"event":"item_started","index":0,"job":"6F1C2A40-3B7D-4E58-9A21-0C5D8E7F1B02","schema":"com.macnifyit.agent.progress/1","source":"/Users/k/a.jpg","ts":"2026-10-26T03:14:08Z"}
{"event":"item_progress","fraction":0.5,"index":0,"job":"6F1C2A40-3B7D-4E58-9A21-0C5D8E7F1B02","schema":"com.macnifyit.agent.progress/1","source":"/Users/k/a.jpg","ts":"2026-10-26T03:14:09Z"}
{"event":"item_completed","index":0,"job":"6F1C2A40-3B7D-4E58-9A21-0C5D8E7F1B02","output":"/Users/k/a_4x.jpg","schema":"com.macnifyit.agent.progress/1","source":"/Users/k/a.jpg","ts":"2026-10-26T03:14:10Z"}
{"event":"item_started","index":1,"job":"6F1C2A40-3B7D-4E58-9A21-0C5D8E7F1B02","schema":"com.macnifyit.agent.progress/1","source":"/Users/k/b.heic","ts":"2026-10-26T03:14:11Z"}
{"error":{"code":"unreadable_source","message":"The file could not be decoded."},"event":"item_failed","index":1,"job":"6F1C2A40-3B7D-4E58-9A21-0C5D8E7F1B02","schema":"com.macnifyit.agent.progress/1","source":"/Users/k/b.heic","ts":"2026-10-26T03:14:12Z"}
{"event":"job_finished","job":"6F1C2A40-3B7D-4E58-9A21-0C5D8E7F1B02","schema":"com.macnifyit.agent.progress/1","state":"partial","ts":"2026-10-26T03:14:13Z"}Exit codes
The exit code tells a script what happened without parsing anything. Rejected jobs use the exit code of their error.
| Exit code | Name | Meaning |
|---|
0 | ok | every item completed (or skipped by --if-exists skip) |
1 | usage | usage or validation error; nothing was submitted |
2 | partial | some items failed |
3 | failed | all items failed |
4 | trial_or_licence | trial exhausted or licence invalid |
5 | app_unavailable | app not installed, version mismatch, onboarding not done, or app quit mid-job |
6 | timeout | --timeout reached; the job keeps running and its id is printed |
130 | interrupted | interrupted; the job was cancelled |
Error codes
error.code in the JSON output is always one of these closed values, and the same table is printed at the end of every --help screen.
error.code | Exit code | Scope | Message |
|---|
invalid_argument | 1 | request | A request field is missing, malformed or out of range. |
not_absolute_path | 1 | request | Paths must be absolute (start with /); ~ and relative paths are not accepted. |
source_missing | 3 | item | The source file or folder does not exist. |
unreadable_source | 3 | item | The source exists but could not be read or decoded. |
unsupported_format | 3 | item | The source image format is not supported. |
out_required_for_folder | 1 | request | A folder input needs an explicit --out directory. |
output_exists | 3 | item | The output file already exists and could not be written under the chosen --if-exists policy. |
recipe_not_found | 1 | request | No recipe with that id or name exists. |
recipe_invalid | 1 | request | The recipe could not be loaded or applied. |
trial_exhausted | 4 | job | The free trial is used up; a licence is required to export more. |
licence_invalid | 4 | job | The stored licence is not valid. |
onboarding_incomplete | 5 | job | Open MacnifyIt once to finish setup. |
app_not_found | 5 | cli | MacnifyIt is not installed or could not be launched. |
version_mismatch | 5 | job | The CLI and the app speak different protocol versions. |
app_quit | 5 | cli | MacnifyIt quit while the job was running; run macnifyit status <job> after relaunch. |
timeout | 6 | cli | The --timeout elapsed; the job is still running. |
cancelled | 130 | job | The job or item was cancelled. |
request_expired | 1 | request | The request is older than 24 hours and was ignored. |
export_failed | 3 | item | The export pipeline failed for this item. |
internal | 3 | job | Unexpected internal error. |
Shortcuts
On macOS 13 or later the Shortcuts app has three MacnifyIt actions. They run in the background and return the new files, so a shortcut can pass them on to the next action:
| Action | What it does |
|---|
| Enlarge Images | Enlarges the images you give it. Choose the size (2×, 4×, 8× or a long edge in pixels), the method (Exact, Clarity or Enhance), the format (same as source, PNG, JPEG, TIFF, WebP, AVIF or HEIC) and optionally a folder to save to. The size in this action starts at 4×. |
| Run MacnifyIt Recipe | Runs a saved recipe on the images you give it, optionally saving to a folder you choose. |
| Get MacnifyIt Recipes | Returns the recipes saved in MacnifyIt, to pick from in a shortcut. |
The actions go through the same trial and licence check as the app and the command. If something fails, the action stops with the same code and message as the command, for example trial_exhausted. Enhance in a shortcut uses the default strength of 50%.
Background behaviour
- No focus steal. A job started from the command line or an action does not bring MacnifyIt to the front and does not open a window. If the app was not running it starts in the background, does the job and quits when it is done. If you were already using MacnifyIt, it stays as it was.
- Your tabs are left alone. A job never opens, closes, reorders or changes a tab in the app, and never touches the settings of a photo you have open. Tabs belong to the app window; agent jobs run beside them.
- No sheets. There is no first-run sheet, no "Export N images?" confirmation and no resume prompt on this path. Use
--dry-run to look before you export. - Setup must have been finished once in the app, as described above.
- Finishing. When a job ends, a notification says how many files were exported, unless you passed
--no-notify. --no-wait returns immediately with a job id; use macnifyit status <job> later. - Interrupting. Ctrl-C or a termination signal cancels the job and exits 130.
--timeout leaves the job running and exits 6.
Trial and licence
The command counts exactly like the app, because it is the app doing the work:
- The free trial is 12 exports. Only images that finish writing count; failures, skips and
--dry-run never do. Previews in the app stay free. - If a batch is larger than what is left of the trial, the first files that fit are exported, the rest fail with
trial_exhausted, and the exit code is 4. Nothing is exported once the trial is used up. - With a valid licence
trial.licensed is true, exports_remaining is null and there is no limit from the trial. macnifyit doctor shows how much trial or licence is left. The command cannot bypass either: there is no flag, setting or file that skips the check.- A stored licence that is not valid gives
licence_invalid (exit 4).
Privacy
Everything is local. macnifyit and the Shortcuts actions make no network connection, send no telemetry and upload no images or file names. The tool talks only to the MacnifyIt app on the same Mac, through files in the app's support folder and a notification. The only web address it ever prints is the buy link when the trial is used up.
AI-estimated detail
--method enhance adds detail that was estimated by AI rather than captured by the camera. MacnifyIt always says so:
- Text output ends with
Contains AI-estimated detail (Enhance). whenever any exported file used Enhance. - In
--json and --dry-run output every Enhance item has "ai_detail": true. - In Shortcuts the method is labelled "Enhance (AI-estimated detail)".
Exact and Clarity do not add detail.
Defaults
| Setting | Default from the command line |
|---|
| Size | --scale 2 |
| Format | same: the format of the source |
| Enhance strength | 0.50 (50%) |
| When the output exists | number it; nothing is overwritten unless you say --if-exists overwrite |
| Output folder | Beside each source (folders need --out) |
The command starts from the factory defaults, not from whatever options are currently set in the app window, so the same command gives the same result on every Mac. Pass --use-app-settings if you want the app's own saved options instead.