LAN SHARE Download
Docs · Command line

Command line

The lanshare command does everything the app does, without a window: send, receive on a server, manage hosts, share with a phone, read the history. It uses the same settings as the app, so both always agree.

Where to find it on each system is under Install; the Mac App Store version has no command line (editions). lanshare help <command> (or --help after any command) prints the same reference in the terminal.

At a glance
$ lanshare send server ~/Projects/photos
$ lanshare send 192.168.1.20 a.txt b.txt
$ lanshare send --group Office ~/Report.pdf -m "New version"
$ lanshare send nas ~/Project -x node_modules -x .git --compress
$ lanshare discover --add          # find and save computers on the network
$ lanshare hosts add server 192.168.1.20 --group Office
$ lanshare web ~/Photos            # link and QR for a phone: download and upload
$ lanshare receive                 # receive without a window (asks in the terminal)
$ lanshare mcp                     # MCP server for AI assistants

Sending#

A host is a saved host's name (or id, or address), or any host, IP or host:port. A saved host's extra addresses are tried in order (1.5 s each) until one answers. The receiver has up to 3 minutes to accept.

send#

Synopsis
lanshare send [OPTIONS] <HOST> <PATH>...
lanshare send [OPTIONS] --group <GROUP> <PATH>...
OptionDescription
-g, --group <GROUP>Send to every host in this group, one after another (then no host is given).
-m, --message <TEXT>A note for the receiver, shown when they are asked.
-x, --exclude <NAME>Leave these names out of folders (node_modules, .git, *.log); repeat for more. For this send only, on top of the exclude list in the settings (which it does not change).
-z, --compressCompress with zstd (unpacked automatically on arrival).
--no-compressDo not compress. Without either flag the setting decides (auto skips photos, videos and archives).
--syncUpdate the same names on the receiver: unchanged files are not sent, nothing is deleted there.
--jsonEvents as JSON lines, and control lines on stdin (see JSON events). One host only.
Examples
$ lanshare send "Test server" ./build -x node_modules -m "Build 214"
$ lanshare send 10.0.0.20:46000 ~/Movies/demo.mov --no-compress
$ lanshare send --group QA ~/release-notes.pdf
$ lanshare send nas ~/Photos/2026 --sync
Output
→ Test server (10.0.0.20): waiting for approval…
✓ build → Test server: 412.0 MiB (1284 files, 87.6 MiB/s, compressed −30%)

With --group, a host that fails does not stop the others; the command fails at the end with 1 of 3 hosts failed.

send-text#

Sends text (up to 1 MiB) instead of a file: from --text, or everything on stdin until it ends. The receiver sees it in LAN Share.

Synopsis
lanshare send-text [OPTIONS] <HOST>
OptionDescription
-t, --text <TEXT>The text. Without it, stdin is read to the end.
--jsonEvents as JSON lines, as with send --json.
Examples
$ lanshare send-text "Anna's MacBook" -t "https://staging.example.com/build/214"
$ git log -5 --oneline | lanshare send-text server
$ pbpaste | lanshare send-text office-pc          # the Mac clipboard

web#

Shares with a phone or any browser on the network, no app needed: prints a link to a page with the given files for download (folders as .zip) and an upload button. Without paths the page is upload-only. Runs until the time is up or Ctrl+C.

