No DOM · No accessibility tree · No browser surface

Give your coding agent
eyes on macOS.

Plumshot's command-line tool lets coding agents capture and annotate the native windows, menus, and sheets that browser tools can't see. It runs locally — no account, no API token.

plumshot capture-window --app "MyApp" --out /tmp/shot.pngSet up your agent

See the commands

macOS 14 Sonoma or later · Screen Recording permission · Any agent with a shell · 100% on-device

What your agent hands back — a marked-up PNG, not a paragraph of coordinates.

Screenshots become a conversation

Loop A

The agent shows you

Your agent captures a window, marks the problem with a box, an arrow, and a number, and hands back an annotated PNG. Every capture prints its path as JSON, so any agent that can open an image sees the result.

  1. capture-window
  2. annotate
  3. show the human

Loop B

You show the agent

Mark up a screenshot yourself — in Plumshot, Preview, anything — and your agent reads the marks as instructions. No capture, no permission needed.

  1. you annotate
  2. agent reads the PNG
  3. agent acts

Works with any agent that has a shell

Coding agents already run shell commands, so they drive the CLI directly. No MCP setup.

Available now

Headless CLI

plumshot …

Every capture prints { path, width, height, bbox } as JSON. The CLI is the signed app binary itself — nothing else to install.

Coming soon

MCP server + Claude Code plugin

stdio MCP · Claude Code skill

The same commands as native MCP tools, plus a Claude Code skill. Until they ship, the CLI does the same job.

Want to hear when they ship? Write to support@plumshot.app

Set up in 5 steps

