localsendd
[!NOTE] This is NOT a gui. it don't got buttons. If ya want to see it in action, check out israshell.
If you js wanna use localsend, get the official LocalSend app or some other tui.
This module aims for scripts, widgets, and whatever else program you'd wanna control localsend from
A LocalSend peer that runs in the background and talks JSON over a unix socket. One process holds the protocol state, and anything local just connects and asks for things instead of reimplementing multicast discovery and mTLS itself.
Socket's 0600 btw, so that's the whole auth story - nothing to configure, nothing to leak.
Full v2.2: multicast discovery with http subnet scan fallback, mutual-TLS
HTTPS mode, SHA-256 verification, PIN gating, sanitized file names so a peer
can't write outside download_dir or clobber something that's already there.
Install
uv tool install localsendd
or pipx install localsendd
Needs Python 3.11+ and openssl on PATH for HTTPS mode.
Run
Add to your autostart / execute:
localsendd &
then from anywhere:
localsendctl devices --scan
localsendctl send ~/Pictures/brian.png --to "Gassy Mario" --wait
localsendctl watch
Something incoming shows up in localsendctl status; localsendctl accept takes it and localsendctl reject turns it down.
Only one transfer moves at a time either direction though - start a second and
you just get busy back, no queue.
Running it supervised
localsendd is a foreground process that logs to stdout, so whatever starts it just captures the log. Point your init system at localsendd and das it
Pass --no-log-time if your logger already stamps lines (svlogd,
journald) or you'll get double timestamps.........
Configuration
defaults are optional, set them in $XDG_CONFIG_HOME/localsendd/config.toml:
alias = "workstation"
device_type = "desktop" # mobile | desktop | web | headless | server
port = 53317
download_dir = "~/Downloads/LocalSend"
encryption = true # HTTPS
pin = "1234"
unattended = false # see "Headless behavior"
CLI flags win over everything, then LOCALSEND_ALIAS, LOCALSEND_PIN and LOCALSENDD_SOCKET, then this file. Use the file for pin if you can bc --pin is visible to every local user in ps. --config PATH points the daemon at a different file, and config.example.toml has every key with comments.
alias, device_type, pin, encryption and visibility can be changed at runtime over the socket without a restart, the rest need one. Either way the file itself never hot reloads, and runtime changes aren't written back to it.
Disabling
set_discoverable false (or localsendctl visible off) keeps the daemon up and the port bound, but kills multicast announces, stops replying to other peers' announces, and 404s/403s /info, /register, prepare-upload, prepare-download, and download. Sending out still works.
Headless behavior
Accepting a transfer needs a human to click accept. With no control client attached, the daemon stays discoverable and answers /info, but declines incoming transfers immediately instead of parking the sender on a confirmation timeout nobody's there to answer. Sending out still works.
Setting unattended = true auto accepts into download_dir without confirmation. Now, anything on your network can send files to ya disk, so use a pin unless you enjoy surprises 👀.
Documentation
DOCS.md has the full control socket protocol reference, the complete configuration table, and a runnable Python client example.
Development
PYTHONPATH=src:tests python -m unittest discover -s tests -t tests
No dependencies beyond the standard library. Each test spins up a real daemon behind a real HTTP server on an ephemeral port, not mocks. Multicast and the subnet scan are stubbed out so none of it touches the actual network.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file localsendd-0.1.1.tar.gz.
File metadata
- Download URL: localsendd-0.1.1.tar.gz
- Upload date:
- Size: 55.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e60797f5f1746154d6f00ded56840eb8a2a8a6c4adcba350b7c467ef96880b4
|
|
| MD5 |
4dca8ae0a3cc8e84236ec75d1f6170cf
|
|
| BLAKE2b-256 |
932dd6a8c5d901f1201bf52197071e1543ffa3036ae9e8a5f698646eda033562
|
Provenance
The following attestation bundles were made for localsendd-0.1.1.tar.gz:
Publisher:
release.yml on hireri/localsendd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
localsendd-0.1.1.tar.gz -
Subject digest:
6e60797f5f1746154d6f00ded56840eb8a2a8a6c4adcba350b7c467ef96880b4 - Sigstore transparency entry: 2705029603
- Sigstore integration time:
-
Permalink:
hireri/localsendd@910790f2389d913203f54809d816ec4f93dd114f -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/hireri
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@910790f2389d913203f54809d816ec4f93dd114f -
Trigger Event:
push
-
Statement type:
File details
Details for the file localsendd-0.1.1-py3-none-any.whl.
File metadata
- Download URL: localsendd-0.1.1-py3-none-any.whl
- Upload date:
- Size: 39.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ea9ed89dbfca7ef55ec5519fcd67fd599b21b28137cd8023c90bdc64bde08a5
|
|
| MD5 |
f84a8044e4dc4af661b655491c255bc3
|
|
| BLAKE2b-256 |
26e346913d72490def7b0ad2f12a2a1de76ce3f63741100daf4d6a8e470d11c6
|
Provenance
The following attestation bundles were made for localsendd-0.1.1-py3-none-any.whl:
Publisher:
release.yml on hireri/localsendd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
localsendd-0.1.1-py3-none-any.whl -
Subject digest:
3ea9ed89dbfca7ef55ec5519fcd67fd599b21b28137cd8023c90bdc64bde08a5 - Sigstore transparency entry: 2705029679
- Sigstore integration time:
-
Permalink:
hireri/localsendd@910790f2389d913203f54809d816ec4f93dd114f -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/hireri
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@910790f2389d913203f54809d816ec4f93dd114f -
Trigger Event:
push
-
Statement type: