# How to Develop Multi-Step Workflow Skills with Conditional Logic in Claude

> Develop multi-step Claude workflow skills with conditional logic. Master branching loops using natural language conditionals variable assignment tool hints and if else blocks for step by step execution.

- Repository: [Composio/awesome-claude-skills](https://github.com/composiohq/awesome-claude-skills)
- Tags: how-to-guide
- Published: 2026-07-26

---

**Build Claude skills that branch and loop by writing natural-language conditionals inside SKILL.md files, using variable assignment, idempotent tool hints, and explicit if/else blocks that the model executes as step-by-step instructions.**

ComposioHQ’s `awesome-claude-skills` repository provides a framework for packaging Claude capabilities as reusable skills. To develop multi-step workflow skills with conditional logic, you write instructional markdown that Claude interprets as an execution plan, combining tool definitions in JSON with human-readable control flow statements.

## Architecture of a Conditional Workflow Skill

A skill that supports branching execution consists of four distinct layers stored in the skill directory.

**Skill Metadata** ([`SKILL.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/SKILL.md) frontmatter) declares the skill name, description, and required tools. The `requires` field can list optional tools; their presence or absence serves as a boolean condition for later branches.

**Tool Definitions** (JSON configurations) describe each external API or CLI Claude may invoke. According to [`mcp-builder/reference/python_mcp_server.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/mcp-builder/reference/python_mcp_server.md), tools accept `idempotentHint` and `openWorldHint` booleans that inform the model whether a call can be safely retried or requires external knowledge.

**Workflow Instructions** (the body of [`SKILL.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/SKILL.md)) provide the execution script. Unlike imperative code, this is natural-language prose containing **branching blocks** (`If … then … else …`) and **loop constructs** (`While …`). Claude scans these instructions to determine the highest-scoring next step based on current context.

**Reference Files** (`reference/*.md`) store large static resources like JSON schemas. Conditional steps can include these only when needed, keeping the active prompt window small.

## Implementing Conditional Logic in SKILL.md

Claude parses the markdown as instructional prose, not code, so conditionals must be explicit and unambiguous.

### Branching with Natural-Language If-Else

Write branches using bold keywords and backtick variables.

```markdown
- **If** `user_input.file` is present **then**  
  - `upload = file_upload(user_input.file)`  
  - Respond: "File uploaded successfully."  
- **Else**  
  - Ask: "Please attach the file you'd like me to process."

```

The model evaluates the condition by checking the bound variables in its working memory. If the condition evaluates true, it executes the indented sub-steps; otherwise, it jumps to the **Else** block.

### Variable Assignment and State Management

Create variables by wrapping tool calls or literals in backticks. This binds the result to a name you can reference in subsequent conditions.

```markdown
- `page = http_fetch(url)`  
- **If** `page` contains "Error 404" **then**  
  - Respond: "The page was not found."  
  - **Goto** Step 1

```

Variables persist across steps, allowing you to build state machines where the value of `attempt` or `success` determines the next branch.

### Looping and Retry Logic

Implement loops using **While** guards that combine Boolean conditions.

```markdown
- `attempt = 0`  
- **While** `attempt < 3` **and** not `sent`  
  - `sent = email_send(to, subject, body)`  
  - **If** not `sent` **then**  
    - `attempt = attempt + 1`  
    - `sleep(2)`  
- **If** `sent` **then**  
  - Respond: "Email sent!"  
- **Else**  
  - Respond: "Failed after 3 attempts."

```

As documented in [`skill-creator/SKILL.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/skill-creator/SKILL.md), the **Goto** keyword redirects execution to a labeled step, enabling you to restart a workflow or skip sections without deep nesting.

### Configuring Tool Hints for Safe Branching

When a tool is safe to call multiple times (e.g., a GET request), set `idempotentHint: true` in its JSON definition. This allows Claude to retry the tool inside loops without fear of side-effects. For tools that reach live external systems, set `openWorldHint: true` so the model treats the step as a discovery operation. These hints are defined in [`mcp-builder/reference/python_mcp_server.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/mcp-builder/reference/python_mcp_server.md) and consumed by the planner in [`mcp-builder/SKILL.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/mcp-builder/SKILL.md).

## Complete SKILL.md Template for Multi-Step Workflows

Below is a minimal skeleton you can copy from [`template-skill/SKILL.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/template-skill/SKILL.md) and adapt for conditional workflows.

```markdown

# My Conditional Skill

description: "Example skill that demonstrates conditional branching and loops."
requires:
  - http_fetch
  - optional: report_generator

workflow:
  - **Step 1 – Gather input**  
    Ask the user for a URL (`url`).

  - **Step 2 – Validate input**  
    **If** `url` is empty **then**  
      - Prompt: "Please provide a valid URL."  
      - **Goto** Step 1  
    **Else**  
      - **Goto** Step 3

  - **Step 3 – Fetch the page**  
    `page = http_fetch(url)`

  - **Step 4 – Check for errors**  
    **If** `page` contains "Error 404" **then**  
      - Respond: "The page was not found. Try another URL."  
      - **Goto** Step 1  
    **Else**  
      - **Goto** Step 5

  - **Step 5 – Process the content**  
    Extract the title with a regex.

  - **Step 6 – Optional extra step**  
    **If** the title includes the word "Report" **then**  
      - Call the `report_generator` tool.  
    **Else**  
      - Return the title to the user.

  - **Step 7 – Completion**  
    Summarise what was done and finish.

```

## Practical Code Examples

### Conditional Tool Invocation

Check a boolean flag before invoking an expensive operation.

```markdown
- **If** `needs_summary` is true **then**  
  - `summary = summarizer(text)`  
  - Return `summary`  
- **Else**  
  - Return the original `text`

```

### Input Validation Branch

Route the workflow based on file presence.

```markdown
- **If** `user_input.file` is present **then**  
  - `upload = file_upload(user_input.file)`  
- **Else**  
  - Ask: "Please attach the file."

```

### Retry With Idempotent Safety

Leverage the `idempotentHint` to safely repeat a network call.

```markdown
- `attempt = 0`  
- **While** `attempt < 3` **and** not `success`  
  - `success = api_call(endpoint)`  
  - **If** not `success` **then** `attempt = attempt + 1`

```

## Best Practices for Production Skills

Keep each atomic step limited to a single action (fetch, then check). This improves reliability when Claude backtracks. Use explicit variable names like `page_content` rather than `result` to reduce ambiguity in condition evaluation.

Limit prompt size by moving large JSON schemas into separate files under `reference/` and including them only when the condition requires. As noted in [`skill-share/SKILL.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/skill-share/SKILL.md), versioning your skill allows downstream users to inspect the conditional logic without parsing the entire instruction set.

Test each branch independently by simulating inputs that trigger the **Else** path and the **While** exit condition before publishing.

## Summary

- **Structure**: Package conditional workflows in [`SKILL.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/SKILL.md) using metadata headers, tool definitions, and natural-language instructions.
- **Syntax**: Use bold **If**, **Then**, **Else**, and **While** keywords with backtick variables for branching and looping.
- **Safety**: Configure `idempotentHint` and `openWorldHint` in tool JSON to control retry behavior inside loops.
- **State**: Assign results to variables (`page = http_fetch(url)`) and reference them in subsequent conditions.
- **References**: Offload large schemas to `reference/*.md` files to avoid context window overflow.

## Frequently Asked Questions

### How does Claude evaluate conditions in a SKILL.md file?

Claude treats the markdown as an instruction manual. When it encounters a line starting with **If**, it evaluates the backtick variable against the condition using its reasoning engine, then selects the indented block beneath **then** or **Else** based on the outcome. This process is documented in [`skill-creator/SKILL.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/skill-creator/SKILL.md) as "instructional prose parsing."

### Can I nest conditional blocks inside loops?

Yes. Indent sub-steps beneath a parent **If** or **While** to create nested scopes. Ensure you maintain consistent indentation (two spaces or four spaces) so Claude recognizes the hierarchy. Variables assigned inside a loop remain available in the outer scope after the loop terminates.

### What is the difference between `idempotentHint` and `openWorldHint`?

`idempotentHint: true` tells Claude that calling the tool multiple times produces the same result as calling it once, making it safe for retry loops. `openWorldHint: true` signals that the tool accesses external live systems that the model cannot fully predict, prompting Claude to treat the step as a discovery action. Both are defined in [`mcp-builder/reference/python_mcp_server.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/mcp-builder/reference/python_mcp_server.md).

### Where should I store complex conditional logic to keep the main file readable?

Move large schemas, API response examples, or detailed regex patterns into separate markdown files under a `reference/` directory. Use conditional includes (or simply reference them by name in a step) to load this content only when a specific branch requires it, following the pattern established in [`template-skill/SKILL.md`](https://github.com/ComposioHQ/awesome-claude-skills/blob/main/template-skill/SKILL.md).