Skip to main content
Glama
RamboRogers

FAL Image/Video MCP Server

by RamboRogers

flux_dev

Generate images from text prompts using a high-quality 12B parameter model. Customize image size, quantity, and generation parameters for tailored visual outputs.

Instructions

FLUX Dev - High-quality 12B parameter model

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
promptYesText prompt for image generation
image_sizeNolandscape_4_3
num_imagesNo
num_inference_stepsNo
guidance_scaleNo

Implementation Reference

  • Core handler logic for the flux_dev tool. Dispatched when 'flux_dev' tool is called. Configures parameters based on flux model detection (model.id.includes('flux')), calls fal.subscribe('fal-ai/flux/dev'), processes images with downloads/data URLs.
    private async handleImageGeneration(args: any, model: any) {
      const {
        prompt,
        image_size = 'landscape_4_3',
        num_inference_steps = 25,
        guidance_scale = 3.5,
        num_images = 1,
        negative_prompt,
        safety_tolerance,
        raw,
      } = args;
    
      try {
        // Configure FAL client lazily with query config override
        configureFalClient(this.currentQueryConfig);
        const inputParams: any = { prompt };
        
        // Add common parameters
        if (image_size) inputParams.image_size = image_size;
        if (num_images > 1) inputParams.num_images = num_images;
        
        // Add model-specific parameters based on model capabilities
        if (model.id.includes('flux') || model.id.includes('stable_diffusion')) {
          if (num_inference_steps) inputParams.num_inference_steps = num_inference_steps;
          if (guidance_scale) inputParams.guidance_scale = guidance_scale;
        }
        if ((model.id.includes('stable_diffusion') || model.id === 'ideogram_v3') && negative_prompt) {
          inputParams.negative_prompt = negative_prompt;
        }
        if (model.id.includes('flux_pro') && safety_tolerance) {
          inputParams.safety_tolerance = safety_tolerance;
        }
        if (model.id === 'flux_pro_ultra' && raw !== undefined) {
          inputParams.raw = raw;
        }
    
        const result = await fal.subscribe(model.endpoint, { input: inputParams });
        const imageData = result.data as FalImageResult;
    
        const processedImages = await downloadAndProcessImages(imageData.images, model.id);
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify({
                model: model.name,
                id: model.id,
                endpoint: model.endpoint,
                prompt,
                images: processedImages,
                metadata: inputParams,
                download_path: DOWNLOAD_PATH,
                data_url_settings: {
                  enabled: ENABLE_DATA_URLS,
                  max_size_mb: Math.round(MAX_DATA_URL_SIZE / 1024 / 1024),
                },
                autoopen_settings: {
                  enabled: AUTOOPEN,
                  note: AUTOOPEN ? "Files automatically opened with default application" : "Auto-open disabled"
                },
              }, null, 2),
            },
          ],
        };
      } catch (error) {
        throw new Error(`${model.name} generation failed: ${error}`);
      }
    }
  • Dynamically generates the input schema for flux_dev tool (name: model.id). Includes flux-specific parameters num_inference_steps and guidance_scale since model.id.includes('flux'). Used in tools/list response.
    private generateToolSchema(model: any, category: string) {
      const baseSchema = {
        name: model.id,
        description: `${model.name} - ${model.description}`,
        inputSchema: {
          type: 'object',
          properties: {} as any,
          required: [] as string[],
        },
      };
    
      if (category === 'imageGeneration') {
        baseSchema.inputSchema.properties = {
          prompt: { type: 'string', description: 'Text prompt for image generation' },
          image_size: { type: 'string', enum: ['square_hd', 'square', 'portrait_4_3', 'portrait_16_9', 'landscape_4_3', 'landscape_16_9'], default: 'landscape_4_3' },
          num_images: { type: 'number', default: 1, minimum: 1, maximum: 4 },
        };
        baseSchema.inputSchema.required = ['prompt'];
        
        // Add model-specific parameters
        if (model.id.includes('flux') || model.id.includes('stable_diffusion')) {
          baseSchema.inputSchema.properties.num_inference_steps = { type: 'number', default: 25, minimum: 1, maximum: 50 };
          baseSchema.inputSchema.properties.guidance_scale = { type: 'number', default: 3.5, minimum: 1, maximum: 20 };
        }
        if (model.id.includes('stable_diffusion') || model.id === 'ideogram_v3') {
          baseSchema.inputSchema.properties.negative_prompt = { type: 'string', description: 'Negative prompt' };
        }
      } else if (category === 'textToVideo') {
        baseSchema.inputSchema.properties = {
          prompt: { type: 'string', description: 'Text prompt for video generation' },
          duration: { type: 'number', default: 5, minimum: 1, maximum: 30 },
          aspect_ratio: { type: 'string', enum: ['16:9', '9:16', '1:1', '4:3', '3:4'], default: '16:9' },
        };
        baseSchema.inputSchema.required = ['prompt'];
      } else if (category === 'imageToVideo') {
        baseSchema.inputSchema.properties = {
          image_url: { type: 'string', description: 'URL of the input image' },
          prompt: { type: 'string', description: 'Motion description prompt' },
          duration: { type: 'string', enum: ['5', '10'], default: '5', description: 'Video duration in seconds' },
          aspect_ratio: { type: 'string', enum: ['16:9', '9:16', '1:1'], default: '16:9' },
          negative_prompt: { type: 'string', description: 'What to avoid in the video' },
          cfg_scale: { type: 'number', default: 0.5, minimum: 0, maximum: 1, description: 'How closely to follow the prompt' }
        };
        baseSchema.inputSchema.required = ['image_url', 'prompt'];
      }
    
      return baseSchema;
    }
  • src/index.ts:106-106 (registration)
    Registry entry for flux_dev tool defining its ID, endpoint, name, and description. Used by getModelById and schema/handler dispatch.
    { id: 'flux_dev', endpoint: 'fal-ai/flux/dev', name: 'FLUX Dev', description: 'High-quality 12B parameter model' },
  • Helper function to retrieve flux_dev model configuration by tool name during tool call dispatch.
    function getModelById(id: string) {
      const allModels = getAllModels();
      return allModels.find(model => model.id === id);
    }
  • Dispatch logic in CallToolRequestSchema handler that routes flux_dev calls to handleImageGeneration based on registry presence.
    const model = getModelById(name);
    if (!model) {
      throw new McpError(
        ErrorCode.MethodNotFound,
        `Unknown model: ${name}`
      );
    }
    
    // Determine category and handle accordingly
    if (MODEL_REGISTRY.imageGeneration.find(m => m.id === name)) {
      return await this.handleImageGeneration(args, model);
    } else if (MODEL_REGISTRY.textToVideo.find(m => m.id === name)) {
      return await this.handleTextToVideo(args, model);
    } else if (MODEL_REGISTRY.imageToVideo.find(m => m.id === name)) {
      return await this.handleImageToVideo(args, model);
    }

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/RamboRogers/fal-image-video-mcp'

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