# Best Practices for Implementing Agent Handoff Workflows in Claude Plugins

> Learn best practices for implementing agent handoff workflows in Claude plugins. Ensure transparent and error-free context transfers by validating requests and explicitly stating subdomains.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: best-practices
- Published: 2026-09-12

---

**Agent handoff workflows should validate requests early, explicitly state the subdomain and filters being passed, place URLs on isolated lines, and never include false boolean values to ensure transparent, error-free context transfers between skills.**

The `anthropics/claude-plugins-community` repository establishes concrete patterns for implementing agent handoff workflows that minimize user friction while preserving conversational context. These patterns appear throughout the Tres Finance plugin skills and the generic `agent-handoff` plugin definition, providing a canonical reference for routing control between skills, UIs, and external services.

## Validate Requests Before Initiating Handoffs

Early validation prevents unnecessary API calls and keeps conversations focused. According to the ledger-link skill specification in [`tres-finance-plugin/skills/tres-ledger-link/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-ledger-link/SKILL.md) (lines 55-59), you must confirm scope, required filters, and optional parameters before proceeding with any handoff. This validation step acts as a gatekeeper that ensures only well-formed requests trigger URL generation or skill transitions.

## Structure Handoff Messages for Maximum Clarity

Clean handoff messages reduce copy-paste errors and enable user sanity checks. The following rules from [`tres-finance-plugin/skills/tres-ledger-link/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-ledger-link/SKILL.md) govern message formatting:

- **State the subdomain and filters explicitly** – Users must see exactly which context is being passed, as documented in lines 14-15.
- **Place the URL on its own line** – A clean, copy-ready link reduces errors and simplifies downstream parsing (lines 55-66).
- **Include only requested filters** – Omit default or false values to prevent target UI misinterpretation (lines 10-12).
- **Avoid duplicate keys** – Combine multiple values with commas rather than repeating query keys (lines 11-12).
- **Never append `=false` to boolean filters** – Omitting the flag entirely is the canonical way to express false values (lines 10-11).

## Generate URLs Programmatically

Never hand-craft URLs outside the skill logic. The ledger-link skill mandates that all URL generation rely on the skill's internal logic to guarantee correct query-parameter encoding (lines 8-9). This prevents malformed URLs and ensures consistent encoding of special characters across different subdomains.

## Route to Appropriate Skills

When a request falls outside the current skill's scope, explicitly hand off to a more suitable skill. In [`tres-finance-plugin/skills/tres-rollup-rules/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-rollup-rules/SKILL.md) (lines 46-52), requests requiring deeper inspection are routed to `tres-rollup-review` via an explicit "hand off" instruction. This pattern ensures that specialized logic always handles the specific domain it was designed for.

## Implement the Three-Stage Workflow

The generic `agent-handoff` plugin definition in [`.claude-plugin/marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json) (lines 529-533) standardizes a three-stage workflow: **plan → execute → verify**. This structure ensures consistency across all plugins in the ecosystem. Before responding, the skill must run a "Step 4 checklist" validating filters, URL format, and message structure (as required in [`tres-finance-plugin/skills/tres-ledger-link/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-ledger-link/SKILL.md), lines 57-64).

## Code Implementation Examples

### Constructing Filter-Safe Handoff Messages

The following Python implementation follows the ledger-link skill requirements: it omits false booleans, prevents duplicate keys, and isolates the URL on its own line.

```python
import urllib.parse

def build_handoff(subdomain: str, filters: dict) -> str:
    """
    Returns a hand-off string that:
    • States the subdomain and the filters used
    • Places the URL on its own line
    """
    # 1. Encode parameters – omit any key whose value is False or None

    encoded = "&".join(
        f"{k}={urllib.parse.quote(str(v))}"
        for k, v in filters.items()
        if v not in (False, None, "")
    )
    url = f"https://{subdomain}.tres.finance/ledger?{encoded}"

    # 2. Human-readable description

    filter_desc = ", ".join(f"{k}={v}" for k, v in filters.items() if v)
    return (
        f"Built for org `{subdomain}`: filters are {filter_desc}.\n"
        f"{url}"
    )

```

### Declarative Skill Routing

When a request requires capabilities from another skill, use a declarative handoff structure. This YAML fragment mirrors the routing pattern found in [`tres-finance-plugin/skills/tres-rollup-rules/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-rollup-rules/SKILL.md) (lines 46-52):

```yaml
name: tres-rollup-rules
description: Create and manage roll-up rules for transaction data.
steps:
  - name: "Routing"
    actions:
      - type: "handoff"
        target: "tres-rollup-review"
        reason: "User asked to see what a specific rule would match"

```

### Pre-Handoff Validation Checklist

Implement the required Step 4 checklist before emitting any handoff message. This shell script validates the constraints documented in [`tres-finance-plugin/skills/tres-ledger-link/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-ledger-link/SKILL.md) (lines 57-64):

```bash

# Step 4 checklist (simplified)

if [[ -z "$SUBDOMAIN" ]]; then echo "Missing subdomain"; exit 1; fi
if [[ "${#FILTERS[@]}" -eq 0 ]]; then echo "No filters supplied"; exit 1; fi

# Ensure no duplicate keys

declare -A seen
for k in "${!FILTERS[@]}"; do
  [[ -n "${seen[$k]}" ]] && { echo "Duplicate key: $k"; exit 1; }
  seen[$k]=1
done

# If all checks pass → hand off

hand_off_message=$(python -c "import handoff; print(handoff.build_handoff('$SUBDOMAIN', $FILTERS))")
echo "$hand_off_message"

```

## Summary

- **Validate early** to prevent unnecessary API calls and maintain conversation focus.
- **Use programmatic URL generation** rather than string concatenation to ensure proper encoding.
- **Omit false boolean values entirely** rather than setting them to `=false`.
- **Place URLs on isolated lines** to facilitate copying and parsing.
- **Route to specialized skills** when requests fall outside the current scope.
- **Run the Step 4 checklist** before finalizing any handoff message.

## Frequently Asked Questions

### What is an agent handoff workflow in Claude plugins?

An agent handoff workflow is a structured pattern for transferring control between skills, UIs, or external services within the Claude plugin ecosystem. According to the `agent-handoff` entry in [`.claude-plugin/marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json) (lines 529-533), it follows a three-stage process of planning, executing, and verifying the transfer to preserve context and minimize user friction.

### Why should boolean filters omit `=false` in handoff URLs?

Omitting the flag entirely is the canonical way to express "false" in the Tres Finance plugin specifications. Including `=false` adds noise to the URL and can cause target UIs to misinterpret the intent, as documented in [`tres-finance-plugin/skills/tres-ledger-link/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-ledger-link/SKILL.md) (lines 10-11).

### How do I route a request to a different skill?

Emit an explicit handoff instruction specifying the target skill name and reason. The `tres-rollup-rules` skill demonstrates this pattern by routing detailed rule reviews to `tres-rollup-review` via a declarative handoff action (see [`tres-finance-plugin/skills/tres-rollup-rules/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-rollup-rules/SKILL.md), lines 46-52).

### Where is the agent handoff workflow documented in the repository?

The primary documentation resides in three locations: the ledger-link skill ([`tres-finance-plugin/skills/tres-ledger-link/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-ledger-link/SKILL.md)) defines concrete formatting rules, the rollup-rules skill ([`tres-finance-plugin/skills/tres-rollup-rules/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-rollup-rules/SKILL.md)) shows inter-skill routing, and the marketplace configuration ([`.claude-plugin/marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json), lines 529-533) documents the generic three-stage workflow structure.