A local-first, automation-first P2P download manager for humans and software agents.
agpeer is a general-purpose transfer and post-processing client. It handles
user-supplied BitTorrent magnets / .torrent files and Soulseek
search/downloads under one normalized job model, exposes the same capabilities
through a stable local REST API, and provides a desktop UI over that API.
The project is intentionally provider-neutral on the torrent side. It does not build or bundle torrent indexers, warez catalogues, DRM bypasses, cracks, key generators, or first-party discovery integrations for unauthorized commercial content.
- BitTorrent — add magnets, local
.torrentfiles, and remote.torrentURLs; per-file selection; pause/resume/cancel; progress, peers, speeds, ETA; restart/resume persistence. - Soulseek — search with incremental results, file and folder
downloads, queue position and progress — via the native
rustsoseekclient. - Built-in magnet search — generic engine search scoped to your configured domains plus optional per-site templates; fully domain-neutral, zero external files. A user script can override it.
- One normalized job model — transfers from every backend normalize into a single typed model with opaque application-owned IDs.
- One binary — the Desktop UI can be embedded into the core binary
(
--features webui) and served fromGET /: one process, one port, no Vite/Tauri needed. Runs as a Windows service (NSSM), systemd, or a Docker container. - Post-processing — rule-driven pipeline (classify, verify, extract, inspect, organize) with safe archive extraction and explicit installer execution policy.
- Agent-first REST API — versioned
/api/v1, bearer-token auth, SSE events, OpenAPI documentation. The core service is the product; the desktop UI, CLI, and future MCP adapter are clients of it. - Local-first and private — loopback binding by default, secrets in OS secure storage, no silent firewall changes.
Rust-first architecture:
| Layer | Technology |
|---|---|
| Core / service | Rust (crates/), Tokio |
| Torrent engine | librqbit embedded behind a TransferBackend trait |
| Soulseek engine | rustsoseek native client, clean-room wire protocol |
| HTTP API | Axum, versioned /api/v1, bearer token required |
| Realtime events | Server-Sent Events (/api/v1/events) |
| Magnet search | crates/hook — built-in engine/site-template search (no compiled sites) or user-script override |
| Persistence | SQLite (sqlx), source of truth for application state |
| Desktop UI | React + TypeScript + Vite; optional Tauri shell or embedded into the core binary (webui feature) |
| Agent interface | REST first (/api/v1); MCP server (agpeer-mcp) over it |
The core service runs as a single binary (agpeer). The Tauri shell spawns it
as a child process; the core also runs standalone for API-only use. With the
webui build feature the core is the whole app: one process serves the API
and the UI. See
docs/architecture.md for details.
/
├─ crates/
│ ├─ common/ shared typed models, opaque IDs, errors, backend traits
│ ├─ storage/ SQLite (sqlx) migrations and stores
│ ├─ core/ app state, config, secrets, event bus
│ ├─ api/ Axum HTTP API + SSE + bearer-token auth
│ ├─ torrent/ librqbit-backed TransferBackend
│ ├─ soulseek/ rustsoseek adapter (SearchBackend + TransferBackend)
│ ├─ jobs/ post-processing job/step model
│ ├─ postprocess/ post-processing engine (Phase 3)
│ ├─ mcp/ MCP server bridging agents to the REST API
│ └─ debug-mcp/ MCP server for fast, low-token debugging (logs/code/git)
├─ apps/desktop/ Tauri 2 + React + TypeScript shell
├─ docs/ architecture, API, job model, post-processing, security
└─ tests/ integration tests and fixtures
- Rust stable (1.80+, per the workspace
rust-version) - Node.js 20+ (for the desktop shell)
- 7-Zip (
7z.exe/7zz) onPATHfor archive extraction
The default build includes the real librqbit torrent engine (the rqbit
feature is enabled by default):
cargo build --release --bin agpeer
# binary: target/release/agpeer.exeThe repository ships a ready-made runtime environment under run/:
# Edit run/config.toml and fill in your Soulseek username/password first.
powershell -ExecutionPolicy Bypass -File .\run\start.ps1start.ps1 builds the binary if needed, runs migrations, then starts the core
on 127.0.0.1:41000 with:
- the rqbit torrent engine (magnet /
.torrent/ HTTPS adds), - the native rustsoseek Soulseek client (login, search, download over the wire protocol),
- automatic post-processing: completed downloads are moved into
E:\Media(configurable via[postprocess].library_root) as a Jellyfin/Plex-friendly tree (<root>/TV Shows/<Title>/Season NN/,<root>/Movies/<Title> (<Year>)/,<root>/Music/<Artist>/<Album>/, …).
The core connects directly to the Soulseek server using the username /
password in run/config.toml; no sidecar process or external engine is
required.
For API-only/manual workflow:
agpeer migrate --config run/config.toml
agpeer serve --config run/config.tomlBy default the core listens on 127.0.0.1:41000. On first boot it generates a
bearer token, persists it in the private data directory, and prints the
location — the token value itself is never written to logs. The Tauri shell
reads the token automatically; agents can read it from the same file.
Ship the whole product as a single executable — core + magnet search + UI:
# 1. Build the desktop UI once
cd apps/desktop
npm ci
npm run build
cd ../..
# 2. Build the core with the UI embedded
cargo build --release --features webui --bin agpeer
# target/release/agpeer.exe — start it, open http://127.0.0.1:41000The browser UI bootstraps the bearer token from the loopback-only
GET /__agpeer_token. Environment overrides (AGPEER_HOST, AGPEER_PORT,
AGPEER_DATA_DIR, AGPEER_CONFIG, AGPEER_SOULSEEK_*) make headless
deployments work without editing a TOML. Service recipes and a config example
live in deploy/: service-install.ps1 (NSSM/Windows),
systemd/agpeer.service (Linux), plus docker-compose.example
and the Dockerfile.
cd apps/desktop
npm ci
npm run tauri devThe desktop UI talks only to the core API — it never touches backends or the database directly.
The core service is the product. The desktop UI, CLI, MCP server, and future integrations are clients of it. REST commands work without the desktop UI running, as long as the core service is running:
# Add a magnet
curl -X POST http://127.0.0.1:41000/api/v1/transfers \
-H "Authorization: Bearer $AGPEER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"backend":"torrent","source":"magnet:?xt=urn:btih:..."}'
# List transfers
curl http://127.0.0.1:41000/api/v1/transfers \
-H "Authorization: Bearer $AGPEER_TOKEN"See docs/api.md for the full endpoint reference and docs/job-model.md for the normalized transfer model.
agpeer-mcp exposes the same /api/v1 surface as MCP tools over stdio, so
Claude Code, Kilo, Cursor, and other MCP clients can drive downloads and
Soulseek searches. See docs/mcp.md for build, run, and
mcpServers configuration examples. For fast, low-token debugging of logs,
source, and git state, agpeer-debug-mcp is a companion MCP server — see
docs/mcp-debug.md.
- Core API binds to
127.0.0.1by default; LAN binding is an explicit, advanced-user action that requires authentication. - A bearer token is required on all requests, including loopback.
- Secrets live in OS secure storage (Windows DPAPI primary, keyring fallback); they are never committed, logged, or returned over the API.
- Download roots are enforced and canonicalized; archive contents are treated as hostile (path-traversal protected).
- Downloaded executables are never auto-launched.
run_installeris an explicit, confirmed, audited action.
See docs/security.md for the full model.
- docs/architecture.md — components, process model, reconciliation
- docs/api.md — REST API reference
- docs/job-model.md — normalized transfer model
- docs/postprocessing.md — post-processing pipeline
- docs/security.md — security model
- docs/mcp.md — MCP server for coding agents
- docs/mcp-debug.md — debugging MCP server (logs/code/git)
- THIRD_PARTY_NOTICES.md — third-party licensing
- tests/README.md — testing strategy
Licensed under Apache-2.0. See
THIRD_PARTY_NOTICES.md for the full third-party
licensing record. The Soulseek wire-protocol client is rustsoseek
(Apache-2.0).
