Skip to main content
Glama
mikeyny

Image Generation MCP Server

by mikeyny

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
NameRequiredDescriptionDefault
promptYes
output_dirYesFull 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.
filenameNoBase filename to save the image(s) with
go_fastNo
megapixelsNo
num_outputsNo
aspect_ratioNo
output_formatNo
output_qualityNo
num_inference_stepsNo

Implementation Reference

  • 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}`
            }]
          };
        }
      }
    );
  • 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;
    }
  • 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;
    }

Tool Definition Quality

Score is being calculated. Check back soon.

Install Server

Other Tools

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/mikeyny/ai-image-gen-mcp'

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