CLI reference
Every command accepts --json: stdout then carries one JSON object per line, each with an event field, and progress goes to stderr. Nothing ever prompts.
ferry send
ferry send [contact] <path>
Send a file or folder; prints a code unless a contact is named.
ferry send ./file print a code, wait for the other side to run ferry get <code>
ferry send ./folder folders keep their layout; symlinks are skipped
ferry send sam ./file to a paired contact; no code. They must be online:
running ferry up, ferry mcp, or ferry get.
Interrupted? Run the same command again; it resumes from what arrived.
| flag | default | meaning |
|---|---|---|
--lanes |
0 |
parallel connections (default: by size, up to 16) |
ferry get
ferry get [code] [--to dir]
Receive with a code, or from a contact.
ferry get 7-acorn-tulip-otter receive with a code into this folder
ferry get 7-acorn-tulip-otter --to ~/Downloads
ferry get --from ana wait for a paired contact to send
A name that is taken gets a suffix (photos-2/). Partial data is kept and
resumed when the same files are sent again.
| flag | default | meaning |
|---|---|---|
--from |
|
only accept from this contact |
--to |
. |
folder to save into |
ferry pair
ferry pair [code] [--name name]
Pair with someone once, so later sends need no code.
ferry pair print a code for the other person
ferry pair 7-acorn-tulip-otter --name sam
Both screens then show the same two words; if they differ, someone is in
the middle: run ferry forget <name> and pair again.
| flag | default | meaning |
|---|---|---|
--name |
|
what to call them (default: the name they chose) |
ferry msg
ferry msg <contact> "text"
Send a message (pipe text in for long ones).
ferry msg sam "I pushed branch x"
ferry msg sam --type request "please review branch x"
git diff | ferry msg sam --type patch
Delivered live if they are online, otherwise left in their mailbox.
| flag | default | meaning |
|---|---|---|
--data |
|
JSON to attach |
--reply-to |
|
ID of the message this answers |
--type |
note |
note, request, patch, file-offer, or your own |
ferry inbox
ferry inbox [--since n] [--from contact]
Show messages.
| flag | default | meaning |
|---|---|---|
--from |
|
only this contact |
--since |
0 |
only messages after this number |
ferry wait
ferry wait [--from contact] [--timeout 10m]
Wait for the next message.
ferry wait --from sam --timeout 10m
Exits 0 with the message, or 5 on timeout. --since <n> also returns a
message that arrived after cursor n but before you started waiting.
| flag | default | meaning |
|---|---|---|
--from |
|
only this contact |
--since |
-1 |
return the first message after this number (default: from now) |
--timeout |
10m0s |
give up after this long (e.g. 30s, 10m, 2h) |
ferry files
ferry files
List files contacts have sent to this machine.
| flag | default | meaning |
|---|---|---|
--since |
0 |
only files after this number |
ferry pipe
ferry pipe <contact> [port]
Connect stdin/stdout to a port on a contact's localhost (ssh ProxyCommand).
ssh -o ProxyCommand='ferry pipe box 2222' friend@box
Connects stdin and stdout to a port on a paired contact's localhost, over
the direct link (never a relay). The other side must run
ferry up --allow-pipe 2222; every other port, and anyone not paired, is
refused and logged there. With no port, ferry pipe uses the one port the
other side allows, if it allows exactly one. With ferry up running here,
the pipe goes through it.
ferry up
ferry up [--unit] [--allow-pipe ports]
Stay online in the background so contacts can reach you.
Stays online so contacts can reach this machine: messages are kept for
ferry inbox, files land in the files folder (ferry files). ferry up --unit
prints a systemd user unit and how to install it; ferry never installs it.
| flag | default | meaning |
|---|---|---|
--allow-pipe |
|
comma-separated localhost ports contacts may reach with ferry pipe (default: none) |
--unit |
false |
print a systemd user unit for running ferry in the background, and how to install it |
ferry check
ferry check
Test the connection to the rendezvous and STUN, and explain the results.
ferry mcp
ferry mcp
Serve ferry as MCP tools on stdio (for Claude Code and other agents).
Add to Claude Code once:
claude mcp add ferry -s user -- ferry mcp
Tools: send_message, read_messages, wait_for_message, send_file,
list_files_received, fetch_file, list_contacts, channel_status.
ferry contacts
ferry contacts
List paired contacts.
ferry forget
ferry forget <contact>
Remove a contact.
ferry config
ferry config [key [value]]
Show or change settings.
Exit codes
| code | meaning |
|---|---|
| 0 | ok |
| 1 | error (the message says what to do) |
| 2 | usage: a command or flag was wrong |
| 3 | authentication: wrong code, or a contact's key changed |
| 4 | offline: the contact or the rendezvous could not be reached |
| 5 | timeout: nothing happened in time (ferry wait) |
| 6 | integrity: data failed a hash check |
| 7 | declined: the other side said no |
| 130 | interrupted |