> ## Documentation Index
> Fetch the complete documentation index at: https://magica.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Building Workflows

> Use the MCP builder tools to create, edit, and rewire workflows from a conversation.

The workflow builder tools let AI assistants create, edit, and restructure workflows step-by-step. Each tool validates independently, so errors are caught early — your assistant gets a clear error and can self-correct.

***

## Typical build flow

<Steps>
  <Step title="Discover nodes">
    Call `list_node_types` to see available node types and their ports.
  </Step>

  <Step title="Scaffold a workflow">
    Call `create_workflow` to create a workflow with Request and Response nodes.
  </Step>

  <Step title="Add processing nodes">
    Call `add_node` for each model (image generator, LLM, etc.).
  </Step>

  <Step title="Wire it together">
    Call `connect_nodes` to wire outputs to inputs — type-checked automatically.
  </Step>
</Steps>

***

## Editing an existing workflow

Already built a workflow and need to tweak it? Use these tools:

* `update_node` — change input values on an existing node
* `delete_node` — remove a node; all connected edges are cleaned up automatically
* `disconnect_nodes` — remove a single edge (by edge ID or source/target pair)
* `add_node` + `connect_nodes` — rewire the workflow

***

## Examples

Four common patterns. Switch tabs to see each one.

<Tabs>
  <Tab title="Image + Describe">
    Generate an image with Flux, then describe it with a vision LLM.

    ```text theme={null}
    list_node_types(category: "image") → sees flux_2_pro with out:result (image)
    list_node_types(category: "llm") → sees gpt_5_4 with in:image_urls, out:output
    create_workflow("Image + Describe") → gets workflowId + request/response node IDs
    add_node(workflowId, "flux_2_pro") → gets flux node ID + ports
    add_node(workflowId, "gpt_5_4") → gets LLM node ID + ports
    connect_nodes(flux out:result → llm in:image_urls) → validated (image→image)
    connect_nodes(llm out:output → response in:result) → validated (text→any)
    ```
  </Tab>

  <Tab title="Parallel LLMs + Image">
    Run two LLMs in parallel and feed both into an image generator.

    ```text theme={null}
    create_workflow("Parallel LLMs", requestFields: [
      {name: "Cat", type: "text", value: "Cat"},
      {name: "Dog", type: "text", value: "Dog"}
    ])
    add_node(workflowId, "gpt_5_4_mini", column:1, row:0,
      inputs: {system_prompt: "Provide me in 1 line."}) → LLM 1 (top)
    add_node(workflowId, "claude_sonnet_4_6", column:1, row:1,
      inputs: {system_prompt: "Provide me in 1 line."}) → LLM 2 (bottom)
    add_node(workflowId, "nano_banana_pro", column:2, row:0) → image gen
    connect_nodes(request field_cat → llm1 in:prompt)
    connect_nodes(request field_dog → llm2 in:prompt)
    connect_nodes(llm1 out:output → nano in:prompt)
    connect_nodes(nano out:result → response result)
    connect_nodes(llm1 out:output → response result)
    connect_nodes(llm2 out:output → response result)
    ```

    Nodes in the same column (column 1: both LLMs) are placed in parallel — stacked vertically by row.
  </Tab>

  <Tab title="System Template">
    Run a saved system-workflow template by name — no building needed.

    ```text theme={null}
    start_run(workflowName: "Nano Banana Pro", values: {
      prompt: "Add a dog to the scene",
      image_url: "https://example.com/photo.jpg"
    })
    → Fuzzy-matches user workflows first, then system templates.
    → Returns a runId. Use get_run_status(runId) to long-poll for the result.
    ```

    `start_run` validates Request Node fields automatically. If you call it without `values`, it returns the field schema instead — call again with values filled in.
  </Tab>

  <Tab title="Direct Generation">
    Quick single-model task — no workflow, no template.

    ```text theme={null}
    search_tools(query: "image") → sees flux_2_pro, nano_banana_pro, etc.
    get_model_schema(modelId: "flux_2_pro") → input field schema
    execute_tool({
      tool_name: "generate",
      input: { modelId: "flux_2_pro", prompt: "A red Ferrari" }
    }) → returns runId
    get_run_status(runId) → long-polls until COMPLETED
    ```

    Prefer this over building a workflow for single-step generation. Workflows are for reusable multi-step pipelines.
  </Tab>
</Tabs>

***

<Info>
  Port names returned by `add_node` and `list_node_types` use the `in:` / `out:`
  prefix format expected by `connect_nodes`. The `connect_nodes` tool validates
  type compatibility (e.g. image→image), prevents cycles, and enforces
  single-input rules. Use `disconnect_nodes` to remove a connection, or
  `delete_node` to remove a node along with all its connections.
</Info>
