# How to Create Orchestration Skills that Coordinate Sub-Skills in Claude Plugins

> Learn to create orchestration skills that coordinate sub-skills in Claude Plugins. Build multi-step workflows, manage data flow, and handle user interactions efficiently.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: how-to-guide
- Published: 2026-09-13

---

**Orchestration skills act as a "conductor" for multi-step workflows, sequencing existing sub-skills via Claude's Message-Calling-Protocol (MCP), handling data flow between steps, and managing user interactions without containing domain-specific logic.**

The Claude Plugins Community repository demonstrates a battle-tested architectural pattern for building orchestration skills that delegate specialized work to sub-skills while maintaining clean separation of concerns. Rather than embedding low-level business logic, orchestrators contain only glue code to parse MCP payloads, invoke sub-skills, and coordinate execution sequences, making complex workflows modular and maintainable.

## Minimal Core Logic and the Conductor Pattern

Effective orchestration skills follow the **conductor pattern**: they contain no domain-specific processing logic, only the coordination code necessary to sequence sub-skills and pass data forward. As implemented in the TRES Finance plugin's onboarding skill, the orchestrator "does not contain its own low-level logic – instead, it drives the user through 8 sequential steps, invoking the dedicated skill for each one" ([`tres-finance-plugin/skills/tres-onboarding/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-onboarding/SKILL.md)).

This architectural constraint ensures that:
- **Domain logic remains encapsulated** in specialized sub-skills
- **Orchestration stays testable** with minimal mocking requirements
- **Workflows remain flexible** as steps can be rearranged without rewriting business logic

## MCP-Driven Invocation and Data Flow

Each sub-skill invocation occurs through Claude's **Message-Calling-Protocol (MCP)**. The orchestrator prepares JSON payloads representing the MCP request, delegates execution to Claude, then parses the response to extract data for subsequent steps.

In [`tres-finance-plugin/skills/tres-asc845-swap-reprice-skill/scripts/orchestrate_reprice.py`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-asc845-swap-reprice-skill/scripts/orchestrate_reprice.py), the orchestrator handles the full MCP lifecycle: parsing the JSON response, filtering data, creating a human-readable preview, and writing a mutation plan for the next execution step. This pattern appears in lines 14-27 and 38-48, where the script processes raw subtransaction data before forwarding it to domain-specific helpers.

```python
#!/usr/bin/env python3
"""
General pattern for an orchestration skill.
1️⃣ Parse MCP JSON input.
2️⃣ Optionally filter / configure.
3️⃣ Call a low-level sub-skill (via an imported helper).
4️⃣ Print a preview for the user.
5️⃣ Write a machine-readable plan + mutation list.
"""
import argparse, json, sys
from reprice_swaps import build_reprice_plan, print_preview   # ← reusable logic

def main():
    parser = argparse.ArgumentParser(description="Example orchestrator")
    parser.add_argument("--input", "-i", required=True, help="MCP JSON input")
    parser.add_argument("--output", "-o", default="plan.json")
    parser.add_argument("--mutations-output", default="mutations.json")
    args = parser.parse_args()

    # 1️⃣ Load MCP payload

    with open(args.input) as f:
        raw = json.load(f)

    # 2️⃣ Normalise to a list of subtransactions

    subtxs = raw.get("data", {}).get("subTransaction", {}).get("results", [])
    
    # 3️⃣ Build the domain-specific plan

    plan = build_reprice_plan(subtransactions=subtxs)
    
    # 4️⃣ Show preview

    print_preview(plan)

    # 5️⃣ Persist plan & mutations

    with open(args.output, "w") as f:
        json.dump(plan, f, indent=2)

if __name__ == "__main__":
    main()

```

## Standardized Input/Output Contracts

Orchestration scripts maintain strict contracts for data exchange. They accept a well-defined input file (typically the raw MCP JSON) and emit two distinct artifacts:

- **Human-readable preview**: A formatted summary for user confirmation
- **Machine-readable plan**: A JSON structure consumed by downstream mutation runners

