jdownloader-mcp
The jdownloader-mcp server enables an AI agent to fully control a local JDownloader 2 instance across its download lifecycle.
Add Downloads: Add URLs with optional package name, priority, passwords, destination folder, and autostart; add encrypted container files (DLC, RSDF, CCF) by their content.
Inspect & Monitor: List linkgrabber packages/links with online status and resolution state; list download queue items with progress, speed, ETA, status, and save path; get overall download controller status; check URL availability without queuing; find packages by name; wait for a download package to finish/fail/stall (with timeout); monitor changes via server-side wait_for_change.
Control Downloads: Start, stop, pause, resume the entire queue; force-start specific items bypassing limits; set priority; enable/disable items; reset items for re-download; remove items with optional file deletion; promote linkgrabber items to download queue; set per-package save directory and configure extraction settings; one-shot download to add, queue, start, and retrieve a package in a single call.
Accounts & Hosters: List, add, remove, enable/disable, refresh premium/hoster accounts; query supported hosters and get premium signup URLs; manage FTP/HTTP basic-auth entries.
Configuration & Extensions: Get, list, and set ~2200 configuration keys; list and enable/disable extensions.
Issue Resolution: List pending captchas, fetch image, and submit a solution; list, get, and answer interactive dialogs; diagnose stuck queues and get prioritized fixes; trigger router reconnect; get a quick health summary with diagnose_queue and recommend.
Cleanup & Maintenance: Clear entire linkgrabber with backup/restore; clean download queue by category (finished, failed, offline, disabled, all); remove individual items.
System Control: Get storage info, restart JDownloader, get/set speed limit.
Advanced Features: Get/set variants for multi-variant links; rename packages/links; move items to new packages; retrieve resolved original download URLs.
Raw API Access: Call any JDownloader API endpoint via raw_action.
Enables downloading Instagram content through the server's smart_download router, using yt-dlp as a fallback when JDownloader cannot handle the URL.
Enables downloading Reddit videos through the server's smart_download router, using yt-dlp as a fallback when JDownloader cannot handle the URL.
Enables downloading TikTok videos through the server's smart_download router, using yt-dlp as a fallback when JDownloader cannot handle the URL.
Enables downloading YouTube videos through the server's smart_download router, using yt-dlp as a fallback when JDownloader cannot handle the URL.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@jdownloader-mcpAdd this .dlc container to JDownloader and start downloads when resolved."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
jdownloader-mcp
An MCP server that lets an agent drive a local JDownloader 2 through its entire download lifecycle — add links / containers, watch the linkgrabber resolve them, move them to the queue, set priority, force-start, track progress, inspect download/extract directories, and clean up.
It exists for the one download workload the shell can't already do: premium
hosters, one-click hosters, .dlc/.crypt containers, and captcha-gated folder
links. JDownloader stays the moat for that case — but plain video/social
URLs (TikTok, YouTube, X, Instagram, Reddit, ...) are often where JD's
plugins fall behind (anti-bot walls, "plugin outdated"). For those, the
server also carries a yt-dlp backend and a smart_download router that
tries JDownloader first and auto-falls-back to yt-dlp when a link breaks, so
the agent can finish the download either way instead of stopping at "left to
the shell."
Thin wrapper over myjdapi
and yt-dlp; built on the mcp 1.x FastMCP API.
Status: v0.6.0 — 62 tools.
monitor()is the tool for watching a queue over time: a live snapshot for polling — overall state + speed, download counts bucketed by category, active-download progress, and blocked hosts, in one call. The full v0.3 tool surface has now been exercised live against a real JDownloader 2: 24 safe tools (config, cleanup/update, variants/organize, extensions, dialogs, basic-auth/account creds reads, plus the original 34 v0.2.0 lifecycle/query/account tools) are live-verified, on top of 91+ mocked unit tests and the fullsmoke_test.pylifecycle. That live pass found and fixed two bugs:get_download_urls(now returns each link'surlviaquery_links) andget_variants(now handles non-variant links gracefully) — both are now live-verified working, as isset_variant. Destructive tools (clear_linkgrabber,update_jd,restart_jd,reconnect) remain unit-tested only by design — not exercised live.
Lifecycle
add_links / add_container ─▶ LINKGRABBER ─(move_to_downloads)─▶ DOWNLOADS ─▶ extract ─▶ remove
list_linkgrabber list_downloads / force_start / wait_forItem IDs (uuid) come from the list_* tools; most tools take
package_ids / link_ids plus a stage (linkgrabber | downloads).
See Agent lifecycle below for worked tool-call flows, and the full tool reference for every parameter.
Related MCP server: revula
Tools (62)
Every tool returns {"ok": true, "result": ...} on success or
{"ok": false, "error": "..."} on failure — no tool raises.
Lifecycle (16)
Tool | Parameters | Description |
|
| Add URLs to the linkgrabber. |
|
| Add a link container ( |
| — | List linkgrabber packages+links (online/offline status) and whether JD is still collecting. Use the |
| — | List download-queue packages with |
| — | Overall dashboard: state, running/paused, aggregate speed (bytes/s), premium, speed-limit state, bytes downloaded, and |
|
| Bounded poll of one download package (cap 120s). Returns finished / failed / stalled / still_running / not_found — finished/failed/stalled are terminal, re-call only on still_running. |
|
| Promote resolved linkgrabber items to the download queue. |
|
| Global queue control. |
|
| Force the given items to download now, bypassing queue/connection limits. |
|
| Set priority (HIGHEST..LOWEST) on items in the given stage (linkgrabber | downloads). |
|
| Enable/disable items in the given stage (linkgrabber | downloads). |
|
| Per-package save paths + the default download folder + extraction settings (extension enabled, custom extract path). |
|
| Set the download directory for the given download-queue packages. |
|
| Toggle the extraction extension and/or set a custom extract path. |
|
| Remove items from a list. |
|
| Reset download-queue items so they re-download from scratch. |
Ergonomic / composite (3)
Tool | Parameters | Description |
|
| One-shot download: add URLs, auto-move to the queue, start, and return the resulting download package. The common case in a single call. |
|
| Check whether URLs are online (and their size) WITHOUT queueing them. Resolves in the linkgrabber, reports per-link availability, then cleans up. |
|
| Find packages by name substring across both lists -> uuid + stage. |
Accounts / premium hosters (6)
Tool | Parameters | Description |
| — | List premium/hoster accounts: hostname, username, valid, traffic left, expiry (-1 = unlimited/none), enabled, uuid. |
|
| List hosters JDownloader supports (optionally filtered by substring). |
|
| Add a premium/hoster account. The password is a hoster credential supplied by the user; it travels through the My.JDownloader relay (end-to-end encrypted) to your JDownloader instance and is never stored by this server. |
|
| Remove hoster accounts by uuid. Irreversible — re-adding requires the credentials again. |
|
| Enable or disable hoster accounts by uuid. Disabling can stop in-flight premium downloads that rely on the account. |
|
| Refresh hoster account status/traffic (all accounts if none given). |
System / control (5)
Tool | Parameters | Description |
| — | Free/total disk per drive (with |
| — | Restart the JDownloader application (recovery). |
| — | Current download speed-limit state: enabled + limit in bytes/s. |
|
| Enable/disable the download speed limit and optionally set it (bytes/s). |
| — | Trigger a router reconnect to get a new IP (resets some hoster limits). |
Captcha — human-in-the-loop (3)
Tool | Parameters | Description |
| — | List captchas JDownloader is currently waiting on. |
|
| Fetch a pending captcha (image data) for a human to solve. |
|
| Submit a human-provided solution for a pending captcha. |
Config (generic settings) (3)
Tool | Parameters | Description |
|
| Read one JDownloader config value. |
|
| List JD config entries (interface/key/value), optionally filtered by substring. JD exposes ~2200 keys — always pass a filter and expect |
|
| Write one JDownloader config value; returns the re-read value. Use |
Cleanup, update & diagnostics (8)
Tool | Parameters | Description |
|
| Clear the ENTIRE linkgrabber list. With |
|
| Re-add links from a backup file written by |
|
| Remove a category of links from the download list (files stay on disk): |
| — | One-shot health summary of the download queue: totals, unfinished links bucketed by status and host, and pending captcha/dialog counts. The fast way to understand WHY a queue is stuck without dumping every link. |
| — | Turn the current queue state into prioritized, actionable fixes (offline links, anti-bot/plugin hosts, waiting captchas, stopped-with-pending, low disk, bad accounts). Priority 1 = most urgent. The "what should I do?" tool. |
| — | Live monitoring snapshot for polling: overall state + speed, download counts bucketed by category (downloading | pending | done | stopped | error | blocked), the currently-active downloads with progress/speed/eta, and which hosts are blocked. |
|
| Block (server-side) until the queue status changes, then return the new |
| — | Apply an available JDownloader update and restart it. Disruptive — downloads pause during the restart. |
Variants & organize (5)
Tool | Parameters | Description |
|
| List the variants (audio/video/quality) of a multi-variant link. |
|
| Select a variant (from |
|
| Rename a linkgrabber package ( |
|
| Move the given items into a new package named |
|
| Get the resolved original download URLs for the given linkgrabber items. |
Extensions (2)
Tool | Parameters | Description |
| — | List JDownloader extensions (id, name, installed, enabled). |
|
| Enable or disable a JDownloader extension by id (from |
Dialogs (3)
Tool | Parameters | Description |
| — | List interactive dialogs JDownloader is currently waiting on. |
|
| Fetch a pending dialog's details/options. |
|
| Answer a pending dialog with a data payload (shape per the dialog type). |
Basic-auth & account credentials (5)
Tool | Parameters | Description |
| — | List stored FTP/HTTP basic-auth entries. |
|
| Add an FTP/HTTP basic-auth entry ( |
|
| Remove FTP/HTTP basic-auth entries by id. |
|
| Update a hoster account's username/password. The password is a user-supplied credential; it travels the My.JDownloader relay (end-to-end encrypted) and is never stored by this server. |
|
| Get the signup/premium URL for a hoster. |
Escape hatch (1)
Tool | Parameters | Description |
|
| Call any JD API endpoint not wrapped above (e.g. premium accounts, captcha, reconnect, speed-limit). |
yt-dlp backend (2)
Tool | Parameters | Description |
|
| Download a URL directly via yt-dlp (thousands of video/social sites); bypasses JDownloader. For private/login-gated content pass |
|
| Known video/social sites (tiktok, youtube, x, instagram, reddit, ...) go straight to yt-dlp. Everything else is tried on JDownloader first; if the link breaks within |
16 + 3 + 6 + 5 + 3 + 3 + 8 + 5 + 2 + 3 + 5 + 1 + 2 = 62 tools.
Agent lifecycle
JDownloader keeps two separate lists. Understanding this is the key to using the tools correctly:
Linkgrabber — a staging area.
add_links/add_containerdrop URLs here; JD resolves them (checks online/offline, size, host) in the background. Inspect withlist_linkgrabber.Downloads queue — the actual download engine. Nothing downloads until an item is here. Promote resolved linkgrabber items with
move_to_downloads, or add withautostart=True/ use thedownloadtool to skip straight there. Inspect and poll withlist_downloads/status/wait_for.
uuid values returned by any list_* tool are the IDs (package_ids /
link_ids) that every other tool expects — there is no other way to get an
ID.
Config surface: JD exposes its full ~2,200-key settings tree via
get_config / list_config / set_config. Don't try to enumerate it —
start with list_config(filter=...) to find the interface/key you need, then
get_config/set_config on that exact pair. List cleanup: once you're
done with a package, clear_linkgrabber wipes the whole staging list —
by default it backs up every link URL first (backup=True), so the wipe is
recoverable via restore_linkgrabber(backup_file) — and clean_downloads
(what = finished | offline | failed | disabled | all) removes a category
of entries from the download queue (files stay on disk) — both are separate
from the per-item remove tool above. Stuck queue? Call diagnose_queue
first — it buckets unfinished links by status/host and surfaces pending
captcha/dialog counts in one call, before you reach for
list_downloads/list_captchas individually. Then call recommend() for
the quickest path to an actionable next step — it turns that same queue
state (offline links, anti-bot/plugin hosts, waiting captchas,
stopped-with-pending, low disk, bad accounts) into a prioritized fix list. Watching a queue over
time? monitor gives the same status/host buckets plus per-download
progress/speed/eta for active items — it's the one to poll on an interval
instead of re-calling diagnose_queue/list_downloads separately. Token-free
waiting: instead of calling monitor() on a timer, call wait_for_change
(optionally with since = the last snapshot's signature) — it blocks
server-side and only returns when the queue actually changes or the timeout
elapses, so you don't burn tokens on unchanged snapshots.
stateDiagram-v2
[*] --> Linkgrabber: add_links / add_container
Linkgrabber --> Linkgrabber: list_linkgrabber while resolving
Linkgrabber --> Downloads: move_to_downloads
Linkgrabber --> [*]: remove to discard
Downloads --> Downloads: control_downloads / force_start / set_priority
Downloads --> Downloads: list_downloads / status / wait_for to poll
Downloads --> Finished: wait_for returns finished
Downloads --> Failed: wait_for returns failed or stalled
Finished --> [*]: remove / get_directories
Failed --> Downloads: reset to retry
Failed --> [*]: removePolling pattern: list_downloads / status are the workhorses — call
them as often as you like. wait_for is a bounded convenience (hard-capped
at 120s server-side); for anything longer, loop: call wait_for, and if it
returns still_running, call it again. A stalled result means the item is
idle with no progress (captcha / reconnect needed / all links offline) —
don't re-poll blindly, investigate first (e.g. list_captchas).
"Just download this" (fire and forget)
1. download(urls=[...]) # add + auto-queue + start in one call
2. wait_for(package_id) # poll until finished/failed/stalled
3. get_directories(package_ids) # confirm where the files landedFor a fast preflight check without committing to a download, use
check_availability(urls) first — it reports online/offline + size and
leaves nothing queued (timed_out flags if the check itself ran out of time).
"Careful lifecycle" (inspect before committing)
1. add_links(urls, package="my-set")
2. list_linkgrabber() # confirm links resolved online, get uuid
3. move_to_downloads(package_ids=[uuid])
4. force_start(package_ids=[uuid]) # or control_downloads("start")
5. wait_for(package_id=uuid)
6. remove(stage="downloads", package_ids=[uuid]) # cleanup once finished"Manage premium accounts"
1. list_accounts() # see current hosters, validity, traffic
2. add_account(hoster, username, password) # add a new one, or:
set_account_enabled(enabled, account_ids) # temporarily disable one, or:
refresh_accounts(account_ids) # re-check traffic/validity"Precondition checks" (before a large or unattended download)
1. get_storage_info() # confirm free_gb on the target drive
2. list_accounts() # confirm the needed hoster account is valid/enabled
3. download(urls, dest=...)Downloading video / social (yt-dlp)
smart_download(url) is JDownloader-first with an auto-fallback to yt-dlp.
Known video/social hosts (tiktok, youtube, x/twitter, instagram, facebook,
reddit, vimeo, twitch, soundcloud, ...) route straight to ytdlp_download.
Everything else is tried on JDownloader's download first; if that link
breaks within jd_wait_s seconds (default 45 — offline / error /
plugin-outdated / stalled), the failed JD entry is auto-removed and the URL
falls back to ytdlp_download. The result carries "routed_to": "jd" when
JD is handling it, or "routed_to": "jd->ytdlp" plus jd_outcome/jd_reason
when a fallback happened. Override with backend='ytdlp'|'jd' to force one
engine (strict, no fallback), or call ytdlp_download directly to skip the
router.
Private/login-gated content (your own TikTok videos, members-only posts) needs cookies — pick one:
cookies_from_browser='chrome'|'firefox'|'edge'|...— reads that browser's cookie store directly. On Windows the browser must be closed first (it locks the cookie DB while running).cookies_file='path/to/cookies.txt'— a Netscape-format cookies file exported via a "Get cookies.txt" browser extension. Works while the browser stays open.
ffmpeg must be on PATH for audio_only=True (audio extraction) and for
merging separate video+audio streams on formats that need it — yt-dlp will
otherwise fail or fall back to a lower-quality single-stream format.
Connection modes
Set via MYJD_CONNECT_MODE in .env (default relay):
relay(default) — connects via My.JDownloader, which works through NAT with no port-forwarding.myjdapiautomatically upgrades data calls to a direct LAN connection when JD advertises one, so only the initial handshake actually touches the cloud. UsesMYJD_EMAIL/MYJD_PASSWORD/MYJD_DEVICE.direct— pure-local via JDownloader's built-in RemoteAPI, no cloud account involved. SetMYJD_CONNECT_MODE=directplusMYJD_DIRECT_IP(default127.0.0.1) /MYJD_DIRECT_PORT(default3128). Requires enabling RemoteAPI in JDownloader first (Settings → Advanced Settings, search "RemoteAPI" / "Deprecated"). It's a deprecated, more limited API that may not support every tool here —relayis the full-featured default; only usedirectif you specifically need to avoid the cloud account.
Setup
In JDownloader: pick a connection mode (see above). For the default
relaymode, go to Settings → My.JDownloader, sign in / link the device, note its device name. Fordirectmode, instead enable RemoteAPI (Settings → Advanced Settings, search "RemoteAPI").Configure creds:
cp .env.example .env # then edit .envInstall deps (already done if you used
uv):uv syncDeps:
mcp,myjdapi,requests,yt-dlp. For the yt-dlp backend, also putffmpegon PATH (needed foraudio_onlyextraction and video+audio merges) — JDownloader-only usage doesn't need it.
Verify
uv run pytest # mocked unit tests (no JD needed)
uv run python smoke_test.py # live end-to-end against your JD2 (uses .env)The smoke test walks the whole lifecycle with a tiny file and cleans up. It SKIPs cleanly if the env vars aren't set.
Register with Claude Code
claude mcp add jdownloader -- uv run --directory E:/SWE-Pioneers/projects/jdownloader-mcp jdownloader-mcpor add to your MCP client config (stdio):
{
"mcpServers": {
"jdownloader": {
"command": "uv",
"args": ["run", "--directory", "E:/SWE-Pioneers/projects/jdownloader-mcp", "jdownloader-mcp"]
}
}
}The server reads MYJD_CONNECT_MODE plus either the relay creds
(MYJD_EMAIL / MYJD_PASSWORD / MYJD_DEVICE) or the direct-mode settings
(MYJD_DIRECT_IP / MYJD_DIRECT_PORT) from .env (or the environment). See
Connection modes.
Docs
docs/2026-08-01-jdownloader-mcp-design.md— design spec.docs/myjdapi-api-reference.md— exact installed-API reference the code targets.
License
MIT — see LICENSE.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server that wraps CubeCoders AMP to list, inspect, and control game-server instances.84MIT
- AlicenseNot gradedqualityCmaintenanceProduction-grade MCP server for universal reverse engineering automation.71GPL 3.0
- FlicenseAqualityDmaintenanceMCP server wrapping yt-dlp for downloading videos and audio from URLs, providing tools to check dependencies, retrieve video metadata, and perform downloads.4
- AlicenseNot gradedqualityAmaintenanceMCP server for interacting with Creo Parametric CAD software. Enables tool calls like file_open, feature_set, and J-Link execution through a Python-based server and optional Java gateway.MIT
Related MCP Connectors
An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform
MCP server for the FFmpeg Micro video transcoding API — create, monitor, download transcodes.
A basic MCP server to operate on the Postman API.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/swe-sanad/jdownloader-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server