- Go 99.7%
- Dockerfile 0.3%
| app | ||
| assets/icon | ||
| cmd | ||
| docs | ||
| docker-compose.yml | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| README.md | ||
Only Torrents
A self-hosted Stremio addon that streams movies and TV series via BitTorrent through Jackett indexers, with caching, DHT seed counting, content deduplication, and per-user quality profiles.
Quick Start
go build -o only ./cmd/main.go
TMDB_API_KEY=key JACKETT_URL=http://jackett:9117 JACKETT_KEY=key ./only
Open http://localhost:8080/configure to generate a Stremio install link.
Features
- Jackett Indexing: Torznab search with automatic indexer discovery
- TMDB Metadata: Title resolution, TV season completion, episode air dates
- DHT Seed Counting: Real peer discovery for accurate seeder counts
- Multi-Tier Caching: RawCache for unfiltered results, ProfileCache per user profile, StreamCache for finalized streams (24h) caches
- Content Dedup: Three-tier dedup (infoHash → title+size → Jaccard similarity)
- Per-User Profiles: Resolution range, audio language, min seeders, max results
- Quality Scoring: Multi-factor ranking (source, codec, HDR, audio, release group)
- Adult Filtering: Jackett category-based (6010, 100048) + low-quality content filter
- 1337x Handling: Configurable
block/deprior/allowviaBLOCK_1337X - IP Auth: HMAC-SHA256 whitelist with S-Auth-Key header
- Rate Limiting: Per-user token bucket (default 20 req/min)
- Background Prefetch: Proactively caches next episodes for active series
- Query Dedup: Per-query mutex prevents duplicate Jackett searches
Configuration
Environment Variables
| Variable | Required | Description |
|---|---|---|
TMDB_API_KEY |
yes | TMDB API key |
JACKETT_URL |
yes | Jackett server URL |
JACKETT_KEY |
yes | Jackett API key |
S_AUTH_KEY |
— | Auth header + IP whitelist HMAC key |
RATE_PER_MIN |
— | Rate limit (reqs/min, default 20) |
BLOCK_1337X |
— | 1337x handling: block, deprior, allow |
DHT_BOOTSTRAP_WAIT |
— | DHT bootstrap wait in seconds (default: 30) |
TRUSTED_PROXIES |
— | Comma-separated CIDR ranges (default: localhost) |
CLI Flags
-port 8080 -min-seeders 0 -max-results 50 -config-dir ./configs
Config Files
configs/*.json — Per-user Jackett/TMDB/filter configs
configs/allowed_ip.txt — IP whitelist (HMAC-SHA256 hashed)
configs/installs.json — Install mappings with profile IDs
configs/unwanted.txt — Low-quality release filter (cams, screeners, trailers)
API
| Endpoint | Description |
|---|---|
GET /manifest.json |
Stremio addon manifest |
GET /stream/{type}/{id}.json |
Stream results (movie/series, IMDb ID) |
POST /install |
Create install with profile settings |
GET /configure |
Configuration web UI |
GET /health |
Health check (version, cache counts, DHT, indexers) |
GET /indexers?jackett_url=&jackett_key= |
Available Jackett indexers |
GET /auth |
Authorization page (POST to authenticate IP) |
Stream IDs: tt1234567 for movies, tt1234567:season:episode for series.
Content Profiles
Format: {minRes}-{maxRes}-{langCodes}. Example: 720p-1080p-en (720p–1080p, English).
- Resolution: 480p / 720p / 1080p / 2160p
- Languages: en, es, fr, de, it, pt, ru, ja, ko, zh, hi, ar, dub, multi
Architecture
Stremio → HTTP Server → Jackett (torrent search)
TMDB (metadata)
DHT (seeder counts)
→ Caches (Profile + Raw, Stream)
→ Dedup (infoHash → title+size → Jaccard)
→ Sort (quality → seeders → size)
→ Response
| Module | File | Role |
|---|---|---|
| Server | app/server.go |
HTTP mux, caches, config, installs |
| Stream | app/stream.go |
Search orchestration, dedup, prefetch |
| Indexer | app/indexer.go |
Jackett Torznab client |
| Metadata | app/tmdb.go |
TMDB TV/movie queries |
| DHT | app/dht.go |
Bittorrent peer discovery |
| Parser | app/parser.go |
Title → quality info |
| Sorter | app/sorter.go |
Filtering + quality sorting |
| Auth | app/auth.go |
IP whitelist, proxy headers |
| Rate Limit | app/ratelimit.go |
Token bucket limiter |
| Install | app/install.go |
Profile/install management |
Community
Development
Prerequisites
- Go 1.26+
- A Jackett instance with API key
- A TMDB API key
Local Setup
# Clone and enter the repo
git clone <repo> && cd <repo>
# Install dependencies
go mod download
# Create config directory
mkdir -p configs
# Create a default config (optional — env vars work too)
cat > configs/default.json << 'EOF'
{
"jackett_url": "http://localhost:9117",
"jackett_key": "your_jackett_api_key",
"tmdb_key": "your_tmdb_api_key",
"min_seeders": 1,
"max_results": 12,
"min_resolution": "720p",
"max_resolution": "1080p",
"audio_languages": ["english"]
}
EOF
# Run the server
TMDB_API_KEY=key JACKETT_URL=http://jackett:9117 JACKETT_KEY=key ./only -port 8080
Documentation
Detailed technical docs in docs/:
01-architecture-overview.txt— Full system architecture with component interaction03-caching-system.txt— All caches, key formats, TTLs, lookup flows04-data-structures.txt— Complete type reference and parsing rules05-external-integrations.txt— DHT, TMDB, and Jackett integration specifics06-deduplication-system.txt— Three-tier dedup algorithm details07-regression-test-plan.md— Test coverage documentation
Build
go build -o only ./cmd/main.go
Version, commit, and build time are auto-detected at runtime by app/version.go.
Docker
docker-compose (recommended)
The repo includes a docker-compose.yml for easy deployment:
services:
only-torrents:
build: .
container_name: only-torrents
ports:
- "8080:8080"
volumes:
- ./configs:/app/configs
environment:
- S_AUTH_KEY=${S_AUTH_KEY:-}
- TMDB_API_KEY=${TMDB_API_KEY}
- JACKETT_URL=${JACKETT_URL}
- JACKETT_KEY=${JACKETT_KEY}
restart: unless-stopped
Create a .env file alongside docker-compose.yml:
TMDB_API_KEY=your_tmdb_api_key
JACKETT_URL=http://jackett:9117
JACKETT_KEY=your_jackett_api_key
S_AUTH_KEY=your_auth_key
BLOCK_1337X=deprior
Then:
docker compose up -d
Building the Image Manually
docker build -t only-torrents .
docker run -d \
--name only-torrents \
-p 8080:8080 \
-e TMDB_API_KEY=key \
-e JACKETT_URL=http://jackett:9117 \
-e JACKETT_KEY=key \
-v ./configs:/app/configs \
only-torrents