The [`orchestrate_reprice.py`](https://github.com/anthropics/claude-plugins-community/blob/main/orchestrate_reprice.py) script demonstrates this dual-output pattern in lines 92-100, where `--output` writes the reprice plan and `--mutations-output` writes the ready-to-execute mutation list. This separation allows Claude to present results to users while simultaneously preparing structured data for automated execution.

```python
def generate_execution_script(plan, out_path):
    """Create a JSON file with mutation details Claude can execute."""
    execution = {
        "summary": plan["summary"],
        "mutation_template": {
            "query": """mutation SetManualFiatValue($id: ID!, $newFiatValue: String!, $currency: String) {
  setManualFiatValue(id: $id, newFiatValue: $newFiatValue, currency: $currency) {
    subTransaction { id fiatValue isManualFiatValue }
  }
}""",
            "note": "Execute one per inflow subtransaction."
        },
        "mutations": [
            {
                "variables": {
                    "id": m["subtx_id"],
                    "newFiatValue": m["new_fiat_value"],
                    "currency": m["currency"],
                },
                "description": f"Reprice subtx {m['subtx_id']}"
            }
            for m in plan.get("mutations", [])
        ],
        "total_mutations": len(plan.get("mutations", [])),
    }
    with open(out_path, "w") as f:
        json.dump(execution, f, indent=2)
    return execution

```

## Filtering and Configuration Pass-Through

Orchestration skills expose command-line flags that narrow workflow scope without implementing filtering logic themselves. These flags are parsed and forwarded directly to the sub-skills performing the computation.

In the ASC-845 reprice orchestrator, flags like `--account-name`, `--activity-tags`, and `--currency` are defined in the argument parser and passed to `build_reprice_plan` ([`tres-finance-plugin/skills/tres-asc845-swap-reprice-skill/scripts/orchestrate_reprice.py`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-asc845-swap-reprice-skill/scripts/orchestrate_reprice.py), lines 98-104). This allows users to constrain operations while keeping the orchestrator agnostic of filtering implementation details.

```python
parser.add_argument("--account-name", help="Filter by account")
parser.add_argument("--currency", default="usd")
args = parser.parse_args()

# Forward configuration to sub-skill

plan = build_reprice_plan(
    subtransactions=subtxs,
    target_name=args.account_name,
    currency=args.currency,
)

```

## Progressive Roadmap Presentation for Users

User-facing orchestrators (such as the onboarding workflow) implement **progressive disclosure** by confirming intent, gathering context, then displaying a plain-text roadmap before execution begins. The roadmap enumerates the sequence of sub-skills that will run, setting clear expectations.

According to [`tres-onboarding/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-onboarding/SKILL.md) (lines 47-61), the orchestrator prints a structured roadmap like:

```

Here's the onboarding roadmap for Acme Corp:

1. Upload Wallets — Add on-chain wallets and/or exchange accounts
2. Data Collection (Commit) — Pull on-chain data for the uploaded wallets
3. Validate Balances — Cross-check TRES balances against on-chain sources
4. Reconciliation — Review and resolve any balance gaps
5. Cost Basis — Configure and run cost basis calculation
6. Export Unidentified Addresses — Extract 3rd-party addresses
7. Import Contacts — Label and import the identified addresses
8. Rollup Rules — Set up transaction aggregation for high-volume wallets

```

This pattern ensures users understand the multi-step commitment before the orchestrator begins invoking sub-skills via MCP calls.

## Resumability and Step Tracking

Because each step executes as a separate sub-skill invocation, orchestrators can pause after any step and resume from the next incomplete step later. The onboarding skill ([`tres-onboarding/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-onboarding/SKILL.md), lines 92-98) explicitly defines resumability mechanisms by tracking the last completed step in state, allowing workflows to survive interruptions without restarting from step one.

This architecture requires:
- **State persistence** between steps (storing the last completed step index)
- **Idempotent sub-skills** that can be safely re-invoked if needed
- **Conditional logic** in the orchestrator to skip already-completed steps

## Reusable Utilities and Helper Modules

Common helper functions (mutation batching, JSON formatting, data transformation) are extracted into separate modules and imported by orchestrators. The [`orchestrate_reprice.py`](https://github.com/anthropics/claude-plugins-community/blob/main/orchestrate_reprice.py) script imports `build_reprice_plan` and `print_preview` from [`reprice_swaps.py`](https://github.com/anthropics/claude-plugins-community/blob/main/reprice_swaps.py) (lines 32-34), demonstrating how domain logic remains in specialized modules while orchestrators focus on coordination.

This separation enables:
- **Code reuse** across multiple orchestrators requiring similar transformations
- **Independent testing** of business logic without MCP infrastructure
- **Easier maintenance** as fixes to helper functions propagate to all dependent orchestrators

## Summary

- **Orchestration skills contain only glue code** to sequence sub-skills and manage data flow, delegating all domain logic to specialized sub-skills
- **MCP-driven invocation** allows orchestrators to trigger sub-skills via JSON payloads and parse responses for subsequent steps
- **Standardized contracts** require orchestrators to produce both human-readable previews and machine-readable execution plans
- **Configuration pass-through** enables user-defined filters (`--account-name`, `--currency`) to narrow scope without bloating orchestrator logic
- **Resumability** is inherent to the architecture because discrete sub-skill invocations allow workflows to pause and resume at step boundaries
- **Helper modules** encourage code reuse across orchestrators while keeping the conductor layer thin and testable

## Frequently Asked Questions

### What is the primary responsibility of an orchestration skill?

An orchestration skill acts as a workflow conductor that sequences sub-skills, manages data handoffs between steps, and handles user interaction. According to the Claude Plugins Community patterns, it should never contain domain-specific business logic—that processing belongs entirely in the sub-skills being orchestrated.

### How do orchestration skills communicate with sub-skills?

They communicate via **Claude MCP (Message-Calling-Protocol)**. The orchestrator constructs a JSON payload representing the request, delegates execution to Claude, then parses the MCP response to extract results for the next workflow step. This appears in [`orchestrate_reprice.py`](https://github.com/anthropics/claude-plugins-community/blob/main/orchestrate_reprice.py) where the script parses raw MCP JSON before forwarding data to helper functions.

### Why should orchestrators output both preview and plan files?

Dual output serves different consumers: the **human-readable preview** provides immediate user feedback confirming what actions will occur, while the **machine-readable plan** (typically JSON) provides structured data for automated mutation runners or subsequent sub-skills. This separation of concerns appears in the ASC-845 reprice skill where `--output` and `--mutations-output` serve distinct downstream needs.

### Can users filter workflows without modifying orchestrator code?

Yes. Orchestration skills expose command-line flags (`--account-name`, `--activity-tags`, `--currency`) that narrow scope. These flags are parsed by the orchestrator and passed directly to sub-skills like `build_reprice_plan`, allowing users to constrain operations while the orchestrator remains agnostic of filtering implementation details.