tsm — Transmission CLI
A CLI for managing Transmission BitTorrent client via RPC. All commands output structured data with --json for easy parsing.
Setup
# Install
brew install lu-zhengda/tap/tsm
# Configure connection (interactive)
tsm login # plaintext password in config
tsm login --keychain # macOS Keychain (recommended)
tsm login --profile seedbox # named profile for multiple servers
# Verify
tsm health
Config file: ~/.config/tsm/config.toml (or ~/Library/Application Support/tsm/config.toml on macOS).
Env vars: TSM_HOST, TSM_PORT, TSM_USERNAME, TSM_PASSWORD, TSM_PROFILE.
Commands
Listing and Searching
tsm list # all torrents
tsm list --json # JSON output
tsm list --ids-only # one ID per line (pipe-friendly)
tsm list --filter downloading # by status
tsm list --filter "ratio>2.0 AND label:movies" # advanced filter
tsm list --filter "size>1GB AND age<7d" # size and age
tsm list --sort speed-down # sort by field
tsm search "ubuntu" # name search
Filter fields: ratio, size (KB/MB/GB/TB), progress, age (d/h/m).
Key:value: label:x, name:x, status:x. Combinator: AND.
Adding Torrents
tsm add path/to/file.torrent
tsm add "magnet:?xt=urn:btih:..."
tsm add https://example.com/file.torrent
tsm add <source> --paused # add without starting
tsm add <source> --download-dir /path # custom download location
Torrent Control
tsm start <id> # start (also accepts "all")
tsm stop <id> # stop (also accepts "all")
tsm verify <id> # verify data integrity
tsm reannounce <id> # force tracker reannounce
tsm move <id> /new/path # relocate data
tsm remove <id> # remove from client
tsm remove <id> --delete # remove and delete data (DESTRUCTIVE)
Sequential Download
tsm sequential <id> # enable (default)
tsm sequential <id> --on # enable explicitly
tsm sequential <id> --off # disable
Torrent Details and Files
tsm info <id> # detailed info
tsm info <id> --json # JSON output
tsm files <id> # list files with priority and wanted status
tsm files <id> --json # JSON file list
# Per-file priority
tsm files <id> --priority high --priority-indices 0,1
tsm files <id> --priority low --priority-indices 3
tsm files <id> --priority normal --priority-indices 0,1,2,3
# Skip/unskip files
tsm files <id> --skip 2,3 # don't download these files
tsm files <id> --unskip 2 # resume downloading this file
Labels
tsm label add <id> <label>
tsm label remove <id> <label>
tsm label list <id>
Tracker Management
tsm tracker list <id> # list with stats
tsm tracker add <id> <url> # add tracker
tsm tracker remove <id> <url> # remove tracker
tsm tracker replace --from <old-url> --to <new-url> # bulk replace across ALL torrents
Speed Limits
# Session-level
tsm speed # show current limits
tsm speed --set-down 1000 --set-up 500 # set limits (KB/s)
tsm speed --no-limit # remove all limits
tsm speed --alt-on # enable alt-speed mode
tsm speed --alt-off # disable alt-speed mode
# Per-torrent
tsm speed <id> # show torrent limits
tsm speed <id> --set-down 500 --set-up 100 # set limits
tsm speed <id> --priority high # high/normal/low
tsm speed <id> --no-honor-global # exempt from session limits
tsm speed <id> --no-limit # remove torrent limits
Seeding Policies
Policies are defined in config.toml:
[[policies]]
name = "hd-movies"
match_label = "4k"
seed_ratio = 2.5
seed_idle_minutes = 4320
[[policies]]
name = "tv-shows"
match_label = "tv"
seed_ratio = 1.5
seed_idle_minutes = 1440
tsm policy list # show configured policies
tsm policy apply --dry-run # preview what would change
tsm policy apply # apply to matching torrents
Monitoring
tsm health # connectivity, disk, port check
tsm session # server info
tsm stats # cumulative statistics
tsm free # disk space
tsm top # live TUI dashboard (q to quit)
tsm top --interval 5 # custom refresh interval
Watch Directory
tsm watch ~/Downloads # auto-add .torrent files
tsm watch ~/Downloads --paused --delete-after-add # add paused, remove .torrent
tsm watch ~/Downloads --notify # completion notifications
tsm watch ~/Downloads --on-complete "script.sh {name} {id} {download_dir}"
Template variables: {name}, {id}, {download_dir}, {size}, {ratio}.
Other
tsm config # show resolved configuration
tsm completions bash # shell completions (bash/zsh/fish)
JSON Mode
All read commands support --json. Always use --json when you need to parse output programmatically.
tsm list --json | jq '.[].name'
tsm list --ids-only | xargs -I{} tsm info {} --json
tsm health --json
tsm --json tracker list <id>
tsm --json policy list
tsm files <id> --json
Common Automation Patterns
Add torrent and prioritize video files
ID=$(tsm add "magnet:..." --json | jq -r '."torrent-added".id')
tsm files $ID --json | jq -r '.[] | select(.name | test("\\.(mkv|mp4|avi)$")) | .index' | \
tr '\n' ',' | sed 's/,$//' | xargs -I{} tsm files $ID --priority high --priority-indices {}
Clean up well-seeded torrents
tsm list --json | jq -r '.[] | select(.uploadRatio > 3.0) | .id' | \
while read id; do echo "Removing ID $id"; tsm remove $id; done
Apply policies and report
tsm policy apply --dry-run --json | jq '.[] | "\(.name): \(.policy)"'
Replace dead tracker everywhere
tsm tracker replace --from "udp://dead-tracker.com:1337/announce" --to "udp://new-tracker.com:1337/announce"
Monitor active downloads
tsm list --filter downloading --json | jq '.[] | {name, progress: (.percentDone * 100 | floor), speed: .rateDownload}'
Safety Rules
- NEVER run
tsm remove <id> --deletewithout explicit user confirmation — this permanently deletes downloaded data. - NEVER run
tsm removein a loop without showing the user what will be removed first. - Prefer
--dry-runbeforetsm policy apply. - Use read-only commands (
list,info,files,health,stats) freely. - Mutations (
start,stop,add,remove,speed,label,tracker,policy apply) should be confirmed when acting on multiple torrents. - When in doubt, show the user what you plan to do before executing.
Profiles
tsm --profile seedbox list # use named profile
TSM_PROFILE=seedbox tsm list # via env var
Exit Codes
0— success1— connection/RPC/IO error2— config/filter/keychain error3— torrent not found