An intelligent, autonomous media acquisition and streaming system. ShowShepherd uses natural language processing to understand your media requests, automatically tracks your favorite movies and TV Shows, learns your quality preferences, and manages downloads through a fully containerized stack.
- Setup Guide - Complete installation and configuration instructions
- Architecture - System design and technical architecture
- Troubleshooting - Common issues and solutions
-
Natural Language Queries: "Download the latest episode of Pluribus in 1080p"
-
Automated Infrastructure: Docker Compose orchestration with Prowlarr, qBittorrent, Plex, and FlareSolverr
-
Smart Storage Management: Hardlinks and atomic moves following TRaSH Guides methodology
-
Flexible Storage: Easy configuration for external SSD/HDD storage
-
Quality Intelligence: Automatic parsing and scoring of releases (resolution, codec, source, seeders)
-
Database-Backed Tracking: SQLite schema for series tracking, download history, and user preferences
-
Service Integration:
- Prowlarr client with REST API support
- qBittorrent client with category management and authentication
- Configuration management with Pydantic
-
Secure Architecture: Internal Docker networking, API key management, optional VPN support
-
Claude AI Integration: Natural language intent parsing for accurate media requests
-
Telegram Bot: Interactive UI with inline keyboards, pagination, and notifications
-
Release Calendar: TVDB/TMDB integration for tracking upcoming episodes
-
Behavioral Learning: System learns your quality preferences (resolution, codec, source) over time
-
Auto-Download: Automatically detects and downloads new episodes of tracked series
-
File Management: Smart renaming, atomic moves, and hardlinking for Plex compliance
-
Plex Integration: Library statistics, recent additions, and library search
- Advanced Plex features (library scanning triggers, watch status)
┌─────────────────┐
│ Telegram Bot │ ◄── User interacts via natural language
└────────┬────────┘
│
┌────▼─────┐
│ Claude AI│ ─── Parses intent → Series, Quality, Episode
└────┬─────┘
│
┌────────▼──────────┐
│ ShowShepherd │
│ - Query Parser │
│ - Tracker │
│ - Downloader │
│ - File Manager │
└┬──────┬──────┬───┘
│ │ │
│ │ └──────┐
│ │ │
┌▼──────▼──┐ ┌──────▼─────┐ ┌──────────┐
│ Prowlarr │ │ qBittorrent│ │ Plex │
│ (Search) │ │ (Direct) │ │ Server │
└───────────┘ └──────┬─────┘ └─────┬────┘
│ │
/data/torrents /data/media
└───────┬───────┘
Hardlinked
│
External SSD
(Optional)
✅ Windows (10/11 with Docker Desktop) ✅ macOS (Intel & Apple Silicon with Docker Desktop) ✅ Linux (Ubuntu, Debian, Fedora, etc.)
- Docker and Docker Compose installed
- Windows/Mac: Docker Desktop
- Linux: Docker Engine + Docker Compose
- API Keys:
- Anthropic Claude API
- Telegram Bot Token (from @BotFather)
- TVDB API Key
- TMDB API Key (Optional - only for movie release dates)
- UV Package Manager (for local development):
curl -LsSf https://astral.sh/uv/install.sh | sh
- External SSD/HDD: For storing large media files (recommended 500GB+)
- VPN: If you want to route downloads through VPN (requires additional configuration)
cd /your/path/ShowShepherd
# Copy environment template
cp .env.example .env
# Edit .env with your API keys and settings
nano .envTo use external SSD/HDD for media storage:
Edit .env and add:
# Use your external drive path
HOST_DATA_PATH=/Volumes/YourDrive/ShowShepherd/data # macOS
# HOST_DATA_PATH=D:/ShowShepherd/data # Windows
# HOST_DATA_PATH=/mnt/media/ShowShepherd/data # LinuxOr use default (project directory):
# Leave HOST_DATA_PATH unset to use ./dataLinux / macOS:
# Create directory structure
mkdir -p data/{torrents,media}/{tv,movies}
mkdir -p docker/appdata/{prowlarr,qbittorrent,plex}
# Set permissions (PUID/PGID should match your user)
sudo chown -R 1000:1000 data docker/appdataWindows (PowerShell):
# Create directory structure
New-Item -ItemType Directory -Force -Path data/torrents/tv, data/torrents/movies
New-Item -ItemType Directory -Force -Path data/media/tv, data/media/movies
New-Item -ItemType Directory -Force -Path docker/appdata/prowlarr, docker/appdata/qbittorrent, docker/appdata/plex# Start all services
docker-compose up -d
# View logs
docker-compose logs -f ai_agentProwlarr (http://localhost:9696)
- Complete initial setup wizard
- Add indexers (trackers you have access to)
- Go to Settings → General → Security and copy your API key
- Add the API key to
.envasPROWLARR_API_KEY
qBittorrent (http://localhost:8080)
- Default login:
admin/adminadmin - Change password immediately!
- Update
.envwith new credentials - Verify Categories are set correctly:
tv→/data/torrents/tvmovies→/data/torrents/movies
Note: qBittorrent runs with direct internet connection (no VPN) for better download speeds. If you need VPN, see TROUBLESHOOTING.md for configuration instructions.
Plex (http://localhost:32400/web)
- Complete initial setup and claim server
- Add library: TV Shows →
/media/tv - Add library: Movies →
/media/movies - Get your Plex token:
- Settings → Network → Show Advanced
- Or visit: https://support.plex.tv/articles/204059436/
- Add token to
.envasPLEX_TOKEN
- Message @BotFather on Telegram
- Create new bot with
/newbot - Copy the token to
.envasTELEGRAM_BOT_TOKEN - Get your user ID from @userinfobot
- Add your user ID to
.envasTELEGRAM_ALLOWED_USERS
docker-compose restart ai_agent
docker-compose logs -f ai_agent📖 Need more detailed instructions? See the Complete Setup Guide for step-by-step instructions with troubleshooting.
Talk to your ShowShepherd bot naturally! Here are some examples:
Searching & Downloading:
- "Download The Mandalorian season 3"
- "Find Inception in 1080p"
- "Get Breaking Bad S05E14"
- "Search for Dune 2021"
Status & Monitoring:
- "What's downloading right now?"
- "Check download status"
- "Show me active downloads"
Plex Library:
- "Show me library stats"
- "What did you add recently?"
- "Get library info"
Series Tracking:
- "Track House of the Dragon"
- "When does the next episode of Succession air?"
- "List my tracked shows"
- "Stop tracking The Office"
Advanced:
- "Download the first result"
- "Cancel the Breaking Bad download"
- "Track The Last of Us in 4K"
/start - Initialize the bot
/search <query> - Search for media
/track <series name> - Track a series for auto-downloads
/status - View active downloads
/tracked - List tracked series
/settings - Configure preferences
/help - Show help message
ShowShepherd/
├── agent/ # Python application
│ ├── src/
│ │ ├── bot/ # Telegram bot handlers
│ │ ├── llm/ # Claude AI integration
│ │ ├── services/ # Service clients
│ │ │ ├── prowlarr.py ✅ Torznab API client
│ │ │ ├── qbittorrent.py ✅ Download manager
│ │ │ ├── plex.py 🚧 Media server client
│ │ │ └── tvdb_tmdb.py 🚧 Release calendar
│ │ ├── tracking/ # Behavioral learning
│ │ ├── database/ # SQLAlchemy models
│ │ │ └── models.py ✅ Complete schema
│ │ └── utils/ # Configuration & logging
│ │ ├── config.py ✅ Pydantic settings
│ │ └── logger.py ✅ Rich logging
│ ├── data/ # Persistent storage
│ │ └── agent.db # SQLite database
│ ├── pyproject.toml ✅ UV configuration
│ └── Dockerfile ✅ Multi-stage build
├── data/ # Media & torrents
│ ├── torrents/
│ │ ├── tv/ # qBittorrent downloads TV
│ │ └── movies/
│ └── media/
│ ├── tv/ # Plex library TV
│ └── movies/
│ ├── docker/
│ └── appdata/ # Container configs
├── docker-compose.yml ✅ Full stack
├── .env.example ✅ Environment template
└── README.md # You are here
# Install UV if you haven't
curl -LsSf https://astral.sh/uv/install.sh | sh
# Navigate to agent directory
cd agent/
# Install dependencies
uv pip install -e ".[dev]"
# Run linting
uv run ruff check src/
uv run black src/
# Run tests (when implemented)
uv run pytest- Never commit
.env- Added to.gitignore - Change default qBittorrent password immediately
- Use strong API keys - Rotate periodically
- Telegram whitelist - Only authorized users can control the bot
- VPN kill-switch - Downloads stop if VPN disconnects
- Internal networking - Services communicate via Docker bridge network
- File permissions - PUID/PGID match your user (1000:1000)
See .env.example for the complete list. Key variables:
| Variable | Required | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN |
✅ | Bot token from @BotFather |
TELEGRAM_ALLOWED_USERS |
✅ | Comma-separated user IDs |
ANTHROPIC_API_KEY |
✅ | Claude API key |
PROWLARR_API_KEY |
✅ | From Prowlarr settings |
QBITTORRENT_USERNAME |
✅ | qBittorrent login |
QBITTORRENT_PASSWORD |
✅ | qBittorrent password |
PLEX_TOKEN |
✅ | Plex authentication token |
TVDB_API_KEY |
✅ | TVDB API key |
TMDB_API_KEY |
❌ | TMDB API key (Optional) |
HOST_DATA_PATH |
❌ | Host data path (defaults to ./data) |
# Check VPN logs
docker-compose logs qbittorrent | grep -i vpn
# Verify VPN file is in correct location
ls docker/appdata/qbittorrent/wireguard/
# Check container has NET_ADMIN capability
docker inspect qbittorrent | grep -i cap_add# Verify all containers use same /data mount
docker-compose config | grep -A 2 "/data"
# Check if files are on same filesystem
df -h data/torrents/tv data/media/tv
# Test hardlink manually (inside container)
docker exec ai_agent ln /data/torrents/tv/test.txt /data/media/tv/test.txt# Check indexer status in Prowlarr
# Settings → Indexers → Test
# Verify FlareSolverr is running (for public trackers)
curl http://localhost:8191
# Check API key
docker-compose logs ai_agent | grep -i prowlarr# Trigger manual library scan via agent (when implemented)
# Or use Plex web UI: Library → Scan Library Files
# Check volume mapping
docker exec plex ls -la /media/tv# If services can't reach each other:
# 1. Restart Docker Desktop
# 2. Check Docker network:
docker network ls
docker network inspect media-handler-ai-agent_media_network
# 3. Verify all containers are on the same network:
docker inspect -f '{{.NetworkSettings.Networks}}' showshepherdThis is currently a personal project based on the technical specification from the PDF. Contributions, suggestions, and improvements are welcome!
- TRaSH Guides - Hardlinks
- Prowlarr Documentation
- qBittorrent API
- Plex API
- Telegram Bot API
- Anthropic Claude API
MIT License - See LICENSE file for details
This tool is for educational and personal use. Ensure you have the legal right to download and possess any media you acquire. Respect copyright laws in your jurisdiction.
Built with ❤️ using Claude AI, Python, Docker, and the arr stack