UNPKG

@raihan0824/mcp-veo2

Version:

MCP server for generating videos with Google Veo2

166 lines 7.08 kB
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; import { videoResourceTemplate, readVideoResource, videoPromptsResource } from './resources/videos.js'; import { imageResourceTemplate, readImageResource, imagePromptsResource } from './resources/images.js'; import { generateImage, listGeneratedImages, getImage } from './tools/generateVideo.js'; import { log } from './utils/logger.js'; /** * Creates and configures the MCP server for Veo2 video generation * * @returns The configured MCP server */ export function createServer() { // Create the MCP server const server = new McpServer({ name: 'veo2-video-generation', version: '1.0.0' }, { capabilities: { resources: { listChanged: true, subscribe: true }, tools: { listChanged: true } } }); log.info('Initializing MCP server for Veo2 video generation'); // Register resources log.info('Registering video and image resources'); // Register the video resource template server.resource('videos', videoResourceTemplate, { description: 'Access generated videos' }, async (uri, variables) => { // Since we can't access query parameters directly, we'll just pass an empty URLSearchParams return readVideoResource(uri, variables); }); // Register the video templates resource server.resource('video-templates', videoPromptsResource.uri, { description: videoPromptsResource.description }, async () => videoPromptsResource.read()); // Register the image resource template server.resource('images', imageResourceTemplate, { description: 'Access generated images' }, async (uri, variables) => { // Since we can't access query parameters directly, we'll just pass an empty URLSearchParams return readImageResource(uri, variables); }); // Register the image templates resource server.resource('image-templates', imagePromptsResource.uri, { description: imagePromptsResource.description }, async () => imagePromptsResource.read()); // Register tools log.info('Registering video generation tools'); // Define schemas for tool inputs const TextToVideoConfigSchema = z.object({ aspectRatio: z.enum(['16:9', '9:16']).default('16:9'), personGeneration: z.enum(['dont_allow', 'allow_adult']).default('dont_allow'), numberOfVideos: z.union([z.literal(1), z.literal(2)]).default(1), durationSeconds: z.number().min(5).max(8).default(5), enhancePrompt: z.boolean().default(false), negativePrompt: z.string().default(''), }); // COMMENTED OUT: Register the text-to-video generation tool /* server.tool( 'generateVideoFromText', 'Generate a video from a text prompt', { prompt: z.string().min(1).max(1000), aspectRatio: z.enum(['16:9', '9:16']).default('16:9'), personGeneration: z.enum(['dont_allow', 'allow_adult']).default('dont_allow'), numberOfVideos: z.union([z.literal(1), z.literal(2)]).default(1), durationSeconds: z.number().min(5).max(8).default(5), enhancePrompt: z.union([z.boolean(), z.string()]).default(false), negativePrompt: z.string().default(''), includeFullData: z.union([z.boolean(), z.string()]).default(false), autoDownload: z.union([z.boolean(), z.string()]).default(true), }, generateVideoFromText ); */ // COMMENTED OUT: Register the image-to-video generation tool /* server.tool( 'generateVideoFromImage', 'Generate a video from an image', { prompt: z.string().min(1).max(1000).optional().default('Generate a video from this image'), image: z.union([ // ImageContent object z.object({ type: z.literal('image'), mimeType: z.string(), data: z.string().min(1) // base64 encoded image data }), // URL string z.string().url(), // File path string z.string().min(1) ]), aspectRatio: z.enum(['16:9', '9:16']).default('16:9'), personGeneration: z.enum(['dont_allow', 'allow_adult']).default('dont_allow'), numberOfVideos: z.union([z.literal(1), z.literal(2)]).default(1), durationSeconds: z.number().min(5).max(8).default(5), enhancePrompt: z.union([z.boolean(), z.string()]).default(false), negativePrompt: z.string().default(''), includeFullData: z.union([z.boolean(), z.string()]).default(false), autoDownload: z.union([z.boolean(), z.string()]).default(true), }, generateVideoFromImage ); */ // Schema for image generation configuration const ImageGenerationConfigSchema = z.object({ numberOfImages: z.number().min(1).max(4).default(1), // Add other Imagen parameters as needed }); // Register the image generation tool server.tool('generateImage', 'Generate an image from a text prompt using Google Imagen', { prompt: z.string().min(1).max(1000), numberOfImages: z.number().min(1).max(4).default(1), includeFullData: z.union([z.boolean(), z.string()]).default(false), }, generateImage); // COMMENTED OUT: Register the image-to-video generation with generated image tool /* server.tool( 'generateVideoFromGeneratedImage', 'Generate a video from a generated image (one-step process)', { prompt: z.string().min(1).max(1000), videoPrompt: z.string().min(1).max(1000).optional(), // Image generation parameters numberOfImages: z.number().min(1).max(4).default(1), // Video generation parameters aspectRatio: z.enum(['16:9', '9:16']).default('16:9'), personGeneration: z.enum(['dont_allow', 'allow_adult']).default('dont_allow'), numberOfVideos: z.union([z.literal(1), z.literal(2)]).default(1), durationSeconds: z.number().min(5).max(8).default(5), enhancePrompt: z.union([z.boolean(), z.string()]).default(false), negativePrompt: z.string().default(''), includeFullData: z.union([z.boolean(), z.string()]).default(false), autoDownload: z.union([z.boolean(), z.string()]).default(true), }, generateVideoFromGeneratedImage ); */ // COMMENTED OUT: Register the list videos tool /* server.tool( 'listGeneratedVideos', 'List all generated videos', listGeneratedVideos ); */ // Register the get image tool server.tool('getImage', 'Get a specific image by ID', { id: z.string().min(1), includeFullData: z.union([z.boolean(), z.string()]).default(true), }, getImage); // Register the list images tool server.tool('listGeneratedImages', 'List all generated images', listGeneratedImages); log.info('MCP server initialized successfully'); return server; } //# sourceMappingURL=server.js.map