Skip to main content
Glama

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
NameRequiredDescriptionDefault
languageNoko
video_idYes

Implementation Reference

  • 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)}
  • 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)}
  • 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)}" }] }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jikime/py-mcp-youtube-toolbox'

If you have feedback or need assistance with the MCP directory API, please join our Discord server