For Claude · Free

Move your files by
just asking Claude

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.

Ship a build to your web server
You
Upload the latest build in my Downloads to the releases folder on my web server.
Claude
On it — I’ll use your saved webserver connection.
Ferryferry put ~/Downloads/app-2.1.0.zip webserver:/var/www/releases/
Claude
Done — uploaded app-2.1.0.zip (4.2 MB) to 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.

Three steps to a file-moving assistant

  1. 1

    Save your connections

    Add your FTP, SFTP, S3 or cloud connections in the Ferry app once. Credentials are encrypted and stay on your machine.

  2. 2

    Install the command & skill

    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/.

  3. 3

    Just ask

    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.

See it in action

Ask in plain language; Claude picks the right connection and runs Ferry. Here’s what that looks like.

Check a remote log
You
Anything worrying in the nginx error log on prod?
Ferryferry cat prod:/var/log/nginx/error.log --max-bytes 200000
Claude
Mostly noise, but there are 12 “upstream timed out” errors in the last hour, all on /api/report. That endpoint looks slow — want me to pull the app log too?
Pull down last night’s backups
You
Download yesterday’s database backups from the backups bucket.
Ferryferry get backups:/db/2026-07-16 ./restore -r
Claude
Downloaded 3 files (1.2 GB) into ./restore. They’re gzip’d SQL dumps — want me to check they extract cleanly?

Safe by design

Giving Claude access, safely

An assistant that can move files is powerful — so Ferry makes sure it can do that without ever holding a secret.

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.

You stay in control.

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.

Every action is logged.

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.

No cloud middleman.

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.

Get the Ferry skill

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/.

Preview SKILL.md
---
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.

Ready to let Claude do the fetching and carrying?

Download Ferry, save your connections, install the skill — then just ask.