generateImage
Create custom images from text descriptions using AI. Specify prompts, dimensions, and parameters to generate visual content.
Instructions
Generate an image based on a prompt
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | No | ||
| negative_prompt | No | ||
| width | No | ||
| height | No | ||
| steps | No | ||
| seed | No | ||
| guidance_scale | No | ||
| random_string | No |
Implementation Reference
- Core handler function that validates input parameters, merges with defaults, calls Draw Things API for txt2img generation, saves the image to disk, and returns formatted result or error.async generateImage( inputParams: Partial<ImageGenerationParams> = {} ): Promise<DrawThingsGenerationResult> { try { // handle input params let params: Partial<ImageGenerationParams> = {}; // validate params try { const validationResult = validateImageGenerationParams(inputParams); if (validationResult.valid) { params = inputParams; } else { console.error("parameter validation failed, use default params"); } } catch (error) { console.error("parameter validation error:", error); } // handle random_string special case if ( params.random_string && (!params.prompt || Object.keys(params).length === 1) ) { params.prompt = params.random_string; delete params.random_string; } // ensure prompt if (!params.prompt) { params.prompt = inputParams.prompt || defaultParams.prompt; } // merge params const requestParams = { ...defaultParams, ...params, seed: params.seed ?? Math.floor(Math.random() * 2147483647), }; console.error(`use prompt: "${requestParams.prompt}"`); // send request to Draw Things API console.error("send request to Draw Things API..."); const response = await this.axios.post( "/sdapi/v1/txt2img", requestParams ); // handle response if ( !response.data || !response.data.images || response.data.images.length === 0 ) { throw new Error("API did not return image data"); } // handle image data const imageData = response.data.images[0]; // format image data const formattedImageData = imageData.startsWith("data:image/") ? imageData : `data:image/png;base64,${imageData}`; console.error("image generation success"); // record the start time of image generation const startTime = Date.now() - 2000; // assume the image generation took 2 seconds const endTime = Date.now(); // automatically save the generated image const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); const defaultFileName = `generated-image-${timestamp}.png`; // save the generated image const imagePath = await this.saveImage({ base64Data: formattedImageData, fileName: defaultFileName }); return { isError: false, imageData: formattedImageData, imagePath: imagePath, metadata: { alt: `Image generated from prompt: ${requestParams.prompt}`, inference_time_ms: endTime - startTime, } }; } catch (error) { console.error("image generation error:", error); // error message let errorMessage = "unknown error"; if (error instanceof Error) { errorMessage = error.message; } // handle axios error const axiosError = error as any; if (axiosError.response) { errorMessage = `API error: ${axiosError.response.status} - ${ axiosError.response.data?.error || axiosError.message }`; } else if (axiosError.code === "ECONNREFUSED") { errorMessage = "cannot connect to Draw Things API. please ensure Draw Things is running and API is enabled."; } else if (axiosError.code === "ETIMEDOUT") { errorMessage = "connection to Draw Things API timeout. image generation may take longer, or API not responding."; } return { isError: true, errorMessage, }; } }
- src/index.ts:155-233 (registration)MCP server.tool registration for 'generateImage', defines Zod input schema, handles MCP params, delegates to service handler, and returns standardized MCP content response.server.tool( "generateImage", "Generate an image based on a prompt", paramsSchema, async (mcpParams: any) => { try { log("Received image generation request"); log(`mcpParams====== ${JSON.stringify(mcpParams)}`); // handle ai prompts const parameters = mcpParams?.params?.arguments || mcpParams?.arguments || mcpParams || {}; if (parameters.prompt) { log(`Using provided prompt: ${parameters.prompt}`); } else { log("No prompt provided, using default"); parameters.prompt = "A cute dog"; } // Generate image const result: ImageGenerationResult = await drawThingsService.generateImage(parameters); // Handle generation result if (result.isError) { log(`Error generating image: ${result.errorMessage}`); throw new Error(result.errorMessage || "Unknown error"); } if (!result.imageData && (!result.images || result.images.length === 0)) { log("No image data returned from generation"); throw new Error("No image data returned from generation"); } const imageData = result.imageData || (result.images && result.images.length > 0 ? result.images[0] : undefined); if (!imageData) { log("No valid image data available"); throw new Error("No valid image data available"); } log("Successfully generated image, returning directly via MCP"); // calculate the difference between the start and end time (example value) const startTime = Date.now() - 2000; // assume the image generation took 2 seconds const endTime = Date.now(); // build the response format const responseData = { image_paths: result.imagePath ? [result.imagePath] : [], metadata: { alt: `Image generated from prompt: ${parameters.prompt}`, inference_time_ms: result.metadata?.inference_time_ms || endTime - startTime, }, }; return { content: [ { type: "text", text: JSON.stringify(responseData, null, 2), }, ], }; } catch (error) { log( `Error handling image generation: ${ error instanceof Error ? error.message : String(error) }` ); await logError(error); throw error; } } );
- src/services/schemas.ts:6-29 (schema)TypeScript interface defining the input parameters for image generation, used for type safety in the handler.export interface ImageGenerationParams { // basic params prompt?: string; negative_prompt?: string; // size params width?: number; height?: number; // generate control params steps?: number; seed?: number; guidance_scale?: number; // model params model?: string; sampler?: string; // MCP special params random_string?: string; // allow other params [key: string]: any; }
- src/index.ts:144-153 (schema)Zod schema for input validation in the MCP tool registration.const paramsSchema = { prompt: z.string().optional(), negative_prompt: z.string().optional(), width: z.number().optional(), height: z.number().optional(), steps: z.number().optional(), seed: z.number().optional(), guidance_scale: z.number().optional(), random_string: z.string().optional(), };
- src/services/defaultParams.ts:4-71 (helper)Default parameters used by the handler when user params are incomplete.export const defaultParams: ImageGenerationParams = { speed_up_with_guidance_embed: true, motion_scale: 127, image_guidance: 1.5, tiled_decoding: false, decoding_tile_height: 640, negative_prompt_for_image_prior: true, batch_size: 1, decoding_tile_overlap: 128, separate_open_clip_g: false, hires_fix_height: 960, decoding_tile_width: 640, diffusion_tile_height: 1024, num_frames: 14, stage_2_guidance: 1, t5_text_encoder_decoding: true, mask_blur_outset: 0, resolution_dependent_shift: true, model: "flux_1_schnell_q5p.ckpt", hires_fix: false, strength: 1, loras: [], diffusion_tile_width: 1024, diffusion_tile_overlap: 128, original_width: 512, seed: -1, zero_negative_prompt: false, upscaler_scale: 0, steps: 8, upscaler: null, mask_blur: 1.5, sampler: "DPM++ 2M AYS", width: 320, negative_original_width: 512, batch_count: 1, refiner_model: null, shift: 1, stage_2_shift: 1, open_clip_g_text: null, crop_left: 0, controls: [], start_frame_guidance: 1, original_height: 512, image_prior_steps: 5, guiding_frame_noise: 0.019999999552965164, clip_weight: 1, clip_skip: 1, crop_top: 0, negative_original_height: 512, preserve_original_after_inpaint: true, separate_clip_l: false, guidance_embed: 3.5, negative_aesthetic_score: 2.5, aesthetic_score: 6, clip_l_text: null, hires_fix_strength: 0.699999988079071, guidance_scale: 7.5, stochastic_sampling_gamma: 0.3, seed_mode: "Scale Alike", target_width: 512, hires_fix_width: 960, tiled_diffusion: false, fps: 5, refiner_start: 0.8500000238418579, height: 512, prompt: "A cute koala sitting on a eucalyptus tree, watercolor style, beautiful lighting, detailed", negative_prompt: "deformed, distorted, unnatural pose, extra limbs, blurry, low quality, ugly, bad anatomy, poor details, mutated, text, watermark" };