Custom Tools

Workflow Chains

Workflow chains run multiple tools in sequence — pull data from one service, transform it, post it somewhere else — all in a single request. Your AI builds these by combining tools you already have.

You don't write this code

The definitions below are what your AI generates. You just describe the workflow: "build a chain that pulls my open PRs from GitHub and posts a summary to Slack."

Aliases

The old create_dynamic_tool(...) syntax still works but is deprecated. Use tool(action="create", tool_type="chain", ...) instead.


Creating a Chain Tool

tool(action="create",
  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}}"
        }
      }
    ]
  })

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

tool(action="create",
  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

tool(action="create",
  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.


API Reference

For the full technical reference including all parameters and options, see tool Tool Reference.

Previous
Data Transforms