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.