Skip to main content
Glama

generate_image

Create images from text descriptions using Fal.ai's AI models like Flux or Stable Diffusion. Specify size, quantity, and seed for customized visual content generation.

Instructions

Generate an image using Fal.ai models like Flux or Stable Diffusion

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
promptYesText description of the image to generate
modelNoModel to use (default: fal-ai/flux/schnell)fal-ai/flux/schnell
image_sizeNoImage size presetlandscape_4_3
num_imagesNoNumber of images to generate (1-4)
seedNoSeed for reproducible generation

Implementation Reference

  • Main handler for the generate_image tool: parses input schema, calls fal.subscribe to generate images using the specified model and parameters, optionally downloads images locally using downloadImage helper, formats a detailed text response with image URLs and local paths.
    case "generate_image": {
      const params = GenerateImageSchema.parse(args);
      const result = await fal.subscribe(params.model, {
        input: {
          prompt: params.prompt,
          image_size: params.image_size,
          num_images: params.num_images,
          ...(params.seed && { seed: params.seed }),
        },
        logs: true,
        onQueueUpdate: (update: any) => {
          console.error(`Queue position: ${update.position || "processing"}`);
        },
      });
    
      // Format the response nicely
      const images = (result as any).images || [];
      let responseText = `āœ… Generated ${images.length} image(s) successfully!\n\n`;
      
      // Download images locally if requested
      const downloadedPaths: string[] = [];
      const shouldDownload = params.download_images !== false;
      
      for (let idx = 0; idx < images.length; idx++) {
        const img = images[idx];
        responseText += `Image ${idx + 1}:\n`;
        
        if (shouldDownload) {
          try {
            const localPath = await downloadImage(img.url);
            downloadedPaths.push(localPath);
            responseText += `šŸ“ Saved to: ${localPath}\n`;
          } catch (error: any) {
            responseText += `āš ļø Download failed: ${error.message}\n`;
          }
        }
        
        responseText += `🌐 URL: ${img.url}\n`;
        if (img.width && img.height) {
          responseText += `šŸ“ Size: ${img.width}x${img.height}\n`;
        }
        responseText += `\n`;
      }
      
      if ((result as any).seed) {
        responseText += `šŸŽ² Seed: ${(result as any).seed}\n`;
      }
      
      if (downloadedPaths.length > 0) {
        responseText += `\nšŸ“‚ Images saved to: ${path.join(process.cwd(), "fal-images")}/\n`;
      } else if (shouldDownload && images.length > 0) {
        responseText += `\nšŸ’” Tip: Images URLs are temporary. Save them soon if needed.\n`;
      }
      
      return {
        content: [
          {
            type: "text",
            text: responseText,
          },
        ],
      };
    }
  • Zod schema defining input parameters for generate_image tool, used for validation in the handler.
    const GenerateImageSchema = z.object({
      prompt: z.string().describe("Text description of the image to generate"),
      model: z.string().default("fal-ai/flux/schnell").describe("Model to use for generation"),
      image_size: z.enum(["square", "landscape_4_3", "portrait_3_4"]).default("landscape_4_3").optional(),
      num_images: z.number().min(1).max(4).default(1).optional(),
      seed: z.number().optional(),
      download_images: z.boolean().default(true).optional().describe("Whether to download images locally"),
    });
  • src/index.ts:104-137 (registration)
    Tool registration in the ListToolsRequestHandler response, defining name, description, and JSON inputSchema matching the Zod schema.
    {
      name: "generate_image",
      description: "Generate an image using Fal.ai models like Flux or Stable Diffusion",
      inputSchema: {
        type: "object",
        properties: {
          prompt: {
            type: "string",
            description: "Text description of the image to generate",
          },
          model: {
            type: "string",
            description: "Model to use (default: fal-ai/flux/schnell)",
            default: "fal-ai/flux/schnell",
          },
          image_size: {
            type: "string",
            enum: ["square", "landscape_4_3", "portrait_3_4"],
            description: "Image size preset",
            default: "landscape_4_3",
          },
          num_images: {
            type: "number",
            description: "Number of images to generate (1-4)",
            default: 1,
          },
          seed: {
            type: "number",
            description: "Seed for reproducible generation",
          },
        },
        required: ["prompt"],
      },
    },
  • Helper function to download generated image from URL to local fal-images directory, used optionally in the generate_image handler.
    async function downloadImage(url: string, outputDir: string = process.cwd()): Promise<string> {
      try {
        // Create images directory if it doesn't exist
        const imagesDir = path.join(outputDir, "fal-images");
        if (!fs.existsSync(imagesDir)) {
          fs.mkdirSync(imagesDir, { recursive: true });
        }
        
        // Generate filename from URL or timestamp
        const urlParts = url.split("/");
        const originalName = urlParts[urlParts.length - 1];
        const timestamp = new Date().getTime();
        const filename = `${timestamp}-${originalName}`;
        const filepath = path.join(imagesDir, filename);
        
        // Download the image using buffer approach
        const response = await fetch(url);
        if (!response.ok) throw new Error(`Failed to download: ${response.statusText}`);
        
        const buffer = await response.buffer();
        fs.writeFileSync(filepath, buffer);
        
        // Verify the file was created
        if (!fs.existsSync(filepath)) {
          throw new Error("File was not created successfully");
        }
        
        return filepath;
      } catch (error) {
        console.error(`Failed to download image: ${error}`);
        throw error;
      }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions using Fal.ai models but doesn't describe what happens during generation (e.g., processing time, cost implications, rate limits, authentication needs, or what happens if generation fails). For a tool that likely involves external API calls and resource consumption, this is a significant gap in behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that gets straight to the point with no wasted words. It's appropriately sized for a tool with good schema documentation. However, it could be slightly more structured by front-loading the core purpose more explicitly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an image generation tool with 5 parameters, no annotations, and no output schema, the description is incomplete. It doesn't explain what the tool returns (image data, URLs, metadata), doesn't mention potential costs or limitations, and provides minimal behavioral context. Given the complexity of image generation and lack of structured metadata, the description should do more to help agents understand the tool's behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 5 parameters thoroughly with descriptions, defaults, and constraints. The description adds no additional parameter semantics beyond what's in the schema. The baseline score of 3 is appropriate when the schema does all the parameter documentation work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'generate' and resource 'image', specifying it uses Fal.ai models like Flux or Stable Diffusion. It distinguishes from siblings like 'check_status' or 'list_popular_models' by focusing on image generation rather than status checking or listing. However, it doesn't explicitly differentiate from 'run_model' which might also generate images, leaving some ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'run_model' or 'run_workflow'. It mentions specific models (Flux, Stable Diffusion) but doesn't explain why to choose this tool over others for image generation tasks. There are no explicit when/when-not instructions or prerequisites stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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/gravicity-archive/fal-mcp-server'

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