Metadata-Version: 2.4
Name: aria2cli-agent
Version: 1.1.0
Summary: AI Agent-first aria2 RPC wrapper with MCP support. Kills the pre-allocation false-positive problem forever.
Author-email: CatPaw <catpaw@example.com>
License: MIT
Project-URL: Homepage, https://github.com/Rehui-2006/aria2-agent
Project-URL: Repository, https://github.com/Rehui-2006/aria2-agent
Project-URL: Issues, https://github.com/Rehui-2006/aria2-agent/issues
Project-URL: Changelog, https://github.com/Rehui-2006/aria2-agent/blob/main/CHANGELOG.md
Keywords: aria2,ai-agent,mcp,download,rpc,cli,large-file,resume,json-rpc,model-context-protocol,claude,llm-tools
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Networking
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: mcp
Requires-Dist: mcp[cli]>=0.9.0; extra == "mcp"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Dynamic: license-file

<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.

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![Zero Dependencies](https://img.shields.io/badge/dependencies-0-green.svg)](#)
[![MCP Compatible](https://img.shields.io/badge/MCP-compatible-purple.svg)](https://modelcontextprotocol.io)
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)](#)
[![Based on aria2](https://img.shields.io/badge/built%20on-aria2-red.svg)](https://github.com/aria2/aria2)

[![CI](https://github.com/Rehui-2006/aria2-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/Rehui-2006/aria2-agent/actions/workflows/ci.yml)
[![Daily Health](https://github.com/Rehui-2006/aria2-agent/actions/workflows/daily-health.yml/badge.svg)](https://github.com/Rehui-2006/aria2-agent/actions/workflows/daily-health.yml)
[![GitHub stars](https://img.shields.io/github/stars/Rehui-2006/aria2-agent?style=social)](https://github.com/Rehui-2006/aria2-agent/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/Rehui-2006/aria2-agent?style=social)](https://github.com/Rehui-2006/aria2-agent/network/members)
[![Lines of Code](https://img.shields.io/tokei/github.com/Rehui-2006/aria2-agent?label=LOC)](#)
[![Last Commit](https://img.shields.io/github/last-commit/Rehui-2006/aria2-agent)](https://github.com/Rehui-2006/aria2-agent/commits/main)
[![Repo Size](https://img.shields.io/github/repo-size/Rehui-2006/aria2-agent)](#)

**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>
