findConsistentOutlierChannels
Discover emerging YouTube channels that consistently outperform their size in a specific topic.
Instructions
A powerful, high-cost discovery tool. It finds emerging channels that show consistent, high-performance relative to their size within a specific topic and timeframe.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Required. The core topic or niche to investigate (e.g., 'stoic philosophy', 'AI history explainers'). | |
| channelAge | No | Optional. Filters by channel age. Default: 'NEW'. 'NEW' = under 6 months (emerging), 'ESTABLISHED' = 6-24 months (proven). | NEW |
| consistencyLevel | No | Optional. Minimum required consistency. Default: 'MODERATE'. 'MODERATE' (~30%) for broad discovery. 'HIGH' (~50%) for exceptional channels. | MODERATE |
| outlierMagnitude | No | Optional. Required 'viral factor' for videos. Default: 'STANDARD'. 'STANDARD' (views>subs) for regular content. 'STRONG' (views>3x subs) for viral channels. | STANDARD |
| videoCategoryId | No | Optional. YouTube video category ID to narrow search (e.g., '27' for Education). Improves relevance. | |
| regionCode | No | Optional. ISO 2-letter country code (e.g., 'US', 'DE') to target a regional audience. | |
| maxResults | No | Optional. Max number of channels to return. Default: 10. |
Implementation Reference
- The FindConsistentOutlierChannelsTool class with executeImpl() method - the primary handler that validates params via Zod schema, creates NicheRepository and NicheAnalyzerService instances, then calls nicheAnalyzer.findConsistentOutlierChannels() and formats the result.
export class FindConsistentOutlierChannelsTool extends BaseTool< typeof findConsistentOutlierChannelsSchema > { name = "findConsistentOutlierChannels"; description = "A powerful, high-cost discovery tool. It finds emerging channels that show consistent, high-performance relative to their size within a specific topic and timeframe."; schema = findConsistentOutlierChannelsSchema; protected async executeImpl( params: z.infer<typeof findConsistentOutlierChannelsSchema> ): Promise<CallToolResult> { // --- THIS IS THE EXPLICIT CONVERSION POINT --- // We use Zod to parse the user's flexible input. // The result of `parse` is a new, complete object with all defaults applied. // This new object perfectly matches the strict `...Options` type. const validatedOptions: FindConsistentOutlierChannelsOptions = params; // Now, we create our services and pass them the strict, validated options. const nicheRepository = new NicheRepository(); const nicheAnalyzer = new NicheAnalyzerService( this.container.youtubeService, nicheRepository ); // The analyzer's method is called with the guaranteed, complete options object. const searchResults = await nicheAnalyzer.findConsistentOutlierChannels(validatedOptions); return formatSuccess(searchResults); } } - Zod schema (findConsistentOutlierChannelsSchema) defining the tool's input parameters: query (required string), channelAge (default NEW), consistencyLevel (default MODERATE), outlierMagnitude (default STANDARD), videoCategoryId (optional), regionCode (optional), maxResults (default 10, max 50).
export const findConsistentOutlierChannelsSchema = z.object({ query: z .string() .min(1, "Query is required") .describe( "Required. The core topic or niche to investigate (e.g., 'stoic philosophy', 'AI history explainers')." ), channelAge: z .enum(["NEW", "ESTABLISHED"]) .default("NEW") .describe( "Optional. Filters by channel age. Default: 'NEW'. 'NEW' = under 6 months (emerging), 'ESTABLISHED' = 6-24 months (proven)." ), consistencyLevel: z .enum(["MODERATE", "HIGH"]) .default("MODERATE") .describe( "Optional. Minimum required consistency. Default: 'MODERATE'. 'MODERATE' (~30%) for broad discovery. 'HIGH' (~50%) for exceptional channels." ), outlierMagnitude: z .enum(["STANDARD", "STRONG"]) .default("STANDARD") .describe( "Optional. Required 'viral factor' for videos. Default: 'STANDARD'. 'STANDARD' (views>subs) for regular content. 'STRONG' (views>3x subs) for viral channels." ), videoCategoryId: z .string() .optional() .describe( "Optional. YouTube video category ID to narrow search (e.g., '27' for Education). Improves relevance." ), regionCode: regionCodeSchema .optional() .describe( "Optional. ISO 2-letter country code (e.g., 'US', 'DE') to target a regional audience." ), maxResults: z .number() .int() .min(1) .max(50) .default(10) .describe("Optional. Max number of channels to return. Default: 10."), }); - src/types/analyzer.types.ts:1-9 (schema)TypeScript interface FindConsistentOutlierChannelsOptions used by the service layer - the strict type that params are cast to after Zod parsing.
export interface FindConsistentOutlierChannelsOptions { query: string; channelAge: "NEW" | "ESTABLISHED"; consistencyLevel: "MODERATE" | "HIGH"; outlierMagnitude: "STANDARD" | "STRONG"; videoCategoryId?: string; regionCode?: string; maxResults: number; } - src/types/tools.ts:51-59 (schema)FindConsistentOutlierChannelsParams interface - an alternative param type definition with optional fields for the tool input.
export interface FindConsistentOutlierChannelsParams { query: string; channelAge?: "NEW" | "ESTABLISHED"; consistencyLevel?: "MODERATE" | "HIGH"; outlierMagnitude?: "STANDARD" | "STRONG"; videoCategoryId?: string; regionCode?: string; maxResults?: number; } - src/tools/index.ts:39-89 (registration)Registration in registerTools() - the tool is imported at line 16, added to toolsToRegister at line 49 (only when MDB_MCP_CONNECTION_STRING is set), and registered with the MCP server via server.registerTool() at line 65.
export function registerTools(server: McpServer, container: IServiceContainer) { const hasYoutubeKey = !!process.env.YOUTUBE_API_KEY; const toolsToRegister: ToolConstructor[] = []; if (hasYoutubeKey) { // Register all standard YouTube tools toolsToRegister.push(...(TOOL_CLASSES as ToolConstructor[])); // Register analytics tools if connection string is present if (process.env.MDB_MCP_CONNECTION_STRING) { toolsToRegister.push(FindConsistentOutlierChannelsTool); } } else { // Only register tools that don't require the API key toolsToRegister.push(GetTranscriptsTool); } for (const ToolClass of toolsToRegister) { // Instantiate with DI container const toolInstance = new ToolClass(container); const humanReadableTitle = toolInstance.name .replace(/([A-Z])/g, " $1") .replace(/^./, (str: string) => str.toUpperCase()); // Register with MCP Server server.registerTool( toolInstance.name, { description: toolInstance.description, inputSchema: toolInstance.schema, annotations: { title: humanReadableTitle, readOnlyHint: true, idempotentHint: true, }, }, // eslint-disable-next-line @typescript-eslint/no-unsafe-argument (async ( args: z.infer<typeof toolInstance.schema> ): Promise<CallToolResult> => { try { return await toolInstance.execute(args); } catch (err) { return formatError(err); } // eslint-disable-next-line @typescript-eslint/no-explicit-any }) as any ); } }