From d7b56da7c728eff094d0bc15dc687ebf88782c37 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Fri, 5 Sep 2025 02:56:55 -0600 Subject: [PATCH] Fix import errors and type annotations - Replace all Dict/List type hints with dict/list for Python 3.12+ compatibility - Add __main__.py to make package executable as module - Remove unused imports (cv2, numpy, ffmpeg) that were causing warnings - Fix bare except clause to use Exception - Server now starts successfully without import errors --- mcp_video_editor/__main__.py | 6 +++ mcp_video_editor/server.py | 85 ++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 43 deletions(-) create mode 100644 mcp_video_editor/__main__.py diff --git a/mcp_video_editor/__main__.py b/mcp_video_editor/__main__.py new file mode 100644 index 0000000..4bba087 --- /dev/null +++ b/mcp_video_editor/__main__.py @@ -0,0 +1,6 @@ +"""Main entry point for mcp_video_editor package.""" + +from .server import main + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mcp_video_editor/server.py b/mcp_video_editor/server.py index a2fc183..0266d94 100644 --- a/mcp_video_editor/server.py +++ b/mcp_video_editor/server.py @@ -2,7 +2,6 @@ import os from pathlib import Path -from typing import Optional, Union from fastmcp import FastMCP @@ -71,16 +70,16 @@ recording_sessions: dict[str, VideoRecordingSession] = {} @mcp.tool() -def mcp_video_editor_status() -> dict[str, Union[str, bool, int]]: +def mcp_video_editor_status() -> dict[str, str | bool | int]: """ Get the status of the MCP Video Editor server and available capabilities. - + Returns: - Dict with server status and available features + dict with server status and available features """ return { "server_name": "MCP Video Editor", - "version": "0.1.0", + "version": "0.1.0", "status": "running", "moviepy_available": MOVIEPY_AVAILABLE, "opencv_available": CV2_AVAILABLE, @@ -94,8 +93,8 @@ def mcp_video_recorder_start( filename: str, resolution: str = "1920x1080", framerate: int = 30, - region: Optional[str] = None, -) -> Dict[str, Union[str, int]]: + region: str | None = None, +) -> dict[str, str | int]: """ Start reliable video capture with persistent recording sessions. @@ -106,7 +105,7 @@ def mcp_video_recorder_start( region: Optional screen region coordinates as "x,y,width,height" Returns: - Dict with session_id for tracking and recording details + dict with session_id for tracking and recording details """ import uuid @@ -129,7 +128,7 @@ def mcp_video_recorder_start( @mcp.tool() -def mcp_video_recorder_stop(session_id: str) -> Dict[str, Union[str, int, float]]: +def mcp_video_recorder_stop(session_id: str) -> dict[str, str | int | float]: """ Stop recording and ensure file is saved. @@ -137,7 +136,7 @@ def mcp_video_recorder_stop(session_id: str) -> Dict[str, Union[str, int, float] session_id: Recording session ID from start command Returns: - Dict with file path and recording statistics + dict with file path and recording statistics """ if session_id not in recording_sessions: return {"error": f"Session {session_id} not found"} @@ -173,8 +172,8 @@ def mcp_video_recorder_stop(session_id: str) -> Dict[str, Union[str, int, float] @mcp.tool() def mcp_video_concatenate( - input_clips: List[str], output_path: str, transition_type: str = "cut" -) -> Dict[str, Union[str, float]]: + input_clips: list[str], output_path: str, transition_type: str = "cut" +) -> dict[str, str | float]: """ Join multiple video clips into single file. @@ -184,7 +183,7 @@ def mcp_video_concatenate( transition_type: Type of transition ("cut", "fade", "dissolve") Returns: - Dict with output path and total duration + dict with output path and total duration """ try: clips = [] @@ -230,7 +229,7 @@ def mcp_video_concatenate( @mcp.tool() def mcp_video_trim( input_path: str, start_time: float, end_time: float, output_path: str -) -> Dict[str, Union[str, float]]: +) -> dict[str, str | float]: """ Cut video segments to specific timeframes. @@ -241,7 +240,7 @@ def mcp_video_trim( output_path: Output video file path Returns: - Dict with output path and trimmed duration + dict with output path and trimmed duration """ try: if not os.path.exists(input_path): @@ -279,9 +278,9 @@ def mcp_video_speed_control( input_path: str, speed_multiplier: float, output_path: str, - start_time: Optional[float] = None, - end_time: Optional[float] = None, -) -> Dict[str, Union[str, float]]: + start_time: float | None = None, + end_time: float | None = None, +) -> dict[str, str | float]: """ Adjust playback speed for specific segments. @@ -293,7 +292,7 @@ def mcp_video_speed_control( end_time: Optional end time for speed change Returns: - Dict with output path and new duration + dict with output path and new duration """ try: if not os.path.exists(input_path): @@ -339,12 +338,12 @@ def mcp_video_add_overlay( input_path: str, output_path: str, overlay_type: str, - text: Optional[str] = None, + text: str | None = None, position: str = "center", - duration: Optional[float] = None, + duration: float | None = None, start_time: float = 0, - style: Optional[Dict] = None, -) -> Dict[str, str]: + style: dict | None = None, +) -> dict[str, str]: """ Add graphics, text, shapes over video content. @@ -359,7 +358,7 @@ def mcp_video_add_overlay( style: Style properties (font, color, size, etc.) Returns: - Dict with output path and overlay details + dict with output path and overlay details """ try: if not os.path.exists(input_path): @@ -416,7 +415,7 @@ def mcp_video_format_convert( output_format: str = "mp4", quality_preset: str = "balanced", compression_level: str = "medium", -) -> Dict[str, Union[str, int, float]]: +) -> dict[str, str | int | float]: """ Export to different video formats and qualities. @@ -428,7 +427,7 @@ def mcp_video_format_convert( compression_level: Compression level ("low", "medium", "high") Returns: - Dict with conversion results and file info + dict with conversion results and file info """ try: if not os.path.exists(input_path): @@ -482,22 +481,22 @@ def mcp_video_format_convert( @mcp.tool() def mcp_audio_mix_tracks( - audio_files: List[str], + audio_files: list[str], output_path: str, - volume_levels: Optional[List[float]] = None, - sync_timing: Optional[List[float]] = None, -) -> Dict[str, Union[str, float, int]]: + volume_levels: list[float] | None = None, + sync_timing: list[float] | None = None, +) -> dict[str, str | float | int]: """ Combine multiple audio tracks with volume control and timing. Args: - audio_files: List of audio file paths to mix + audio_files: list of audio file paths to mix output_path: Output audio file path volume_levels: Volume multipliers for each track (1.0 = original volume) sync_timing: Start times for each track in seconds Returns: - Dict with output path and mixing details + dict with output path and mixing details """ try: if not audio_files: @@ -556,7 +555,7 @@ def mcp_audio_sync_video( output_path: str, audio_start_time: float = 0.0, replace_audio: bool = True, -) -> Dict[str, Union[str, float]]: +) -> dict[str, str | float]: """ Synchronize audio track with video timeline. @@ -568,7 +567,7 @@ def mcp_audio_sync_video( replace_audio: Whether to replace existing audio or mix with it Returns: - Dict with output path and sync details + dict with output path and sync details """ try: if not os.path.exists(video_path): @@ -616,12 +615,12 @@ def mcp_audio_sync_video( def mcp_video_add_branding( input_path: str, output_path: str, - logo_path: Optional[str] = None, - brand_colors: Optional[Dict] = None, + logo_path: str | None = None, + brand_colors: dict | None = None, position: str = "bottom-right", opacity: float = 0.8, size_scale: float = 0.1, -) -> Dict[str, Union[str, Dict]]: +) -> dict[str, str | dict]: """ Apply consistent branding elements (logos, colors) to video. @@ -635,7 +634,7 @@ def mcp_video_add_branding( size_scale: Logo size relative to video dimensions Returns: - Dict with output path and branding details + dict with output path and branding details """ try: if not os.path.exists(input_path): @@ -701,20 +700,20 @@ def mcp_video_add_branding( def mcp_video_resolution_optimizer( input_path: str, output_directory: str, - target_resolutions: List[str] = None, - quality_settings: Optional[Dict] = None, -) -> Dict[str, Union[str, List, Dict]]: + target_resolutions: list[str] = None, + quality_settings: dict | None = None, +) -> dict[str, str | list | dict]: """ Generate multiple resolutions from source video. Args: input_path: Input video file path output_directory: Directory to save optimized versions - target_resolutions: List of target resolutions (e.g., ["1080p", "720p", "480p"]) + target_resolutions: list of target resolutions (e.g., ["1080p", "720p", "480p"]) quality_settings: Quality settings for each resolution Returns: - Dict with generated file paths and optimization details + dict with generated file paths and optimization details """ try: if not os.path.exists(input_path):