VFX MCP

Un potente servidor de edición de video que utiliza ffmpeg-python para procesar archivos de video externos.

Documentación

vfx-mcp 🎬

Un potente servidor MCP (Model Context Protocol) para edición de video, construido con FastMCP y ffmpeg-python. Este servidor permite a los LLMs realizar operaciones de edición de video a través de una interfaz estandarizada, habilitando flujos de trabajo de manipulación y procesamiento de video impulsados por IA.

Características

Operaciones Principales de Video

  • Corte y Recorte: Extraer segmentos específicos de videos
  • Concatenación: Unir múltiples videos
  • Conversión de Formato: Transcodificar entre diferentes formatos de video
  • Resolución y Calidad: Redimensionar, cambiar bitrate, ajustar calidad
  • Procesamiento de Audio: Extraer, reemplazar o mezclar pistas de audio
  • Efectos y Filtros: Aplicar filtros y efectos de ffmpeg
  • Análisis: Obtener metadatos de video, generar miniaturas
  • Operaciones Avanzadas: Cambios de velocidad, reproducción inversa, bucles

Capacidades MCP

  • Herramientas: Ejecutar operaciones de edición de video
  • Recursos: Acceder y gestionar archivos de video
  • Contexto: Reporte de progreso para operaciones largas
  • Streaming: Soporte para flujos de trabajo basados en archivos y streaming

Instalación

Desde PyPI (Recomendado) 🎉

# Install directly from PyPI
pip install vfx-mcp

# Run the server
vfx-mcp

Usando uv (Desarrollo)

# Clone the repository
git clone https://github.com/conneroisu/vfx-mcp.git
cd vfx-mcp

# Install dependencies with uv
uv sync

# Run the server
uv run python main.py

Usando Nix

# Enter the development shell
nix develop

# Run the server
python main.py

Requisitos del Sistema

  • Python 3.13+
  • FFmpeg (se instala automáticamente con Nix, o instalar manualmente)
  • Gestor de paquetes uv (para instalación sin Nix)

Inicio Rápido

Uso Básico

# Connect to the VFX MCP server
from fastmcp import Client

async with Client("python main.py") as client:
    # Trim a video
    result = await client.call_tool("trim_video", {
        "input_path": "input.mp4",
        "output_path": "trimmed.mp4",
        "start_time": 10.0,
        "duration": 30.0
    })
    
    # Get video information
    info = await client.call_tool("get_video_info", {
        "video_path": "input.mp4"
    })
    print(info)

Uso CLI con Claude Desktop

Agregar a la configuración de Claude Desktop:

{
  "mcpServers": {
    "vfx": {
      "command": "vfx-mcp",
      "args": []
    }
  }
}

O si se usa la versión de desarrollo:

{
  "mcpServers": {
    "vfx": {
      "command": "uv",
      "args": ["run", "python", "/path/to/vfx-mcp/main.py"],
      "cwd": "/path/to/vfx-mcp"
    }
  }
}

Referencia de API

Herramientas de Procesamiento de Video

trim_video

Extraer un segmento de un video.

Parámetros:

  • input_path (str): Ruta al archivo de video de entrada
  • output_path (str): Ruta para el archivo de video de salida
  • start_time (float): Tiempo de inicio en segundos
  • duration (float, opcional): Duración en segundos (si no se especifica, corta hasta el final)

concatenate_videos

Unir múltiples videos.

Parámetros:

  • input_paths (list[str]): Lista de rutas de archivos de video a concatenar
  • output_path (str): Ruta para el archivo de video de salida
  • transition (str, opcional): Tipo de transición entre videos

convert_format

Convertir video a diferente formato o códec.

Parámetros:

  • input_path (str): Ruta al archivo de video de entrada
  • output_path (str): Ruta para el archivo de video de salida
  • format (str, opcional): Formato de salida (mp4, avi, mov, webm, etc.)
  • codec (str, opcional): Códec de video (h264, h265, vp9, etc.)
  • audio_codec (str, opcional): Códec de audio (aac, mp3, opus, etc.)

