Skip to main content
Glama
server-utils.ts10.1 kB
import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; import { VideoService } from './services/video.js'; import { TranscriptService } from './services/transcript.js'; import { PlaylistService } from './services/playlist.js'; import { ChannelService } from './services/channel.js'; const packageVersion = '0.1.12'; /** * Creates and configures a YouTube MCP server with all tools, resources, and prompts registered */ export function createYouTubeMcpServer() { const server = new McpServer({ name: 'youtube-mcp', version: packageVersion, }, { capabilities: { resources: {}, prompts: {}, tools: {}, } }); const videoService = new VideoService(); const transcriptService = new TranscriptService(); const playlistService = new PlaylistService(); const channelService = new ChannelService(); // Register static resource for Smithery discovery server.registerResource( 'info', 'youtube://info', { title: 'YouTube MCP Server Information', description: 'Information about available YouTube MCP resources and how to use them', mimeType: 'application/json', }, async (uri) => ({ contents: [{ uri: uri.href, text: JSON.stringify({ message: "YouTube MCP Server Resources", availableResources: { transcripts: { description: "Access YouTube video transcripts", uriPattern: "youtube://transcript/{videoId}", example: "youtube://transcript/dQw4w9WgXcQ", note: "Replace {videoId} with actual YouTube video ID" } }, tools: [ "videos_getVideo", "videos_searchVideos", "transcripts_getTranscript", "channels_getChannel", "channels_listVideos", "playlists_getPlaylist", "playlists_getPlaylistItems" ], prompts: [ "summarize-video", "analyze-channel" ] }, null, 2) }] }) ); // Register dynamic resource for transcripts server.registerResource( 'transcript', new ResourceTemplate('youtube://transcript/{videoId}', { list: undefined }), { title: 'YouTube Video Transcript', description: 'Get the transcript for a YouTube video. Use URI format: youtube://transcript/{videoId}', mimeType: 'application/json', }, async (uri, variables) => { const { videoId } = variables as unknown as { videoId: string }; const result = await transcriptService.getTranscript({ videoId }); return { contents: [{ uri: uri.href, text: JSON.stringify(result, null, 2), mimeType: "application/json" }] }; } ); // Register prompts server.registerPrompt( 'summarize-video', { description: "Summarize a YouTube video", argsSchema: { videoId: z.string().describe("The ID of the video to summarize") } }, ({ videoId }) => ({ messages: [{ role: 'user', content: { type: 'text', text: `Please get the transcript for video ID ${videoId} and summarize the key points.` } }] }) ); server.registerPrompt( 'analyze-channel', { description: "Analyze a YouTube channel", argsSchema: { channelId: z.string().describe("The ID of the channel to analyze") } }, ({ channelId }) => ({ messages: [{ role: 'user', content: { type: 'text', text: `Please analyze the channel with ID ${channelId}. Look at its recent videos, playlists, and statistics to provide an overview of its content strategy and performance.` } }] }) ); // Register video tools server.registerTool( 'videos_getVideo', { title: 'Get Video Details', description: 'Get detailed information about a YouTube video including URL', annotations: { readOnlyHint: true, idempotentHint: true }, inputSchema: { videoId: z.string().describe('The YouTube video ID'), parts: z.array(z.string()).optional().describe('Parts of the video to retrieve'), }, }, async ({ videoId, parts }) => { const result = await videoService.getVideo({ videoId, parts }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } ); server.registerTool( 'videos_searchVideos', { title: 'Search Videos', description: 'Search for videos on YouTube and return results with URLs', annotations: { readOnlyHint: true, idempotentHint: true }, inputSchema: { query: z.string().describe('Search query'), maxResults: z.number().optional().describe('Maximum number of results to return'), }, }, async ({ query, maxResults }) => { const result = await videoService.searchVideos({ query, maxResults }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } ); // Register transcript tool server.registerTool( 'transcripts_getTranscript', { title: 'Get Video Transcript', description: 'Get the transcript of a YouTube video', annotations: { readOnlyHint: true, idempotentHint: true }, inputSchema: { videoId: z.string().describe('The YouTube video ID'), language: z.string().optional().describe('Language code for the transcript'), }, }, async ({ videoId, language }) => { const result = await transcriptService.getTranscript({ videoId, language }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } ); // Register channel tools server.registerTool( 'channels_getChannel', { title: 'Get Channel Information', description: 'Get information about a YouTube channel', annotations: { readOnlyHint: true, idempotentHint: true }, inputSchema: { channelId: z.string().describe('The YouTube channel ID'), }, }, async ({ channelId }) => { const result = await channelService.getChannel({ channelId }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } ); server.registerTool( 'channels_listVideos', { title: 'List Channel Videos', description: 'Get videos from a specific channel', annotations: { readOnlyHint: true, idempotentHint: true }, inputSchema: { channelId: z.string().describe('The YouTube channel ID'), maxResults: z.number().optional().describe('Maximum number of results to return'), }, }, async ({ channelId, maxResults }) => { const result = await channelService.listVideos({ channelId, maxResults }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } ); // Register playlist tools server.registerTool( 'playlists_getPlaylist', { title: 'Get Playlist Information', description: 'Get information about a YouTube playlist', annotations: { readOnlyHint: true, idempotentHint: true }, inputSchema: { playlistId: z.string().describe('The YouTube playlist ID'), }, }, async ({ playlistId }) => { const result = await playlistService.getPlaylist({ playlistId }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } ); server.registerTool( 'playlists_getPlaylistItems', { title: 'Get Playlist Items', description: 'Get videos in a YouTube playlist', annotations: { readOnlyHint: true, idempotentHint: true }, inputSchema: { playlistId: z.string().describe('The YouTube playlist ID'), maxResults: z.number().optional().describe('Maximum number of results to return'), }, }, async ({ playlistId, maxResults }) => { const result = await playlistService.getPlaylistItems({ playlistId, maxResults }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } ); return server; }

Implementation Reference

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/sfiorini/youtube-mcp'

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