We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Vasallo94/obsidian-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""
Herramientas para interactuar con YouTube (obtención de transcripciones).
"""
import re
from typing import Optional
from urllib.parse import parse_qs, urlparse
from fastmcp import FastMCP
from youtube_transcript_api import YouTubeTranscriptApi
from youtube_transcript_api.formatters import TextFormatter
def extract_video_id(url: str) -> str:
"""
Extrae el ID de un video de YouTube desde diferentes formatos de URL.
"""
# Patrones comunes de URL de YouTube
patterns = [
r"(?:v=|\/)([0-9A-Za-z_-]{11}).*",
r"(?:youtu\.be\/)([0-9A-Za-z_-]{11})",
r"(?:embed\/)([0-9A-Za-z_-]{11})",
]
# Intentar parsear URL estándar primero
parsed_url = urlparse(url)
if parsed_url.hostname in ("www.youtube.com", "youtube.com"):
if parsed_url.path == "/watch":
params = parse_qs(parsed_url.query)
if "v" in params:
return params["v"][0]
if parsed_url.path.startswith("/shorts/"):
return parsed_url.path.split("/shorts/")[1]
# Intentar con regex para otros casos (youtu.be, embeds, etc)
for pattern in patterns:
match = re.search(pattern, url)
if match:
return match.group(1)
# Si la entrada ya parece un ID (11 chars)
if len(url) == 11 and re.match(r"^[0-9A-Za-z_-]{11}$", url):
return url
return ""
def get_transcript_text(url: str, language: Optional[str] = None) -> str:
"""
Obtiene la transcripción de un video de YouTube.
Args:
url: URL del video de YouTube o ID del video.
language: Código del idioma preferido. Si es None, intenta detectar
el idioma original o usa el generadado automáticamente.
Returns:
El texto completo de la transcripción o un mensaje de error.
"""
video_id = extract_video_id(url)
if not video_id:
return (
"❌ Error: No se pudo extraer un ID de video válido "
"de la URL proporcionada."
)
try:
# Instanciar la API
api = YouTubeTranscriptApi()
# Obtener lista de transcripciones disponibles
transcript_list = api.list(video_id)
target_transcript = None
if language:
# Si se especificó un idioma, intentar encontrarlo (manual o generado)
try:
target_transcript = transcript_list.find_transcript([language])
except Exception:
# Si falla, intentar traducirlo
try:
# Buscar cualquiera y traducir
# (Esto es simplificado, idealmente buscaríamos el mejor origen)
# Por ahora fallamos al catch general si no existe el idioma directo
pass
except Exception:
pass
else:
# Lógica "Auto": Priorizar manual en idioma cualquiera, o generado.
# Normalmente la lista viene con manuales primero o podemos iterar.
# 1. Buscar manuales (is_generated=False)
for t in transcript_list:
if not t.is_generated:
target_transcript = t
break
# 2. Si no hay manual, usar el primero (que será generado)
if not target_transcript:
# Iterar para tomar el primero disponible.
# transcript_list es iterable
for t in transcript_list:
target_transcript = t
break
if not target_transcript:
# Fallback a lógica antigua de "fetch" con defaults si algo falló arriba
# aunque transcript_list debería lanzar error si está vacío.
languages = ["es", "en"] if not language else [language]
target_transcript = transcript_list.find_transcript(languages)
# Hacer fetch de la transcripción seleccionada
transcript_data = target_transcript.fetch()
# Formatear a texto plano
formatter = TextFormatter()
text_formatted = formatter.format_transcript(transcript_data)
metadata = (
f"Idioma: {target_transcript.language} ({target_transcript.language_code})"
)
if target_transcript.is_generated:
metadata += " [Autogenerado]"
else:
metadata += " [Manual]"
return (
f"✅ Transcripción obtenida para video {video_id}\n"
f"ℹ️ {metadata}:\n\n{text_formatted}"
)
except Exception as e:
return f"❌ Error al obtener transcripción para {video_id}: {e}"
def register_youtube_tools(mcp: FastMCP) -> None:
"""
Registra las herramientas de YouTube en el servidor MCP.
"""
@mcp.tool()
def get_youtube_transcript(url: str, language: Optional[str] = None) -> str:
"""
Obtiene la transcripción de un video de YouTube.
Args:
url: URL del video de YouTube o ID del video.
language: Código del idioma opcional (ej: 'es', 'en').
Si se omite, busca subtítulos manuales en el idioma original,
o falla al autogenerado del video.
Returns:
El texto completo de la transcripción o un mensaje de error.
"""
return get_transcript_text(url, language)