resize_video

Cambiar la resolución del video.

Parámetros:

  • input_path (str): Ruta al archivo de video de entrada
  • output_path (str): Ruta para el archivo de video de salida
  • width (int, opcional): Ancho objetivo (mantiene la relación de aspecto si no se especifica altura)
  • height (int, opcional): Altura objetivo (mantiene la relación de aspecto si no se especifica ancho)
  • scale (float, opcional): Factor de escala (ej., 0.5 para la mitad del tamaño)

extract_audio

Extraer pista de audio de un video.

Parámetros:

  • input_path (str): Ruta al archivo de video de entrada
  • output_path (str): Ruta para el archivo de audio de salida
  • format (str, opcional): Formato de audio (mp3, wav, aac, etc.)

add_audio

Agregar o reemplazar pista de audio en un video.

Parámetros:

  • video_path (str): Ruta al archivo de video de entrada
  • audio_path (str): Ruta al archivo de audio
  • output_path (str): Ruta para el archivo de video de salida
  • replace (bool, opcional): Reemplazar audio existente (predeterminado: true)

apply_filter

Aplicar filtro de ffmpeg a un video.

Parámetros:

  • input_path (str): Ruta al archivo de video de entrada
  • output_path (str): Ruta para el archivo de video de salida
  • filter (str): Cadena de filtro de FFmpeg (ej., "blur=10", "hflip", "reverse")

change_speed

Ajustar la velocidad de reproducción del video.

Parámetros:

  • input_path (str): Ruta al archivo de video de entrada
  • output_path (str): Ruta para el archivo de video de salida
  • speed (float): Multiplicador de velocidad (ej., 2.0 para doble velocidad, 0.5 para media velocidad)

generate_thumbnail

Extraer un fotograma como imagen miniatura.

Parámetros:

  • video_path (str): Ruta al archivo de video de entrada
  • output_path (str): Ruta para el archivo de imagen de salida
  • timestamp (float, opcional): Tiempo en segundos (predeterminado: mitad del video)

get_video_info

Obtener metadatos detallados del video.

Parámetros:

  • video_path (str): Ruta al archivo de video

Retorna:

  • Metadatos del video incluyendo duración, resolución, códec, bitrate, fps, etc.

Endpoints de Recursos

videos://list

Listar archivos de video disponibles en el espacio de trabajo.

videos://{filename}/metadata

Obtener metadatos de un archivo de video específico.

videos://workspace/info

Obtener información del espacio de trabajo y almacenamiento disponible.

Ejemplos

Crear un Montaje de Video

async with Client("python main.py") as client:
    # 1. Trim clips from source videos
    clips = []
    for i, (video, start, duration) in enumerate([
        ("vacation.mp4", 30, 5),
        ("birthday.mp4", 120, 8),
        ("concert.mp4", 45, 6)
    ]):
        clip_path = f"clip_{i}.mp4"
        await client.call_tool("trim_video", {
            "input_path": video,
            "output_path": clip_path,
            "start_time": start,
            "duration": duration
        })
        clips.append(clip_path)
    
    # 2. Concatenate clips
    await client.call_tool("concatenate_videos", {
        "input_paths": clips,
        "output_path": "montage.mp4",
        "transition": "fade"
    })
    
    # 3. Add background music
    await client.call_tool("add_audio", {
        "video_path": "montage.mp4",
        "audio_path": "background_music.mp3",
        "output_path": "final_montage.mp4"
    })

Procesar Video para Web

async with Client("python main.py") as client:
    # Convert to web-friendly format with optimized settings
    await client.call_tool("convert_format", {
        "input_path": "raw_video.mov",
        "output_path": "web_video.mp4",
        "format": "mp4",
        "codec": "h264",
        "audio_codec": "aac"
    })
    
    # Create multiple resolutions
    for width in [1920, 1280, 854]:
        await client.call_tool("resize_video", {
            "input_path": "web_video.mp4",
            "output_path": f"web_video_{width}.mp4",
            "width": width
        })
    
    # Generate thumbnail
    await client.call_tool("generate_thumbnail", {
        "video_path": "web_video.mp4",
        "output_path": "thumbnail.jpg"
    })

