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 Serversearch 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.
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 2 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, 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 |
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. Unset = the web UI runs without the pairing gate and Telegram features stay hidden. |
| (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 authorized session tokens (SHA-256 hashes only); shared between API and MCP processes via mtime-based reload. |
| (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. Telegram sending requires one-time QR pairing when configured.POST /torrent/search: Search for torrents. Query params:query(required),max_items(optional, default20; uncapped whenper_sourceis set) andper_source(optional, 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) 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).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). Send the session token asAuthorization: Bearer.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 for the browser to store.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.POST /forward_telegram: Send torrent info to the Telegram chat bound to the presented session 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).
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).
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Pairing code shown in the webapp 'Telegram Access' gate. | |
| chat_id | Yes | The owner's Telegram chat id the webapp access is bound to. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full behavioral burden. It discloses important non-obvious traits: codes are single-use, expire after 5 minutes, and authentication is only completed in the browser once the user returns to the webapp. This is strong transparency for an authorization tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single-sentence purpose statement is front-loaded, followed by a compact workflow explanation. No filler or redundant content; every sentence adds relevant operational detail, though the length is slightly more than minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with a full schema and output schema, the description covers the complete invocation flow: source of the code, required inputs, single-use/expiry constraint, and the required post-call user action. Minor details like error handling for invalid/expired codes are absent but acceptable given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds meaningful context beyond the schema by explaining where the code comes from, its exact message format, and that it must be paired with the user's Telegram chat id. This helps an agent correctly extract and pass parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Authorize a browser on the Torrent Search webapp via its pairing code.' This clearly identifies the tool's action and distinguishes it from sibling tools like search, get, and forward, which have different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It thoroughly explains when to use the tool: when a user sends an 'Authorize <CODE> for Torrent Search' message, with the code and chat id as inputs. It doesn't explicitly list alternative tools to use instead, but no siblings fulfill this same role, so exclusion is not necessary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
available_sourcesAvailable SourcesB
Get the list of available torrent sources.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only says 'Get the list', implying a read operation, but gives no detail on side effects, permissions, caching, or failure modes. There is no contradiction, but the disclosure is too thin.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It is concise, though it is also very sparse – perhaps too sparse to fully convey the tool's role.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple zero-parameter interface and the presence of an output schema, the description is mostly adequate. However, it omits any context about what a 'torrent source' is, why a user would call this, or how it fits into the workflow (e.g., before searching).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so no parameter semantics are needed. Schema description coverage is trivially 100% and the baseline for a no-parameter tool is 4, which applies here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get the list of available torrent sources'. It clearly indicates a retrieval operation unlike the sibling search, popular, or forward tools, though it doesn't explicitly contrast itself with them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus its siblings. It doesn't mention that it could be a prerequisite for search_torrents or that it only lists supported sources. No alternatives or exclusions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| size | No | Optional human-readable size (e.g. '1.2 GiB'). | |
| chat_id | Yes | The owner's Telegram chat id the torrent is sent to. | |
| seeders | No | Optional seeder count. | |
| filename | Yes | Exact torrent filename shown in the search results. | |
| magnet_link | Yes | Magnet link of the torrent (from get_torrent, or from a search run with INCLUDE_LINKS=true), as the bare magnet: drop the untrusted-data notice and tag lines, they are not part of the link and would break the forward. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does it well: it discloses the REST API dependency, bot-token ownership, required TORRENT_SEARCH_API_KEY and TORRENT_SEARCH_API_URL, the per-chat rate limit of 20/min, and — importantly — that PRUNE_MAGNET_LINKS may rewrite the magnet payload before sending. It omits failure behavior (e.g. what happens when the rate limit is hit) and whether forwards are persisted or deduplicated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The action is front-loaded in the first sentence, followed by tightly packed operational detail (API dependency, pruning, credentials, rate limit). No sentence is filler, though the environment-variable clause is slightly dense and could be trimmed for an agent-facing reader.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description covers the prerequisites, the rate limit, and the payload-mutation behavior an agent must know before calling. It is nearly complete for a 5-parameter side-effecting tool, with only error/retry semantics left unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters including the optional size and seeders fields and the bare-magnet requirement. The description adds only the 'filename + magnet' pairing, which the schema already implies; baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — 'Send a torrent (filename + magnet) to the user's Telegram chat' — which immediately tells an agent this is a delivery/forwarding action rather than a lookup. It does not explicitly contrast itself with siblings like get_torrent, search_torrents, or torrent_webapp, so the boundary is inferred rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied through the mention that the magnet comes 'from get_torrent, or from a search run with INCLUDE_LINKS=true', which routes the agent to the right sibling for input gathering. However there is no explicit when-to-use vs when-not statement (e.g. forwarding vs opening the webapp), so the guidance is indirect.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| torrent_id | Yes | Torrent ID returned by a previous search_torrents or popular_torrents call. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it delivers a genuinely non-obvious behavioral detail: the magnet is wrapped in an untrusted-data fence, and the fenced value itself is the link while notice/tag lines are not. That directly affects how an agent consumes the result. It stops short of disclosing auth needs, error behavior for missing ids, or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the purpose, followed by the essential result-parsing rule. No filler and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter getter with an output schema present, the description covers purpose and the non-obvious fencing semantics of the return value. It omits what happens when the id does not resolve, which is a minor but real gap for a lookup tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter already documents that the id is 'returned by a previous search_torrents or popular_torrents call.' The description repeats only 'by id' and adds no format or validation detail, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Get the magnet link for a specific torrent by id.' That is concrete and distinct from search_torrents and popular_torrents. It does not explicitly name a sibling to differentiate against, which keeps it below a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'by id' and the schema note that the id comes from a previous search_torrents or popular_torrents call imply the use case (you already have an id). There is no explicit when/when-not guidance or comparison against forward_torrent or torrent_webapp, so guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| per_source | No | How many top results to keep per source (default 20). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly explains that output is grouped per source, limited to per_source results per site, and pre-ranked by swarm health. It also details the expected response format via the 'Response Requirements' section. It does not disclose rate limits, authentication needs, or failure modes, but for a read-only list tool, the disclosed behavior is fairly comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a clear purpose sentence, a grouping/ranking explanation, and a bulleted list of response requirements. It is front-loaded with the core purpose. The response requirements are useful instructions but add length; still, every sentence serves a purpose. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given one parameter with full schema coverage and an output schema (indicated), the description covers the tool's purpose, output grouping, ranking, and response format. It lists the exact sources and the per_source limit. It does not mention potential edge cases like empty results or error handling, but for a list tool with an output schema, this is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes the only parameter `per_source` with full coverage. The description adds value by explaining that per_source controls 'how many top results to keep per source' and ties it to the grouping behavior. This reinforces the parameter's effect on output, going beyond the schema's simple description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get the most popular torrents right now across providers with an official top listing.' It clearly differentiates this from search_torrents and get_torrent by emphasizing 'most popular' and 'official top listing.' The mention of specific sources (thepiratebay.org, uindex.org, etc.) further concretizes the scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (for fetching popular torrent lists) but does not explicitly state when to prefer it over search_torrents or get_torrent. It mentions 'across providers with an official top listing' as a distinguishing factor, but no explicit 'when-not-to-use' or alternative names are provided. The response requirements give guidance on output formatting but not on tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Optimized search keywords, lowercase and space-separated. Strip generic terms (movie, torrent, download), filler words (the, a, of) and technical tags (1080p, h265, bluray) unless explicitly requested. TV shows: 'name sXXeYY' for episodes, 'name sXX' for seasons. Add 'multi' only if a multi-language version is requested. | |
| user_intent | Yes | User's overall intention (e.g. 'latest episode of Sample Show'). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It transparently explains the ranking criteria (quality, efficiency, health, size, language) and the response format (top 3-5 results with specific fields and 'Why this?' reasons), plus the fallback of suggesting keywords. This is substantial and goes beyond basic operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with headers and bullet points, making it scannable, but it's fairly long with detailed ranking and response requirements. While each section is informative, it could be more concise; the ranking criteria and response format are somewhat verbose, though they do add context. It's not overly redundant but is longer than strictly necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of the tool (multi-provider search, ranking, response formatting) and the presence of an output schema, the description covers the essential behavior, query construction, ranking logic, and response requirements, including a fallback for poor results. It doesn't mention auth or limitations, but for a search tool with an output schema, it's sufficiently complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes both parameters with 100% coverage, so the baseline is 3. The description adds significant value by detailing how to construct the query (strip generic terms, TV show format, 'multi' flag), which is not in the schema. This enriches the meaning of the query parameter beyond its type/description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool performs an advanced torrent search across multiple providers, which is a specific action and resource. However, it doesn't explicitly differentiate itself from siblings like popular_torrents or get_torrent beyond calling itself 'advanced' and mentioning 'multiple providers', so it's clear but not fully distinguishing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance on when to use this tool versus alternatives. It gives detailed ranking and response instructions, but doesn't say when to prefer this over popular_torrents or other siblings, nor does it mention exclusions or conditions. Usage is only implied by the search nature.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It transparently explains the pairing dialog, the buttons, the code expiration (5 minutes), and instructs the agent to call authorize_webapp with the extracted code and chat id. This covers all relevant behaviors and side effects (the tool returns a URL and guides a user interaction). The only minor gap is not explicitly stating that no data is modified, but it's implied by the presentation nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but every sentence contributes to the user interaction flow—it explains the URL, the pairing dialog, the actions, the code extraction, and the expiry. It is well-structured, starting with the purpose and then detailing steps. It could be slightly more compact by merging some sentences, but the detail is necessary for this interactive tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (an interactive pairing process with user involvement), the description is complete. It covers the output (webapp URL), the steps the agent must take, the exact message format, the expiry, and the call to authorize_webapp. An output schema exists (though not shown), so return-value details are presumably covered there. Nothing essential is missing for an agent to correctly invoke and follow through.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so schema coverage is trivially 100%. The description correctly does not need to explain parameters, and it adds no parameter-related details. Baseline for zero parameters is 4, and the description's focus on behavior is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: to present the Torrent Search webapp and its Telegram pairing system, returning the webapp URL and the authorization procedure. It distinguishes itself from sibling tools like search_torrents or authorize_webapp by focusing on the initial presentation and pairing flow, not on searching or authorizing directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit step-by-step usage instructions: tell the user to open the URL, guide them through the QR code/Telegram options, extract the code from their message, and call authorize_webapp. It clearly defines when to use this tool (to initiate pairing) and the follow-up action, though it doesn't explicitly contrast with alternatives like 'use search_torrents when searching'—but the flow is self-contained and unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v4.6.1- Changed
forward_torrent5 fields changed- changed
Input schema / properties / magnet_link / descriptionPrevious value: -"Magnet link of the torrent (from get_torrent, or from a search run with INCLUDE_LINKS=true)."New value: +"Magnet link of the torrent (from get_torrent, or from a search run with INCLUDE_LINKS=true), as the bare magnet: drop the untrusted-data notice and tag lines, they are not part of the link and would break the forward." - changed
Input schema / properties / seeders / anyOfPrevious value: -[ - { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "description": "Optional seeder count." - }, - { - "type": "null" - } -]New value: +[ + { + "type": "integer" + }, + { + "type": "null" + } +] - added
Input schema / properties / seeders / descriptionAdded value: +"Optional seeder count." - changed
Input schema / properties / size / anyOfPrevious value: -[ - { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Optional human-readable size (e.g. '1.2 GiB')." - }, - { - "type": "null" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - added
Input schema / properties / size / descriptionAdded value: +"Optional human-readable size (e.g. '1.2 GiB')."
2 tool updates
v4.5.0- Added
forward_torrent - Changed
search_torrents1 field changed- changed
Input schema / properties / user_intent / descriptionPrevious value: -"User's overall intention (e.g. 'latest episode of Breaking Bad')."New value: +"User's overall intention (e.g. 'latest episode of Sample Show')."
6 tool updates
v4.3.3- Added
authorize_webapp - Added
available_sources - Changed
get_torrent1 field changed- added
Input schema / properties / torrent_id / descriptionAdded value: +"Torrent ID returned by a previous search_torrents or popular_torrents call."
- Added
popular_torrents - Changed
search_torrents2 fields changed- added
Input schema / properties / query / descriptionAdded value: +"Optimized search keywords, lowercase and space-separated. Strip generic terms (movie, torrent, download), filler words (the, a, of) and technical tags (1080p, h265, bluray) unless explicitly requested. TV shows: 'name sXXeYY' for episodes, 'name sXX' for seasons. Add 'multi' only if a multi-language version is requested." - added
Input schema / properties / user_intent / descriptionAdded value: +"User's overall intention (e.g. 'latest episode of Breaking Bad')."
- Added
torrent_webapp
4 tool updates
v2.4.0- Added
get_torrent - Removed
get_ygg_magnet_link - Removed
get_ygg_torrent_details - Changed
search_torrents7 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / max_itemsRemoved value: -{ - "default": 10, - "title": "Max Items", - "type": "integer" -} - removed
Input schema / properties / query / titleRemoved value: -"Query" - removed
Input schema / properties / sourcesRemoved value: -{ - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Sources" -} - added
Input schema / properties / user_intentAdded value: +{ + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "query" -]New value: +[ + "user_intent", + "query" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "result": { + "type": "string" + } + }, + "required": [ + "result" + ], + "type": "object", + "x-fastmcp-wrap-result": true +}
3 tool updates
v1.0.0- First observed
get_ygg_magnet_link - First observed
get_ygg_torrent_details - First observed
search_torrents
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
- AlicenseBqualityCmaintenancePython wrapper & MCP server for the rqbit API83MIT
- AlicenseBqualityFmaintenanceA Python MCP server that allows programmatic interaction to find torrents programmatically on YggTorrent and La Cale.455 PyPI2MIT
- AlicenseAqualityDmaintenanceMCP server for searching, viewing details, and downloading torrents from kinozal.tv34 npm2MIT