XCopy is a macOS menu bar app for pasting local screenshots into remote terminal workflows.
It watches for a configurable global shortcut, uploads the image currently in the macOS clipboard to the matched SSH remote, then pastes the remote file path back into the focused input.
Remote terminal tools often cannot receive image paste events directly. XCopy turns this flow:
- Take a screenshot on macOS.
- Focus a remote terminal or coding agent session.
- Press the XCopy shortcut.
- Get a remote image path pasted into the prompt.
- Menu bar app with a compact native macOS UI.
- Default shortcut:
Command + Shift + V. - Configurable shortcut recording from the menu bar panel.
- Automatic SSH session detection through shell integration.
- Remote host configuration for user, host, port, upload directory, and transfer method.
- Built-in
scpandrsynctransfer modes. - Custom command templates for advanced transfer workflows.
- DMG packaging script.
-
Open
XCopy.app. -
Allow Accessibility permission when macOS asks.
-
Configure one or more remotes from the menu bar panel.
-
Open a new terminal after SSH integration is installed.
-
Connect normally:
ssh my-host
-
Copy a screenshot to the macOS clipboard.
-
Press
Command + Shift + Vin the remote terminal.
XCopy uploads the clipboard image and pastes a path like:
/data00/tmp/xcopy/xcopy-20260519-203303-134.png
On first launch, XCopy installs a shell integration into ~/.zshrc and creates:
~/.xcopy/bin/xcopy
The integration wraps interactive ssh calls so XCopy can map the focused terminal window to the correct remote host. Open a new terminal or run:
source ~/.zshrcThe wrapper still calls the system SSH binary at /usr/bin/ssh.
Each remote includes:
- Name
- User
- Host
- Port
- Remote directory
- Transfer mode
The pasted path is the remote absolute file path.
Custom commands run locally. Exit code 0 means the transfer succeeded.
Available placeholders:
{local}: local temporary image path{remote}: remote absolute path{fileName}: generated file name{host}: remote host{user}: remote user{port}: SSH port{directory}: remote directory{connection}:user@host
Example:
scp -P {port} {local} {connection}:{remote}Build and run:
./script/build_and_run.shVerify launch:
./script/build_and_run.sh --verifyPackage DMG:
./script/package_dmg.shThe DMG is written to:
dist/XCopy.dmg
For a GitHub release that opens without Gatekeeper warnings, build with a Developer ID Application certificate and notarize the DMG:
XCOPY_BUNDLE_ID="com.your-team.XCopy" \
XCOPY_CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
XCOPY_NOTARY_KEYCHAIN_PROFILE="xcopy-notary" \
./script/package_dmg.shCreate the keychain profile once with:
xcrun notarytool store-credentials xcopy-notary \
--apple-id "you@example.com" \
--team-id "TEAMID" \
--password "app-specific-password"You can also skip XCOPY_NOTARY_KEYCHAIN_PROFILE and pass
XCOPY_NOTARY_APPLE_ID, XCOPY_NOTARY_TEAM_ID, and
XCOPY_NOTARY_PASSWORD directly.
Validate the final artifact:
spctl -a -vvv -t open dist/dmg-root/XCopy.app
xcrun stapler validate dist/XCopy.dmg- macOS 14+
- Xcode / Swift toolchain
- SSH access to configured remotes
- macOS Accessibility permission for global shortcut handling