editImage
Edit an existing image by providing a text description and image URL. Modify elements like adding or removing objects, or changing backgrounds.
Instructions
Edit or modify an existing image based on a text prompt. User-configured settings in MCP config will be used as defaults unless specifically overridden.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | The text description of how to edit the image (e.g., "remove the cat and add a dog", "change background to mountains") | |
| imageUrl | Yes | Public HTTP(S) URL(s) of the input image(s) to edit. Accepts a string or an array for multiple references (first is most important). Local file paths, file uploads, or base64/data URLs are not supported. | |
| model | No | Model name to use for editing (default: user config or "kontext"). Available: "kontext", "nanobanana", "seedream" | |
| seed | No | Seed for reproducible results (default: random) | |
| width | No | Width of the generated image (default: 1024) | |
| height | No | Height of the generated image (default: 1024) | |
| enhance | No | Whether to enhance the prompt using an LLM before generating (default: true) | |
| safe | No | Whether to apply content filtering (default: false) | |
| outputPath | No | Directory path where to save the image (default: user config or "./mcpollinations-output") | |
| fileName | No | Name of the file to save (without extension, default: generated from prompt) | |
| format | No | Image format to save as (png, jpeg, jpg, webp - default: png) |
Implementation Reference
- src/services/imageService.js:218-357 (handler)The main handler function for the editImage tool. Takes a prompt and image URL(s), calls the Pollinations Image API, returns base64 image data, and saves the image to disk.
export async function editImage(prompt, imageUrl, model = 'kontext', seed = Math.floor(Math.random() * 1000000), width = 1024, height = 1024, enhance = true, safe = false, outputPath = './mcpollinations-output', fileName = '', format = 'png', authConfig = null) { if (!prompt || typeof prompt !== 'string') { throw new Error('Prompt is required and must be a string'); } if (!imageUrl || (typeof imageUrl !== 'string' && !Array.isArray(imageUrl))) { throw new Error('Image URL(s) are required and must be a string or array of strings'); } // Support multi-reference images. Prefer repeating the `image` param per URL // to avoid comma-encoding ambiguities. const imageList = Array.isArray(imageUrl) ? imageUrl.filter(Boolean) : (typeof imageUrl === 'string' && imageUrl.includes(',')) ? imageUrl.split(',').map(s => s.trim()).filter(Boolean) : [imageUrl]; // Build the query parameters const queryParams = new URLSearchParams(); queryParams.append('model', model); for (const u of imageList) { queryParams.append('image', u); } if (seed !== undefined) queryParams.append('seed', seed); if (width !== 1024) queryParams.append('width', width); if (height !== 1024) queryParams.append('height', height); // Add enhance parameter if true if (enhance) queryParams.append('enhance', 'true'); // Add parameters queryParams.append('nologo', 'true'); // Always set nologo to true queryParams.append('private', 'true'); // Always set private to true) queryParams.append('safe', safe.toString()); // Use the customizable safe parameter // Construct the URL const encodedPrompt = encodeURIComponent(prompt); const baseUrl = 'https://image.pollinations.ai'; let url = `${baseUrl}/prompt/${encodedPrompt}`; // Add query parameters const queryString = queryParams.toString(); url += `?${queryString}`; try { // Prepare fetch options with optional auth headers const fetchOptions = {}; if (authConfig) { fetchOptions.headers = {}; if (authConfig.token) { fetchOptions.headers['Authorization'] = `Bearer ${authConfig.token}`; } if (authConfig.referrer) { fetchOptions.headers['Referer'] = authConfig.referrer; } } // Fetch the image from the URL const response = await fetch(url, fetchOptions); if (!response.ok) { throw new Error(`Failed to edit image: ${response.statusText}`); } // Get the image data as an ArrayBuffer const imageBuffer = await response.arrayBuffer(); // Convert the ArrayBuffer to a base64 string const base64Data = Buffer.from(imageBuffer).toString('base64'); // Determine the mime type from the response headers or default to image/jpeg const contentType = response.headers.get('content-type') || 'image/jpeg'; // Prepare the result object const result = { data: base64Data, mimeType: contentType, metadata: { prompt, inputImageUrl: imageUrl, width, height, model, seed, enhance, private: true, nologo: true, safe } }; // Always save the image to a file // Import required modules const fs = await import('fs'); const path = await import('path'); // Create the output directory if it doesn't exist if (!fs.existsSync(outputPath)) { fs.mkdirSync(outputPath, { recursive: true }); } // Generate a filename if not provided let finalFileName = fileName; if (!finalFileName) { // Create a filename from the prompt (first 20 characters) and timestamp const sanitizedPrompt = prompt.replace(/[^a-zA-Z0-9]/g, '_').substring(0, 20); const timestamp = Date.now(); const randomSuffix = Math.floor(Math.random() * 1000); finalFileName = `edited_${sanitizedPrompt}_${timestamp}_${randomSuffix}`; } // Ensure the filename has the correct extension const extension = format.toLowerCase(); if (!finalFileName.endsWith(`.${extension}`)) { finalFileName += `.${extension}`; } // Check if file already exists and add a number suffix if needed let finalFilePath = path.join(outputPath, finalFileName); let counter = 1; while (fs.existsSync(finalFilePath)) { const nameWithoutExt = finalFileName.replace(`.${extension}`, ''); const numberedFileName = `${nameWithoutExt}_${counter}.${extension}`; finalFilePath = path.join(outputPath, numberedFileName); counter++; } // Write the image data to the file fs.writeFileSync(finalFilePath, Buffer.from(base64Data, 'base64')); // Add the file path to the result result.filePath = finalFilePath; return result; } catch (error) { log('Error editing image:', error); throw error; } } - src/services/imageSchema.js:114-172 (schema)Schema definition for the editImage tool, defining input properties (prompt, imageUrl, model, seed, width, height, enhance, safe, outputPath, fileName, format) and validation rules.
* Schema for the editImage tool */ export const editImageSchema = { name: 'editImage', description: 'Edit or modify an existing image based on a text prompt. User-configured settings in MCP config will be used as defaults unless specifically overridden.', inputSchema: { type: 'object', properties: { prompt: { type: 'string', description: 'The text description of how to edit the image (e.g., "remove the cat and add a dog", "change background to mountains")' }, imageUrl: { oneOf: [ { type: 'string' }, { type: 'array', items: { type: 'string' } } ], description: 'Public HTTP(S) URL(s) of the input image(s) to edit. Accepts a string or an array for multiple references (first is most important). Local file paths, file uploads, or base64/data URLs are not supported.' }, model: { type: 'string', description: 'Model name to use for editing (default: user config or "kontext"). Available: "kontext", "nanobanana", "seedream"' }, seed: { type: 'number', description: 'Seed for reproducible results (default: random)' }, width: { type: 'number', description: 'Width of the generated image (default: 1024)' }, height: { type: 'number', description: 'Height of the generated image (default: 1024)' }, enhance: { type: 'boolean', description: 'Whether to enhance the prompt using an LLM before generating (default: true)' }, safe: { type: 'boolean', description: 'Whether to apply content filtering (default: false)' }, outputPath: { type: 'string', description: 'Directory path where to save the image (default: user config or "./mcpollinations-output")' }, fileName: { type: 'string', description: 'Name of the file to save (without extension, default: generated from prompt)' }, format: { type: 'string', description: 'Image format to save as (png, jpeg, jpg, webp - default: png)' } }, required: ['prompt', 'imageUrl'] } }; - pollinations-mcp-server.js:363-398 (registration)MCP server registration of the editImage tool handler. Extracts args, calls the editImage function, and formats the response with image data and metadata.
} else if (name === 'editImage') { try { const { prompt, imageUrl, model = 'kontext', seed, width = defaultConfig.image.width, height = defaultConfig.image.height, enhance = defaultConfig.image.enhance, safe = defaultConfig.image.safe, outputPath = defaultConfig.resources.output_dir, fileName = '', format = 'png' } = args; const result = await editImage(prompt, imageUrl, model, seed, width, height, enhance, safe, outputPath, fileName, format, finalAuthConfig); // Prepare the response content const content = [ { type: 'image', data: result.data, mimeType: result.mimeType } ]; // Prepare the response text let responseText = `Edited image from prompt: "${prompt}"\nInput image: ${imageUrl}\n\nImage metadata: ${JSON.stringify(result.metadata, null, 2)}`; // Add file path information if the image was saved to a file if (result.filePath) { responseText += `\n\nImage saved to: ${result.filePath}`; } content.push({ type: 'text', text: responseText }); return { content }; } catch (error) { return { content: [ { type: 'text', text: `Error editing image: ${error.message}` } ], isError: true }; } - src/schemas.js:32-44 (registration)Central registration of all tool schemas, including editImageSchema in the getAllToolSchemas() array used by the MCP server's ListToolsRequestSchema handler.
export function getAllToolSchemas() { return [ generateImageUrlSchema, generateImageSchema, editImageSchema, generateImageFromReferenceSchema, listImageModelsSchema, respondAudioSchema, listAudioVoicesSchema, respondTextSchema, listTextModelsSchema ]; } - src/index.js:8-29 (helper)Re-exports the editImage function from imageService.js as part of the public API of the src library.
import { generateImageUrl, generateImage, editImage, generateImageFromReference, listImageModels } from './services/imageService.js'; import { respondAudio, listAudioVoices } from './services/audioService.js'; import { respondText, listTextModels } from './services/textService.js'; // Export all service functions export { // Image services generateImageUrl, generateImage, editImage, generateImageFromReference, listImageModels, // Audio services respondAudio, listAudioVoices, // Text services respondText, listTextModels, };