Skip to main content
Glama
README.md
# torrent-mcp

A personal movie/series torrent-queue pipeline — IMDb list scraping, OMDb
title lookups, Jackett search, and qBittorrent RSS queue management — as a
tested Python library, a CLI, and an [MCP](https://modelcontextprotocol.io)
server so a natural-language client (a Telegram bot, Claude Desktop, etc.)
can drive the whole thing in plain English.

This replaces a folder of ad hoc scripts (`B6_imdb-torrents/`) that each
hardcoded one person's Jackett API key, OMDb key, LAN IP, and `/home/b/...`
paths directly in source. All of that is now environment configuration —
see `.env.sample` — so the code itself has nothing sensitive in it.

## What it does

| Area | CLI command(s) | MCP tool(s) |
|---|---|---|
| Find candidate titles from an IMDb list page | `find-candidates` | `find_imdb_candidates` |
| Check IMDb ids against what's already queued (and, optionally, a Plex export) | `check-candidates` | `check_candidates` |
| Add/remove/list a queue's `feeds.json` entries | `add-to-queue`, `remove-from-queue`, `list-queue` | `add_to_queue`, `remove_from_queue`, `list_queue` |
| Repoint a queue at a different Jackett indexer | `switch-indexer` | `switch_indexer` |
| Jackett indexer discovery & search | `list-indexers`, `check-imdb-support`, `search`, `find-largest` | `list_indexers`, `check_imdb_search_support`, `search_torrents`, `find_largest_torrent` |
| OMDb title lookups | `lookup`, `search-title`, `identify-file` | `lookup_title`, `search_title`, `identify_title` |
| Library maintenance | `find-duplicates`, `diff-urls`, `archive-downloads`, `backup-queue` | `find_duplicate_filenames`, `diff_missing_urls`, `archive_downloads`, `backup_queue` |

`list_profiles` (MCP only) reports which queue profiles are configured.

## Install

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
```

Copy `.env.sample` to `.env` and fill in your own `OMDB_API_KEY`,
`JACKETT_URL`/`JACKETT_API_KEY`, and `TORRENT_MCP_PROFILES` (one entry per
qBittorrent+Jackett RSS queue — movies, series, upgrades, ...). See the
comments in `.env.sample` for every setting.

## CLI

```bash
torrent-mcp find-candidates "https://www.imdb.com/list/ls0123456789/"
torrent-mcp check-candidates movies tt1375666 tt0111161
torrent-mcp add-to-queue movies tt1375666 --indexer yts
torrent-mcp list-queue movies --resolve-titles
torrent-mcp switch-indexer movies yts torrentgalaxy
torrent-mcp lookup tt1375666
torrent-mcp --help   # full command list
```

## MCP server

```bash
torrent-mcp-server
```

Runs over stdio, ready for any MCP client (Claude Desktop, the MCP
Inspector, a custom client) to spawn as a subprocess. Example
`claude_desktop_config.json` entry:

```json
{
  "mcpServers": {
    "torrent-mcp": {
      "command": "/absolute/path/to/.venv/bin/torrent-mcp-server",
      "env": { "OMDB_API_KEY": "...", "JACKETT_API_KEY": "...", "...": "..." }
    }
  }
}
```

### Integration with ocabra_telegram

[ocabra_telegram](https://github.com/luisriverag/ocabra_telegram) drives
this server the same way it already drives
[homebox_mcp](https://github.com/luisriverag/homebox_mcp) — over stdio via
a small JSON-RPC client (`homebox_tools.McpStdioClient`, reused as-is by
its `torrent_tools.py`) and `bot.py`'s `call_ocabra_with_tools` tool-calling
loop, which now runs over whichever backends (Homebox, torrent-mcp, both)
are active for the current user. See that repo's README, "Torrent Queue
Integration", for the `TORRENT_MCP_*` env vars to set there. Once wired,
Telegram messages like *"what's queued for movies?"* or *"add tt1375666 to
the movies queue"* drive this project directly — this project only owns
the MCP server side; the client-side wiring lives in `ocabra_telegram`.

## Development

```bash
pip install -e ".[dev]"
pytest
```

Tests mock all external HTTP (OMDb, Jackett, IMDb) with
[`respx`](https://github.com/lundberg/respx) and use `tmp_path` for
filesystem operations — nothing touches the network or a real queue.

## Notes on the original scripts

- `manage_queue/queue_get-titles.py` used `imdbpy` to scrape IMDb directly
  for titles; this project uses OMDb everywhere instead (already needed
  for other lookups), so there's one metadata dependency, not two.
- The ten near-identical `switchindexer_*.sh` scripts (one hardcoded
  path + container per direction) are now one `switch-indexer` command
  parameterized by profile and indexer names.
- `trackers/check_imdbsearch.py` logged into Jackett's dashboard with an
  admin password before calling its API; the API calls it made only ever
  needed the API key, so that login step (and the password) is gone.
- Nothing here runs `sudo` or shells out to `docker` unless
  `DOCKER_RESTART_ENABLED=true`, and then only for a container name from
  your own `TORRENT_MCP_PROFILES` config — never a name supplied through a
  tool call.

TDQS

A3.7/5.0

Scored across 18 tools

Disambiguation4/5

Most tools are clearly separated by object (profiles, queue entries, indexers, titles, files), and descriptions specify exact inputs and outputs. The main potential confusion is between lookup_title/search_title/identify_title and search_torrents/find_largest_torrent, but their boundary conditions are stated clearly enough.

Naming Consistency5/5

Every tool uses a consistent snake_case, imperative verb-first naming pattern such as list, add, remove, search, find, or check. Even longer names like check_imdb_search_support and find_duplicate_filenames follow the same convention, making the set predictable.

Tool Count4/5

At 18 tools, this is slightly above the typical sweet spot, but the server spans queue management, indexer operations, metadata resolution, and media-file housekeeping. Each tool maps to a distinct operation, so the count feels broad rather than redundant.

Completeness4/5

The core pipeline—finding IMDb candidates, checking them against the queue/Plex, adding and removing queue entries, searching indexers, and archiving downloads—is well covered. Minor gaps such as profile creation/deletion and directly adding a found torrent to qBittorrent exist but can be worked around with the available tools.

Maintenance

ActivityMaintained
ResponsivenessNo issues