Automate SFTP and S3 uploads on a Mac with Shortcuts
The usual way to automate SFTP uploads on a Mac is a shell script around sftp or scp, run by hand or on a schedule. That works, but the script needs credentials it can use unattended, which usually means an SSH key with no passphrase sitting in a file. If your file transfer app exposes actions to Shortcuts, you can build the same automation without a script holding secrets: the app keeps the credentials in the Keychain, and Shortcuts, Finder or launchd tells it what to send. This post covers both approaches, with working examples.
The script approach, and its trade-offs
OpenSSH's sftp has a batch mode that reads commands from a file:
# upload.batch
cd /var/www/example.com/downloads
put build/release.zip
sftp -b upload.batch deploy@example.com
In batch mode, sftp stops at the first failing command and exits non-zero, which makes it easy to check from a script. The catch is authentication: batch mode can't answer a password prompt, so it needs key-based login, and a scheduled job can't type a key passphrase either. You end up with a passphrase-less key, or an ssh-agent that has to be running and unlocked whenever the job fires. Neither is wrong, but it's worth knowing that's the cost.
The sftp manual page documents batch mode and the - prefix that lets a command fail without aborting the batch.
Using Shortcuts to automate SFTP uploads on a Mac
Shortcuts on macOS can run actions provided by apps, take files as input, and be triggered in several ways that don't involve opening the Shortcuts app:
- From Finder, as a Quick Action: turn on "Use as Quick Action" in the shortcut's details, and it appears when you right-click a file.
- From the menu bar or Spotlight, by name.
- From the terminal, with the
shortcutscommand. - On a schedule, by having
launchdrun theshortcutscommand.
Apple's Shortcuts User Guide for Mac covers building shortcuts and Quick Actions in detail.
Wharf's Shortcuts actions
Wharf adds four actions to Shortcuts, and they work with any saved site, whether SFTP, FTP, FTPS or S3:
| Action | Takes | Returns |
|---|---|---|
| Upload File | File, Site, Remote Folder | The remote path it uploaded to |
| Download File | Site, Remote Path | The downloaded file |
| List Files | Site, Folder | The names in that folder, sorted |
| Sync Folder | Site, Local Folder, Remote Folder | A summary such as "3 uploaded, 0 downloaded" |
The Site parameter is a picker of the sites already saved in Wharf, not a hostname field. A shortcut can only reach servers you've set up, and no password, key or secret ever appears in the shortcut itself. Leave Upload File's Remote Folder empty and it uses the site's start folder.
Sync Folder copies whatever is missing on either side, and where a file differs on both sides the newer copy wins. Files whose timestamps are too close to call are skipped and counted in the summary. It never deletes anything: deletion propagation needs a human to review the list, and a scheduled job has nobody to show it to. The post on sync deletions explains why that matters.
What a site needs before it can be automated
An automation has nobody to answer questions, so Wharf refuses rather than prompting, with an error saying what's missing:
- A saved credential. The password, S3 secret or imported key must be stored in the Keychain. Connect once in Wharf and save it.
- A trusted host key. For SFTP, connect once in Wharf and accept the server's host key. An automation never trusts an unknown key on your behalf; the host key guide explains why that check matters.
- No two-factor prompt. Sites set to SSH key + 2FA or Interactive / 2FA can't be automated, because a code has to come from a person.
- A direct connection. Automations connect straight to the site's host, so a site that's only reachable through a jump host won't connect from a shortcut.
Transfers made by these actions are recorded in Wharf's activity log alongside everything else, so an unattended upload is still on record.
Example: a Finder Quick Action that uploads
- In Shortcuts, create a new shortcut and name it "Upload to staging".
- In its details, turn on "Use as Quick Action" and choose Finder, so it receives files.
- Add Wharf's Upload File action. Set File to the shortcut's input, pick your staging site, and type the Remote Folder, for example
/var/www/staging/uploads. - Optionally, add a Show Notification action using the action's result, so you see the remote path when it's done.
Now right-click a file in Finder, choose Quick Actions, then "Upload to staging".
Example: a nightly upload on a schedule
First, build and test a shortcut, say "Nightly report upload", that uses Upload File or Sync Folder. Then check it runs from the terminal:
shortcuts run "Nightly report upload"
If the shortcut takes a file as input, pass it with --input-path:
shortcuts run "Upload to staging" --input-path ~/Desktop/report.pdf
To run it every night at 02:30, create ~/Library/LaunchAgents/com.example.nightly-upload.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.nightly-upload</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/shortcuts</string>
<string>run</string>
<string>Nightly report upload</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>2</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
</dict>
</plist>
Load it into your user session:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.nightly-upload.plist
A launch agent runs while you're logged in. If the Mac is asleep at 02:30, launchd runs the job when it wakes. To remove it later, use launchctl bootout with the same arguments.
Checking that it worked
Scheduled jobs fail quietly unless you look. Two places to check:
- The action's result. Upload File returns the remote path, and Sync Folder returns its summary. Add a notification, or append the result to a text file, so you have something to look at in the morning.
- Wharf's activity log. Open it with View › Activity Log… (
⌘⇧L) and filter to the site. An Upload File run is listed with its remote path and size, and a Sync Folder run as "Sync finished" with its summary. If Wharf was already open when the job ran, relaunch it to see the new entries. The audit trail post covers filtering and CSV export.
The Shortcuts actions are part of every edition of Wharf; see the features page for the rest, and the support page for credentials and Keychain questions.