Torrent Search MCP Server
This server lets you search and browse torrents from multiple sources, retrieve magnet links, and manage Telegram-based webapp authorization.
search_torrents: Perform advanced searches across providers, returning ranked top 3-5 recommendations with reasons and source details.
popular_torrents: Get the most popular torrents per site (e.g., thepiratebay.org, 1337x.to, nyaa.si), pre-ranked by swarm health.
get_torrent: Resolve the magnet link for a specific torrent by its ID.
available_sources: List the configured torrent source domains.
authorize_webapp: Approve a one-time Telegram pairing code to grant browser access to the web UI.
torrent_webapp: Present the web UI URL and explain how the user can authorize via Telegram.
Provides a containerized deployment option with preconfigured DNS settings (using quad9) to bypass common connection issues when accessing torrent sites
Supports configuration through .env files for storing sensitive information like YggTorrent passkeys
Includes a FastAPI server as an alternative interface with interactive API documentation (Swagger UI and ReDoc) for direct HTTP access
Available as a PyPI package for easy installation and integration into other Python applications
Provides a Python API wrapper for programmatic access to torrent search functionality
Uses Shields.io for generating status badges in the README
Offers Swagger UI documentation for the FastAPI interface, enabling easy API exploration and testing
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Torrent Search MCP Server search for the latest Ubuntu ISO torrent"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Torrent Search MCP/API/WebUI
This repository provides a Python API/WebUI and an MCP (Model Context Protocol) server to find torrents programmatically on ThePirateBay, 1337x, Nyaa, YTS, EZTV, FitGirl, SubsPlease and UIndex. It allows for easy integration into other applications or services.
Quickstart
uvx torrent-search-mcp --mode cli "sample show"
# MCP server over stdio (default)
uvx torrent-search-mcp --mode stdio
# MCP server over streamable HTTP (port 8000, endpoint /mcp)
uvx torrent-search-mcp --mode http
# MCP server over SSE (port 8000, endpoint /sse, legacy)
uvx torrent-search-mcp --mode sse
# Standalone API server (port 8000)
uvx torrent-search-mcp --mode apiRelated MCP server: rqbit Torrent Client MCP
Table of Contents
Features
API wrapper for ThePirateBay, 1337x, Nyaa, YTS, EZTV, FitGirl, SubsPlease and UIndex.
1337x searches cover Movies, TV, Games, Apps, Music and Anime categories (popular pages for the same set); TPB search maps the full category tree (video, audio, applications, games, other).
Search results are deduplicated across providers by BitTorrent info hash (the healthiest copy wins); short connection-reset retries and an 8 MiB response cap keep flaky sources contained.
Search URLs are shareable:
/?q=...reopens the same search; browser back/forward switches between searches and popular.MCP server interface (FastMCP 4) serving the
2026-07-28protocol revision overstdioor streamable HTTP (http), with automatic negotiation of older handshake revisions and legacy transport aliases (streamable-http,sse).API server interface for alternative HTTP access (e.g., for direct API calls or testing).
CLI mode for quick one-off searches directly from the terminal.
popular_torrentscached for 5 minutes for Web UI delivery (a Web UI POPULAR click passesrefresh=trueto drop the caches and re-scrape every source); searches are never cached (only identical concurrent requests are coalesced) so new results appear immediately.In-memory 1-hour, 5000-entry torrent cache used only to resolve magnet links via
get_torrentwithout re-scraping.Magnet links are always stored internally; MCP hides them unless
INCLUDE_LINKS=true.Configurable source filtering via environment variables.
Telegram-gated web UI: one-time QR/deep-link pairing, HttpOnly session cookie (set at approval, survives tab close), forward-to-Telegram popup and (optional) server-side forwarding.
Tools:
Search for torrents across all available sources.
Get the most popular torrents per source (apibay, uindex, 1337x, YTS, nyaa, EZTV).
Get the magnet link for a specific torrent by id.
List available sources.
Present the web UI and its Telegram pairing access, approve pairing codes, and forward torrents to Telegram chats.
Supported Sources
Source | Scraping domain | Fetch method |
ThePirateBay |
| JSON API |
1337x |
| HTML search/top pages (6 categories) |
Nyaa |
| RSS + HTML top page |
YTS |
| JSON API |
EZTV |
| JSON API |
FitGirl |
| RSS |
SubsPlease |
| JSON API |
UIndex |
| HTML top list |
The API exposes public display domains where applicable: apibay.org is shown as thepiratebay.org, and yts.mx as yts.vg. Results may include a validated HTTP(S) page_url linking back to their source page.
Note on UIndex: the site exposes no programmatic search endpoint (its search path is protected by a browser challenge), so queries are matched client-side against its live top list - which conveniently carries magnet links inline.
Sources can be excluded individually via the EXCLUDE_SOURCES env var.
Setup
Prerequisites
Python 3.10+ (required for PyPI install). CI and Docker images use Python 3.14.
uv(for local development).Docker and Docker Compose (for Docker setup).
Configuration (Optional)
The application reads configuration from environment variables. The recommended way to set them is by creating a .env file in your project's root directory. The application will load it automatically. See .env.example for all available options.
Variable | Default | Description |
|
| When |
| (none) | Comma-separated list of sources to exclude from results (e.g. |
| (none) | MCP only: base URL of a running Torrent Search REST API - tools proxy it instead of scraping locally. Unset = standalone. |
| (none) | Telegram bot handle used by the Web UI torrent action. The pairing gate is enabled only when this and |
| (none) | Secret required to approve Web UI pairing codes (register endpoint + |
| (none) | Bot token enabling server-side sending via |
| (none) | Agent relay mode (with |
| (none) | Agent relay mode: shared secret sent as the |
| (none) | Agent relay mode: |
| (none) | Agent relay mode: |
|
| When |
|
| Persistence file for the API server's authorized session tokens (SHA-256 hashes only). The standalone MCP server proxies the API and does not keep a local copy. |
| auto | Force the Web UI session cookie's |
| (none) | MCP only: public URL of the web UI; enables the |
Installation
Choose one of the following installation methods.
Install from PyPI (Recommended)
This method is best for using the package as a library or running the server without modifying the code.
Install the package from PyPI:
pip install torrent-search-mcpCreate a
.envfile in the directory where you'll run the application (optional).Run the MCP server (default: stdio):
python -m torrent_searchFor Local Development
This method is for contributors who want to modify the source code.
Using uv:
Clone the repository:
git clone https://github.com/philogicae/torrent-search-mcp.git
cd torrent-search-mcpInstall dependencies using
uv:
uv sync --frozenCreate your configuration file by copying the example:
cp .env.example .envRun the MCP server (default: stdio):
uv run -m torrent_searchThe repo also ships a dev.sh helper that locks/syncs deps, formats, lints, type-checks (ty) and runs the test suite with coverage:
./dev.shFor Docker
This method uses Docker Compose to run two containers: the REST API + web UI, and an MCP server that proxies the API (no local scraping).
compose.yaml is configured to bypass DNS issues (using quad9 DNS).
Container | Mode | Host port | Endpoints |
|
|
|
|
|
|
|
|
Clone the repository (if you haven't already):
git clone https://github.com/philogicae/torrent-search-mcp.git
cd torrent-search-mcpCreate your configuration file by copying the example:
cp .env.example .envBuild and run the containers using Docker Compose:
docker compose up --build -dAccess container logs:
docker logs torrent-search-api -f
docker logs torrent-search-mcp -fUsage
The package exposes a single entry point, torrent-search-mcp (installed by pip/uvx), equivalent to python -m torrent_search. It supports the following --mode values:
Mode | Endpoint | Description |
| - | Run a single search query and print results to stdout. |
| - | MCP server over stdio (default). |
|
| MCP server using streamable HTTP. Serves MCP protocol revision |
|
| Alias of |
|
| MCP server using Server-Sent Events. Legacy HTTP transport (deprecated by the MCP spec in favor of |
|
| Standalone API HTTP server (see As API Server). |
The server is built on FastMCP 4 (MCP SDK v2). Clients supporting the 2026-07-28 revision negotiate it automatically (stateless requests, server/discover, no session IDs); older clients fall back to the previous handshake era against the same deployment.
MCP modes (stdio, http, streamable-http, sse) run standalone by default (tools scrape locally). Set TORRENT_SEARCH_API_URL to switch to API mode: the tools proxy a running Torrent Search REST API instead.
Common flags (for http, streamable-http, sse and api modes): --host (default 0.0.0.0), --port (default 8000), --reload, --workers (API only).
As CLI
Run a one-off search directly from the terminal. Prints each result as id (seeders|leechers|downloads) - filename, then fetches the magnet/torrent for the top hit.
# Using the installed entry point
torrent-search-mcp --mode cli "sample show"
# Or via uvx without installing
uvx torrent-search-mcp --mode cli "sample show"
# Or from source
uv run -m torrent_search --mode cli "sample show"As Python Wrapper
from torrent_search import torrent_search_api
results = await torrent_search_api.search_torrents("sample show")
for torrent in results:
print(
f"{torrent.filename} | {torrent.size} | {torrent.seeders} SE | {torrent.leechers} LE | {torrent.date} | {torrent.source}"
)search_torrents is async and accepts an optional max_items (default 20). popular_torrents(per_source=20) returns the current most popular torrents from sources with a top listing - up to per_source results per source (pass per_source=None for everything), merged and ranked by seeders + leechers. Each Torrent exposes id, filename, category, size, seeders, leechers, downloads, date, source, uploader, and, when available, magnet_link and a validated HTTP(S) page_url. Pass a torrent's id to get_torrent() to retrieve its magnet link.
As MCP Server
from torrent_search import torrent_search_mcp
torrent_search_mcp.run(transport="http")As API Server
This project also includes a API server as an alternative way to interact with the library via a standard HTTP API. This can be useful for direct API calls, integration with other web services, or for testing purposes.
Running the API Server:
# With Python
python -m torrent_search --mode api
# With uv
uv run -m torrent_search --mode api--host <host>: Default:0.0.0.0.--port <port>: Default:8000.--reload: Enables auto-reloading when code changes (useful for development).--workers <workers>: Default:1. Caching and request coalescing are in-process, so each worker keeps its own cache; use the default single worker unless per-worker caches are acceptable (a shared backend such as Redis would be needed to scale out).
The API server will then be accessible at http://<host>:<port>.
Available Endpoints: The API server exposes similar functionalities to the MCP server. Key endpoints include:
GET /: Built-in web UI (dark/light) - search, per-site popular tiles, sortable results, source-page links and magnet actions. Searches are shareable via?q=<query>(the URL restores the search on load and back/forward navigates between searches and popular). Telegram sending requires one-time QR pairing when configured.POST /torrent/search: Search for torrents. Query params:query(required, 1-200 chars),max_items(optional, default20, 1-200; uncapped whenper_sourceis set) andper_source(optional, 1-200; keep up to N results per source, ranked by swarm health).GET /sources: List the available torrent source domains.GET /torrent/popular: Get the most popular torrents. Query params:per_source(optional, default20, 1-200) andrefresh(optional, defaultfalse;truedrops the server-side caches and fetches a fresh listing from every source - the Web UI POPULAR button does this on each click). The listing is cached for 5 minutes.GET /torrent/{torrent_id}: Get the magnet link for a specific torrent by id. Returns the magnet URI as a JSON string.GET /telegram/session: Web UI auth state (enabled,authenticated, public bothandle,prune_magnet_links). The browser sends the HttpOnly session cookie automatically; a legacy Bearer token is still accepted and migrated to the cookie.POST /telegram/auth/challenge: Create a one-time 16-character alphanumeric pairing code (rate-limited). Codes expire after ~5 minutes and are shown as a QR + deep link in the pairing popup.GET /telegram/auth/poll?code=: Poll a pairing code; on approval returns the one-time session token and sets the HttpOnlytorrent_sessioncookie (30 days,SameSite=Lax). The cookie is set before the JS continues, so closing the tab immediately does not lose the session.DELETE /telegram/auth/challenge/{code}: Cancel a pending pairing code.POST /telegram/auth/register: Approve a pairing code bound to a Telegramchat_id. RequiresAuthorization: Bearer $TORRENT_SEARCH_API_KEY.POST /telegram/auth/logout: Revoke the presented session token and clear the session cookie.POST /forward_telegram: Send torrent info to the Telegram chat bound to the presented session cookie/token; server-to-server callers may instead useAuthorization: Bearer $TORRENT_SEARCH_API_KEYwith the targetchat_idquery param. JSON body:filename(required),magnet_link(required), optionalsize,seeders. WhenPRUNE_MAGNET_LINKS=truethe forwarded magnet is pruned; requiresTELEGRAM_BOT_TOKEN, otherwise 503./docs: Interactive API documentation (Swagger UI)./redoc: Alternative API documentation (ReDoc).
When TELEGRAM_BOT_HANDLE and TORRENT_SEARCH_API_KEY are both configured, /torrent/* requires either a valid browser session (HttpOnly cookie, or a legacy Bearer token) or the API key (Authorization: Bearer $TORRENT_SEARCH_API_KEY); search/popular/magnet lookups are also rate-limited per client IP. Swagger/ReDoc/OpenAPI require the same authentication while the gate is active.
Environment variables are configured the same way as for the MCP server (via an .env file in the project root).
Via MCP Clients
Usable with any MCP-compatible client. Available tools:
search_torrents(user_intent, query): Search for torrents across all available sources.user_intent: A short description reflecting the user's overall intention (e.g."latest episode of Sample Show").query: Optimized, lowercase, space-separated keywords (e.g."sample show s01e05"). Generic/filler/technical terms should be stripped per the tool's docstring.By default magnet links are stripped from the response to save tokens; set
INCLUDE_LINKS=trueto include them.Magnet round trips: with
INCLUDE_LINKSunset, results keep theiridbut no magnet. After picking the 2-5 torrents worth recommending, callget_torrent(id)once per pick: the server resolves it from its 1-hour torrent cache, or re-runs the search if the entry expired. Do not fetch magnets for every result.
popular_torrents(per_source=20): Get the most popular torrents right now from sources with an official top listing (apibay, uindex, 1337x, YTS, nyaa, EZTV) - up toper_sourceresults each, grouped per source and pre-ranked by seeders + leechers.By default magnet links are stripped from the response to save tokens; set
INCLUDE_LINKS=trueto include them.
available_sources(): Get the list of available torrent sources.get_torrent(torrent_id): Get the magnet link for a specific torrent by id (theidreturned bysearch_torrentsorpopular_torrents).authorize_webapp(code, chat_id): Approve a Web UI pairing code bound to your Telegram chat id (the code shown in the browser pairing gate). RequiresTORRENT_SEARCH_API_KEYandTORRENT_SEARCH_API_URL.forward_torrent(filename, magnet_link, chat_id, size=None, seeders=None): Forward a torrent (filename + magnet) to your Telegram chat through the REST API (magnet pruned whenPRUNE_MAGNET_LINKS=true). RequiresTORRENT_SEARCH_API_KEYandTORRENT_SEARCH_API_URL; rate-limited per chat (20/min).torrent_webapp(): Present the web UI URL (WEBUI_URL) and its pairing-based access system.
Example with Devin
Configuration:
{
"mcpServers": {
...
# with stdio (only requires uv)
"torrent-search-mcp": {
"command": "uvx",
"args": [ "torrent-search-mcp" ]
},
# with streamable-http transport (Docker compose: MCP on port 8001; standalone server: 8000)
"torrent-search-mcp": {
"serverUrl": "http://127.0.0.1:8001/mcp"
},
# with sse transport (legacy; requires running server)
"torrent-search-mcp": {
"serverUrl": "http://127.0.0.1:8001/sse"
},
...
}
}Changelog
See CHANGELOG.md for a history of changes to this project.
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Available Tools
7 toolsauthorize_webappAuthorize WebappA
Authorize a browser on the Torrent Search webapp via its pairing code.
The code comes from an user interaction on the webapp: they click "Open in Telegram", scan the QR code, or copy the prompt message, which sends "Authorize for Torrent Search" to you. Take the code from that message and call this tool with it and the user's Telegram chat id. Codes are single-use and expire after 5 minutes. After approval the user MUST go back to the webapp: the browser polls and completes the authentication there (it shows "Access granted" and unlocks the app permanently).
Inputs: code (required), chat_id (required). Returns: result
available_sourcesAvailable SourcesB
Get the list of available torrent sources.
Inputs: no named parameters. Returns: result
forward_torrentForward TorrentA
Send a torrent (filename + magnet) to the user's Telegram chat.
The forward goes through the Torrent Search REST API, which owns the Telegram bot token; when PRUNE_MAGNET_LINKS is enabled the magnet is pruned to 'magnet:?xt=urn:btih:HASH&dn=' before sending. Requires TORRENT_SEARCH_API_KEY (same value as the API server) and TORRENT_SEARCH_API_URL. Forwards are rate-limited per chat (20/min).
Inputs: chat_id (required), filename (required), magnet_link (required), size, +1 more. Returns: result
get_torrentGet TorrentA
Get the magnet link for a specific torrent by id.
The result is wrapped in the untrusted-data fence: the magnet is the fenced value itself, the notice and tag lines are not part of the link.
Inputs: torrent_id (required). Returns: result
popular_torrentsPopular TorrentsA
Get the most popular torrents right now across providers with an official top listing.
Output is grouped per source (thepiratebay.org, uindex.org, 1337x.to, eztvx.to,
yts.vg, nyaa.si), keeping up to per_source results per site, each site's
entries pre-ranked by swarm health.
Response Requirements:
Recommend the top 5-10 results maximum, focused on latest releases.
For each recommendation, include: Filename, Size, Seeds/Leechs, Date, Source, and a 1-sentence "Why this?" reason.
Inputs: per_source. Returns: result
search_torrentsSearch TorrentsA
Perform an advanced torrent search across multiple providers.
Result Analysis & Ranking:
Quality: Prefer 1080p or 4k, over 720p.
Efficiency: Prefer h265/HEVC for better quality/size ratio.
Health: Maximize seeders + leechers.
Size: Prefer smaller files within the same quality bracket.
Language: Ultimately, if multiple equivalent options are available, choose the one with more languages.
Response Requirements:
Recommend the top 3-5 results maximum.
For each recommendation, include: Filename, Size, Seeds/Leechs, Date, Source, and a 1-sentence "Why this?" reason.
If results are poor, irrelevant or too diverse, suggest specific keywords to improve the search.
Inputs: query (required), user_intent (required). Returns: result
torrent_webappTorrent WebappA
Present the Torrent Search webapp and its Telegram pairing access system.
Returns the webapp URL and how to get authorized by you. Tell the user to open the URL: on first visit the site shows a pairing dialog with a QR code and buttons ("Open in Telegram", "t.me" fallback, "Copy Prompt"). Ask the user to scan the QR code, click "Open in Telegram", or copy the prompt message and send it to you in the Telegram chat. That message ("Authorize for Torrent Search") carries the code; when it arrives, extract it and call authorize_webapp with it and the user's Telegram chat id. Codes expire after 5 minutes.
Inputs: no named parameters. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Most tools have clearly distinct purposes: search, popular listings, source listing, magnet retrieval, forwarding, and webapp authorization. The main potential confusion is between torrent_webapp and authorize_webapp, though the descriptions distinguish presenting the webapp from performing the actual authorization.
All tool names use snake_case, which is consistent and readable. However, the naming patterns vary between verb_noun (get_torrent, forward_torrent), adjective_noun (available_sources, popular_torrents), and noun_noun (torrent_webapp), so it is not a uniform verb_noun convention.
Seven tools is a well-scoped set for torrent search plus Telegram forwarding and webapp authorization. Each tool appears to earn its place, with no obvious redundant operations.
The set covers the core workflows: discovering sources, searching, browsing popular torrents, retrieving a magnet link, forwarding to Telegram, and authorizing the webapp. Minor gaps might include richer torrent detail retrieval or pagination/filtering by source, but agents can work around them.
Maintenance
Related MCP Connectors
A simple MCP server built with FastMCP and python
MCP server for the Vulners.com API
Related MCP Servers
- AlicenseBqualityNot gradedmaintenanceA Python MCP server that allows programmatic interaction with YggTorrent, enabling torrent search, details retrieval, and magnet link generation without exposing your Ygg passkey.418MIT
- AlicenseBqualityDmaintenancePython wrapper & MCP server for the rqbit API810 PyPI3MIT
- AlicenseBqualityFmaintenanceA Python MCP server that allows programmatic interaction to find torrents programmatically on YggTorrent and La Cale.42MIT
- AlicenseAqualityDmaintenanceMCP server for searching, viewing details, and downloading torrents from kinozal.tv33 npm2MIT