UNPKG

@kinetixarts/server-craft-it

Version:

Craft IT - Model Context Protocol (MCP) compliant Server for AI-Powered Asset Generation using Gemini

77 lines 3.76 kB
import { GoogleGenAI, Modality } from '@google/genai'; import { v4 as uuidv4 } from 'uuid'; import { storeAsset, DEFAULT_IMAGE_PATH } from '../assetStore.js'; // The API key is required for the service to function const GEMINI_API_KEY = process.env.GEMINI_API_KEY; // Throw a clear error if the API key is missing if (!GEMINI_API_KEY) { throw new Error('GEMINI_API_KEY is not set in environment variables. ' + 'Please provide your Gemini API key via .env file or CLI configuration.'); } const ai = new GoogleGenAI({ apiKey: GEMINI_API_KEY }); export class ImageGenerationService { static async generateImage({ prompt, parameters, output_config, commandLineStoragePath, }) { // Compose the prompt with style/parameters if provided let fullPrompt = prompt; if (parameters) { if (parameters.primary_color) { fullPrompt += ` Primary color: ${parameters.primary_color}.`; } if (parameters.style_descriptor) { fullPrompt += ` Style: ${parameters.style_descriptor}.`; } } // Gemini requires responseModalities to include IMAGE const response = await ai.models.generateContent({ model: 'gemini-2.0-flash-preview-image-generation', contents: fullPrompt, config: { responseModalities: [Modality.TEXT, Modality.IMAGE], }, }); if (!response.candidates || !response.candidates[0] || !response.candidates[0].content || !response.candidates[0].content.parts) { throw new Error('No candidates or content returned from Gemini API'); } for (const part of response.candidates[0].content.parts) { if (part.inlineData && part.inlineData.data) { try { // Determine storage path priority: command line > output_config > env var > default const storagePath = commandLineStoragePath || output_config.storage_path || DEFAULT_IMAGE_PATH; // Generate a unique ID for this asset const assetId = uuidv4(); // Create the initial asset data const assetData = { base64: part.inlineData.data, mimeType: typeof part.inlineData.mimeType === 'string' ? part.inlineData.mimeType : 'image/png', }; // Store the asset both in memory and on disk const storedAsset = await storeAsset(assetId, assetData, storagePath); // Return the complete result // Return the complete result const result = { id: assetId, base64: storedAsset.base64, mimeType: storedAsset.mimeType, filePath: storedAsset.filePath, }; return result; } catch (error) { console.error('Error storing generated image:', error); // Return just the image data if storage fails // Return just the image data if storage fails const result = { id: uuidv4(), base64: part.inlineData.data, mimeType: typeof part.inlineData.mimeType === 'string' ? part.inlineData.mimeType : 'image/png', }; return result; } } } throw new Error('No image data returned from Gemini API'); } } //# sourceMappingURL=ImageGenerationService.js.map