generate_with_workflow
Submit a ComfyUI workflow JSON to generate images. Returns image URLs for custom node graphs like ControlNet or upscaling.
Instructions
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)'.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| workflow | Yes | Complete ComfyUI workflow JSON (node graph as returned by ComfyUI's 'Save (API Format)' export) |
Implementation Reference
- src/tools/generate.ts:68-74 (schema)Zod schema for generate_with_workflow: accepts a 'workflow' field which is a record of strings to any (the complete ComfyUI workflow JSON node graph).
const generateWithWorkflowSchema = { workflow: z .record(z.string(), z.any()) .describe( "Complete ComfyUI workflow JSON (node graph as returned by ComfyUI's 'Save (API Format)' export)", ), }; - src/tools/generate.ts:132-144 (handler)Handler for generate_with_workflow tool. Casts args.workflow to Workflow type, calls client.runWorkflow(workflow), and returns image URLs with prompt_id.
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/tools/generate.ts:76-144 (registration)The registerGenerateTools function (line 76) registers all generate tools including generate_with_workflow (line 132-144) via server.tool(). It is called from 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:61-68 (helper)The runWorkflow method on ComfyUIClient that generate_with_workflow's handler calls. Submits the workflow via HTTP POST to /prompt, then polls /history until completion, extracting image URLs.
async runWorkflow(workflow: Workflow): Promise<GenerateResult> { const { prompt_id } = await this.submit(workflow); const entry = await this.waitForCompletion(prompt_id); return { promptId: prompt_id, images: extractImageUrls(entry, this.publicUrl), }; }