LocalSend MCP Skill
Use This Skill When
- The user mentions LocalSend, AirDrop-like transfer, or peer-to-peer file sharing.
- The task asks for an MCP server or tool set around LocalSend.
- Discovery/advertising needs to use NATS or Tailscale before transferring data.
Reality Check (LocalSend in This Repo)
localsend (Flox package) launches a GUI and does not exit for --help.
- Discovery uses UDP multicast
224.0.0.167:53317 (LAN only).
- Transfer runs HTTPS on port
53317; direct IPs are required across subnets.
- For headless automation, prefer a CLI client (e.g.,
jocalsend) or a small protocol wrapper.
Architecture: Advertise -> Negotiate -> Transfer -> Tune
- Advertise capabilities over NATS (or Tailscale if LAN multicast is blocked).
- Negotiate transport and parameters (LAN multicast vs direct IP).
- Transfer via LocalSend protocol/CLI.
- Tune throughput until spectral gap <= 0.25 (>= 75% of target throughput).
MCP Tool Set (Draft)
Discovery / Advertising
localsend_advertise:
- Inputs:
agent_id, device_name, localsend_port, tailscale_ip?, capabilities, spectral_gap_target
localsend_list_peers:
- Inputs:
source = localsend_multicast | nats | tailscale
Session Negotiation
localsend_negotiate:
- Inputs:
peer_id, preferred_transport, max_chunk_bytes, max_parallel
- Output:
session_id, transport, target_ip, port
Transfer
localsend_send:
- Inputs:
session_id, file_path, chunk_bytes, parallelism
localsend_receive:
- Inputs:
session_id, dest_dir, accept
Throughput Tuning
localsend_probe:
- Inputs:
session_id, probe_bytes, probe_parallelism
- Output:
throughput_bps, rtt_ms, loss_rate
localsend_session_status:
- Inputs:
session_id
- Output:
bytes_sent, bytes_received, throughput_bps, spectral_gap
Spectral Gap Heuristic (Practical)
Define:
spectral_gap = 1.0 - (observed_throughput / target_throughput)
Stop tuning when spectral_gap <= 0.25.
Tuning Loop:
- Start
chunk_bytes = 256KB, parallelism = 1
- Increase parallelism to 2, 4, 8 while loss < 1%
- Increase chunk size up to 1MB while RTT stable
- Recompute spectral gap each step
Integration Points in This Repo
- NATS broadcast helpers:
lib/synadia_broadcast.rb
- Tailscale patterns:
lib/tailscale_file_transfer_skill.rb
- MCP server reference:
mcp_unified_server.py
GitHub GraphQL (GH CLI) Reference
Use gh api graphql for contributor snapshots (limit: history(first: 100)):
gh api graphql \
-F owner=localsend \
-F name=localsend \
-F history=100 \
-f query='query($owner:String!,$name:String!,$history:Int!){
repository(owner:$owner,name:$name){
defaultBranchRef{name target{
... on Commit{
history(first:$history){
nodes{author{user{login} name}}
}
}
}}
}
}'
Aggregate top contributors:
gh api graphql -F owner=localsend -F name=localsend -F history=100 -f query='query($owner:String!,$name:String!,$history:Int!){repository(owner:$owner,name:$name){defaultBranchRef{name target{... on Commit{history(first:$history){nodes{author{user{login} name}}}}}}}}' \
| jq -r '.data.repository.defaultBranchRef.target.history.nodes[].author | if .user then .user.login else .name end' \
| sort | uniq -c | sort -nr | head -20
Duck Lake Snapshots (Feedback + Bidirectional Flow)
Persist LocalSend sessions and GitHub snapshots into DuckDB for time travel:
CREATE TABLE IF NOT EXISTS localsend_sessions (
session_id TEXT,
peer_id TEXT,
direction TEXT, -- send|receive
bytes BIGINT,
throughput_bps DOUBLE,
spectral_gap DOUBLE,
created_at TIMESTAMP
);
CREATE TABLE IF NOT EXISTS localsend_contributors_snapshot (
snapshot_at TIMESTAMP,
repo TEXT,
contributor TEXT,
commit_count INT
);
Store snapshots per run and query later with existing DuckDB time-travel commands.
Implementation Notes
- Avoid assuming LocalSend has a stable CLI; verify with
jocalsend --help if installed.
- If multicast discovery fails (Tailscale), use NATS to exchange
target_ip + port.
- Keep tool outputs structured; avoid dumping large blobs through MCP.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: localsend-mcp3description: LocalSend-based P2P transfer with MCP server design for NATS/Tailscale discovery and throughput tuning. Use when this capability is needed.4---56# LocalSend MCP Skill78## Use This Skill When9- The user mentions LocalSend, AirDrop-like transfer, or peer-to-peer file sharing.10- The task asks for an MCP server or tool set around LocalSend.11- Discovery/advertising needs to use NATS or Tailscale before transferring data.1213## Reality Check (LocalSend in This Repo)14- `localsend` (Flox package) launches a GUI and does not exit for `--help`.15- Discovery uses UDP multicast `224.0.0.167:53317` (LAN only).16- Transfer runs HTTPS on port `53317`; direct IPs are required across subnets.17- For headless automation, prefer a CLI client (e.g., `jocalsend`) or a small protocol wrapper.1819## Architecture: Advertise -> Negotiate -> Transfer -> Tune20211. **Advertise** capabilities over NATS (or Tailscale if LAN multicast is blocked).222. **Negotiate** transport and parameters (LAN multicast vs direct IP).233. **Transfer** via LocalSend protocol/CLI.244. **Tune** throughput until spectral gap <= 0.25 (>= 75% of target throughput).2526## MCP Tool Set (Draft)2728**Discovery / Advertising**29- `localsend_advertise`:30 - Inputs: `agent_id`, `device_name`, `localsend_port`, `tailscale_ip?`, `capabilities`, `spectral_gap_target`31- `localsend_list_peers`:32 - Inputs: `source` = `localsend_multicast` | `nats` | `tailscale`3334**Session Negotiation**35- `localsend_negotiate`:36 - Inputs: `peer_id`, `preferred_transport`, `max_chunk_bytes`, `max_parallel`37 - Output: `session_id`, `transport`, `target_ip`, `port`3839**Transfer**40- `localsend_send`:41 - Inputs: `session_id`, `file_path`, `chunk_bytes`, `parallelism`42- `localsend_receive`:43 - Inputs: `session_id`, `dest_dir`, `accept`4445**Throughput Tuning**46- `localsend_probe`:47 - Inputs: `session_id`, `probe_bytes`, `probe_parallelism`48 - Output: `throughput_bps`, `rtt_ms`, `loss_rate`49- `localsend_session_status`:50 - Inputs: `session_id`51 - Output: `bytes_sent`, `bytes_received`, `throughput_bps`, `spectral_gap`5253## Spectral Gap Heuristic (Practical)5455Define:56```57spectral_gap = 1.0 - (observed_throughput / target_throughput)58```59Stop tuning when `spectral_gap <= 0.25`.6061**Tuning Loop**:621. Start `chunk_bytes = 256KB`, `parallelism = 1`632. Increase parallelism to 2, 4, 8 while loss < 1%643. Increase chunk size up to 1MB while RTT stable654. Recompute spectral gap each step6667## Integration Points in This Repo68- NATS broadcast helpers: `lib/synadia_broadcast.rb`69- Tailscale patterns: `lib/tailscale_file_transfer_skill.rb`70- MCP server reference: `mcp_unified_server.py`7172## GitHub GraphQL (GH CLI) Reference7374Use `gh api graphql` for contributor snapshots (limit: `history(first: 100)`):7576```bash77gh api graphql \78 -F owner=localsend \79 -F name=localsend \80 -F history=100 \81 -f query='query($owner:String!,$name:String!,$history:Int!){82 repository(owner:$owner,name:$name){83 defaultBranchRef{name target{84 ... on Commit{85 history(first:$history){86 nodes{author{user{login} name}}87 }88 }89 }}90 }91 }'92```9394Aggregate top contributors:95```bash96gh api graphql -F owner=localsend -F name=localsend -F history=100 -f query='query($owner:String!,$name:String!,$history:Int!){repository(owner:$owner,name:$name){defaultBranchRef{name target{... on Commit{history(first:$history){nodes{author{user{login} name}}}}}}}}' \97 | jq -r '.data.repository.defaultBranchRef.target.history.nodes[].author | if .user then .user.login else .name end' \98 | sort | uniq -c | sort -nr | head -2099```100101## Duck Lake Snapshots (Feedback + Bidirectional Flow)102103Persist LocalSend sessions and GitHub snapshots into DuckDB for time travel:104105```sql106CREATE TABLE IF NOT EXISTS localsend_sessions (107 session_id TEXT,108 peer_id TEXT,109 direction TEXT, -- send|receive110 bytes BIGINT,111 throughput_bps DOUBLE,112 spectral_gap DOUBLE,113 created_at TIMESTAMP114);115116CREATE TABLE IF NOT EXISTS localsend_contributors_snapshot (117 snapshot_at TIMESTAMP,118 repo TEXT,119 contributor TEXT,120 commit_count INT121);122```123124Store snapshots per run and query later with existing DuckDB time-travel commands.125126## Implementation Notes127- Avoid assuming LocalSend has a stable CLI; verify with `jocalsend --help` if installed.128- If multicast discovery fails (Tailscale), use NATS to exchange `target_ip` + `port`.129- Keep tool outputs structured; avoid dumping large blobs through MCP.130131---132> Converted and distributed by [TomeVault](https://tomevault.io/claim/plurigrid) — claim your Tome and manage your conversions.133<!-- tomevault:4.0:skill_md:2026-04-11 -->