Skip to main content
Glama

generate-image

Create images from text descriptions using customizable AI models. Specify prompts, select models, adjust parameters, and generate multiple images with controlled settings.

Instructions

Generate an image from a text prompt using a selectable text-to-image model.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
promptYesText prompt describing the image to generate
modelNoID of the text-to-image model to use (any valid fal.ai model ID)fal-ai/recraft-v3
image_sizeNoSize of the generated imagelandscape_4_3
num_imagesNoNumber of images to generate
num_inference_stepsNoNumber of inference steps
guidance_scaleNoClassifier Free Guidance scale
enable_safety_checkerNoEnable the safety checker

Implementation Reference

  • Core implementation of the generate-image tool: validates parameters, calls fal.ai API with dynamic model support, downloads images locally, and returns enhanced results with file paths.
    export async function generateImageFromText(
      prompt: string,
      imageSize: ImageSize = 'landscape_4_3',
      numInferenceSteps = 28,
      guidanceScale = 3.5,
      numImages = 1,
      enableSafetyChecker = true,
      model: string = SUPPORTED_MODELS[0].id // default to first model
    ) {
      // --- Pre-validation and user guidance ---
      // 1. Prompt required
      if (!prompt || !prompt.trim()) {
        throw new Error(
          'Prompt is required. Please describe the image you want to generate. Example: generate an image of a red apple'
        );
      }
      // 2. Image size validation
      const SUPPORTED_SIZES = [
        'square_hd',
        'square',
        'portrait_4_3',
        'portrait_16_9',
        'landscape_4_3',
        'landscape_16_9',
      ];
      if (imageSize && !SUPPORTED_SIZES.includes(imageSize)) {
        throw new Error(
          `Error: '${imageSize}' is not a supported image size.\nSupported sizes: ${SUPPORTED_SIZES.join(
            ', '
          )}`
        );
      }
      // 3. Batch size validation
      const MAX_IMAGES = 5;
      if (numImages > MAX_IMAGES) {
        throw new Error(
          `Error: Maximum number of images per request is ${MAX_IMAGES}. Please request ${MAX_IMAGES} or fewer images.`
        );
      }
      // 4. Safety checker toggle validation (should be boolean)
      if (typeof enableSafetyChecker !== 'boolean') {
        throw new Error(
          "'safety checker' must be either 'on' (true) or 'off' (false). Example: safety checker on"
        );
      }
      // 5. Dynamic model selection: allow any model ID, warn if not in SUPPORTED_MODELS
      const foundModel = SUPPORTED_MODELS.find((m) => m.id === model);
      if (!foundModel) {
        console.warn(
          `Warning: Model '${model}' is not in the recommended list. Attempting generation anyway.\n` +
            `If you encounter errors, check the model ID at https://fal.ai/models or the fal.ai API docs.\n` +
            `Recommended models:\n${SUPPORTED_MODELS.map(
              (m) => `- ${m.name} (${m.id})`
            ).join('\n')}`
        );
      }
      try {
        const result = await fal.subscribe(model, {
          input: {
            prompt,
            image_size: imageSize,
            num_inference_steps: numInferenceSteps,
            guidance_scale: guidanceScale,
            num_images: numImages,
            enable_safety_checker: enableSafetyChecker,
          },
          logs: true,
          onQueueUpdate: (update: any) => {
            if (update.status === 'IN_PROGRESS' && update.logs) {
              update.logs.map((log: any) => log.message).forEach(console.error);
            }
          },
        });
        console.error('Image generation result:', result.data);
    
        // Download images and enhance the result with local paths
        if (result.data && result.data.images) {
          const downloadedImages = await Promise.all(
            result.data.images.map(async (img: any, idx: number) => {
              try {
                const localPath = await downloadImage(img.url, prompt, idx);
                console.error(`Image #${idx + 1} saved to: ${localPath}`);
                return { ...img, localPath };
              } catch (error) {
                console.error(`Failed to download image #${idx + 1}:`, error);
                return img;
              }
            })
          );
    
          // Replace the images with the enhanced versions that include local paths
          result.data.images = downloadedImages;
        }
    
        return result.data;
      } catch (err: any) {
        console.error('FAL text-to-image error:', err?.response?.data || err);
        throw err;
      }
    }
  • Input schema for the 'generate-image' tool, defining parameters like prompt, model, image size, and defaults.
    inputSchema: {
      type: 'object',
      properties: {
        prompt: {
          type: 'string',
          description: 'Text prompt describing the image to generate',
        },
        model: {
          type: 'string',
          description:
            'ID of the text-to-image model to use (any valid fal.ai model ID)',
          default: SUPPORTED_MODELS[0].id,
        },
        image_size: {
          type: 'string',
          enum: [
            'square_hd',
            'square',
            'portrait_4_3',
            'portrait_16_9',
            'landscape_4_3',
            'landscape_16_9',
          ],
          default: 'landscape_4_3',
          description: 'Size of the generated image',
        },
        num_images: {
          type: 'integer',
          default: 1,
          description: 'Number of images to generate',
        },
        num_inference_steps: {
          type: 'integer',
          default: 28,
          description: 'Number of inference steps',
        },
        guidance_scale: {
          type: 'number',
          default: 3.5,
          description: 'Classifier Free Guidance scale',
        },
        enable_safety_checker: {
          type: 'boolean',
          default: true,
          description: 'Enable the safety checker',
        },
      },
      required: ['prompt'],
    },
  • src/index.ts:298-352 (registration)
    Registration of the 'generate-image' tool in the ListToolsRequestSchema handler, specifying name, description, and input schema.
      {
        name: 'generate-image',
        description:
          'Generate an image from a text prompt using a selectable text-to-image model.',
        inputSchema: {
          type: 'object',
          properties: {
            prompt: {
              type: 'string',
              description: 'Text prompt describing the image to generate',
            },
            model: {
              type: 'string',
              description:
                'ID of the text-to-image model to use (any valid fal.ai model ID)',
              default: SUPPORTED_MODELS[0].id,
            },
            image_size: {
              type: 'string',
              enum: [
                'square_hd',
                'square',
                'portrait_4_3',
                'portrait_16_9',
                'landscape_4_3',
                'landscape_16_9',
              ],
              default: 'landscape_4_3',
              description: 'Size of the generated image',
            },
            num_images: {
              type: 'integer',
              default: 1,
              description: 'Number of images to generate',
            },
            num_inference_steps: {
              type: 'integer',
              default: 28,
              description: 'Number of inference steps',
            },
            guidance_scale: {
              type: 'number',
              default: 3.5,
              description: 'Classifier Free Guidance scale',
            },
            enable_safety_checker: {
              type: 'boolean',
              default: true,
              description: 'Enable the safety checker',
            },
          },
          required: ['prompt'],
        },
      },
    ],
  • MCP CallToolRequestSchema handler branch that invokes generateImageFromText for 'generate-image' tool calls and handles responses/errors.
    if (name === 'generate-image') {
      try {
        const result = await generateImageFromText(
          args.prompt,
          args.image_size,
          args.num_inference_steps,
          args.guidance_scale,
          args.num_images,
          args.enable_safety_checker,
          args.model // new model param
        );
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(result, null, 2),
            },
          ],
        };
      } catch (error: any) {
        // --- Enhanced error handling for guidance ---
        let errorMsg = error instanceof Error ? error.message : String(error);
        // If model error, append recommended models and link
        if (errorMsg.match(/model/i)) {
          errorMsg +=
            '\n\nRecommended models:\n' +
            SUPPORTED_MODELS.map((m) => `- ${m.name} (${m.id})`).join('\n') +
            '\nSee all models: https://fal.ai/models';
        }
        // If image size error, append supported sizes
        if (errorMsg.match(/image size|supported sizes/i)) {
          errorMsg +=
            '\nSupported sizes: square_hd, square, portrait_4_3, portrait_16_9, landscape_4_3, landscape_16_9';
        }
        // If prompt error, add example
        if (errorMsg.match(/prompt is required/i)) {
          errorMsg += '\nExample: generate an image of a red apple';
        }
        return {
          isError: true,
          content: [
            {
              type: 'text',
              text: `Error generating image: ${errorMsg}`,
            },
          ],
        };
      }
  • Helper utility to download generated images from fal.ai URLs to a local directory, appending local paths to results.
    async function downloadImage(
      url: string,
      prompt: string,
      idx?: number
    ): Promise<string> {
      ensureDownloadDir();
    
      // Generate a filename from the prompt and timestamp
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const sanitizedPrompt = prompt
        .slice(0, 30)
        .replace(/[^a-z0-9]/gi, '_')
        .toLowerCase();
      const filename = `${sanitizedPrompt}_${timestamp}${
        typeof idx === 'number' ? `_${idx + 1}` : ''
      }.png`;
      const filepath = path.join(FAL_IMAGES_DIR, filename);
    
      try {
        const response = await fetch(url);
        if (!response.ok)
          throw new Error(`Failed to fetch: ${response.statusText}`);
    
        const buffer = await response.arrayBuffer();
        fs.writeFileSync(filepath, Buffer.from(buffer));
        console.error(`✅ Downloaded image to: ${filepath}`);
        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?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions 'selectable text-to-image model' but fails to detail critical aspects like rate limits, authentication requirements, cost implications, or output format (e.g., image URL, base64). For a generative tool with zero annotation coverage, this is a significant gap in transparency.

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

Conciseness5/5

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

The description is a single, efficient sentence that front-loads the core functionality without unnecessary details. It avoids redundancy and wastes no words, making it easy for an agent to parse quickly.

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?

Given the tool's complexity (7 parameters, generative nature) and lack of annotations or output schema, the description is insufficient. It omits behavioral traits like safety, performance, or output handling, leaving the agent under-informed about how to effectively invoke and interpret results from this tool.

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%, meaning all parameters are well-documented in the schema itself. The description adds no additional parameter semantics beyond what the schema provides, such as explaining trade-offs between model choices or image size effects. This meets the baseline for high schema coverage but doesn't enhance understanding.

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 tool's purpose: 'Generate an image from a text prompt using a selectable text-to-image model.' It specifies the verb ('Generate'), resource ('image'), and mechanism ('text-to-image model'). However, with no sibling tools mentioned, it lacks explicit differentiation from alternatives, preventing a perfect score.

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, prerequisites, or exclusions. It merely states what the tool does without context for its application, leaving the agent to infer usage scenarios independently.

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/madhusudan-kulkarni/mcp-fal-ai-image'

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