get_video_transcript
Extract transcript or captions from a YouTube video by providing the video ID and preferred language. Use this tool for accessing text content directly from videos.
Instructions
Get transcript/captions for a YouTube video
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | ko | |
| video_id | Yes |
Implementation Reference
- server.py:1132-1205 (handler)MCP tool handler implementation for get_video_transcript. Fetches video metadata and formats the transcript with timestamps using the YouTubeService helper.@mcp.tool( name="get_video_transcript", description="Get transcript/captions for a YouTube video", ) async def get_video_transcript(video_id: str, language: Optional[str] = 'ko') -> Dict[str, Any]: """ Get transcript/captions for a YouTube video Args: video_id (str): YouTube video ID language (str, optional): Language code (e.g., 'en', 'ko', 'fr') Returns: Dict[str, Any]: Transcript data """ try: # Get video details for metadata video_data = youtube_service.get_video_details(video_id) if not video_data.get('items'): return {'error': f"Video with ID {video_id} not found"} video = video_data['items'][0] # Get transcript try: transcript_data = youtube_service.get_video_transcript(video_id, language) # Format transcript with timestamps formatted_transcript = [] for segment in transcript_data: text = getattr(segment, 'text', '') start = getattr(segment, 'start', 0) duration = getattr(segment, 'duration', 0) formatted_transcript.append({ 'text': text, 'start': start, 'duration': duration, 'timestamp': youtube_service.format_time(int(start * 1000)) }) # Create metadata metadata = { 'videoId': video.get('id'), 'title': video.get('snippet', {}).get('title'), 'channelTitle': video.get('snippet', {}).get('channelTitle'), 'language': language or 'default', 'segmentCount': len(transcript_data) } # Create timestamped text version timestamped_text = "\n".join([ f"[{item['timestamp']}] {item['text']}" for item in formatted_transcript ]) return { 'metadata': metadata, 'transcript': formatted_transcript, 'text': timestamped_text, 'channelId': video.get('snippet', {}).get('channelId') } except Exception as e: return { 'error': f"Could not retrieve transcript: {str(e)}", 'videoId': video_id, 'title': video.get('snippet', {}).get('title') } except Exception as e: logger.exception(f"Error in get_video_transcript: {e}") return {'error': str(e)}
- server.py:312-342 (helper)Core helper method in YouTubeService that retrieves raw transcript segments using youtube_transcript_api, with language fallback logic.def get_video_transcript(self, video_id: str, language: Optional[str] = 'ko') -> List[Dict[str, Any]]: """ Get transcript for a specific YouTube video """ video_id = self.parse_url(video_id) try: if language: transcript_list = YouTubeTranscriptApi.list_transcripts(video_id) try: transcript = transcript_list.find_transcript([language]) return transcript.fetch() except NoTranscriptFound: # Fallback to generated transcript if available try: transcript = transcript_list.find_generated_transcript([language]) return transcript.fetch() except: # Final fallback to any available transcript transcript = transcript_list.find_transcript(['en']) return transcript.fetch() else: return YouTubeTranscriptApi.get_video_transcript(video_id) except (TranscriptsDisabled, NoTranscriptFound) as e: logger.error(f"No transcript available for video {video_id}: {e}") return [] except Exception as e: logger.error(f"Error getting transcript for video {video_id}: {e}") raise e
- server.py:1132-1205 (registration)The @mcp.tool decorator registers the get_video_transcript tool with MCP server, defining its name and description. Input schema derived from function parameters.@mcp.tool( name="get_video_transcript", description="Get transcript/captions for a YouTube video", ) async def get_video_transcript(video_id: str, language: Optional[str] = 'ko') -> Dict[str, Any]: """ Get transcript/captions for a YouTube video Args: video_id (str): YouTube video ID language (str, optional): Language code (e.g., 'en', 'ko', 'fr') Returns: Dict[str, Any]: Transcript data """ try: # Get video details for metadata video_data = youtube_service.get_video_details(video_id) if not video_data.get('items'): return {'error': f"Video with ID {video_id} not found"} video = video_data['items'][0] # Get transcript try: transcript_data = youtube_service.get_video_transcript(video_id, language) # Format transcript with timestamps formatted_transcript = [] for segment in transcript_data: text = getattr(segment, 'text', '') start = getattr(segment, 'start', 0) duration = getattr(segment, 'duration', 0) formatted_transcript.append({ 'text': text, 'start': start, 'duration': duration, 'timestamp': youtube_service.format_time(int(start * 1000)) }) # Create metadata metadata = { 'videoId': video.get('id'), 'title': video.get('snippet', {}).get('title'), 'channelTitle': video.get('snippet', {}).get('channelTitle'), 'language': language or 'default', 'segmentCount': len(transcript_data) } # Create timestamped text version timestamped_text = "\n".join([ f"[{item['timestamp']}] {item['text']}" for item in formatted_transcript ]) return { 'metadata': metadata, 'transcript': formatted_transcript, 'text': timestamped_text, 'channelId': video.get('snippet', {}).get('channelId') } except Exception as e: return { 'error': f"Could not retrieve transcript: {str(e)}", 'videoId': video_id, 'title': video.get('snippet', {}).get('title') } except Exception as e: logger.exception(f"Error in get_video_transcript: {e}") return {'error': str(e)}
- server.py:805-891 (helper)Related MCP resource that provides transcript data via URI, reusing the same helper logic.@mcp.resource( uri='youtube://transcript/{video_id}?language={language}', name="transcript", description="Get the transcript/captions for a specific YouTube video", ) async def get_video_transcript_resource(video_id: str, language: Optional[str] = None) -> Dict[str, Any]: """ Resource for getting transcript/captions for a specific YouTube video Args: video_id (str): YouTube video ID language (str, optional): Language code for transcript Returns: Dict[str, Any]: Transcript resource """ try: # Get video details for metadata video_data = youtube_service.get_video_details(video_id) if not video_data.get('items'): return { "contents": [{ "uri": f"youtube://transcript/{video_id}", "text": f"Video with ID {video_id} not found." }] } video = video_data['items'][0] try: # Get transcript transcript_data = youtube_service.get_video_transcript(video_id, language) # Format transcript with timestamps formatted_transcript = [] for segment in transcript_data: # FetchedTranscriptSnippet 객체에서 속성으로 접근 text = getattr(segment, 'text', '') start = getattr(segment, 'start', 0) duration = getattr(segment, 'duration', 0) formatted_transcript.append({ 'text': text, 'start': start, 'duration': duration, 'timestamp': youtube_service.format_time(int(start * 1000)) }) # Create metadata metadata = { 'videoId': video.get('id'), 'title': video.get('snippet', {}).get('title'), 'channelTitle': video.get('snippet', {}).get('channelTitle'), 'language': language or 'default', 'segmentCount': len(transcript_data) } # Create timestamped text version timestamped_text = "\n".join([ f"[{item['timestamp']}] {item['text']}" for item in formatted_transcript ]) return { "contents": [{ "uri": f"youtube://transcript/{video_id}", "text": f"# Transcript for: {metadata['title']}\n\n{timestamped_text}" }], "metadata": metadata } except Exception as e: return { "contents": [{ "uri": f"youtube://transcript/{video_id}", "text": f"Transcript not available for video ID {video_id}. Error: {str(e)}" }] } except Exception as e: logger.exception(f"Error in get_video_transcript_resource: {e}") return { "contents": [{ "uri": f"youtube://transcript/{video_id}", "text": f"Error fetching transcript: {str(e)}" }] }