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.Last updated83MIT
- Alicense-qualityCmaintenanceProduction-grade MCP server for universal reverse engineering automation.Last updated69GPL 3.0
- Flicense-qualityDmaintenanceMCP server wrapping yt-dlp for downloading videos and audio from URLs, providing tools to check dependencies, retrieve video metadata, and perform downloads.Last updated
- Flicense-qualityCmaintenanceA production-ready MCP server providing file, system, math, and text utilities through a simple CLI client.Last updated
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