Skip to main content
Glama
main.py6.65 kB
#!/usr/bin/env python3 """ YouTube MCP Server for Dedalus A Model Context Protocol server that provides YouTube search capabilities via HTTP transport for remote deployment on Dedalus platform. Features: - Remote HTTP server mode (Dedalus deployment) - Local STDIO mode (development) - YouTube search tool - Health check endpoint - Environment-based configuration """ import os import sys from pathlib import Path from dotenv import load_dotenv from mcp.server.fastmcp import FastMCP from starlette.requests import Request from starlette.responses import PlainTextResponse # Import YouTube search functionality from src.search import handle_get_serps # Load environment variables env_path = Path(".") / ".env" if env_path.exists(): load_dotenv(env_path) # Server configuration SERVER_NAME = "YouTube Search MCP" DEFAULT_HOST = "0.0.0.0" DEFAULT_PORT = 8080 # Get configuration from environment HOST = os.getenv("HOST", DEFAULT_HOST) PORT = int(os.getenv("PORT", str(DEFAULT_PORT))) # Create FastMCP server instance mcp = FastMCP( name=SERVER_NAME, host=HOST, port=PORT, instructions="""YouTube MCP Server - Search YouTube videos and channels Available tools: - search_youtube: Search YouTube and return video results with metadata This server supports: - Multiple languages (en, es, fr, de, etc.) - Configurable result limits - Rich video metadata (views, duration, channel info) - Pagination handling Example usage: search_youtube("machine learning tutorial", lang="en", max_results=10) """, ) @mcp.custom_route("/health", methods=["GET"]) async def health_check(request: Request) -> PlainTextResponse: """Health check endpoint for load balancers and monitoring systems. Returns: PlainTextResponse: "OK" with 200 status code when server is healthy """ return PlainTextResponse("OK") @mcp.tool() def search_youtube(query: str, lang: str = "en", max_results: int = 30) -> list[dict]: """Search YouTube and return video results. This tool searches YouTube using the official YouTube API and returns structured video metadata including titles, channels, views, and duration. Args: query: Search query string (e.g., "machine learning tutorial", "Veritasium") lang: Language code for results (e.g., "en", "es", "fr", "de") (default: "en") max_results: Maximum number of results to return, up to 100 (default: 30) Returns: List of search result dictionaries, each containing: - video_id: YouTube video ID (can be used to construct URLs) - video_title: Full video title - channel_id: YouTube channel ID - channel_name: Channel display name - channel_link: Channel URL path (relative) - view_count: Formatted view count (e.g., "1.2M views") - published_date: Human-readable publish time (e.g., "2 days ago") - duration: Video duration string (e.g., "10:23") Example: >>> results = search_youtube("Andrej Karpathy", lang="en", max_results=10) >>> print(results[0]["video_title"]) "Let's build GPT: from scratch, in code, spelled out." >>> results = search_youtube("machine learning tutorial", max_results=5) >>> for video in results: >>> print(f"{video['video_title']} - {video['channel_name']}") Notes: - Results are sorted by YouTube's relevance algorithm - Maximum max_results is capped at 100 per request - Language codes follow ISO 639-1 standard - View counts and publish dates are localized """ # Validate max_results if max_results > 100: max_results = 100 elif max_results < 1: max_results = 1 # Call YouTube search handler results = handle_get_serps( query=query, langauge_code=lang, max_results=max_results ) # Convert Pydantic models to dictionaries return [r.model_dump() for r in results] def main(): """Main entry point for the MCP server. This function determines the transport mode based on environment variables and command-line arguments: - HTTP mode (Dedalus deployment): When PORT is set or --port is provided - STDIO mode (local development): Default when no port is specified Environment Variables: PORT: Port number for HTTP server (default: 8080) HOST: Host address for HTTP server (default: 0.0.0.0) Command-Line Arguments: --port PORT: Override port for HTTP mode --host HOST: Override host for HTTP mode --stdio: Force STDIO transport mode --help: Show help message Returns: Exit code (0 for success, non-zero for errors) """ import argparse # Parse command-line arguments parser = argparse.ArgumentParser( description="YouTube MCP Server - Search YouTube via MCP" ) parser.add_argument( "--port", type=int, help=f"Port for HTTP transport (default: {DEFAULT_PORT})", ) parser.add_argument( "--host", type=str, default=DEFAULT_HOST, help=f"Host for HTTP transport (default: {DEFAULT_HOST})", ) parser.add_argument( "--stdio", action="store_true", help="Force STDIO transport mode (for local development)", ) args = parser.parse_args() # Determine transport mode # Use HTTP if port is specified (from env or CLI) and not forcing stdio use_http = (args.port or os.getenv("PORT")) and not args.stdio if use_http: # HTTP transport mode (for Dedalus deployment) actual_host = args.host if args.host != DEFAULT_HOST else HOST actual_port = args.port if args.port else PORT print(f"[YouTube MCP] Starting HTTP server on {actual_host}:{actual_port}") print(f"[YouTube MCP] Health check: http://{actual_host}:{actual_port}/health") print(f"[YouTube MCP] SSE endpoint: http://{actual_host}:{actual_port}/sse") try: mcp.run(transport="sse") return 0 except Exception as e: print(f"[YouTube MCP] Error starting HTTP server: {e}", file=sys.stderr) return 1 else: # STDIO transport mode (for local development) print("[YouTube MCP] Starting STDIO server", file=sys.stderr) print("[YouTube MCP] Connect via MCP client using stdio", file=sys.stderr) try: mcp.run(transport="stdio") return 0 except Exception as e: print(f"[YouTube MCP] Error starting STDIO server: {e}", file=sys.stderr) return 1 if __name__ == "__main__": sys.exit(main())

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

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