get_summary
Generate summaries of YouTube videos in multiple languages and formats, extracting key information from video content for quick understanding.
Instructions
Get summary for a YouTube video
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| videoId | Yes | YouTube video ID | |
| lang | No | Target language (default: zh-tw) | zh-tw |
| mode | No | Summary mode (default: narrative) | narrative |
Implementation Reference
- src/index.ts:130-259 (handler)Main execution handler for the 'get_summary' MCP tool. Validates input, fetches YouTube video metadata and captions using InnerTube API, selects appropriate caption track, calls DeepSRT API for video summary and title translation, then formats a Markdown response with title, metadata, and summary.private async handleGetSummary(args: any): Promise<CallToolResult> { if (!this.isValidSummaryArgs(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid summary arguments. Required: videoId' ); } try { const videoId = args.videoId; const lang = args.lang || 'zh-tw'; const mode = args.mode || 'narrative'; // Step 1: Get video info and captions from YouTube const videoInfo = await this.getVideoInfo(videoId); if (!videoInfo.videoDetails) { throw new Error('Could not fetch video details'); } const { title, author, lengthSeconds } = videoInfo.videoDetails; // Step 2: Extract captions const captionTracks = videoInfo.captions?.playerCaptionsTracklistRenderer?.captionTracks; if (!captionTracks || captionTracks.length === 0) { throw new Error('No captions available for this video'); } // Step 3: Select best caption const selectedCaption = this.selectBestCaption(captionTracks); if (!selectedCaption) { throw new Error('No suitable captions found'); } // Step 4: Extract transcript argument from caption URL const transcriptArg = new URL(selectedCaption.baseUrl).search.slice(1); // Step 5: Call DeepSRT API for summarization const summaryParams = new URLSearchParams({ v: videoId, action: 'summarize', lang: lang, mode: mode }); const titleParams = new URLSearchParams({ v: videoId, txt: title, action: 'translate', lang: lang, mode: mode }); const [summaryResponse, titleResponse] = await Promise.all([ this.axiosInstance.get(`https://worker.deepsrt.com/transcript2?${summaryParams}`, { headers: { 'Accept': 'application/json', 'X-Transcript-Arg': transcriptArg, 'User-Agent': 'DeepSRT-CLI/1.5.4' } }), this.axiosInstance.get(`https://worker.deepsrt.com/transcript2?${titleParams}`, { headers: { 'Accept': 'application/json', 'X-Transcript-Arg': transcriptArg, 'User-Agent': 'DeepSRT-CLI/1.5.4' } }) ]); const summaryData = summaryResponse.data; const titleData = titleResponse.data; // Format response const translatedTitle = titleData.success ? (titleData.result || titleData.translation || title) : title; const summaryText = summaryData.summary || summaryData.result || summaryData.content; if (!summaryText) { return { content: [ { type: 'text', text: `Error getting summary: ${summaryData.error || 'No summary generated'}` } ], isError: true }; } // Format summary with video information const duration = Math.floor(parseInt(lengthSeconds) / 60) + ':' + (parseInt(lengthSeconds) % 60).toString().padStart(2, '0'); const formattedSummary = `# ${translatedTitle} **Author:** ${author} **Duration:** ${duration} **Language:** ${lang} **Mode:** ${mode} ## Summary ${summaryText} --- *Generated using DeepSRT MCP Server*`; return { content: [ { type: 'text', text: formattedSummary } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error getting summary: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } }
- src/index.ts:71-91 (schema)JSON Schema defining the input parameters for the 'get_summary' tool: videoId (required string), lang (optional string, default 'zh-tw'), mode (optional enum ['narrative','bullet'], default 'narrative').inputSchema: { type: 'object', properties: { videoId: { type: 'string', description: 'YouTube video ID', }, lang: { type: 'string', description: 'Target language (default: zh-tw)', default: 'zh-tw', }, mode: { type: 'string', enum: ['narrative', 'bullet'], description: 'Summary mode (default: narrative)', default: 'narrative', }, }, required: ['videoId'], },
- src/index.ts:68-92 (registration)Tool registration in the ListTools response, defining name 'get_summary', description, and inputSchema.{ name: 'get_summary', description: 'Get summary for a YouTube video', inputSchema: { type: 'object', properties: { videoId: { type: 'string', description: 'YouTube video ID', }, lang: { type: 'string', description: 'Target language (default: zh-tw)', default: 'zh-tw', }, mode: { type: 'string', enum: ['narrative', 'bullet'], description: 'Summary mode (default: narrative)', default: 'narrative', }, }, required: ['videoId'], }, },
- src/index.ts:117-120 (registration)Dispatch logic in CallToolRequest handler that routes 'get_summary' calls to the handleGetSummary method.if (request.params.name === 'get_summary') { return this.handleGetSummary(request.params.arguments); } else if (request.params.name === 'get_transcript') { return this.handleGetTranscript(request.params.arguments);
- src/index.ts:493-506 (helper)Validation helper function for get_summary arguments, type-guarding the expected input shape.private isValidSummaryArgs( args: any ): args is { videoId: string; lang?: string; mode?: SummaryMode } { return ( typeof args === 'object' && args !== null && typeof args.videoId === 'string' && args.videoId.length > 0 && (args.lang === undefined || typeof args.lang === 'string') && (args.mode === undefined || args.mode === 'narrative' || args.mode === 'bullet') ); }