Custom Tools

Chain Tools

Chain tools execute multiple tools in sequence, passing results between steps to create complex workflows.


Creating a Chain Tool

create_dynamic_tool({
  name: "deploy_and_notify",
  description: "Deploy to production and notify the team",
  tool_type: "chain",
  input_schema: {
    type: "object",
    properties: {
      environment: { type: "string" },
      message: { type: "string" }
    },
    required: ["environment"]
  },
  chain_config: {
    steps: [
      {
        tool_name: "cloudflare_deploy",
        input_mapping: {
          env: "{{environment}}"
        }
      },
      {
        tool_name: "slack_notify",
        input_mapping: {
          channel: "#deployments",
          text: "Deployed to {{environment}}: {{message}}"
        }
      }
    ]
  },
  activate: true
})

Chain Config Structure

{
  chain_config: {
    steps: [
      {
        tool_name: "tool_1",      // Tool to execute
        input_mapping: { ... },    // Map inputs to tool params
        output_key: "step1_result" // Optional: name for this step's output
      },
      {
        tool_name: "tool_2",
        input_mapping: {
          data: "{{step1_result}}" // Reference previous step output
        }
      }
    ],
    continue_on_error: false  // Stop if any step fails (default)
  }
}

Input Mapping

From Chain Input

{
  input_mapping: {
    query: "{{searchTerm}}",     // From chain input
    limit: "{{maxResults}}"
  }
}

From Previous Steps

{
  input_mapping: {
    data: "{{step1.result}}",    // From step with output_key
    id: "{{step1.result.id}}"    // Nested access
  }
}

Static Values

{
  input_mapping: {
    channel: "#notifications",   // Static value
    format: "json"
  }
}

Example: GitHub PR Workflow

create_dynamic_tool({
  name: "create_pr_with_review",
  description: "Create a PR and request review",
  tool_type: "chain",
  input_schema: {
    type: "object",
    properties: {
      owner: { type: "string" },
      repo: { type: "string" },
      title: { type: "string" },
      branch: { type: "string" },
      reviewers: { type: "array", items: { type: "string" } }
    },
    required: ["owner", "repo", "title", "branch"]
  },
  chain_config: {
    steps: [
      {
        tool_name: "github_create_pr",
        input_mapping: {
          owner: "{{owner}}",
          repo: "{{repo}}",
          title: "{{title}}",
          head: "{{branch}}",
          base: "main"
        },
        output_key: "pr"
      },
      {
        tool_name: "github_request_review",
        input_mapping: {
          owner: "{{owner}}",
          repo: "{{repo}}",
          pr_number: "{{pr.number}}",
          reviewers: "{{reviewers}}"
        }
      }
    ]
  }
})

Example: Data Pipeline

create_dynamic_tool({
  name: "fetch_and_process",
  description: "Fetch data from API and process it",
  tool_type: "chain",
  input_schema: {
    type: "object",
    properties: {
      url: { type: "string" },
      filter_field: { type: "string" }
    },
    required: ["url"]
  },
  chain_config: {
    steps: [
      {
        tool_name: "http_fetch",
        input_mapping: {
          url: "{{url}}"
        },
        output_key: "raw_data"
      },
      {
        tool_name: "transform_filter",
        input_mapping: {
          data: "{{raw_data}}",
          field: "{{filter_field}}"
        },
        output_key: "filtered"
      },
      {
        tool_name: "format_output",
        input_mapping: {
          data: "{{filtered}}"
        }
      }
    ]
  }
})

Error Handling

Stop on Error (Default)

{
  chain_config: {
    steps: [...],
    continue_on_error: false  // Chain stops if any step fails
  }
}

Continue on Error

{
  chain_config: {
    steps: [...],
    continue_on_error: true  // Continue even if steps fail
  }
}

Chain Output

The chain returns:

  • Results from all steps
  • Overall success/failure status
  • Error details if any step failed
{
  "success": true,
  "steps": [
    { "tool": "step1", "success": true, "result": {...} },
    { "tool": "step2", "success": true, "result": {...} }
  ],
  "final_result": {...}
}

Best Practices

Keep Chains Focused

Don't create mega-chains. Break complex workflows into smaller, composable chains.

Name Output Keys Clearly

output_key: "created_issue"    // Good
output_key: "result1"          // Less clear

Handle Failures Gracefully

Consider what should happen if intermediate steps fail. Use continue_on_error only when appropriate.

Test Individual Tools First

Before chaining tools, test each one individually to ensure they work as expected.

Previous
Code Tools