Arquitectura

Estructura del Proyecto

vfx-mcp/
├── README.md              # This file
├── flake.nix             # Nix development environment
├── pyproject.toml        # Python project configuration
├── uv.lock              # Locked dependencies
├── main.py              # MCP server entry point
├── src/
│   ├── __init__.py
│   ├── server.py        # FastMCP server configuration
│   ├── tools/           # Video editing tool implementations
│   │   ├── __init__.py
│   │   ├── basic.py     # Basic operations (trim, concat, etc.)
│   │   ├── transform.py # Transformations (resize, rotate, etc.)
│   │   ├── audio.py     # Audio processing tools
│   │   └── effects.py   # Filters and effects
│   ├── resources/       # MCP resource handlers
│   │   └── videos.py    # Video file management
│   └── utils/           # Utility functions
│       ├── ffmpeg.py    # FFmpeg wrapper utilities
│       └── progress.py  # Progress reporting helpers
└── examples/            # Example usage scripts
    ├── montage.py       # Create video montage
    ├── web_process.py   # Process for web
    └── batch_convert.py # Batch conversion

Componentes Clave

  1. Servidor FastMCP: Servidor central que maneja la comunicación del protocolo MCP
  2. Módulos de Herramientas: Organizados por funcionalidad (básico, transformación, audio, efectos)
  3. Integración FFmpeg: Usando ffmpeg-python para procesamiento robusto de video
  4. Reporte de Progreso: Actualizaciones de progreso en tiempo real para operaciones largas
  5. Manejo de Errores: Manejo integral de errores para operaciones de ffmpeg

Desarrollo

Configuración del Entorno de Desarrollo

Con Nix (Recomendado para entorno consistente)

# Enter development shell with all dependencies
nix develop

# Run tests
pytest

# Run linting
ruff check .

# Format code
ruff format .

Con uv

# Install development dependencies
uv sync --dev

# Run tests
uv run pytest

# Run linting
uv run ruff check .

# Format code
uv run ruff format .

Agregar Nuevas Herramientas

  1. Crear una nueva función en el módulo apropiado bajo src/tools/
  2. Usar el decorador @mcp.tool
  3. Agregar sugerencias de tipo y docstring apropiados
  4. Implementar manejo de errores

Ejemplo:

@mcp.tool
async def rotate_video(
    input_path: str,
    output_path: str,
    angle: int,
    ctx: Context
) -> str:
    """Rotate video by specified angle (90, 180, 270 degrees)."""
    if angle not in [90, 180, 270]:
        raise ValueError("Angle must be 90, 180, or 270 degrees")
    
    await ctx.info(f"Rotating video by {angle} degrees...")
    
    # Implementation using ffmpeg-python
    stream = ffmpeg.input(input_path)
    stream = ffmpeg.filter(stream, 'rotate', angle=math.radians(angle))
    stream = ffmpeg.output(stream, output_path)
    
    await run_ffmpeg_with_progress(stream, ctx)
    return f"Video rotated and saved to {output_path}"

Pruebas

Ejecutar la suite de pruebas:

# All tests
pytest

# Specific test file
pytest tests/test_basic_tools.py

# With coverage
pytest --cov=src

Contribuciones

  1. Hacer fork del repositorio
  2. Crear una rama de características (git checkout -b feature/amazing-tool)
  3. Hacer los cambios y agregar pruebas
  4. Ejecutar linting y pruebas
  5. Confirmar los cambios (git commit -m 'Add amazing tool')
  6. Empujar a la rama (git push origin feature/amazing-tool)
  7. Abrir un Pull Request

Licencia

Licencia MIT - ver archivo LICENSE para detalles

Agradecimientos