Documentation
TetherShot · macOS menu-bar app · MIT licensed
Overview
TetherShot is a native macOS menu-bar app that captures pixel-perfect screenshots of an iPhone and saves them to a folder you choose (optionally copying each to your clipboard). It supports two capture paths:
- USB — a trusted, cabled iPhone is exposed to macOS as a screen source via AVFoundation. Instant, no extra setup.
- Wi-Fi — cable-free capture over your local network using Apple's developer-services tunnel (powered by pymobiledevice3). Requires a one-time setup.
The app runs as a background agent — no Dock icon, just a menu-bar glyph.
Requirements
- macOS 14 (Sonoma) or later — developed and tested on macOS 26 (Tahoe).
- Xcode Command Line Tools — needed to build from source:
xcode-select --install. - Node.js 18+ — to install via npm.
- An iPhone you can set to Trust This Computer.
- For Wi-Fi: the iPhone and Mac on the same network, plus pymobiledevice3.
Install
The recommended path is npm. TetherShot builds from source on your machine — a locally compiled app gets no Gatekeeper quarantine, so it launches with no “unidentified developer” warning.
npm install -g tethershot # links the CLI (and builds the app) tethershot install # ensure the app is in ~/Applications tethershot # launch it
Note: npm 11+ blocks postinstall scripts by default, so if the app isn't built after npm install, the explicit tethershot install step always does it.
From source
git clone https://github.com/apoorvdarshan/TetherShot.git
cd TetherShot
./build.sh # compiles + packages TetherShot.app
open TetherShot.app
First capture (USB)
- Connect your iPhone with a cable and tap Trust This Computer (unlock if prompted).
- Click the TetherShot icon in the menu bar.
- Your phone appears as
📸 <name> (USB)— click it. (Use Refresh Devices if it's not listed yet.) - The first capture triggers a one-time Camera permission prompt — allow it. (The iPhone screen rides the camera privacy bucket; your Mac camera is never used.)
- The PNG lands in your folder (default
~/Pictures/TetherShot) and, if enabled, on your clipboard.
Wi-Fi capture
Wireless capture uses a root tunnel daemon (tunneld) that keeps a RemoteXPC tunnel alive so captures need no sudo. One-time setup:
# 1 · install pymobiledevice3 (the engine) pip3 install -U pymobiledevice3 # 2 · install the tunnel service (asks for admin password once) tethershot setup-wifi # 3 · with the iPhone connected over USB once: # enable Developer Mode (Settings ▸ Privacy & Security) pymobiledevice3 lockdown wifi-connections --state on
After that you can unplug. While the iPhone and Mac are on the same Wi-Fi, the menu shows it as (Wi-Fi) and captures are pixel-perfect — even when the phone is locked. The tunnel daemon is discovered automatically.
Why not AirPlay mirroring? On macOS Tahoe, a mirrored iPhone window blacks out whenever any screen-capture context is active, so TetherShot uses the developer-services path instead — it captures the device's own framebuffer regardless of transport.
CLI
tethershot # launch the app tethershot install # build & install to ~/Applications tethershot update # update to the latest published version tethershot setup-wifi # install the Wi-Fi tunnel service tethershot uninstall # remove the app tethershot version # print the installed version
Options
All options live in the menu and persist across launches:
- Copy to Clipboard (on by default) — also place each capture on the clipboard, ready to paste.
- Organize by Device — save into a per-device subfolder.
- Choose Folder… — pick any destination; the choice is remembered.
- Quick capture — press ⌘⇧7 anywhere to capture every connected device without opening the menu.
- Launch at Login — keep TetherShot in your menu bar across reboots.
- Auto-check for Updates — quietly check npm for newer versions.
Updating
Use Check for Updates… in the menu, then Update & Relaunch — it runs npm install -g tethershot@latest, rebuilds, and relaunches itself. Or from the terminal:
tethershot updateHeads-up: the from-source build is ad-hoc signed, which isn't stable across rebuilds, so an update may re-trigger the one-time Camera permission prompt.
Troubleshooting
The iPhone isn't listed
Make sure it's unlocked and trusted, then hit Refresh Devices. Over USB it must appear as a screen source; a wireless-only connection surfaces as a camera, which TetherShot ignores by design.
“Capturing…” hangs or errors
Confirm the iPhone is unlocked. For Wi-Fi, ensure the tunneld service is running (tethershot setup-wifi installs it) and both devices share a network/subnet.
Camera permission blocked
Enable TetherShot under System Settings ▸ Privacy & Security ▸ Camera, then capture again.
Uninstall
tethershot uninstall # removes the app npm uninstall -g tethershot # removes the CLI bash scripts/uninstall-tunneld.sh # removes the Wi-Fi service
Questions or bugs? Open an issue on GitHub.