Claude never sees your passwords.
Credentials stay encrypted inside Ferry (AES-256-GCM). The skill tells Claude to reference connections by name; Ferry loads the secret in-process. It never appears in the chat, on the command line, or in a log.
For Claude · Free
Ferry ships a skill for Claude. Install it, and you can ask Claude to move files across your servers and buckets in plain English — “upload this to my web server,” “grab last night’s backups.” Claude uses Ferry’s ferry command under the hood, so it works by connection name and never sees a password.
Zero-trust by design Claude only ever sees the name of a connection — never a password.
ferry put ~/Downloads/app-2.1.0.zip webserver:/var/www/releases/webserver:/var/www/releases/. Want me to confirm it’s listed there?An example conversation. Claude runs Ferry locally; your credentials never leave the app.
Add your FTP, SFTP, S3 or cloud connections in the Ferry app once. Credentials are encrypted and stay on your machine.
In Ferry, open Command-Line Tool and Claude Skills and click install — or grab the SKILL.md below and drop it in ~/.claude/skills/ferry/.
Tell Claude what you need — “download the latest logs from prod,” “sync this folder to staging.” It picks the right connection and runs Ferry for you.
Ask in plain language; Claude picks the right connection and runs Ferry. Here’s what that looks like.
ferry cat prod:/var/log/nginx/error.log --max-bytes 200000/api/report. That endpoint looks slow — want me to pull the app log too?ferry get backups:/db/2026-07-16 ./restore -r./restore. They’re gzip’d SQL dumps — want me to check they extract cleanly?Safe by design
An assistant that can move files is powerful — so Ferry makes sure it can do that without ever holding a secret.
Credentials stay encrypted inside Ferry (AES-256-GCM). The skill tells Claude to reference connections by name; Ferry loads the secret in-process. It never appears in the chat, on the command line, or in a log.
Claude runs the ferry command locally on your machine — you can see each command it runs, and destructive actions like delete or overwrite always require an explicit confirmation.
The CLI writes what it did to Ferry’s plain-text activity log (never a secret), so there’s always a clear record of what moved where.
Files move directly between your computer and your own servers and buckets. Your connections live only on your machine — no account, nothing uploaded to us.
The easiest way is right inside the app: Ferry → Claude Skills → Install. Prefer to do it by hand? Download SKILL.md and drop it in ~/.claude/skills/ferry/.
--- name: ferry description: >- Move files to and from FTP, SFTP, Amazon S3, Google Cloud, and S3-compatible storage using the user's saved Ferry connections — without ever handling credentials. Use whenever the user asks to upload, download, list, read, or manage files on a remote server or bucket they keep in Ferry (e.g. "upload this to my web server", "what's in my backups bucket?", "download the latest logs from prod", "delete the old build on staging"). --- # Ferry CLI Ferry is a desktop file-transfer app. It ships a `ferry` command-line tool that moves files over the connections the user has **already saved in the app**. You drive that tool. ## The one rule: never handle credentials Connections are referenced **by name**. Ferry stores each connection's credentials encrypted and loads them itself, in-process. Therefore: - **Never ask the user for a password, key, host, or username.** If you need a connection, list the saved ones and use the name. - **Never put secrets on the command line.** There is no flag for a password — by design. - If the user wants a server you can't see, tell them to **add it in the Ferry app** (they may need to open Ferry → Settings → *Command-line tool* and click *Install "ferry" command* first). Do not try to create it with credentials. ## Finding the command Try `ferry` on the PATH first. If it isn't found, fall back to the binary inside the app bundle: ```bash FERRY="$(command -v ferry || echo /Applications/Ferry.app/Contents/MacOS/ferry-cli)" # (~/Applications/Ferry.app/... if it was installed for the current user only) "$FERRY" doctor --json ``` `ferry doctor --json` confirms the tool works and shows the config location and how many connections exist. If it errors or the command is missing, tell the user to install the CLI from **Ferry → Settings → Command-line tool**. ## Always start by listing connections ```bash ferry conn ls --json ``` Returns objects with `name`, `protocol`, `folder`, and a non-secret `summary`. Use the exact `name` (case-insensitive; `folder/name` also works if names collide). Never guess a name — list first. ## Commands Remote paths use `scp`-style syntax: `<connection>:/path`. Add `--json` to any command for machine-readable output you can parse. | Command | What it does | |---|---| | `ferry conn ls` | List saved connections (no secrets) | | `ferry conn test <name>` | Verify a connection works | | `ferry ls <conn>:/path` | List a remote directory (`-l` for sizes/dates) | | `ferry stat <conn>:/path` | Metadata for one entry; exit 4 if it doesn't exist | | `ferry tree <conn>:/path --depth N` | Bounded directory tree | | `ferry cat <conn>:/file` | Print a remote file to stdout (`--max-bytes` guard) | | `ferry get <conn>:/remote [local]` | Download a file (`-r` for a folder) | | `ferry put <local> <conn>:/remote` | Upload a file (`-r` for a folder) | | `ferry mkdir <conn>:/path` | Create a folder (`-p` for parents) | | `ferry mv <conn>:/a <conn>:/b` | Move/rename a file within one connection | | `ferry rm <conn>:/path --yes` | Delete a file (`-r --yes` for a folder) | | `ferry doctor` | Config location + connection count | `<conn>:/` or `<conn>:` means the connection's root. ## Safety and confirmations - **Destructive commands require `--yes`** (`rm`, `log clear`). Before running any `rm`, deleting, or overwriting existing remote data, **state exactly what will be affected and get the user's confirmation.** Do not add `--yes` on the user's behalf for a delete they didn't clearly ask for. - `get`/`put` refuse to overwrite an existing file unless you pass `--overwrite`. Prefer telling the user a file exists over silently clobbering it. - Prefer `ferry cat` / `ferry ls --json` to inspect before you mutate. ## Handling common errors - **Exit 4** = not found. For `stat`, that's a normal "doesn't exist" answer. - **Host key / certificate not trusted** — the error says to open the connection once in the Ferry app to review and trust the server. Relay that; you can't trust it from the CLI. - **"no saved connection called …"** — run `ferry conn ls` and use a real name. ## Examples ```bash # "Upload this build to my web server's releases folder" ferry put ./release.zip webserver:/var/www/releases/ # "What's in my backups bucket for January?" ferry ls backups:/2026/01 -l --json # "Show me the nginx error log on prod" ferry cat prod:/var/log/nginx/error.log --max-bytes 200000 # "Download the whole reports folder from staging" ferry get staging:/reports ./reports -r ``` Work only with the user's own connections and the paths they ask about. Don't send fetched file contents anywhere the user didn't request.
The skill needs Ferry’s ferry command — install it from the CLI page or the app’s Command-Line Tool panel.
Download Ferry, save your connections, install the skill — then just ask.