77 lines
2.9 KiB
TypeScript
77 lines
2.9 KiB
TypeScript
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 };
|
|
}
|
|
},
|
|
);
|
|
}
|