Sendme

v0.1.4

Send and receive files peer-to-peer using the sendme protocol from iroh.computer. Use when the user wants to share files, transfer files between machines, se...

2· 546· 5 versions· 0 current· 0 all-time· Updated 7h ago· MIT-0
byArnon K.@muninn-huginn

Install

openclaw skills install sendme-skill

Sendme

Peer-to-peer file transfer using iroh. No server uploads — files stream directly between machines via encrypted connections with automatic NAT traversal.

Installation

If sendme is not installed:

brew install sendme

Alternatively, install via Cargo: cargo install sendme

Sending Files

sendme send <path>
  • Accepts a file or directory path
  • Outputs a ticket — a long base32-encoded string the recipient needs
  • The process stays running until interrupted with Ctrl+C — the sender must remain online for the recipient to download
  • Present the ticket to the user and instruct them to share it with their recipient

Example:

sendme send ~/Documents/report.pdf
# Outputs: sendme receive blobaa...  (the ticket)

For directories, sendme bundles the entire folder recursively.

Non-Interactive / Headless Environments

sendme requires a TTY — it enables raw terminal mode for interactive features. In non-interactive environments (scripts, Docker, CI, agents), it will fail with:

Failed to enable raw mode: No such device or address

Use the Python PTY wrapper to provide a PTY and extract the ticket programmatically. This uses os.execvp() to invoke sendme directly without shell interpretation, avoiding shell injection risks:

import os, pty, select, signal, sys

def sendme_send(path):
    pid, fd = pty.fork()
    if pid == 0:
        os.execvp("sendme", ["sendme", "send", path])
    output = b""
    ticket = None
    while True:
        ready, _, _ = select.select([fd], [], [], 0.5)
        if ready:
            try:
                chunk = os.read(fd, 4096)
                if not chunk:
                    break
                output += chunk
                for line in output.decode(errors="replace").split("\n"):
                    if "sendme receive blob" in line:
                        ticket = line.strip().replace("sendme receive ", "")
                        print(ticket)
                        sys.stdout.flush()
            except OSError:
                break
        elif ticket:
            try:
                os.waitpid(pid, os.WNOHANG)
            except ChildProcessError:
                break
    try:
        os.kill(pid, signal.SIGTERM)
        os.waitpid(pid, 0)
    except (ProcessLookupError, ChildProcessError):
        pass
    return ticket

Receiving Files

sendme receive <ticket>
  • Downloads the file/folder to the current directory
  • Uses temporary .sendme-* directories during download, then moves atomically
  • Automatically verifies integrity via blake3 hashing
  • Resumes interrupted downloads automatically

Example:

sendme receive blobaafy...

Key Details

  • Connection: Direct peer-to-peer with TLS encryption. Falls back to relay servers if direct connection fails.
  • Resumable: Interrupted downloads continue from where they left off.
  • Integrity: All data is blake3-verified during streaming.
  • Speed: Saturates connections up to 4Gbps.
  • No size limit: Works with files and folders of any size.
  • Sender must stay online: The sendme send process must keep running until the recipient completes the download.

Version tags

latestvk9758y7v7rkde7msqhf5sjg5sh81m73t

Runtime requirements

Any binsendme

Install

Homebrew
Bins: sendme
brew install sendme