Skip to main content
Glama

create_image

Generate images from text prompts using AI, with options for size, format, quality, and background settings.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
promptYes
backgroundNo
nNo
output_compressionNo
output_formatNo
qualityNo
sizeNo
userNo
moderationNo

Implementation Reference

  • The async handler function that implements the 'create_image' tool logic: calls OpenAI's images.generate API with gpt-image-1 model, processes the base64 response, saves images to disk using saveImageToDisk, handles detailed errors, and returns a rich formatted response with text summary and image contents.
      async (args: CreateImageArgs, extra: any) => {
        try {
          // Use the OpenAI SDK's createImage method with detailed error handling
          let apiResponse;
          try {
            apiResponse = await openai.images.generate({
              model: "gpt-image-1",
              prompt: args.prompt,
              size: args.size || "1024x1024",
              quality: args.quality || "high",
              n: args.n || 1
            });
    
            // Check if the response contains an error field (shouldn't happen with SDK but just in case)
            if (apiResponse && 'error' in apiResponse) {
              const error = (apiResponse as any).error;
              throw {
                message: error.message || 'Unknown API error',
                type: error.type || 'api_error',
                code: error.code || 'unknown',
                response: { data: { error } }
              };
            }
          } catch (apiError: any) {
            // Enhance the error with more details if possible
            console.error("OpenAI API Error:", apiError);
    
            // Rethrow with enhanced information
            throw apiError;
          }
    
          // Create a Response-like object with a json() method for compatibility with the built-in tool
          const response = {
            json: () => Promise.resolve(apiResponse)
          };
    
          const responseData = apiResponse;
          const format = args.output_format || "png";
    
          // Save images to disk and create response with file paths
          const savedImages = [];
          const imageContents = [];
    
          if (responseData.data && responseData.data.length > 0) {
            for (const item of responseData.data) {
              if (item.b64_json) {
                // Save the image to disk
                const imagePath = saveImageToDisk(item.b64_json, format);
    
                // Add the saved image info to our response
                savedImages.push({
                  path: imagePath,
                  format: format
                });
    
                // Also include the image content for compatibility
                imageContents.push({
                  type: "image" as const,
                  data: item.b64_json,
                  mimeType: `image/${format}`
                });
              } else if (item.url) {
                console.error(`Image URL: ${item.url}`);
                console.error("The gpt-image-1 model returned a URL instead of base64 data.");
                console.error("To view the image, open the URL in your browser.");
    
                // Add the URL info to our response
                savedImages.push({
                  url: item.url,
                  format: format
                });
    
                // Include a text message about the URL in the content
                imageContents.push({
                  type: "text" as const,
                  text: `Image available at URL: ${item.url}`
                });
              }
            }
          }
    
          // Create a beautifully formatted response with emojis and details
          const formatSize = (size: string | undefined) => size || "1024x1024";
          const formatQuality = (quality: string | undefined) => quality || "high";
    
          // Create a beautiful formatted message
          const formattedMessage = `
    🎨 **Image Generation Complete!** 🎨
    
    ✨ **Prompt**: "${args.prompt}"
    
    πŸ“Š **Generation Parameters**:
       β€’ Size: ${formatSize(args.size)}
       β€’ Quality: ${formatQuality(args.quality)}
       β€’ Number of Images: ${args.n || 1}
       ${args.background ? `β€’ Background: ${args.background}` : ''}
       ${args.output_format ? `β€’ Format: ${args.output_format}` : ''}
       ${args.output_compression ? `β€’ Compression: ${args.output_compression}%` : ''}
       ${args.moderation ? `β€’ Moderation: ${args.moderation}` : ''}
    
    πŸ“ **Generated ${savedImages.length} Image${savedImages.length > 1 ? 's' : ''}**:
    ${savedImages.map((img, index) => `   ${index + 1}. ${img.path || img.url}`).join('\n')}
    
    ${responseData.usage ? `⚑ **Token Usage**:
       β€’ Total Tokens: ${responseData.usage.total_tokens}
       β€’ Input Tokens: ${responseData.usage.input_tokens}
       β€’ Output Tokens: ${responseData.usage.output_tokens}` : ''}
    
    πŸ” You can find your image${savedImages.length > 1 ? 's' : ''} at the path${savedImages.length > 1 ? 's' : ''} above!
    `;
    
          // Return both the image content and the saved file paths with the beautiful message
          return {
            content: [
              {
                type: "text" as const,
                text: formattedMessage
              },
              ...imageContents
            ],
            ...(responseData.usage && {
              _meta: {
                usage: responseData.usage,
                savedImages: savedImages
              }
            })
          };
        } catch (error: any) {
          // Log the full error for debugging
          console.error("Error generating image:", error);
    
          // Extract detailed error information
          const errorCode = error.status || error.code || 'Unknown';
          const errorType = error.type || 'Error';
          const errorMessage = error.message || 'An unknown error occurred';
    
          // Check for specific OpenAI API errors
          let detailedError = '';
    
          if (error.response) {
            // If we have a response object from OpenAI, extract more details
            try {
              const responseData = error.response.data || {};
              if (responseData.error) {
                detailedError = `\nπŸ“‹ **Details**: ${responseData.error.message || 'No additional details available'}`;
    
                // Add parameter errors if available
                if (responseData.error.param) {
                  detailedError += `\nπŸ” **Parameter**: ${responseData.error.param}`;
                }
    
                // Add code if available
                if (responseData.error.code) {
                  detailedError += `\nπŸ”’ **Error Code**: ${responseData.error.code}`;
                }
    
                // Add type if available
                if (responseData.error.type) {
                  detailedError += `\nπŸ“ **Error Type**: ${responseData.error.type}`;
                }
              }
            } catch (parseError) {
              // If we can't parse the response, just use what we have
              detailedError = '\nπŸ“‹ **Details**: Could not parse error details from API response';
            }
          }
    
          // Construct a comprehensive error message
          const fullErrorMessage = `❌ **Image Generation Failed**\n\n⚠️ **Error ${errorCode}**: ${errorType} - ${errorMessage}${detailedError}\n\nπŸ”„ Please try again with a different prompt or parameters.`;
    
          // Return the detailed error to the client
          return {
            content: [{
              type: "text",
              text: fullErrorMessage
            }],
            isError: true,
            _meta: {
              error: {
                code: errorCode,
                type: errorType,
                message: errorMessage,
                raw: JSON.stringify(error, Object.getOwnPropertyNames(error))
              }
            }
          };
        }
      }
  • Zod schema defining the input parameters for the create_image tool, including prompt, size, quality, etc., with validation rules.
    const createImageSchema = z.object({
      prompt: z.string().max(32000, "Prompt exceeds maximum length for gpt-image-1."),
      background: z.enum(["transparent", "opaque", "auto"]).optional(),
      n: z.number().int().min(1).max(10).optional(),
      output_compression: z.number().int().min(0).max(100).optional(),
      output_format: z.enum(["png", "jpeg", "webp"]).optional(),
      quality: z.enum(["high", "medium", "low", "auto"]).optional(),
      size: z.enum(["1024x1024", "1536x1024", "1024x1536", "auto"]).optional(),
      user: z.string().optional(),
      moderation: z.enum(["low", "auto"]).optional()
    });
    type CreateImageArgs = z.infer<typeof createImageSchema>;
  • src/index.ts:168-173 (registration)
    Registers the 'create_image' tool with the MCP server using server.tool(), specifying the name, input schema, metadata title, and handler function.
    server.tool(
      "create_image",
      createImageSchema.shape,
      {
        title: "Generate new images using OpenAI's gpt-image-1 model"
      },
  • Helper utility to save base64-encoded image data to a file in the configured output directory, used by the create_image handler to persist generated images.
    function saveImageToDisk(base64Data: string, format: string = 'png'): string {
      // Create a dedicated folder for generated images if we're using the workspace root
      // This keeps the workspace organized while still saving in the current directory
      const imagesFolder = path.join(outputDir, 'gpt-images');
    
      // Create the images folder if it doesn't exist
      if (!fs.existsSync(imagesFolder)) {
        fs.mkdirSync(imagesFolder, { recursive: true });
        console.error(`Created images folder: ${imagesFolder}`);
      }
    
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const filename = `image-${timestamp}.${format}`;
      const outputPath = path.join(imagesFolder, filename);
    
      // Remove the data URL prefix if present
      const base64Image = base64Data.replace(/^data:image\/\w+;base64,/, '');
    
      // Write the image to disk
      fs.writeFileSync(outputPath, Buffer.from(base64Image, 'base64'));
      console.error(`Image saved to: ${outputPath}`);
    
      return outputPath;
    }
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/CLOUDWERX-DEV/gpt-image-1-mcp'

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