mtp-rs-cli 0.1.0

Universal MTP file transfer CLI built on mtp-rs
mtp-rs-cli-0.1.0 is not a library.

mtp-rs-cli

Crates.io CI License

A universal MTP file transfer CLI built on mtp-rs.

Talk to Android phones, Kindles, Garmin watches, media players, and other MTP devices with the same handful of commands. No libmtp, no libusb, no FFI. Pure Rust.

Install

cargo install mtp-rs-cli

The installed binary is called mtp-rs.

Quick tour

# Show visible devices.
mtp-rs devices
mtp-rs devices --json

# Inspect a specific device and its storages.
mtp-rs info --device SERIAL

# List files.
mtp-rs ls /
mtp-rs ls /Music --recursive

# Upload and download files.
mtp-rs put ./song.mp3 /Music/song.mp3 --replace
mtp-rs get /Music/song.mp3 ./song.mp3

# Create and remove remote objects.
mtp-rs mkdir /Upload
mtp-rs rm /Upload/old.bin --yes

# Rename, move, and copy remote objects.
mtp-rs rename /Upload/old.bin new.bin
mtp-rs mv /Upload/new.bin /Archive/new.bin
mtp-rs cp /Archive/new.bin /Archive/new-copy.bin

# Diagnose access, storage, and common USB ownership issues.
mtp-rs doctor

Remote paths are POSIX-like and absolute: /, /Music/song.mp3, /GARMIN/APPS/app.prg. Device-specific workflows are just normal file operations. For example, Garmin Connect IQ sideloading is:

mtp-rs put ./MyApp.prg /GARMIN/APPS/MyApp.prg --replace --verify

What you get

  • One CLI, every device: phones, watches, e-readers, media players. If it speaks MTP, this works.
  • JSON output with --json: every command emits structured JSON for shell pipelines and scripts.
  • Stable exit codes: 0 success, 2 no device, 3 ambiguous selection, 4 access denied, 5 bad remote path, 6 transfer error, 7 verification failed.
  • Streaming transfers: large uploads and downloads stream straight from disk to USB and back. No silent in-memory buffering.
  • --verify for uploads: read the file back from the device and byte-compare it against the local source.
  • Cross-platform: Linux, macOS, Windows.

Docs

See docs/cli.md for the full command reference: every flag, JSON schemas, exit codes, path semantics, and troubleshooting.

Platform notes

The CLI inherits the platform quirks of the underlying mtp-rs library. The big one to know about is macOS:

  • macOS ships ptpcamerad which grabs MTP devices on connect. You may need to kill it (pkill -9 ptpcamerad) or disable it (sudo launchctl disable system/com.apple.ptpcamerad) before the CLI can open a device.
  • Quit Android File Transfer.app if you have it installed. It also grabs devices on connect.
  • Recent macOS can deny USB access to processes started from background agents or random tool runners. If mtp-rs devices lists a device but info or get fails, try running from Terminal or iTerm with the Mac unlocked.
  • On Linux, you may need udev rules. See the lib README for the snippet.
  • Windows should work out of the box but is not extensively tested.

Garmin sideloading example

# Find the watch.
mtp-rs devices

# Push a Connect IQ app to the watch, replace if it exists, verify after.
mtp-rs put ./MyField.prg /GARMIN/APPS/MyField.prg --replace --verify

The CLI auto-detects Garmin watches that expose MTP as a vendor-class interface with an MTP interface string (Venu 2/2S, and likely others).

Contributing

See CONTRIBUTING.md in the repo root.

License

MIT OR Apache-2.0, at your option.