Command Line (snapzy)
Capture a display, a window, or an area from Terminal, scripts, and AI agents with the snapzy command — no overlay, no clicks — and get back a file path, JSON, and an exit code.
Overview
Snapzy ships a snapzy command so AI agents (Claude Code, Cursor, Codex…), shell scripts, and your own terminal can take screenshots without touching the mouse. Each command returns a file path, JSON metadata, and a meaningful exit code.
- Thin client.
snapzytalks to the running Snapzy app over a private Unix socket. Snapzy does the capture, so the Screen Recording permission stays with Snapzy — your terminal or agent never needs it. - Starts Snapzy for you. If Snapzy is not running, the command opens it in the background and waits for it (no splash screen once onboarding is complete). Pass
--no-launchto fail instead. - Headless. Command line captures never open Quick Access, never touch the clipboard, never add history entries, never apply presets or play a sound, and never trigger a permission prompt.
- Per-app approval. The first time an app uses
snapzy, Snapzy asks whether to allow it.
Install the Command
The binary is always inside the app at:
/Applications/Snapzy.app/Contents/Helpers/snapzy
Agents and scripts can call that path directly. To type snapzy anywhere, put it on your PATH:
| Method | How |
|---|---|
| Settings → Command Line | Click the ⓘ button in the toolbar, then Install. This creates /usr/local/bin/snapzy (asks for an administrator password only if /usr/local/bin is not writable). Turning on the Command line access switch also installs it. Install is refused while Snapzy runs from a DMG or a temporary location — move it to Applications first. |
| Shell script | install.sh links /usr/local/bin/snapzy when it can, or prints the sudo ln -sfn … command to run. It never overwrites a regular file or another tool's link. |
| Homebrew | The cask will link snapzy automatically starting with the first stable release that includes it. If Settings shows Copy Command, run brew reinstall --cask snapzy to create the link. |
| Manual | sudo ln -sfn /Applications/Snapzy.app/Contents/Helpers/snapzy /usr/local/bin/snapzy |
Because the command lives inside the app bundle, in-app updates (Sparkle) update it together with Snapzy. Uninstall in the same popover removes only a link that points to this app.
Verify the setup:
snapzy doctor
Quick Start
# Is Snapzy ready? (never needs approval)
snapzy status
# Find something to capture
snapzy list displays
snapzy list apps
snapzy list windows --app Safari
# Capture
snapzy capture screen -o ~/Desktop/screen.png
snapzy capture window --app Safari --max-dimension 1568 -o shot.png
snapzy capture window --active --no-shadow -o focused.png
snapzy capture area --rect 0,0,800,600 -o area.jpg --quality 0.8
Commands
| Command | What it does |
|---|---|
snapzy status | App version, whether command line access is on, onboarding, Screen Recording permission, and whether the calling app is approved. Never needs approval. |
snapzy doctor | Checks the CLI path, PATH, the app, the connection, and status, and explains each failure with a hint. Never launches Snapzy. |
snapzy version | CLI and app versions. Never launches Snapzy; exits 5 after printing when Snapzy is not reachable. |
snapzy list displays | Connected displays (ID, name, frame, scale, main). |
snapzy list windows [--app NAME] [--all] | Capturable windows, front to back. --all adds windows that are not on screen. |
snapzy list apps | Running apps that have windows. |
snapzy capture screen [--display main|all|ID] | A whole display (default main), or every display — one file per display. |
snapzy capture window --id ID | One window by ID, even when other windows cover it. |
snapzy capture window --app NAME [--title REGEX] [--index N] | The frontmost window of an app; --title filters by a regular expression, --index picks another match (0-based, front to back). |
snapzy capture window --active | The focused window of the frontmost app. |
snapzy capture area --rect x,y,w,h | A rectangle in points. It must lie fully on screen. |
capture window takes exactly one of --id, --app, or --active; --no-shadow captures it without the window shadow. Run snapzy help <command> for built-in help.
Matching apps
--app accepts a bundle ID or a name, case-insensitive, in this order: exact bundle ID, then exact name, then name prefix — and only the best tier is used. So --app Code matches an app named exactly “Code” and never mixes in Codex; if no app is named exactly “Code”, the prefix tier can still match Codex.
When several windows match, the frontmost one wins and the result's matchedCandidates tells you how many matched. Use --index N to pick another, or list windows --app NAME and capture by --id.
Capture Options
| Option | Meaning |
|---|---|
-o, --output PATH | Where to write the capture: a file path, a directory (trailing / or an existing folder keeps Snapzy's file names), or - to write the image bytes to stdout (single file only). With several displays, files are named name-1.png, name-2.png… |
--format png|jpg|webp | Image format. Defaults to the --output extension, else png. A format that conflicts with the extension is an error. |
--quality 0…1 | JPEG quality (jpg only), default 0.9. |
--max-dimension PX | Downscale so the longest edge is at most PX pixels (never upscales). 1568 is a good value for vision models. |
--cursor | Include the mouse pointer. |
--force | Overwrite an existing file at --output. Without it, an existing file fails before capturing. |
Without -o, the file stays in Snapzy's staging folder (~/Library/Application Support/Snapzy/CLI/Captures/) and is deleted after 24 hours — always pass -o when you want to keep it.
Global Options
These work with every command:
| Option | Default | Meaning |
|---|---|---|
--json | off | Print JSON even when stdout is a terminal (pretty-printed). |
--timeout S | 30 | Seconds to wait for each request. |
--launch-timeout S | 15 | Seconds to wait for Snapzy to start. |
--no-launch | off | Fail instead of starting Snapzy when it is not running. |
Output
Output is JSON when stdout is not a terminal (pipes, agents, scripts) or with --json; in a terminal you get one readable line per item. Errors go to stderr in the same mode.
{"durationMs":244,"files":[{"bytes":1204134,"displayID":1,"format":"png","height":2338,"path":"/Users/me/shot.png","scale":2,"width":3600}]}
scaleis pixels per point of the written file (lower than the display scale after--max-dimension).formatispng,jpeg, orwebp.- Window captures also include
window(id,title,app {name, bundleID, pid},frame,displayID,isOnScreen,isActive) andmatchedCandidates. - With
-o -, stdout carries the image bytes; the JSON metadata goes to stderr only when you also pass--json.
Errors look like this:
{"error":{"code":"targetNotFound","message":"…","hint":"…"}}
Coordinates
All frames and --rect values use global points with the origin at the top-left of the main display. Displays to the left of or above the main display have negative coordinates — --rect -1440,0,800,600 works as-is. A window frame from list windows can be passed straight to capture area.
Exit Codes
| Exit | Error codes | Meaning |
|---|---|---|
0 | — | Success |
1 | internal | Unexpected failure |
2 | invalidArguments | Bad flags, an area partly off screen, or an existing --output without --force |
3 | permissionDenied, onboardingIncomplete | Screen Recording is missing or not active yet, or Snapzy setup is unfinished |
4 | targetNotFound | No such display, window, or app, or the area is off screen |
5 | appUnavailable, launchTimeout, disabled, busy, versionMismatch, unknownMethod | Snapzy is not reachable, command line access is off, another capture is running, the screen is locked, or the versions do not match |
7 | notAuthorized | The calling app was denied, not approved in time, or could not be identified |
Approval & Allowed Apps
Every command except status needs the calling app to be approved — the app you run snapzy from, such as Terminal, iTerm, VS Code, Cursor, or Claude. Snapzy identifies it by walking up from the snapzy process to the first regular app, and checks its code signature. Apps that cannot be verified show a generic icon, a warning, and their real location on disk.
The first request shows a prompt with Always Allow, Allow Once, and Don't Allow:
- Return does not pick a button; Escape means Don't Allow.
- The prompt times out after 25 seconds and the command exits with
7. - Allow Once covers only the rest of that
snapzycommand. - Decisions are stored on this Mac only and are never exported to
config.toml.
Review or revoke decisions in Settings → Command Line → Allowed apps (Remove or Remove All). Open it directly with snapzy://settings/command-line.
While a command line capture runs, the menu bar icon is tinted. If the menu bar icon is hidden, a notification names the app instead.
Turning It Off
The Command line access switch in Settings → Command Line is on by default. When it is off, Snapzy closes its socket and every command fails with disabled (exit 5). The same setting is available in config.toml:
[general]
cli_enabled = true
Using snapzy with AI Agents
- Run
snapzy statusonce. Ifauthorizationisundetermined, a Snapzy prompt will appear on the next capture — click Always Allow or Allow Once within 25 seconds. - Discover targets with
list displays,list apps, orlist windows. - Always capture to a path you choose with
-o. - Add
--max-dimension 1568so the image stays small enough for vision input, then read the returnedfiles[].path.
The Snapzy repository includes a ready-made agent skill at skills/snapzy that teaches agents this workflow.
Troubleshooting
Run snapzy doctor first — it explains each failure and suggests a fix.
| Symptom | Cause & fix |
|---|---|
disabled (5) | Command line access is off. Turn it on in Settings → Command Line. |
launchTimeout (5) | Snapzy was started but did not answer within --launch-timeout — most often because command line access is off, or the app is slow to start. |
permissionDenied (3), “granted but not usable yet” | Screen Recording was granted while Snapzy was running. Relaunch Snapzy; if it persists, remove and re-add Snapzy in System Settings → Privacy & Security → Screen & System Audio Recording. |
onboardingIncomplete (3) | Open Snapzy and finish setup. |
appUnavailable (5), “The screen is locked or asleep” | macOS does not allow captures while the session is locked. |
notAuthorized (7) | The calling app was denied, or nobody answered the prompt. Check Settings → Command Line → Allowed apps. |
snapzy: command not found | The command is not on PATH. Use Settings → Command Line → Install, brew reinstall --cask snapzy for Homebrew installs, or call the full path inside Snapzy.app. |