MCP Media Generator

  • src
import mcp.types as types from mcp.server import Server, NotificationOptions from mcp.server.models import InitializationOptions from image import create_image from video import create_video import logging def create_server(): logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger("mcp-media-creator") logger.setLevel(logging.DEBUG) logger.info("Starting MCP Media Creator") # Initialize base MCP server server = Server("pptx_presentation") init_options = InitializationOptions( server_name="mcp-media-creator", server_version="0.1", capabilities=server.get_capabilities( notification_options=NotificationOptions(), experimental_capabilities={}, ), ) @server.list_tools() async def handle_list_tools() -> list[types.Tool]: """ List available tools. Each tool specifies its arguments using JSON Schema validation. Name must be maximum of 64 characters """ return [ types.Tool( name="create-image", description="Create image generated by Amazon Canvas model", inputSchema={ "type": "object", "properties": { "prompt": { "type": "string", "description": "A text prompt to generate the image. Avoid using negating words ('no', 'not', 'without', etc.).", "minLength": 1, "maxLength": 1024 }, "negative_prompt": { "type": "string", "description": "A text prompt to define what not to include in the image. Avoid using negating words ('no', 'not', 'without', etc.).", "minLength": 1, "maxLength": 1024, "default": "low quality" }, "quality": { "type": "string", "enum": ["standard", "premium"], "description": "Quality of the image.", "default": "standard" }, "height": { "type": "integer", "description": "Height of the image. Ratio of image must be between 1:4 to 4:1", "default": 1024, "minimum": 320, "maximum": 4096 }, "width": { "type": "integer", "description": "Width of the image. Ratio of image must be between 1:4 to 4:1", "default": 1024, "minimum": 320, "maximum": 4096 }, "seed_value": { "type": "integer", "description": "Determines the initial noise setting for the generation process. Changing the seed value while leaving all other parameters the same will produce a totally new image that still adheres to your prompt, dimensions, and other settings.", "default": 12, "minimum": 0, "maximum": 858993459 }, }, "required": ["prompt"] } ), types.Tool( name="create-video", description="Create video generated by Amazon Reel model", inputSchema={ "type": "object", "properties": { "prompt": { "type": "string", "description": "A text prompt to generate the video. Avoid using negating words ('no', 'not', 'without', etc.).", "minLength": 1, "maxLength": 512 }, }, "required": ["prompt"] } ), ] @server.call_tool() async def handle_call_tool( name: str, arguments: dict | None ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: """ Handle tool execution requests. """ if not arguments: raise ValueError("Missing arguments") if name == "create-image": prompt: str = arguments.get("prompt") negative_prompt: str = arguments.get("negative_prompt", "low quality") quality: str = arguments.get("quality", "standard") height: int = arguments.get("height", 1024) width: int = arguments.get("width", 1024) seed_value: int = arguments.get("seed_value", 12) if not prompt: raise ValueError("Missing prompt parameter") formatted_response = await create_image(prompt, negative_prompt, quality, width, height, seed_value) return [ types.TextContent( type="text", text=formatted_response ) ] elif name == "create-video": prompt: str = arguments.get("prompt") if not prompt: raise ValueError("Missing prompt parameter.") url = await create_video(prompt) return [ types.TextContent( type="text", text=f"Link to generated video: {url}. Always provide this link to the user in output, in markdown format. Inform user to wait 3-5 minutes before using the link." ) ] else: raise ValueError(f"Unknown tool: {name}") return server, init_options