Synopsis
lanshare web [OPTIONS] [PATH]...
OptionDescription
--minutes <N>How long the link works, 1–1440. Default 15.
-p, --port <PORT>Port for the page. Default: any free one.
-d, --dir <DIR>Where uploads are saved. Default: the receive folder (or that sender's folder from receive-dir-for).
--jsonEvents as JSON lines; the stdin line stop (or the end of stdin) stops it.
Example
$ lanshare web ~/Documents/invoice.pdf ~/Photos/trip --minutes 30
Output
Open on a phone or in a browser (on the same network):

  http://192.168.1.31:51544/9f2c4e7a1b8d3f60c5e2a7b94d1f8e36/

The link is valid for 30 min. Stop: Ctrl+C

Hosts and groups#

hosts#

Synopsis
lanshare hosts list [--group <GROUP>] [--no-check] [--json]
lanshare hosts add <NAME> <ADDRESS> [--alt <ADDRESS>]... [--group <GROUP>]
lanshare hosts edit <HOST> [--name <NAME>] [--address <ADDRESS>] [--alt <ADDRESS>]... [--clear-alt] [--group <GROUP> | --no-group]
lanshare hosts remove <HOST>
lanshare hosts forget-key <HOST>
SubcommandDescription
list (ls)Saved hosts by group, each checked for being online. --no-check skips the check; --group shows one group.
addSaves a host. ADDRESS is host, IP or either with :port. --alt adds another address of the same computer (Wi-Fi, cable, VPN), tried after the main one; repeat for more.
editChanges name, address or group. --alt replaces the extra addresses, --clear-alt removes them, --no-group takes the host out of its group.
remove (rm)Deletes a host (not one from your organisation's policy).
forget-keyForgets the host's remembered key after it changed (for example LAN Share was reinstalled there); the next encrypted connection remembers the new one.
Examples
$ lanshare hosts add "Test server" 10.0.0.20 --alt 10.8.0.20 --group Servers
$ lanshare hosts edit "Test server" --address 10.0.0.42 --alt 10.8.0.42
$ lanshare hosts list --json | jq -r '.[] | select(.online) | .name'

groups#

Synopsis
lanshare groups list [--json]       # each group with how many hosts it has
lanshare groups add <NAME>
lanshare groups rename <GROUP> <NEW_NAME>
lanshare groups remove <GROUP>      # its hosts are kept, without a group

discover#

Finds LAN Share computers on the local network (UDP broadcast on port 45821, on every network this computer is on).

OptionDescription
--addSave the ones found as hosts (with their other addresses, if they answered on several).
--jsonOutput as JSON: [{"name","ip","port","alt"}]; alt (the same computer's other addresses) only when there are any.

ping#

Whether LAN Share answers on a host. Exit code 0 when it does, 1 when not, so it fits in scripts.

Example
$ lanshare ping "Test server" && lanshare send "Test server" ./build
Output
● Test server (10.0.0.20) is online

diagnose#

Checks step by step why sending to a host works or not: name lookup, TCP connection, the LAN Share protocol (with encryption and the key), and the version. Every address of a saved host is tried until one works. Exit code 1 when sending would not work; with --json, the result as one JSON object (the same as the MCP tool diagnose) and exit code 0.

Example
$ lanshare diagnose ubuntu-box
Output
Diagnosis: 192.168.1.50
  ✓ resolve      0.8 ms  192.168.1.50 resolves to 192.168.1.50:45821
  ✗ tcp       3004.5 ms  No answer from 192.168.1.50:45821 within 3 s: the computer is off, on another network, or a firewall blocks TCP port 45821
  ✗ protocol             Skipped: no connection
  ✗ version              Skipped: no connection
Error: cannot send to 192.168.1.50

Trust and keys#

pair#

Pairs with another computer: both show the same 6-digit PIN, the other person confirms, and from then on the two trust each other by key (transfers are accepted without asking). The host is saved if it was not already.

Synopsis
lanshare pair [--json] <HOST>
Output
Code: 482913
Make sure Test server shows the same code, and confirm there.
✓ Paired with test-server (10.0.0.20); it is now trusted.

--json: {"event":"code","code":"482913"}, then {"event":"done","name":…} or {"event":"failed","error":…,"cancelled":bool}; the stdin line cancel cancels.

trust#

Trusted senders: their transfers are accepted without asking.

Synopsis
lanshare trust list
lanshare trust add <SENDER> [--key <64 HEX DIGITS>]
lanshare trust remove <SENDER>

SENDER is an IP, a host name or a saved host's name. With --key only that exact key is trusted; without it, the saved host's key, or the first encrypted connection's, is remembered.

identity#

This computer's key fingerprint and addresses, to compare with what the other computer shows. --json adds the full public key and the key file's path.

Output
UOII-B7MX-GCIA-2VZ4
  192.168.1.31  en0
  10.8.0.31  utun4 (VPN)
  studio-mac.local

Receiving#

receive#

Receives without a window or tray, for servers, Raspberry Pis and terminals. Same protocol and safety rules as the app: each offer is asked about in the terminal.

OptionDescription
-d, --dir <DIR>Where to save. Default: the receive folder from the settings.
-p, --port <PORT>Port. Default: from the settings (45821).
-y, --yesAccept everything without asking. Trusted networks only: anyone on the network can then write files there. Without a terminal and without --yes, offers are declined.
On a server

Run lanshare receive as a service, and instead of --yes, pair the computers that send to it or add them with lanshare trust add: their transfers are accepted, everyone else's are declined when no one is there to answer.

~/.config/systemd/user/lanshare-receive.service
[Unit]
Description=LAN Share receiver

[Service]
ExecStart=/usr/bin/lanshare receive --dir %h/Inbox
Restart=on-failure

[Install]
WantedBy=default.target
Terminal
$ systemctl --user daemon-reload
$ systemctl --user enable --now lanshare-receive
$ loginctl enable-linger "$USER"     # keep it running after you log out

received#

The newest items in the receive folder. -n, --limit (default 20), --json.

This computer#

status#

Whether LAN Share is receiving, the port, the receive folder, the number of hosts and groups, and where the settings file is. --json for scripts.

Output
Computer:       studio-mac
Receiving:      on, port 45821
Receive folder: /Users/you/Downloads/LAN Share
Hosts/groups:   6 / 2
Settings:       /Users/you/Library/Application Support/lan-share/config.json

history#

Sent and received transfers, also declined and failed ones, newest first.

OptionDescription
-n, --limit <N>How many. Default 20.
--sent / --receivedOne direction only.
--jsonThe records as JSON (fields: see the MCP tool history).
Example
$ lanshare history --received --json | jq -r '.[] | select(.status=="done") | "\(.peer)\t\(.items | join(", "))"'

stats#

How much went where, the average speed and what compression saved, with a small chart per day. -d, --days (default 30), --json.

Output (shortened)
Last 7 days
  ↑ Sent:       617.9 MiB  (14 transfers)
  ↓ Received:  1004.9 MiB  (11 transfers)
  ⚡ Compression saved: 294.1 MiB
  Average speed: 5.3 MiB/s

  NAS                      ↑  600.0 MiB  ↓        0 B
  Anna's MacBook           ↑        0 B  ↓  888.0 MiB

config#

Synopsis
lanshare config show [--json]
lanshare config receive-dir <DIR>
lanshare config receive-dir-for <HOST> [DIR] [--clear]
lanshare config port <PORT>
lanshare config exclude [PATTERN]...
lanshare config speed-limit <MIB_PER_SEC>
lanshare config compression off|auto|always
lanshare config encryption on|off
SettingDescription
receive-dirWhere received items are saved.
receive-dir-forA separate folder for transfers from one host. Without DIR it shows the current one; --clear goes back to the usual folder.
portThe TCP and UDP port, default 45821. Restart LAN Share after changing it.
excludeNames always left out of folders; replaces the list. Default: .DS_Store Thumbs.db desktop.ini ._*. Quote patterns: '*.log'.
speed-limitSending speed limit in MiB/s; 0 is no limit.
compressionoff, auto (skips photos, videos and archives) or always.
encryptionon (default) or off, only for very old LAN Share versions.
Examples
$ lanshare config receive-dir-for "Scanner PC" ~/Scans
$ lanshare config exclude .DS_Store node_modules .git '*.log'
$ lanshare config speed-limit 50

open#

Opens the LAN Share window.

Licence and updates#

license#

Synopsis
lanshare license activate <KEY> [--json]
lanshare license status [--json]
lanshare license deactivate [--json]

Activates a LAN Share Pro key (from the purchase e-mail) on this computer, shows whether Pro is active and which tier (Pro, Team, Business), or releases this computer so the key can be used on another. The key is checked about once a week and stays active without a network. The --json output is one line: {"active","customer","email","key_hint","activated_at","validated_at","error","tier"}; the exit code is 0 whenever the command ran, also when the key was refused.

update#

Synopsis
lanshare update check [--auto] [--json]
lanshare update download [--dir <DIR>] [--json]
lanshare update skip [KEY] [--clear]
lanshare update auto [on|off] [--json]

Whether lanshare.io has a newer version, download it (checked against its SHA-256; prints the file's path), skip a version, or switch the daily automatic check on or off. Store versions never check. Details and what a check sends: Updates.

Commands for organisations#

Described with the features they belong to. The last column is what the computer needs: a Team or Business subscription, or nothing. The full edition counts as Business; the Mac App Store version has none of these (editions).

CommandWhat it doesNeeds
policy show [--json], policy check <FILE>The policy in force and where it comes from; check a file before deploying it. PolicyNothing (a policy is only applied with Team or Business)
policy applyPut the policy's computers and groups into the list now.Team
audit export [--days N] [--format csv|json] [-o FILE]Every transfer as CSV or JSON lines. Audit exportBusiness
automate [--once]Watch the policy's hot folders and send what lands in them. Hot foldersTeam
api [--port P] [--token T]A local HTTP API for scripts, on 127.0.0.1. Local APITeam
hub join <URL> [--token T | --token-stdin] [--key K] [--insecure] [--no-check]Join this computer to a Hub. Easiest is the join link from the Hub's Onboarding page, which carries the token and the key: lanshare hub join 'https://hub.example.com/join#token=…&key=…' (in quotes, so the shell leaves # and & alone); the apps take the same link. --key takes only answers signed with that Hub key; a public http:// address needs --insecure; --no-check saves without checking in first. JoinTeam
hub status | checkin | leaveThe Hub this computer belongs to; check in now; leave it.Nothing
hub serve --data DIR [--trusted-proxy IP|CIDR,…]Run LAN Share Hub. Run itNothing (the computers that join need Team)
mcp [--restricted <POLICY>]The MCP server for AI assistants (--restricted is the Mac app's built-in mode). MCPNothing

Scripting#

Exit codes#

  • 0 when the command did what it was asked, 1 when it did not; the reason is on stderr as Error: …. A declined transfer is an error: Error: Test server rejected the transfer.
  • Progress lines and waiting for approval… go to stderr; the results to stdout. Redirect stdout and only the result lines are left.
  • Exceptions, on purpose: send --json and send-text --json report a failure as a failed event and exit 0; diagnose --json exits 0 with "ok": false; license … --json and update check exit 0 when offline or refused (see their error field).
deploy.sh
#!/bin/sh
set -e
npm run build
if lanshare send "Test server" ./dist -x '*.map' -m "Build $(git rev-parse --short HEAD)"; then
  echo "delivered"
else
  echo "not delivered (declined, offline or failed)" >&2
  exit 1
fi

JSON output#

--json prints JSON instead of text for hosts list, groups list, discover, diagnose, status, history, stats, received, identity, config show, license, update, policy show and hub status. The shapes are the same as the results of the MCP tools.

JSON events#

send --json, send-text --json and web --json print one JSON object per line as things happen, and read control lines on stdin. This is how the apps drive the command.

send --json / send-text --json
{"event":"offer","files":1284,"bytes":432013312,"compress":true,"address":"10.0.0.20"}
{"event":"progress","done":104857600,"total":432013312}
{"event":"done","skipped_bytes":0,"encrypted":true,"fingerprint":"XYHX-HOSQ-JBXO-QLAF","sent":{…}}
{"event":"failed","rejected":true,"cancelled":false,"key_changed":false,"no_encryption":false,"message":"…"}

stdin: cancel, pause, resume. offer comes when the offer is sent (the receiver is now being asked), progress at most every 200 ms.

web --json
{"event":"ready","url":"http://192.168.1.31:51544/9f2c4e7a1b8d3f60c5e2a7b94d1f8e36/","urls":[…],"port":51544,"expires_in":900,"items":[{"name":"trip","is_dir":true,"files":48,"bytes":210763776}]}
{"event":"progress","kind":"download","name":"trip.zip","done":52428800,"total":null,"ip":"192.168.1.77"}
{"event":"download","name":"trip.zip","bytes":210763776,"complete":true,"ip":"192.168.1.77"}
{"event":"upload","name":"IMG_2041.HEIC","bytes":2457600,"path":"/Users/you/Downloads/LAN Share/IMG_2041.HEIC","ip":"192.168.1.77"}
{"event":"stopped","reason":"expired"}

stdin: stop, or close stdin. reason: stopped or expired; {"event":"error",…} is a failed upload, {"event":"failed",…} a page that could not start.

Something missing or wrong? Write to [email protected].