GDM can be driven without its window in three ways:
- The app's own command line, the same switches as IDM's: hand a download to the running app from a script, a batch file or another program.
misterdownloadmanager-cli, a separate command-line tool: download files, videos and torrents in a terminal, with progress, without the app.- The automation API: other programs list the running app's downloads (as JSON) and pause, start, remove or delete them, over a local, token-protected channel. AI assistants use it through GDM's MCP server: see AI assistants.
To run the whole app without a window, on a home server or a NAS, see Run GDM on a server (misterdownloadmanager --headless); to control it from a phone, Control GDM from your phone.
The examples use Windows' paths; on macOS and Linux the programs have the same names without .exe.
The app's command line
misterdownloadmanager.exe /d URL [/p folder] [/f name] [/a] [/n] [/s]
| Switch | What it does |
|---|---|
/d URL |
The address to download. |
/p folder |
Save it in this folder (else the category's folder from Options → Save to). |
/f name |
Save it under this name. |
/a |
Add it to the main download queue without starting it. |
/n |
Silent: no Download File Info window, the download starts (or is queued, with /a) at once. |
/s |
Start the main download queue. |
/exit |
Save and close the running app (the installer uses it before an upgrade). |
/startup |
Start in the notification area, the window hidden: what Launch GolinksPRO Download Manager on startup starts GDM with when you sign in. Where no notification area shows GDM's icon (some Linux desktops), GDM starts minimized. A running GDM stays as it is. |
a .torrent file or magnet: link |
Open it in Add torrent (what Windows passes when GDM opens torrents). |
Switches can start with / or -, in any case. If GDM is running, the command goes to it; if not, GDM starts and carries it out. For example:
misterdownloadmanager.exe /d https://example.com/files/report.pdf /p D:\Reports /n
misterdownloadmanager.exe /d https://example.com/big.iso /a
misterdownloadmanager.exe /s
misterdownloadmanager-cli
It comes with every download of GDM, next to the app (the installer puts it in GDM's folder). It works on its own: the app needn't run, except for status and api.
| Command | What it does |
|---|---|
get URL [-o folder\|file] [-c connections] [-H "Header: value"]... [--checksum hash] [--dns choice] [--adapter name] |
Download a file with up to 8 connections (-c, 1 to 128), showing progress. Ctrl+C pauses it; resume continues. --checksum checks the finished file: hex MD5, SHA-1, SHA-256, SHA-512 or CRC32, optionally named (sha256:…). --dns picks the DNS: system (the default); a service and how to ask it, cloudflare-https, quad9-tls, google-plain, adguard-https, nextdns-tls; DNS servers' addresses, 9.9.9.9,149.112.112.112; or a DNS-over-HTTPS address. It never falls back to the system's DNS. --adapter sends every connection through one network adapter, by its name (Ethernet, wg0) or one of its addresses; when it isn't connected, nothing is sent and the download fails. A link from a file host that one of your debrid accounts (Options → Accounts) supports goes through that account, as in the app, and get says through Real-Debrid; --direct downloads the address itself (Debrid service accounts). |
resume file.mdm.json [-c connections] [-H ...] [--direct] |
Continue a paused or broken download from the .mdm.json file next to it. Through a debrid account, as get: the service gives a new link when the old one expired; --direct continues from the address itself. |
install-gallery-dl |
Install or update gallery-dl, for image galleries: its checksum list is checked against its author's signing key, the program against that list (Windows and Linux x86-64; elsewhere install it yourself). |
gallery-get URL [-o folder] [--limit N] [--adapter name] |
Download a gallery's pictures (a Wikimedia Commons category, a Flickr album, ...) into a folder named after it inside -o; --limit takes at most that many, the first the site lists. Started again, it fetches only the new ones. --adapter sends gallery-dl's connections through one network adapter, as for get. |
video-info URL |
What video a page holds (YouTube, Vimeo, ...), and the qualities to choose from. |
playlist-info URL [--from N] [--count N] |
A playlist's or channel's videos, one line each as they're listed: its place, length, title and address. |
playlist-get URL [-f selector] [-o folder] [--from N] [--count N] |
Download a playlist's or channel's videos one after another, into a folder named after the list inside -o. -f is one quality for all, as for video-get (by default each video's best; bv*[height<=720]+ba/b[height<=720] = up to 720p; ba = the original sound; mp3:320, opus:, flac: as for video-get). |
video-get URL [-f selector] [-o folder] [--subs langs] [--auto-subs] [--embed-subs] [--adapter name] |
Download a video; -f takes a quality's selector from video-info (b = the best single file; ba = the sound alone as the site has it, not converted; mp3:320, mp3:256, mp3:192 or mp3:128 = the sound as an MP3 at that bitrate, mp3:0 at its best variable one; opus: = as Opus; flac: = as FLAC, lossless but no better than the site's sound; conversions need ffmpeg). --subs saves subtitles beside it: language codes from video-info (en,fr), or all for every one the uploader gave; --auto-subs takes the site's automatic captions instead; --embed-subs puts them into the video (needs ffmpeg, MP4 or MKV). --adapter sends yt-dlp's connections (and ffmpeg's) through one network adapter, as for get; when it isn't connected, nothing starts. |
install-ytdlp, install-ffmpeg |
Install or update the helpers videos need: yt-dlp (checked against its signing key) and ffmpeg (Windows; on macOS and Linux GDM uses the system's). |
torrent-info SOURCE |
A torrent's name, files (numbered) and size; SOURCE is a magnet link or a .torrent file. |
torrent-get SOURCE [-o folder] [--files 0,2] [--use-existing] |
Download a torrent, or only some of its files. If some of its files are already in the folder, it stops and names them; --use-existing uses them instead (what matches is kept, the rest downloaded). |
torrent-create PATH -o file.torrent |
Make a .torrent of a file or folder (peers find it through the DHT). |
status |
The running app's downloads, as JSON, with their ids (the automation API must be on). |
pause ID..., start ID... |
Pause running downloads, or start (resume) stopped, queued or failed ones, in the running app. |
remove ID..., delete ID... |
Take downloads off the running app's list: remove keeps their files, delete deletes them too. A running download is paused first (pause). |
api on, api off |
Turn the running app's automation API on or off. |
misterdownloadmanager-cli help <command> shows every option. A command that fails (the app isn't running, it answers with an error, a download breaks) exits with code 1. For example:
misterdownloadmanager-cli get https://example.com/big.iso -o D:\Downloads -c 16 --checksum sha256:9f86d0…
misterdownloadmanager-cli video-get "https://www.youtube.com/watch?v=aqz-KE-bpKQ" -f "b[height=720]"
misterdownloadmanager-cli torrent-get "magnet:?xt=urn:btih:…" --files 0
JSON for scripts and programs
With --json (before or after the command), every command prints JSON instead of text, one object per line, for scripts and AI agents to read:
| Command | Prints |
|---|---|
get, resume |
{"event": "through", "service"} first when the download goes through a debrid account, then a {"event": "progress", "downloaded", "size", "speed", "connections", "segments"} line every half second, then {"event": "done", "path", "size", "seconds"}, or {"event": "paused", "state"} after Ctrl+C (state is the file resume takes). |
video-get |
{"event": "progress", "downloaded", "size", "speed"} lines, then {"event": "done", "path", "subtitles", "subtitle_problems"}: the subtitle files saved beside it, and the languages the site refused ({"code", "name", "reason", "beside"}; beside: they came on a second try, beside the video instead of in it). |
torrent-get |
{"event": "progress", "phase", "downloaded", "size", "speed", "peers", "peers_seen"} lines, then {"event": "done", "path", "size"}, or {"event": "stopped", "downloaded", "seconds"} with --seconds. |
video-info |
{"title", "choices": [{"label", "format", "size"}], "subtitles": [{"code", "name", "automatic"}]}; a choice's format is what video-get -f takes, a subtitle's code what --subs takes. |
torrent-info |
{"name", "info_hash", "size", "files": [{"index", "size", "path"}]}. |
torrent-create |
{"info_hash", "path"}. |
install-ytdlp, install-ffmpeg |
{"tool", "version", "path"}. |
status, pause, start, remove, delete, api |
The app's answer, which is JSON already (see below). |
Sizes are in bytes (null while unknown), speeds in bytes per second. A failure prints {"error": "…"} and exits with code 1. For example:
misterdownloadmanager-cli --json get https://example.com/big.iso -o D:\Downloads
{"event":"progress","downloaded":4194304,"size":1073741824,"speed":52428800,"connections":8,"segments":8}
…
{"event":"done","path":"D:\\Downloads\\big.iso","size":1073741824,"seconds":20.4}
The automation API
Other programs can ask the running app what it is downloading, and pause, start, remove or delete downloads. The API is off by default; turn it on with misterdownloadmanager-cli api on (and off with api off).
How a program talks to GDM
- While it runs, GDM listens on a port of
127.0.0.1(this computer only) and writes the port and a secret token toipc.jsonin its data folder: - Windows:%APPDATA%\misterdownloadmanager\ipc.json- macOS:~/Library/Application Support/misterdownloadmanager/ipc.json- Linux:~/.local/share/misterdownloadmanager/ipc.json- A portable copy:data\ipc.jsonnext to the program.
The token changes at every start; only programs that can read your data folder (yours) can use it.
2. Connect to that port and send one line of JSON: the token and the command's fields, e.g. {"token": "<token>", "query": "list"}.
3. GDM answers with one line: ok for a command, or a JSON object for a question.
What it understands
Fields (besides token) |
Answer |
|---|---|
{"query": "list"} |
Every download and the total speed: {"downloads": [{"id", "file", "url", "path", "status", "size", "downloaded", "speed", "added", "category", "error"}], "speed": bytes per second, "queues": [{"name", "running", "ids"}], "categories": [{"key", "name"}], "free": bytes}. status is Queued, Downloading, Stopped, Complete or Error; size is null while unknown; error (why it failed) is there only for a download in Error; category is a category's key; free is the free space where downloads go (null when unknown). Only while the API is on. |
{"action": "pause", "ids": [3, 4]} |
Acts on downloads by id: "pause", "start", "remove" (file kept) or "delete" (file deleted too). Answers {"done": [3], "skipped": [{"id": 4, "why": "not running"}]}; a running download must be paused before it is removed or deleted. Only while the API is on. |
{"action": "start_queue", "queue": "Main download queue"} |
Starts (or with "stop_queue", stops) the queue of that name (a name from the list's queues). Answers {"done": [], "skipped": []}, or {"error": …, "code": "unknown-queue"}. Only while the API is on. |
{"api": true} / {"api": false} |
Turns the API on or off: {"api": true}. |
{"url": "https://…", "dir": "D:\\Files", "name": "a.zip", "silent": true} |
Adds a download, as the command line's /d /p /f /n do ("later": true is /a); ok. "category" (a key from the list's categories) puts it in that category's folder instead of the one its type picks; "queue" (a queue's name) is the queue it waits in with "later". Also with the API off, like the command line. |
{"start_queue": true} |
Starts the main download queue; ok. |
An unknown question or action is answered {"error": "…"}, as is a question while the API is off (then with "code": "api-off", for programs to check: the error text may change). A wrong token is answered denied.
Every request and answer is described, field by field, in a JSON Schema: automation-api.schema.json (also at https://misterdownloadmanager.com/automation-api.schema.json). It is made from the code the app answers with, so it stays exact; programs can check what they send and read against it, or generate their types from it.
Examples
PowerShell (Windows):
$ep = Get-Content "$env:APPDATA\misterdownloadmanager\ipc.json" | ConvertFrom-Json
$client = New-Object Net.Sockets.TcpClient("127.0.0.1", $ep.port)
$stream = $client.GetStream()
$writer = New-Object IO.StreamWriter($stream); $reader = New-Object IO.StreamReader($stream)
$writer.WriteLine((@{ token = $ep.token; query = "list" } | ConvertTo-Json -Compress))
$writer.Flush()
$reader.ReadLine() | ConvertFrom-Json | Select-Object -ExpandProperty downloads | Format-Table file, status, downloaded, size
$client.Close()
Python:
import json, os, socket
ipc = os.path.join(os.environ["APPDATA"], "misterdownloadmanager", "ipc.json") # see above elsewhere
ep = json.load(open(ipc))
with socket.create_connection(("127.0.0.1", ep["port"])) as s:
s.sendall((json.dumps({"token": ep["token"], "query": "list"}) + "\n").encode())
answer = json.loads(s.makefile().readline())
for d in answer["downloads"]:
print(d["file"], d["status"], d["downloaded"], d["size"])
To add a download instead, send {"token": "…", "url": "https://example.com/a.zip", "silent": true}.
Free, open source, no ads, no trial.
Download GolinksPRO Download Manager