aria2-agent
by Rehui-2006
README.md
<div align="center">
# ๐ aria2-agent
### Built on top of [aria2](https://github.com/aria2/aria2) โ the world's fastest download utility.
**[English](./README.md)** ยท **[็ฎไฝไธญๆ](./README_CN.md)**
---
### โก The AI Agent download tool that finally gets it right.
[](https://opensource.org/licenses/MIT)
[](https://www.python.org/downloads/)
[](#)
[](https://modelcontextprotocol.io)
[](#)
[](https://github.com/aria2/aria2)
[](https://github.com/Rehui-2006/aria2-agent/actions/workflows/ci.yml)
[](https://github.com/Rehui-2006/aria2-agent/actions/workflows/daily-health.yml)
[](https://github.com/Rehui-2006/aria2-agent/stargazers)
[](https://github.com/Rehui-2006/aria2-agent/network/members)
[](#)
[](https://github.com/Rehui-2006/aria2-agent/commits/main)
[](#)
**AI Agent First** ยท **MCP Native** ยท **Zero Dependencies** ยท **Cross-Platform** ยท **100% Open Source**
[Quick Start](#-quick-start) ยท
[Why aria2-agent](#-the-problem) ยท
[Safety & Trust](#-safety--trust) ยท
[MCP Integration](#-mcp-server-mode) ยท
[10 Iron Rules](#-the-10-iron-rules)
</div>
---
## ๐ Safety & Trust
> **I built this for myself first. Then I thought, maybe someone else needs it too.**
Let me be straightforward with you:
**This is a wrapper, not a reimplementation.** aria2-agent doesn't replace aria2 โ it wraps aria2's JSON-RPC interface with safety rules that AI Agents need. The actual downloading is still done by [aria2](https://github.com/aria2/aria2), a battle-tested open-source project with 35,000+ stars and 20+ years of history.
**No backdoors. No telemetry. No data collection. None.**
- ๐ **One file, 959 lines.** You can read the entire source code in 10 minutes. There's nowhere to hide anything.
- ๐ซ **Zero network calls except to your own machine.** The only connection is `127.0.0.1` โ your local aria2 daemon. No "phone home", no analytics, no update checks.
- ๐ฆ **Zero dependencies.** Pure Python 3.8 standard library. No `pip install` supply chain risk. No hidden transitive dependencies. What you see is what you get.
- ๐ **Your secrets stay yours.** The RPC secret token is auto-generated locally and stored in `~/.aria2_agent/state.json`. It never leaves your machine.
- ๐ **The daemon only listens on localhost.** `--rpc-listen-all=false` means no external machine can connect. Not even your LAN.
- ๐ **MIT licensed.** Do whatever you want with it. Read it, audit it, fork it, sell it. No strings attached.
I'm a developer who got tired of AI Agents reporting "download complete" on corrupted files. So I wrote this. That's the whole story.
---
## ๐ฏ The Problem
When AI Agents (Claude, GPT, Cursor, etc.) download large files using `aria2c`, they hit a **silent killer**:
```
Agent: "Download this 50GB model file."
aria2c: *pre-allocates 50GB instantly*
Agent: *checks file size* โ "50GB? Download complete!"
Agent: *tries to use the file* โ ๐ฅ CORRUPTED / INCOMPLETE
```
**aria2's default `file-allocation=prealloc` creates a full-size placeholder file before any data arrives.** Any agent that checks file size to determine completion gets a **false positive 100% of the time**.
This isn't a bug in aria2 โ it's a fundamental mismatch between aria2's human-oriented design and what AI Agents need.
## ๐ก The Solution
**aria2-agent** is a purpose-built CLI + MCP Server that wraps aria2's JSON-RPC interface with **10 architecturally-enforced rules**:
1. **Forces `file-allocation=none`** โ no phantom files, ever
2. **Completes judgment via RPC only** โ `status == "complete"` AND `completedLength == totalLength`
3. **Pure JSON output** โ `json.loads(stdout)` and you're done
4. **Blocks rule circumvention** โ `FORBIDDEN_PER_TASK_OPTS` prevents per-task overrides
```bash
# One command. Agent gets clean JSON. No false positives. Ever.
python aria2cli.py add "https://example.com/model.safetensors" \
--dir ./downloads --out model.safetensors --wait --timeout 3600
```
```json
{"ok": true, "gid": "2089b056ea1d1f3c", "complete": true, "timed_out": false,
"elapsed": 120.5, "status": "complete",
"totalLength": "15200000000", "completedLength": "15200000000",
"files": [{"path": "./downloads/model.safetensors", "length": "15200000000"}]}
```
**Agent logic: `if result["complete"]: done` โ that's it.**
## โจ Features
| Feature | aria2c (raw) | aria2p | wget | **aria2-agent** |
|---------|:---:|:---:|:---:|:---:|
| AI Agent JSON output | โ | โ | โ | โ
|
| Pre-allocation false-positive fix | โ | โ | โ | โ
|
| Built-in retry + resume | Manual | Manual | โ | โ
|
| MCP Server mode | โ | โ | โ | โ
|
| Rule circumvention prevention | โ | โ | โ | โ
|
| Zero dependencies | โ
| โ | โ
| โ
|
| Cross-platform | โ
| โ
| โ
| โ
|
| Multi-source mirror download | โ
| โ
| โ | โ
|
| BT / Magnet support | โ
| โ
| โ | โ
|
## ๐ Quick Start
### Prerequisites
- Python 3.8+
- aria2c in PATH ([install guide](https://aria2.github.io/))
### Install
```bash
# Option 1: pip (recommended)
pip install aria2-agent
# Option 2: just download the single file โ zero dependencies
curl -O https://raw.githubusercontent.com/Rehui-2006/aria2-agent/main/aria2cli.py
```
### 3-Step Usage
```bash
# Step 1: Start the RPC daemon (once per session)
python aria2cli.py start --dir ~/Downloads
# Step 2: Download and wait for completion
python aria2cli.py add "https://example.com/large_file.bin" \
--dir ~/Downloads --out file.bin --wait --timeout 3600
# Step 3: Agent reads JSON โ checks "complete" field โ done
```
### Verify Rules Are Enforced
```bash
python aria2cli.py verify
```
```json
{
"ok": true,
"file_allocation": "none",
"no_file_allocation_limit": "0",
"rules_checked": {
"rule2_file_allocation_none": true,
"rule2_no_file_allocation_limit_zero": true,
"rule3_completion_via_rpc_only": true,
"rule4_no_local_file_for_judgment": true
}
}
```
## ๐ Core Usage
### Standard Download (most common)
```bash
python aria2cli.py add "https://example.com/file.zip" \
--dir ./downloads --out file.zip --wait --timeout 3600
```
### Large File Download (models, datasets)
```bash
python aria2cli.py add "https://huggingface.co/model.bin" \
--dir ./models --out model.bin \
--split 16 --wait --timeout 3600 --retries 3
```
- `--split 16`: 16 parallel connections
- `--retries 3`: auto-resubmit on failure (same dir+out = aria2 resume, no re-download)
### Async Download (submit then poll)
```bash
# Submit, get gid
python aria2cli.py add "https://example.com/file.zip" --dir ./dl --out f.zip
# Poll later
python aria2cli.py status <gid>
python aria2cli.py wait <gid> --timeout 3600
```
### Multi-Source Mirror
```bash
python aria2cli.py add \
"https://mirror1.example.com/file.iso" \
"https://mirror2.example.com/file.iso" \
"https://mirror3.example.com/file.iso" \
--dir ./isos --out ubuntu.iso --wait
```
### Proxy / Custom Headers / SSL Bypass
```bash
# Via JSON options (no shell escaping issues)
python aria2cli.py add "https://example.com/file" \
--dir ./dl --out file --wait \
--options '{"all-proxy":"http://127.0.0.1:1080","check-certificate":"false"}'
# Or use --options-file to avoid shell quoting hell
echo '{"header":["Authorization: Bearer xxx","Referer: https://example.com"]}' > opts.json
python aria2cli.py add "https://example.com/file" \
--dir ./dl --out file --wait --options-file opts.json
```
### Task Management
```bash
python aria2cli.py status <gid> # Check status (complete field = done check)
python aria2cli.py list # List all tasks
python aria2cli.py pause <gid> # Pause
python aria2cli.py resume <gid> # Resume
python aria2cli.py remove <gid> # Remove (keeps downloaded data)
python aria2cli.py remove <gid> --force # Force remove
python aria2cli.py stop # Stop daemon
```
## ๐ MCP Server Mode
aria2-agent ships with a built-in [Model Context Protocol](https://modelcontextprotocol.io) server โ **8 tools, zero config**:
```bash
pip install "aria2-agent[mcp]"
python aria2cli.py mcp
```
### MCP Tools
| Tool | Description |
|------|-------------|
| `aria2_add` | Submit download task, returns gid |
| `aria2_status` | Query normalized status (complete via RPC only) |
| `aria2_wait` | Poll until complete (built-in retry + resume) |
| `aria2_pause` | Pause a task |
| `aria2_resume` | Resume a paused task |
| `aria2_remove` | Remove a task |
| `aria2_list` | List all tasks |
| `aria2_verify` | Verify iron rules are enforced |
### Claude Desktop Integration
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"aria2-agent": {
"command": "python",
"args": ["-m", "aria2cli", "mcp"]
}
}
}
```
### Cursor / VS Code Integration
```json
{
"mcp.servers": {
"aria2-agent": {
"command": "python",
"args": ["aria2cli.py", "mcp"]
}
}
}
```
See [docs/AGENT_INTEGRATION.md](docs/AGENT_INTEGRATION.md) for detailed integration guides.
## ๐ก๏ธ The 10 Iron Rules
These rules are **architecturally enforced** โ not guidelines, not config defaults. Violating any rule requires a rewrite.
| # | Rule | Enforcement |
|---|------|-------------|
| 1 | **RPC daemon only** โ no blocking `aria2c` single commands | `start_daemon()` is the only entry point |
| 2 | **Force `--file-allocation=none --no-file-allocation-limit=0`** | `MANDATORY_DAEMON_ARGS` tuple, always prepended |
| 3 | **Complete = RPC `tellStatus` double check** | `is_complete()` checks `status=="complete"` AND `completedLength==totalLength` |
| 4 | **Never read local file size for completion** | Only `show_local` flag reads size, labeled `local_file_size_display_only` |
| 5 | **All params via JSON-RPC, never shell strings** | `rpc_call()` uses `json.dumps()`, never `shell=True` |
| 6 | **Clean subcommand CLI** | `argparse` with `add/status/pause/resume/remove/start/stop/wait/list/verify/mcp` |
| 7 | **Pure JSON output, no logs/progress/colors** | `emit()` writes `json.dumps()` to stdout, nothing else |
| 8 | **Built-in 3x retry, 3600s timeout, resume** | `wait_for_complete()` with `max_retries=3`, `DEFAULT_TIMEOUT=3600` |
| 9 | **Cross-platform Windows/Linux/macOS** | `os.name` detection, `DETACHED_PROCESS` on Windows, `start_new_session` on POSIX |
| 10 | **Optional MCP Server** | `run_mcp_server()` with 8 FastMCP tools |
### Rule Circumvention Prevention
```python
FORBIDDEN_PER_TASK_OPTS = {
"file-allocation",
"no-file-allocation-limit",
"enable-rpc",
"rpc-listen-port",
"rpc-listen-all",
"rpc-secret",
"rpc-allow-origin-all",
}
```
Even if an agent passes `{"file-allocation": "prealloc"}` in `--options`, it's **silently rejected** with a warning. The iron rules cannot be bypassed.
## ๐ Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success / download complete |
| 1 | Business error (RPC error, download failed) |
| 2 | Wait timeout (file may be partially downloaded, can resume) |
## ๐ฏ Use Cases
### Downloading AI Models
```bash
python aria2cli.py add "https://huggingface.co/llama/model.safetensors" \
--dir ./models --split 16 --wait --timeout 7200 --retries 3
```
### Downloading Datasets
```bash
python aria2cli.py add "https://data.example.com/dataset.tar.gz" \
--dir ./data --out dataset.tar.gz --wait
```
### BT / Magnet Links
```bash
python aria2cli.py add "magnet:?xt=urn:btih:..." \
--dir ./torrents --wait --timeout 7200
```
### Multi-Source ISO Download
```bash
python aria2cli.py add \
"https://mirror1/ubuntu.iso" "https://mirror2/ubuntu.iso" \
--dir ./isos --out ubuntu.iso --wait
```
## โ FAQ
<details>
<summary><b>Why not just use aria2c directly?</b></summary>
aria2c is designed for humans. Its default `file-allocation=prealloc` creates full-size placeholder files instantly. AI agents that check file size get false completion signals 100% of the time. aria2-agent forces `file-allocation=none` and uses RPC `tellStatus` for reliable completion detection.
</details>
<details>
<summary><b>Why not use huggingface-cli for model downloads?</b></summary>
Use `huggingface-cli` for HuggingFace downloads โ it has native ETag verification and `hf_transfer` acceleration. aria2-agent is for everything else: direct HTTP links, FTP, BT, magnet, multi-source mirrors, and any scenario needing RPC-precise completion checking.
</details>
<details>
<summary><b>Why not yt-dlp for video downloads?</b></summary>
Use `yt-dlp` for YouTube/Bilibili etc. aria2-agent is for direct file downloads โ models, datasets, ISOs, archives, BT torrents.
</details>
<details>
<summary><b>Is the RPC daemon secure?</b></summary>
Yes. The daemon binds to `127.0.0.1` only (`--rpc-listen-all=false`), auto-generates a random secret token, and stores state in `~/.aria2_agent/state.json`.
</details>
<details>
<summary><b>Can I use an external aria2 RPC daemon?</b></summary>
Yes:
```bash
python aria2cli.py start --external http://your-host:6800/jsonrpc
```
</details>
## ๐๏ธ Architecture
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ AI Agent โ
โ (Claude / GPT / Cursor / ...) โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโ
โ CLI โ MCP
โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโ
โ aria2cli.py โ โ MCP Server (8 tools) โ
โ โ โ โ
โ โโโโโโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโโโโ โ
โ โ 10 Iron Rules โ โ โ โ FastMCP โ โ
โ โ Enforcement โ โ โ โ Tool Registry โ โ
โ โโโโโโโโโฌโโโโโโโโโ โ โ โโโโโโโโโฌโโโโโโโโโโ โ
โ โ โ โ โ โ
โ โโโโโโโโโผโโโโโโโโโ โ โ โโโโโโโโโผโโโโโโโโโโ โ
โ โ JSON-RPC โโโโผโโโผโโโค JSON-RPC โ โ
โ โ Client โ โ โ โ Client โ โ
โ โโโโโโโโโฌโโโโโโโโโ โ โ โโโโโโโโโฌโโโโโโโโโโ โ
โโโโโโโโโโโโผโโโโโโโโโโโโ โโโโโโโโโโโโผโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ aria2c RPC Daemon โ
โ --enable-rpc --file-allocation=none โ
โ --no-file-allocation-limit=0 โ
โ (mandatory, non-overridable) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full design document.
## ๐ฆ Installation (Detailed)
### Install aria2c
| Platform | Command |
|----------|---------|
| Windows | `choco install aria2` or `scoop install aria2` |
| macOS | `brew install aria2` |
| Ubuntu/Debian | `sudo apt install aria2` |
| CentOS/RHEL | `sudo yum install aria2` |
| Arch Linux | `sudo pacman -S aria2` |
### Install aria2-agent
```bash
# Via pip (with MCP support)
pip install "aria2-agent[mcp]"
# Via pip (CLI only, zero deps)
pip install aria2-agent
# Or just download the single file
wget https://raw.githubusercontent.com/Rehui-2006/aria2-agent/main/aria2cli.py
```
## ๐ค Contributing
Contributions are welcome! Please read the [10 Iron Rules](docs/ARCHITECTURE.md#the-10-iron-rules) first โ any PR that weakens a rule will be rejected.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing`)
5. Open a Pull Request
## ๐ Changelog
See [CHANGELOG.md](CHANGELOG.md).
## ๐ License
MIT โ see [LICENSE](LICENSE).
## ๐ Dashboards
- [๐ Health Dashboard](./.github/HEALTH.md) โ Daily automated health check results
- [๐ Stats Dashboard](./.github/STATS.md) โ Weekly repository statistics
---
## โญ Star History
<a href="https://star-history.com/#Rehui-2006/aria2-agent&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Rehui-2006/aria2-agent&type=Date&theme=dark">
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Rehui-2006/aria2-agent&type=Date">
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Rehui-2006/aria2-agent&type=Date">
</picture>
</a>
---
<div align="center">
**If this tool saved your agent from a corrupted download, give it a โญ!**
Made with โค๏ธ for the AI Agent community
</div>
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing