generate-image
Create custom images from text descriptions with configurable settings for size, format, and quality. Save generated images to specified directories for various applications.
Instructions
Generate an image based on a prompt
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | ||
| output_dir | Yes | Full absolute path to output directory. For Windows, use double backslashes like 'C:\\Users\\name\\path'. For Unix/Mac use '/path/to/dir'. Always use the proper path otherwise you will get an error. | |
| filename | No | Base filename to save the image(s) with | |
| go_fast | No | ||
| megapixels | No | ||
| num_outputs | No | ||
| aspect_ratio | No | ||
| output_format | No | ||
| output_quality | No | ||
| num_inference_steps | No |
Implementation Reference
- src/imageService.ts:59-147 (handler)Core handler method of ImageGenerationService that implements the image generation logic: caching, calling Replicate API, downloading images, saving to disk, and error handling.async generateImages(params: ImageGenerationParams): Promise<ImageGenerationResponse> { const startTime = Date.now(); try { // Check cache first const cacheKey = this.generateCacheKey(params); const cached = this.cache.get(cacheKey); if (cached) { // Verify files still exist const allFilesExist = cached.response.image_paths.every(path => fs.existsSync(path)); if (allFilesExist) { return { ...cached.response, metadata: { ...cached.response.metadata, cache_hit: true } }; } // If files don't exist, remove from cache this.cache.delete(cacheKey); } // Prepare model input const modelInput = { prompt: params.prompt, go_fast: params.go_fast ?? false, megapixels: params.megapixels ?? "1", num_outputs: params.num_outputs ?? 1, aspect_ratio: params.aspect_ratio ?? "1:1", num_inference_steps: params.num_inference_steps ?? 4 }; // Call Replicate API const output = await this.replicate.run( this.MODEL, { input: modelInput } ) as string[]; // Download and save images const imagePaths = await this.saveImages( output, params.output_dir, params.output_format ?? 'webp', params.output_quality ?? 80, params.filename ); const endTime = Date.now(); const response: ImageGenerationResponse = { image_paths: imagePaths, metadata: { model: this.MODEL, inference_time_ms: endTime - startTime, cache_hit: false } }; // Cache the result this.cache.set(cacheKey, { response, timestamp: Date.now() }); return response; } catch (error: any) { if (error.response) { const apiError = new Error(error.message) as APIError; apiError.code = 'API_ERROR'; apiError.details = { message: error.message, status: error.response.status }; throw apiError; } const serverError = new Error('Server error occurred') as ServerError; serverError.code = 'SERVER_ERROR'; serverError.details = { message: 'Failed to generate or save images', system_error: error.message }; throw serverError; } }
- src/server.ts:18-52 (registration)MCP server tool registration for 'generate-image', including description, Zod input schema, and wrapper handler delegating to ImageGenerationService.// Register the image generation tool server.tool( "generate-image", "Generate an image based on a prompt", { prompt: z.string(), output_dir: z.string().describe("Full absolute path to output directory. For Windows, use double backslashes like 'C:\\\\Users\\\\name\\\\path'. For Unix/Mac use '/path/to/dir'. Always use the proper path otherwise you will get an error."), filename: z.string().optional().describe("Base filename to save the image(s) with"), go_fast: z.boolean().optional(), megapixels: z.enum(["1", "2", "4"]).optional(), num_outputs: z.number().min(1).max(4).optional(), aspect_ratio: z.enum(["1:1", "4:3", "16:9"]).optional(), output_format: z.enum(["webp", "png", "jpeg"]).optional(), output_quality: z.number().min(1).max(100).optional(), num_inference_steps: z.number().min(4).max(20).optional() }, async (params) => { try { const result = await imageService.generateImages(params); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } catch (error: any) { return { content: [{ type: "text", text: `Error: ${error.message}` }] }; } } );
- src/types.ts:1-12 (schema)TypeScript interface defining the input parameters for the generate-image tool, used by ImageGenerationService.export interface ImageGenerationParams { prompt: string; output_dir: string; filename?: string; go_fast?: boolean; megapixels?: "1" | "2" | "4"; num_outputs?: number; aspect_ratio?: "1:1" | "4:3" | "16:9"; output_format?: "webp" | "png" | "jpeg"; output_quality?: number; num_inference_steps?: number; }
- src/imageService.ts:168-219 (helper)Helper method to download images from URLs (with retries), save them to disk in batches with concurrency limit, and return file paths.private async saveImages( imageUrls: string[], outputDir: string, format: 'webp' | 'png' | 'jpeg', quality: number, baseFilename?: string ): Promise<string[]> { // Create output directory if it doesn't exist if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } // Prepare download tasks const downloadTasks = imageUrls.map(async (imageUrl, i) => { const filename = baseFilename ? (imageUrls.length > 1 ? `${baseFilename}_${i + 1}.${format}` : `${baseFilename}.${format}`) : `output_${i}.${format}`; const filePath = path.join(outputDir, filename); try { // Download image with retry mechanism const buffer = await this.downloadWithRetry(imageUrl); // Save image atomically using temporary file const tempPath = `${filePath}.tmp`; fs.writeFileSync(tempPath, buffer); fs.renameSync(tempPath, filePath); return filePath; } catch (error: any) { const serverError = new Error('Failed to save image') as ServerError; serverError.code = 'SERVER_ERROR'; serverError.details = { message: `Failed to save image ${i}`, system_error: error.message }; throw serverError; } }); // Execute all downloads in parallel with a concurrency limit const CONCURRENCY_LIMIT = 3; const imagePaths: string[] = []; for (let i = 0; i < downloadTasks.length; i += CONCURRENCY_LIMIT) { const batch = downloadTasks.slice(i, i + CONCURRENCY_LIMIT); const results = await Promise.all(batch); imagePaths.push(...results); } return imagePaths; }