trash_list_custom_formats
List available TRaSH Guides custom formats for Radarr or Sonarr media management, with optional filtering by categories like HDR, audio, resolution, and source to organize media quality rules.
Instructions
List available TRaSH Guides custom formats. Can filter by category: hdr, audio, resolution, source, streaming, anime, unwanted, release, language
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| service | Yes | Which service | |
| category | No | Optional filter by category |
Implementation Reference
- src/index.ts:633-650 (registration)Registration of the 'trash_list_custom_formats' tool in the MCP TOOLS array, including name, description, and input schema.{ name: "trash_list_custom_formats", description: "List available TRaSH Guides custom formats. Can filter by category: hdr, audio, resolution, source, streaming, anime, unwanted, release, language", inputSchema: { type: "object" as const, properties: { service: { type: "string", enum: ["radarr", "sonarr"], description: "Which service", }, category: { type: "string", description: "Optional filter by category", }, }, required: ["service"], },
- src/index.ts:1751-1771 (handler)MCP server request handler case for 'trash_list_custom_formats', which delegates to trashClient.listCustomFormats and formats the response.case "trash_list_custom_formats": { const { service, category } = args as { service: TrashService; category?: string }; const formats = await trashClient.listCustomFormats(service, category); return { content: [{ type: "text", text: JSON.stringify({ service, category: category || 'all', count: formats.length, formats: formats.slice(0, 50).map(f => ({ name: f.name, categories: f.categories, defaultScore: f.defaultScore, })), note: formats.length > 50 ? `Showing first 50 of ${formats.length}. Use category filter to narrow results.` : undefined, availableCategories: ['hdr', 'audio', 'resolution', 'source', 'streaming', 'anime', 'unwanted', 'release', 'language'], }, null, 2), }], }; }
- src/trash-client.ts:278-314 (handler)Core handler logic in TrashClient.listCustomFormats: fetches CF list from GitHub, caches, batch fetches details, categorizes, and filters if category provided.async listCustomFormats(service: TrashService, category?: string): Promise<{ name: string; categories: string[]; defaultScore?: number }[]> { // Check cache let cfNames = cache.getCFList(service); if (!cfNames) { cfNames = await listGitHubDir(`${service}/cf`); cache.setCFList(service, cfNames); } // Fetch details for categorization const formats: { name: string; categories: string[]; defaultScore?: number }[] = []; // Batch fetch - limit to prevent rate limiting const batchSize = 20; for (let i = 0; i < cfNames.length; i += batchSize) { const batch = cfNames.slice(i, i + batchSize); const results = await Promise.all( batch.map(async name => { const cf = await this.getCustomFormat(service, name); if (!cf) return null; const cats = categorizeCustomFormat(cf.name); return { name: cf.name, categories: cats, defaultScore: cf.trash_scores?.default, }; }) ); formats.push(...results.filter((f): f is NonNullable<typeof f> => f !== null)); } // Filter by category if specified if (category) { return formats.filter(f => f.categories.includes(category.toLowerCase())); } return formats; }
- src/trash-client.ts:193-201 (helper)Helper function categorizeCustomFormat used by listCustomFormats to assign categories to custom formats based on name patterns.function categorizeCustomFormat(name: string): string[] { const categories: string[] = []; for (const [category, patterns] of Object.entries(CF_CATEGORIES)) { if (patterns.some(p => p.test(name))) { categories.push(category); } } return categories.length > 0 ? categories : ['other']; }
- src/trash-client.ts:17-29 (schema)TypeScript interface defining the structure of a TRaSH Custom Format, used in parsing responses.export interface TrashCustomFormat { trash_id: string; trash_scores?: { default: number }; name: string; includeCustomFormatWhenRenaming: boolean; specifications: Array<{ name: string; implementation: string; negate: boolean; required: boolean; fields: Record<string, unknown>; }>; }