UNPKG

@kevinwatt/yt-dlp-mcp

Version:

An MCP server implementation that integrates with yt-dlp, providing video and audio content download capabilities (e.g. YouTube, Facebook, Tiktok, etc.) for LLMs.

107 lines 4.82 kB
import { getCookieArgs } from "../config.js"; import { _spawnPromise, validateUrl } from "./utils.js"; import { buildCommentExtractorArgs, formatCommentsOutput, formatCommentsSummary, resolveCommentRequestOptions, } from "./comments-core.js"; export async function getVideoComments(url, maxComments = 20, sortOrder = "top", config, options = {}) { if (!validateUrl(url)) { throw new Error("Invalid or unsupported URL format"); } const normalizedView = options.responseFormat === "markdown_tree" ? options.view ?? "threaded" : options.view; if (options.responseFormat === "markdown_tree" && normalizedView !== "threaded") { throw new Error("responseFormat 'markdown_tree' requires view 'threaded'. Omit view to use the threaded default."); } const requestOptions = resolveCommentRequestOptions({ maxComments, sortOrder, view: normalizedView, responseFormat: options.responseFormat, maxParents: options.maxParents, maxReplies: options.maxReplies, maxRepliesPerThread: options.maxRepliesPerThread, maxDepth: options.maxDepth, }); const args = [ "--dump-json", "--no-warnings", "--no-check-certificate", "--write-comments", "--extractor-args", buildCommentExtractorArgs(requestOptions), "--skip-download", ...(config ? getCookieArgs(config) : []), url, ]; try { const output = await _spawnPromise("yt-dlp", args); const metadata = JSON.parse(output); return formatCommentsOutput(metadata.comments, { sourceId: readMetadataString(metadata.id), title: readMetadataString(metadata.title) ?? readMetadataString(metadata.fulltitle), sourceUrl: readMetadataString(metadata.webpage_url) ?? readMetadataString(metadata.original_url) ?? url, extractor: readMetadataString(metadata.extractor_key) ?? readMetadataString(metadata.extractor), }, requestOptions, config?.limits.characterLimit); } catch (error) { handleCommentsError(error, url); } } export async function getVideoCommentsSummary(url, maxComments = 10, config, options = {}) { if (!validateUrl(url)) { throw new Error("Invalid or unsupported URL format"); } const requestOptions = resolveCommentRequestOptions({ maxComments, view: options.view, }); const args = [ "--dump-json", "--no-warnings", "--no-check-certificate", "--write-comments", "--extractor-args", buildCommentExtractorArgs(requestOptions), "--skip-download", ...(config ? getCookieArgs(config) : []), url, ]; try { const output = await _spawnPromise("yt-dlp", args); const metadata = JSON.parse(output); return formatCommentsSummary(metadata.comments, { maxComments: requestOptions.maxComments, view: requestOptions.view, }); } catch (error) { handleCommentsError(error, url); } } function readMetadataString(value) { return typeof value === "string" && value.length > 0 ? value : undefined; } function handleCommentsError(error, url) { if (error instanceof Error) { if (error.message.includes("Video unavailable") || error.message.includes("private")) { throw new Error(`Video is unavailable or private: ${url}. Check the URL and video privacy settings.`); } if (error.message.includes("Unsupported URL") || error.message.includes("extractor")) { throw new Error(`Unsupported platform or video URL: ${url}. Comments extraction is primarily supported for YouTube.`); } if (error.message.includes("network") || error.message.includes("Connection")) { throw new Error("Network error while extracting comments. Check your internet connection and retry."); } if (error.message.includes("comments are disabled") || error.message.includes("Comments are turned off")) { throw new Error(`Comments are disabled for this video: ${url}`); } if (error.message.includes("Sign in") || error.message.includes("age")) { throw new Error(`This video requires authentication to view comments. Configure cookies in your settings.`); } if (error.message.includes("Unexpected token") || error.message.includes("JSON")) { throw new Error(`Failed to parse comments metadata from ${url}. yt-dlp returned invalid JSON output.`); } throw new Error(`Failed to extract video comments: ${error.message}. Verify the URL is correct.`); } throw new Error(`Failed to extract video comments from ${url}`); } //# sourceMappingURL=comments.js.map