Skip to main content
Glama
tool.py6.88 kB
"""LayoutEntrance MCP tool.""" import asyncio import json from chuk_motion.components.component_helpers import parse_nested_component from chuk_motion.generator.composition_builder import ComponentInstance from chuk_motion.models import ComponentResponse, ErrorResponse def register_tool(mcp, project_manager): """Register the LayoutEntrance tool with the MCP server.""" @mcp.tool async def remotion_add_layout_entrance( content: str, entrance_type: str = "fade_in", entrance_delay: float = 0.0, duration: float | str = 5.0, track: str = "main", gap_before: float | str | None = None, ) -> str: """ Add LayoutEntrance wrapper to animate any layout or component in. Universal entrance animation that works with any layout or component. Uses motion tokens for consistent timing and easing across all entrance types. Perfect for: Adding polish to any layout, consistent entrance patterns, zero-config animation Example entrance_type values and their effects: - fade_in: Simple fade (subtle, professional) - fade_slide_up: Fade + slide up (modern, polished) - scale_in_soft: Subtle scale 0.95→1.0 (elegant, refined) - scale_in_pop: Pop with bounce (playful, energetic) - slide_in_left: Slide from left (spatial, directional) - slide_in_right: Slide from right (spatial, alternative) - blur_in: Fade from blur (dramatic, cinematic) - zoom_in: Zoom 0→100% (explosive, hero entrance) Example content Grid layout: { "type": "Grid", "config": { "layout": "3x3", "items": [ {"type": "CodeBlock", "config": {"code": "Item 1"}}, {"type": "CodeBlock", "config": {"code": "Item 2"}}, {"type": "CodeBlock", "config": {"code": "Item 3"}} ] } } Example content Container: { "type": "Container", "config": { "position": "center", "content": {"type": "TitleScene", "config": {"text": "Hello"}} } } Args: content: JSON component to animate (format: {"type": "ComponentName", "config": {...}}) entrance_type: Animation style - one of: none, fade_in, fade_slide_up, scale_in_soft, scale_in_pop, slide_in_left, slide_in_right, blur_in, zoom_in (default: "fade_in") - "none": No animation (instant) - "fade_in": Simple fade in (subtle, professional) - "fade_slide_up": Fade + slide up (content blocks, cards) - "scale_in_soft": Subtle scale 0.95 → 1.0 (elegant) - "scale_in_pop": Pop scale 0.9 → 1.05 → 1.0 (playful) - "slide_in_left": Slide from left (side panels) - "slide_in_right": Slide from right (side panels) - "blur_in": Fade from blur (dramatic) - "zoom_in": Zoom from 0 to 100% (hero elements) entrance_delay: Delay before entrance animation starts (seconds) duration: Total duration in seconds or time string (e.g., "5s", "500ms") track: Track name (default: "main") gap_before: Gap before component in seconds or time string Returns: JSON with component info Example: # Add fade-slide entrance to Grid layout remotion_add_layout_entrance( content='{"type":"Grid","config":{"layout":"3x3","items":[...]}}', entrance_type="fade_slide_up", entrance_delay=0.2, duration=10.0 ) # Add pop entrance to Container remotion_add_layout_entrance( content='{"type":"Container","config":{"content":{...}}}', entrance_type="scale_in_pop", duration=5.0 ) # Add dramatic blur entrance to Timeline remotion_add_layout_entrance( content='{"type":"Timeline","config":{...}}', entrance_type="blur_in", entrance_delay=0.5 ) """ def _add(): if not project_manager.current_timeline: return ErrorResponse(error="No active project.").model_dump_json() try: # Parse nested content content_parsed = json.loads(content) content_component = parse_nested_component(content_parsed) # Validate that we got a ComponentInstance if not isinstance(content_component, ComponentInstance): return ErrorResponse( error="Invalid content format. Use format: {'type': 'ComponentName', 'config': {...}}" ).model_dump_json() # Validate entrance type valid_types = [ "none", "fade_in", "fade_slide_up", "scale_in_soft", "scale_in_pop", "slide_in_left", "slide_in_right", "blur_in", "zoom_in", ] if entrance_type not in valid_types: return ErrorResponse( error=f"Invalid entrance_type. Must be one of: {', '.join(valid_types)}" ).model_dump_json() # Build props props = { "content": content_component, "entranceType": entrance_type, "entranceDelay": entrance_delay, } component = ComponentInstance( component_type="LayoutEntrance", start_frame=0, duration_frames=0, props=props, layer=0, ) component = project_manager.current_timeline.add_component( component, duration=duration, track=track, gap_before=gap_before ) return ComponentResponse( component="LayoutEntrance", start_time=project_manager.current_timeline.frames_to_seconds( component.start_frame ), duration=duration, ).model_dump_json() except json.JSONDecodeError as e: return ErrorResponse(error=f"Invalid JSON: {str(e)}").model_dump_json() except Exception as e: return ErrorResponse(error=str(e)).model_dump_json() return await asyncio.get_event_loop().run_in_executor(None, _add)

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/chrishayuk/chuk-mcp-remotion'

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