| name | vibecanvas-image-generate |
| description | Generate fresh images on the VibeCanvas canvas using the OpenAI-compatible Image 2 API. Use when the user asks to create, produce, draft, imagine, or render a brand-new image (not edit an existing one). Covers single-shot generation, multi-candidate generation, and Prompt Architect-driven brief expansion. |
| license | MIT |
| compatibility | opencode, zcode, mcp |
| metadata | {"product":"vibecanvas","role":"image-generation","protocol":"2.0"} |
VibeCanvas Image Generate
Use this skill when the user wants to create a new image from scratch — text-to-image, multi-candidate generation, or expanding a short brief into a polished prompt. For modifying an existing image (source/reference/mask/annotation), route to vibecanvas-image-edit.
Preconditions
- The VibeCanvas service is registered as MCP. Verify with
get_workspace_context {}. If it errors, ask the user to run install-skills and restart the session.
- An image provider is configured. Call
get_provider_capabilities {}. Read configured — if false, the provider token is missing and generation will fail at run time. Tell the user to set IMAGE_API_KEY (or edit the provider profile via the Web UI's Provider panel) before continuing.
- Read the candidate limits. From the same capabilities response, note
maxCandidates and the capabilities object (e.g. batchN, customSize). Don't request a candidateCount higher than maxCandidates.
Workflow
-
Inspect the current selection.
get_selection_context {}.
- If the user pointed at an existing
input.brief node, read its config.text — that's the creative brief.
- If the user pointed at an
agent.prompt-architect node, they've already authored the prompt spec; skip to step 4.
-
Ensure a brief exists.
- If no brief is selected and the user gave you text, create one with a patch:
{ "op": "addNode", "node": { "id": "node-brief-01", "type": "workflow", "position": { "x": 80, "y": 200 }, "data": { "nodeType": "input.brief", "config": { "text": "<the brief>" }, "status":
Prompt design (when authoring PromptSpec directly)
If you're feeding image.generate.prompt without going through agent.prompt-architect (e.g. via updateNode with a hand-written spec), use this shape:
{
"subject": "Concise subject line (<= 160 chars)",
"purpose": "What the image is for",
"composition": "Framing, perspective, hierarchy",
"lighting": "Direction, quality, color temperature",
"materials": ["..."],
"palette": ["..."],
"style": " Photorealistic / editorial / illustration / ...",
"avoid": ["watermarks", "editor chrome", "annotation arrows", "garbled text"],
"finalPrompt": "The actual prompt sent to the image model — combine everything above into one coherent prompt."
}
Only subject and finalPrompt are required; other fields guide the LLM when agent.prompt-architect runs.
Notes
image.generate writes the generated images as candidate Artifacts under .vibecanvas/artifacts/. Their parentArtifactIds point at any reference images used.
- Provider billing accrues per request, even on cancellation. If the user cancels mid-generation,
cancel_run { runId } propagates an AbortController to the in-flight HTTP request, but the provider may still charge for compute already started.
- For aspect ratios, prefer the
utility.aspect-ratio node over hard-coding { width, height } in image.generate.config — the utility node emits a typed AspectRatio value that the runner normalizes to the provider's supported sizes.
- If the user wants the same prompt at multiple sizes, build parallel
image.generate nodes fed by one agent.prompt-architect; don't try to fan out inside a single node.
See references/provider-contract.md for provider profile details.