Docs / Tutorials

Script a File Transfer with kd

Two daemons on one machine, a file moved by commands alone. About 15 minutes.

What we will do

We run two independent KeibiDrop daemons on one machine, connect them to each other, and move a file from one to the other with kd commands. Everything we type is scriptable; everything we get back is JSON. This is the whole pattern an automation or an AI agent uses.

What you need

Start two daemons

Each instance needs its own state directory, its own socket, and its own ports. In terminal 1, start Alice:

KEIBIDROP_CONFIG_DIR=/tmp/kd-alice \
KD_SOCKET=/tmp/kd-alice.sock \
KD_INBOUND_PORT=26001 KD_OUTBOUND_PORT=26002 \
KD_SAVE_PATH=/tmp/kd-alice-files KD_NO_FUSE=1 \
kd start

In terminal 2, start Bob with different values:

KEIBIDROP_CONFIG_DIR=/tmp/kd-bob \
KD_SOCKET=/tmp/kd-bob.sock \
KD_INBOUND_PORT=26003 KD_OUTBOUND_PORT=26004 \
KD_SAVE_PATH=/tmp/kd-bob-files KD_NO_FUSE=1 \
kd start

Each daemon prints one JSON line and stays in the foreground. The line contains its socket, fingerprint, and paths. The daemons keep running; our commands go in terminal 3.

Talk to each daemon

A client command finds its daemon through KD_SOCKET. Set up two shell aliases in terminal 3:

alias alice='KD_SOCKET=/tmp/kd-alice.sock kd'
alias bob='KD_SOCKET=/tmp/kd-bob.sock kd'

Ask each for its fingerprint:

alice show fingerprint
bob show fingerprint

Each prints one line like {"ok":true,"data":{"fingerprint":"..."}}. Notice the shape: every kd response is one JSON object with an ok field.

Register and connect

Each side registers the other's fingerprint, then both connect:

AF=$(alice show fingerprint | jq -r .data.fingerprint)
BF=$(bob   show fingerprint | jq -r .data.fingerprint)

alice register "$BF"
bob   register "$AF"

alice connect &
bob   connect
wait

Both connect calls return when the session is up. Confirm it:

alice status | jq '.data.connection_status, .data.connection_mode'

The output should be "healthy" and a mode, here "lan" since both daemons share one machine.

Move a file

Create a file, share it as Alice, pull it as Bob:

echo "hello from alice" > /tmp/hello.txt
alice add /tmp/hello.txt
bob list | jq '.data'
bob pull hello.txt /tmp/kd-bob-files/hello.txt
cat /tmp/kd-bob-files/hello.txt

The last line prints hello from alice. The file crossed between two encrypted daemons on your machine.

Check results the right way

Before scripting further, one rule to learn now. Ask Bob for a file that does not exist:

bob pull no-such-file /tmp/x ; echo "exit=$?"

The response says {"ok":false,"error":"file not found: no-such-file"}, and the exit code is 0. kd's exit code is 1 only when the daemon socket is unreachable. A script must test the ok field:

bob pull no-such-file /tmp/x | jq -e '.ok' || echo "pull failed"

Watch an event

The daemon queues events you can poll:

alice poll-event

Right after connecting, this returns a line like {"ok":true,"data":{"event":"connection_mode:lan"}}. An empty queue returns an empty event string. Polling is non-blocking; an automation loops on it.

Shut down

alice stop
bob stop

Each daemon disconnects, cleans up, and exits. The sockets disappear.

What you learned

Where next