Install the app, put a two-line wrapper on your PATH, and tell your agent it's there.

  1. Install Plumshot

    Download the DMG and drag Plumshot into Applications. Needs macOS 14 Sonoma or later.

  2. Grant Screen Recording to your terminal or agent app

    macOS checks the app that runs plumshot (Terminal, iTerm, Cursor, …), not Plumshot itself. In System Settings ▸ Privacy & Security ▸ Screen & System Audio Recording (Screen Recording on macOS 14), enable that app (add it with the + button if it isn't listed), then quit and reopen it. plumshot doctor (step 4) names the app. Auto-scroll in capture-scrolling also needs Accessibility for that app; annotate needs no permission.

  3. Put the CLI on your PATH

    mkdir -p ~/.local/bin
    printf '#!/bin/sh\nexec /Applications/Plumshot.app/Contents/MacOS/Plumshot "$@"\n' > ~/.local/bin/plumshot
    chmod +x ~/.local/bin/plumshot

    This writes a two-line wrapper that runs the app's binary. If ~/.local/bin isn't on your PATH yet, add export PATH="$HOME/.local/bin:$PATH" to ~/.zshrc and open a new terminal.

  4. Verify

    plumshot doctor
      screen recording (TCC): granted ✓
      accessibility (AX):     not granted (optional)
      bundle id:              com.plumshot.app
      binary:                 /Applications/Plumshot.app/Contents/MacOS/Plumshot
      signing:                Developer ID Application: … ✓
      host app (likely):      Terminal (com.apple.Terminal)
      license:                trial not started; the first capture starts it

    Then a smoke test: capture a window and list what's on screen.

    plumshot capture-window --app Finder --out /tmp/cap.png
    plumshot list-targets
  5. Tell your agent

    Paste this into CLAUDE.md (Claude Code) or AGENTS.md (Codex, Cursor, and others) so your agent knows the CLI exists and when to reach for it.

    ## Native macOS screenshots (Plumshot)
    - `plumshot` captures and annotates native macOS UI (windows, menus, sheets,
      the menu bar) that browser tools can't see. `plumshot --help` lists every
      command and flag; https://plumshot.app/agents.md has the full guide.
    - See a window: `plumshot capture-window --app "MyApp" --out /tmp/shot.png`,
      then open the PNG. Captures print JSON: {"path", "width", "height", "bbox"}.
    - Point at something: pipe {"shapes": [...]} (box, arrow, text, number,
      highlight, blur; top-left image pixels) into
      `plumshot annotate --in /tmp/shot.png --out /tmp/marked.png --shapes -`.
    - Read words, not pixels: `plumshot capture-text --app "MyApp"` returns
      {"text", "chars"} via on-device OCR.
    - Errors print {"error": "..."} on stderr with a non-zero exit. If a capture
      fails or comes back black, run `plumshot doctor`.
    - Use a browser tool for web pages; use plumshot for native macOS UI.

Licensing: doctor, list-targets, version, and help are free. annotate and every capture-* command are part of the 3-day full-feature trial, which starts with your first capture; after that they need a $9.90 one-time license.

Screen Recording is the only gate

Only the capture commands need a permission: Screen Recording, granted to your terminal or agent app. No Full Disk Access, and Accessibility only for scrolling auto-scroll.

  • Captures are local files written where --out points. Nothing is uploaded.
  • annotate needs no permission — it only draws on a PNG you already have.
  • capture-scrolling's auto-scroll also needs Accessibility, for the same app; check with plumshot doctor, or pass --no-auto-scroll.
  • PLUMSHOT_SANDBOX_ROOT confines --in, --out, and --shapes to one directory. Off by default.
  • Redact before you share: cover secrets with a blur shape (style blackOut for a hard cover).

The commands

All coordinates are top-left origin, image pixels. Captures print a JSON envelope { path, width, height, bbox } on stdout; failures print { "error": … } on stderr and exit non-zero. plumshot --help lists every flag.

CommandFlagsOutput
capture-window--app <name> (substring, any case) --out <png> [--window <title>]JSON envelope · largest matching window
capture-region--rect x,y,w,h --out <png> [--display-id ID | --display N]JSON envelope
capture-previous-region--out <png>JSON envelope · repeats the last region (CLI or app)
capture-full--out <png> [--display-id ID | --display N]JSON envelope · defaults to the display under the cursor
capture-scrolling--rect x,y,w,h --out <png> [--max-seconds N (30)] [--idle-seconds N (3)] [--no-auto-scroll]JSON envelope · auto-scroll needs Accessibility
capture-text--in <png> | --rect x,y,w,h | --app <name> [--window <title>]; [--no-linebreaks] [--out <png>]JSON { text, chars } · on-device OCR
annotate--in <png> --out <png> [--shapes <file> | -] (stdin by default)JSON envelope · no permission
list-targets—JSON { displays, windows } · free
doctor—Permissions, host app, signing, license · free

Marks are a declarative shape spec

No mouse, no GUI — your agent authors arrows, boxes, labels, and redactions as JSON.

shapes (top-left image pixels)

{ "shapes": [
  { "type": "box",       "x": 980, "y": 60, "w": 260, "h": 96,
                         "color": "#FF3B30", "lineWidth": 3, "filled": false },
  { "type": "arrow",     "from": [880, 200], "to": [1000, 110] },
  { "type": "text",      "x": 700, "y": 210, "text": "label is clipped", "fontSize": 30 },
  { "type": "number",    "x": 1110, "y": 108, "n": 1 },
  { "type": "highlight", "x": 120, "y": 320, "w": 400, "h": 28 },
  { "type": "blur",      "x": 60, "y": 60, "w": 300, "h": 40,
                         "style": "pixelate|secureBlur|smoothBlur|blackOut" }
] }

Defaults: color #FF3B30 (red), lineWidth 3, text fontSize 28, number marker 36, blur pixelate. Pipe the spec in on stdin (--shapes -, the default) or pass --shapes file.json. On Retina, use the pixel numbers Plumshot prints — they are already device pixels.

What to actually say

Try these — they map onto the two loops above.

Loop A — the agent shows you

  • Capture the Preferences window of MyApp and tell me if the Save button label is clipped.
  • Screenshot the Settings sheet, draw a red box around the broken label with an arrow to it, number it 1, and show me.
  • Take a scrolling capture of this list and check that the bottom rows render.

Loop B — you show the agent

  • Read ~/shot.png — I drew arrows on what to fix. Do what they point at.
  • Here's a screenshot I marked up; what does box 1 point at?

Priming

  • Run plumshot doctor and list-targets, then capture the front window of MyApp.

When to reach for Plumshot

Use Plumshot for

  • Native AppKit/SwiftUI windows
  • NSMenu and the menu bar
  • Sheets, alerts, popovers
  • Custom-drawn views & canvases
  • Drag previews and traffic-light spacing
  • Anything with no reliable accessibility tree

Reach for something else for

  • Web UI → Playwright / a browser MCP (you get DOM, console, network)
  • Pure text extraction → capture-text reads the words directly (on-device OCR) — cheaper than shipping pixels to a vision model
  • Headless CI with no display or Screen Recording grant
  • Sub-pixel diffing → capture, then diff with an image tool

Native-macOS failure modes

When in doubt, run plumshot doctor first.

plumshot: command not found

Create the wrapper from step 3 and make sure ~/.local/bin is on your PATH (open a new terminal after editing ~/.zshrc). Or call the binary directly: /Applications/Plumshot.app/Contents/MacOS/Plumshot doctor.

doctor says Screen Recording NOT granted

Enable the app on doctor's host app (likely) line — your terminal or agent app, not Plumshot — under System Settings ▸ Privacy & Security ▸ Screen & System Audio Recording (Screen Recording on macOS 14), then quit and reopen it. If it names a helper (say, Cursor Helper), enable the main app.

Captures are black / empty

The classic missing-Screen-Recording symptom even when the call "succeeds." Confirm with plumshot doctor; make sure the target is on a logged-in GUI session.

No on-screen window for app=…

--app matches part of the app's name (any case) among windows that are on screen. Run plumshot list-targets to see the exact app names and window titles.

Plumshot's trial has ended

annotate and the capture-* commands need a license once the 3-day trial is over. Buy a $9.90 license, then activate it in Plumshot under Settings → License. doctor, list-targets, and help keep working.

capture-scrolling doesn't scroll

Auto-scroll needs Accessibility for the app that runs plumshot. Grant it, or pass --no-auto-scroll and scroll the target yourself.

Built for agents to read, too

Machine-readable twins an agent can fetch directly.

Agent index

A terse llms.txt index: what Plumshot is, price and trial, the CLI, and when to use it.

/llms.txt

Markdown twin

This page as plain markdown: parseable commands and the shape spec, not rendered HTML.

/agents.md

Rather not paste a snippet? Ask your agent to read https://plumshot.app/agents.md before its first capture.

Point your agent at the pixels.

Install the app, add a two-line wrapper, and your agent sees the native UI no browser tool can reach.

Local-only · No account · 3-day free trial · $9.90 one-time