Skip to main content
Glama
jedarden

YouTube Transcript DL MCP Server

by jedarden

get_transcript

Extract transcript text from YouTube videos to access spoken content in text, JSON, or SRT formats for analysis, translation, or accessibility purposes.

Instructions

Extract transcript from a single YouTube video

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
videoIdYesYouTube video ID or URL
languageNoLanguage code (e.g., "en", "es", "fr")en
formatNoOutput formatjson

Implementation Reference

  • MCP tool handler for 'get_transcript'. Validates args, calls YouTubeTranscriptService.getTranscript, formats response as MCP content with JSON text.
    private async handleGetTranscript(args: any) {
      const { videoId, language = 'en', format = 'json' } = args;
      
      if (!videoId) {
        throw new McpError(ErrorCode.InvalidParams, 'videoId is required');
      }
    
      const result = await this.transcriptService.getTranscript(videoId, language, format);
      
      return {
        content: [{
          type: 'text',
          text: JSON.stringify(result, null, 2)
        }]
      };
    }
  • Registration of the 'get_transcript' tool in the listTools response, including name, description, and input schema definition.
    {
      name: 'get_transcript',
      description: 'Extract transcript from a single YouTube video',
      inputSchema: {
        type: 'object',
        properties: {
          videoId: {
            type: 'string',
            description: 'YouTube video ID or URL'
          },
          language: {
            type: 'string',
            description: 'Language code (e.g., "en", "es", "fr")',
            default: 'en'
          },
          format: {
            type: 'string',
            enum: ['text', 'json', 'srt'],
            description: 'Output format',
            default: 'json'
          }
        },
        required: ['videoId']
      }
    },
  • Input schema and metadata for the 'get_transcript' tool used for validation in MCP listTools.
    {
      name: 'get_transcript',
      description: 'Extract transcript from a single YouTube video',
      inputSchema: {
        type: 'object',
        properties: {
          videoId: {
            type: 'string',
            description: 'YouTube video ID or URL'
          },
          language: {
            type: 'string',
            description: 'Language code (e.g., "en", "es", "fr")',
            default: 'en'
          },
          format: {
            type: 'string',
            enum: ['text', 'json', 'srt'],
            description: 'Output format',
            default: 'json'
          }
        },
        required: ['videoId']
      }
    },
  • Core helper function implementing transcript extraction logic: caching, video ID extraction, Python script execution for fetching transcript data from YouTube, result processing, error handling.
    public async getTranscript(
      videoId: string,
      language: string = 'en',
      format: 'text' | 'json' | 'srt' = 'json'
    ): Promise<TranscriptResponse> {
      try {
        // Clean video ID from URL if needed
        const cleanVideoId = this.extractVideoId(videoId);
        const cacheKey = `transcript:${cleanVideoId}:${language}:${format}`;
    
        // Check cache first
        const cached = this.cache.get<TranscriptResponse>(cacheKey);
        if (cached) {
          this.logger.debug(`Cache hit for video ${cleanVideoId}`);
          return cached;
        }
    
        this.logger.info(`Fetching transcript for video: ${cleanVideoId}`);
    
        // Call Python script to get transcript
        const command = `python3 "${this.pythonScript}" fetch --video-id "${cleanVideoId}" --language "${language}"`;
        const { stdout, stderr } = await execAsync(command);
    
        if (stderr) {
          this.logger.warn(`Python script warning: ${stderr}`);
        }
    
        const pythonResult: PythonTranscriptResult = JSON.parse(stdout);
    
        if (!pythonResult.success) {
          throw new Error(pythonResult.error || 'Failed to fetch transcript');
        }
    
        // Convert to our format
        const transcript: TranscriptItem[] = pythonResult.transcript.map(item => ({
          text: item.text,
          start: item.start,
          duration: item.duration
        }));
    
        const response: TranscriptResponse = {
          videoId: cleanVideoId,
          title: await this.getVideoTitle(cleanVideoId), // Try to get title
          language,
          transcript,
          metadata: {
            extractedAt: new Date().toISOString(),
            source: 'youtube-transcript-api',
            duration: pythonResult.metadata?.duration || transcript.reduce((acc, item) => acc + item.duration, 0)
          }
        };
    
        // Cache the response
        this.cache.set(cacheKey, response);
    
        this.logger.info(`Successfully extracted transcript for video ${cleanVideoId}`);
        return response;
    
      } catch (error) {
        this.logger.error(`Failed to extract transcript for video ${videoId}:`, error);
        
        // Return structured error response
        return {
          videoId: this.extractVideoId(videoId),
          title: 'Error',
          language,
          transcript: [],
          metadata: {
            extractedAt: new Date().toISOString(),
            source: 'youtube-transcript-api',
            error: error instanceof Error ? error.message : 'Unknown error'
          }
        };
      }
    }

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/jedarden/yt-transcript-dl-mcp'

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