import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import type { TorrentClawClient } from "../api-client.js"; import { ApiError } from "../api-client.js"; export function registerScanRequest( server: McpServer, client: TorrentClawClient, ): void { server.tool( "submit_scan_request", "Submit a torrent for audio/video quality analysis (codec, tracks, resolution, HDR). Use when the user wants to know the exact media specs of a torrent before downloading. Results are not instant — use get_scan_status to check progress. Rate limited to 5 requests per hour.", { info_hash: z .string() .regex(/^[a-fA-F0-9]{40}$/) .describe("40-character hex torrent info_hash to scan"), email: z .string() .email() .max(200) .describe("Email address for scan completion notification"), }, async (params) => { try { const data = await client.submitScanRequest( params.info_hash.toLowerCase(), params.email, ); return { content: [ { type: "text", text: `Scan request submitted for ${params.info_hash.toLowerCase()}.\nStatus: ${data.status}\nUse get_scan_status(info_hash="${params.info_hash.toLowerCase()}") to check progress.`, }, ], }; } catch (error) { const message = error instanceof ApiError ? `TorrentClaw API error (${error.status}): ${error.message}` : `Request failed: ${error instanceof Error ? error.message : "Unknown error"}`; return { content: [{ type: "text", text: message }], isError: true }; } }, ); server.tool( "get_scan_status", "Check the status of a torrent audio/video scan request. Returns the current scan status (pending, scanning, completed, failed). Use after submit_scan_request.", { info_hash: z .string() .regex(/^[a-fA-F0-9]{40}$/) .describe("40-character hex torrent info_hash to check"), }, async (params) => { try { const data = await client.getScanStatus(params.info_hash.toLowerCase()); const lines = [`Scan status for ${params.info_hash.toLowerCase()}:`]; lines.push(` Status: ${data.status}`); if (data.source) lines.push(` Source: ${data.source}`); if (data.createdAt) lines.push(` Submitted: ${data.createdAt}`); if (data.completedAt) lines.push(` Completed: ${data.completedAt}`); return { content: [{ type: "text", text: lines.join("\n") }], }; } catch (error) { const message = error instanceof ApiError ? `TorrentClaw API error (${error.status}): ${error.message}` : `Request failed: ${error instanceof Error ? error.message : "Unknown error"}`; return { content: [{ type: "text", text: message }], isError: true }; } }, ); }