No description
Find a file
2026-06-25 06:11:01 -04:00
src added files 2026-06-25 06:07:15 -04:00
Cargo.lock added files 2026-06-25 06:07:15 -04:00
Cargo.toml added files 2026-06-25 06:07:15 -04:00
README.md added files 2026-06-25 06:07:15 -04:00

localsend-cli

A command-line client for LocalSend written in Rust. Send files and clipboard text to other devices on your local network, or run in receive mode to accept transfers from the official LocalSend app and other compatible clients.

This tool implements the LocalSend v2 protocol over HTTPS with UDP multicast discovery.

Features

  • Receive mode — Run as a headless LocalSend node that accepts incoming file transfers
  • Send files — Push a file to another device on the LAN
  • Clipboard sharing — Send the current clipboard contents as text to a remote device
  • Device discovery — Automatically scan the network for nearby LocalSend peers, or target a device by address
  • Protocol v2 — Compatible with the LocalSend v2 API (/api/localsend/v2/...)
  • TLS — Self-signed certificates generated at startup, matching LocalSend's fingerprint-based trust model

Requirements

  • Rust 1.70+ (edition 2021)
  • Linux (tested on Arch; uses X11 for clipboard access via arboard)
  • Devices must be on the same local network
  • UDP port 53317 and TCP port 53317 must be available

Installation

Clone the repository and build a release binary:

git clone https://git.sethhurst.com/seth/localsend-cli.git
cd localsend-cli
cargo build --release

The binary is placed at target/release/localsend-cli. You can copy it anywhere on your PATH.

Usage

Receive files (default)

Running without a subcommand starts the node in receive mode. It listens on https://0.0.0.0:53317, announces itself on the network, and saves incoming files to a downloads/ directory in the current working directory.

localsend-cli

Set a custom device name with --alias:

localsend-cli --alias "My Linux Box"

When a text file is received, its contents are also copied to your system clipboard automatically.

Send a file

localsend-cli send /path/to/file.pdf

If no target is given, the CLI scans the network for 3 seconds and prompts you to pick a device:

Scanning for devices (3s)...

Discovered devices:
  1: Alice's Phone (Pixel 8) - 192.168.1.42:53317
  2: Bob's Laptop (MacBook) - 192.168.1.55:53317

Enter the number of the device to send to: 1

To skip discovery, pass the target address directly:

localsend-cli send /path/to/file.pdf 192.168.1.42:53317

Send clipboard text

localsend-cli clipboard

This reads the current clipboard and sends it as a text/plain transfer. Like send, you can omit the target to use interactive device selection:

localsend-cli clipboard 192.168.1.42:53317

How it works

┌─────────────┐     UDP multicast      ┌─────────────┐
│  Device A   │ ◄──── 224.0.0.167 ────► │  Device B   │
│  (sender)   │       :53317            │  (receiver) │
└──────┬──────┘                        └──────┬──────┘
       │                                      │
       │  HTTPS  POST /api/localsend/v2/      │
       │         prepare-upload               │
       │  HTTPS  POST /api/localsend/v2/      │
       └──────── upload ─────────────────────►│
                                              ▼
                                        downloads/
  1. Discovery — Devices announce themselves via UDP multicast on 224.0.0.167:53317 with a JSON payload describing the device (alias, fingerprint, port, protocol).
  2. Prepare upload — The sender POSTs file metadata to the receiver's /api/localsend/v2/prepare-upload endpoint and receives a session ID and per-file tokens.
  3. Upload — The sender streams each file to /api/localsend/v2/upload with the session ID, file ID, and token as query parameters.
  4. Receive — The server writes files to downloads/ and copies text content to the clipboard.

Each run generates a fresh self-signed TLS certificate. The SHA-256 fingerprint of the certificate DER is used as the device identity, consistent with how LocalSend identifies peers.

Development

# Build
cargo build

# Run tests
cargo test

# Run in receive mode (debug build)
cargo run

# Run with a subcommand
cargo run -- send ./example.txt
cargo run -- --alias "Dev Node" clipboard

Project structure

src/
├── main.rs        # CLI entry point and command routing
├── client/        # Outbound file and text upload logic
├── server/        # HTTPS server (receive mode)
├── discovery/     # UDP multicast announce and scan
├── protocol/      # LocalSend v2 request/response types
└── crypto/        # Self-signed TLS certificate generation

Compatibility

Designed to interoperate with the official LocalSend desktop and mobile apps. Both sides must be on the same subnet and able to reach each other on port 53317.

When sending to a manually specified address, HTTPS is assumed. When a device is selected from the discovery scan, the protocol advertised by that device (HTTP or HTTPS) is used automatically.

License

No license file is included yet. Add one before distributing.