edit_image
Modify existing images using text prompts with DALL-E's editing capabilities. Upload an image, describe changes, and generate edited versions with precise control over modifications.
Instructions
Edit an existing image using DALL-E based on a text prompt
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | Text description of the desired edits | |
| imagePath | Yes | Path to the image to edit | |
| mask | No | Path to the mask image (white areas will be edited, black areas preserved) | |
| model | No | DALL-E model to use (currently only dall-e-2 supports editing) | |
| size | No | Size of the generated image | |
| n | No | Number of images to generate (1-10) | |
| saveDir | No | Directory to save the edited images | |
| fileName | No | Base filename for the edited images (without extension) |
Implementation Reference
- src/tools/index.ts:149-199 (handler)The main tool handler for 'edit_image' that processes arguments, resolves paths, calls the DalleService.editImage method, and formats the response with saved image paths.handler: async (args: EditImageArgs): Promise<ToolResponse> => { // Resolve relative paths to absolute paths const imagePath = path.isAbsolute(args.imagePath) ? args.imagePath : path.resolve(process.cwd(), args.imagePath); const mask = args.mask && !path.isAbsolute(args.mask) ? path.resolve(process.cwd(), args.mask) : args.mask; const result = await dalleService.editImage(args.prompt, imagePath, { mask, model: args.model, size: args.size, n: args.n, saveDir: args.saveDir, fileName: args.fileName }); if (!result.success) { return { content: [{ type: "text", text: `Error editing image: ${result.error}` }] }; } const imagePaths = result.imagePaths || []; const imageCount = imagePaths.length; const model = result.model || 'dall-e-2'; let responseText = `Successfully edited image and generated ${imageCount} variation${imageCount !== 1 ? 's' : ''} using ${model}.\n\n`; responseText += `Original image: ${imagePath}\n`; if (mask) { responseText += `Mask: ${mask}\n`; } responseText += `Prompt: "${result.prompt}"\n\n`; responseText += `Edited image${imageCount !== 1 ? 's' : ''} saved to:\n`; imagePaths.forEach(imagePath => { responseText += `- ${imagePath}\n`; }); return { content: [{ type: "text", text: responseText }] }; }
- src/tools/index.ts:107-148 (schema)JSON schema defining the input parameters for the edit_image tool, including required prompt and imagePath.inputSchema: { type: "object", properties: { prompt: { type: "string", description: "Text description of the desired edits" }, imagePath: { type: "string", description: "Path to the image to edit" }, mask: { type: "string", description: "Path to the mask image (white areas will be edited, black areas preserved)" }, model: { type: "string", description: "DALL-E model to use (currently only dall-e-2 supports editing)", enum: ["dall-e-2"] }, size: { type: "string", description: "Size of the generated image", enum: ["256x256", "512x512", "1024x1024"] }, n: { type: "number", description: "Number of images to generate (1-10)", minimum: 1, maximum: 10 }, saveDir: { type: "string", description: "Directory to save the edited images" }, fileName: { type: "string", description: "Base filename for the edited images (without extension)" } }, required: ["prompt", "imagePath"] },
- src/index.ts:24-32 (registration)MCP server capabilities registration enabling the 'edit_image' tool.capabilities: { tools: { generate_image: true, edit_image: true, create_variation: true, validate_key: true }, }, }
- src/index.ts:85-86 (registration)Dispatch handler in the main server that routes calls to the edit_image tool handler.case 'edit_image': response = await (tool as Tool<EditImageArgs>).handler(args as unknown as EditImageArgs);
- Core helper function in DalleService that performs the actual image editing via OpenAI API, handles file I/O, and returns result with image paths.async editImage( prompt: string, imagePath: string, options: { mask?: string; model?: string; size?: string; n?: number; saveDir?: string; fileName?: string; } = {} ): Promise<ImageGenerationResult> { try { // Set default options const model = options.model || 'dall-e-2'; // DALL-E 3 doesn't support image edits yet const size = options.size || '1024x1024'; const n = options.n || 1; const saveDir = options.saveDir || this.config.defaultSaveDir || process.cwd(); const fileName = options.fileName || `dalle-edit-${Date.now()}`; // Ensure save directory exists await fs.ensureDir(saveDir); // Check if image exists if (!await fs.pathExists(imagePath)) { return { success: false, error: `Image file not found: ${imagePath}` }; } // Check if mask exists if provided if (options.mask && !await fs.pathExists(options.mask)) { return { success: false, error: `Mask file not found: ${options.mask}` }; } // Create form data const formData = new FormData(); formData.append('prompt', prompt); formData.append('n', n.toString()); formData.append('size', size); formData.append('response_format', 'b64_json'); // Read image file and append to form const imageBuffer = await fs.readFile(imagePath); formData.append('image', imageBuffer, { filename: path.basename(imagePath), contentType: 'image/png' }); // Add mask if provided if (options.mask) { const maskBuffer = await fs.readFile(options.mask); formData.append('mask', maskBuffer, { filename: path.basename(options.mask), contentType: 'image/png' }); } // Make request to OpenAI API const response = await axios.post( `${this.baseUrl}/images/edits`, formData, { headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${this.config.apiKey}` } } ); // Process response const data = response.data; const imagePaths: string[] = []; // Save each image for (let i = 0; i < data.data.length; i++) { const item = data.data[i]; const resultBuffer = Buffer.from(item.b64_json, 'base64'); let resultPath = path.join(saveDir, `${fileName}${n > 1 ? `-${i + 1}` : ''}.png`); // Ensure the path is absolute if (!path.isAbsolute(resultPath)) { resultPath = path.resolve(process.cwd(), resultPath); } await fs.writeFile(resultPath, resultBuffer); imagePaths.push(resultPath); } return { success: true, imagePaths, model, prompt }; } catch (error) { console.log("DALL-E API Error:", error); let errorMessage = 'Failed to edit image'; if (axios.isAxiosError(error) && error.response?.data?.error) { errorMessage = `DALL-E API Error: ${error.response.data.error.message}`; } else if (error instanceof Error) { errorMessage = error.message; } return { success: false, error: errorMessage }; } }