generate_variations
Generate multiple versions of a text prompt by varying the seed to explore different outcomes and select the best result.
Instructions
Generate multiple variations of the same prompt by varying the seed. Useful for picking the best result or exploring a concept.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | Text prompt for the base image | |
| count | No | Number of variations to generate | |
| negative_prompt | No | ||
| width | No | ||
| height | No | ||
| steps | No | ||
| cfg | No | ||
| base_seed | No | Starting seed; subsequent variations use base_seed + i | |
| checkpoint | No |
Implementation Reference
- src/tools/generate.ts:103-130 (handler)The 'generate_variations' tool handler. Generates multiple image variations by calling client.generate() with different seeds (base_seed + i). Uses Promise.all to run all variations concurrently. Returns image URLs from ComfyUI.
server.tool( "generate_variations", "Generate multiple variations of the same prompt by varying the seed. Useful for picking the best result or exploring a concept.", generateVariationsSchema, async (args) => { const startSeed = args.base_seed ?? Math.floor(Math.random() * 2 ** 32); const results = await Promise.all( Array.from({ length: args.count }, (_, i) => client.generate({ prompt: args.prompt, negativePrompt: args.negative_prompt, width: args.width, height: args.height, steps: args.steps, cfg: args.cfg, seed: startSeed + i, checkpoint: args.checkpoint, }), ), ); const urls = results.flatMap((r) => r.images); return textResult( `Generated ${args.count} variation(s) starting from seed ${startSeed}:`, urls, ); }, ); - src/tools/generate.ts:46-66 (schema)Zod schema for 'generate_variations' input validation. Defines prompt, count (2-16, default 4), negative_prompt, width, height, steps, cfg, base_seed, and checkpoint.
const generateVariationsSchema = { prompt: z.string().min(1).describe("Text prompt for the base image"), count: z .number() .int() .min(2) .max(16) .default(4) .describe("Number of variations to generate"), negative_prompt: z.string().optional(), width: z.number().int().min(64).max(2048).default(1024), height: z.number().int().min(64).max(2048).default(1024), steps: z.number().int().min(1).max(150).default(25), cfg: z.number().min(1).max(30).default(7), base_seed: z .number() .int() .optional() .describe("Starting seed; subsequent variations use base_seed + i"), checkpoint: z.string().optional(), }; - src/tools/generate.ts:76-145 (registration)The registerGenerateTools() function registers all generate tools (including 'generate_variations') on the McpServer via server.tool(). Called from src/server.ts line 42.
export function registerGenerateTools( server: McpServer, client: ComfyUIClient, ): void { server.tool( "generate_image", "Generate an image from a text prompt using ComfyUI's default txt2img workflow. Returns one or more image URLs served directly by the ComfyUI instance.", generateImageSchema, async (args) => { const result = await client.generate({ prompt: args.prompt, negativePrompt: args.negative_prompt, width: args.width, height: args.height, steps: args.steps, cfg: args.cfg, seed: args.seed, checkpoint: args.checkpoint, }); return textResult( `Generated ${result.images.length} image(s) (prompt_id: ${result.promptId}):`, result.images, ); }, ); server.tool( "generate_variations", "Generate multiple variations of the same prompt by varying the seed. Useful for picking the best result or exploring a concept.", generateVariationsSchema, async (args) => { const startSeed = args.base_seed ?? Math.floor(Math.random() * 2 ** 32); const results = await Promise.all( Array.from({ length: args.count }, (_, i) => client.generate({ prompt: args.prompt, negativePrompt: args.negative_prompt, width: args.width, height: args.height, steps: args.steps, cfg: args.cfg, seed: startSeed + i, checkpoint: args.checkpoint, }), ), ); const urls = results.flatMap((r) => r.images); return textResult( `Generated ${args.count} variation(s) starting from seed ${startSeed}:`, urls, ); }, ); server.tool( "generate_with_workflow", "Submit an arbitrary ComfyUI workflow (full node graph) and return the resulting image URLs. Use this when you need a custom workflow like ControlNet, upscaling, or a node graph exported from ComfyUI's 'Save (API Format)'.", generateWithWorkflowSchema, async (args) => { const workflow = args.workflow as Workflow; const result = await client.runWorkflow(workflow); return textResult( `Workflow submitted (prompt_id: ${result.promptId}), ${result.images.length} image(s):`, result.images, ); }, ); } - src/comfyui/client.ts:47-59 (helper)The ComfyUIClient.generate() helper that each variation call invokes. It creates a txt2img workflow and runs it via runWorkflow().
async generate(params: GenerateParams): Promise<GenerateResult> { const workflow = txt2img({ prompt: params.prompt, negativePrompt: params.negativePrompt ?? "", width: params.width ?? 1024, height: params.height ?? 1024, steps: params.steps ?? 25, cfg: params.cfg ?? 7, seed: params.seed ?? Math.floor(Math.random() * 2 ** 32), checkpoint: params.checkpoint ?? DEFAULT_CHECKPOINT, }); return this.runWorkflow(workflow); } - src/comfyui/workflows.ts:30-72 (helper)The txt2img() workflow builder that constructs the ComfyUI node graph used by generate_variations.
export function txt2img(params: Txt2ImgParams): Workflow { return { "3": { class_type: "KSampler", inputs: { seed: params.seed, steps: params.steps, cfg: params.cfg, sampler_name: "euler", scheduler: "normal", denoise: 1, model: ["4", 0], positive: ["6", 0], negative: ["7", 0], latent_image: ["5", 0], }, }, "4": { class_type: "CheckpointLoaderSimple", inputs: { ckpt_name: params.checkpoint }, }, "5": { class_type: "EmptyLatentImage", inputs: { width: params.width, height: params.height, batch_size: 1 }, }, "6": { class_type: "CLIPTextEncode", inputs: { text: params.prompt, clip: ["4", 1] }, }, "7": { class_type: "CLIPTextEncode", inputs: { text: params.negativePrompt, clip: ["4", 1] }, }, "8": { class_type: "VAEDecode", inputs: { samples: ["3", 0], vae: ["4", 2] }, }, "9": { class_type: "SaveImage", inputs: { filename_prefix: "comfyui-mcp", images: ["8", 0] }, }, }; }