Custom Tools
Dynamic Tools Overview
Dynamic tools let you extend Kyew with custom MCP tools. Turn API calls, data transforms, and workflows into reusable tools that Claude can invoke.
Tool Types
Kyew supports four types of custom tools:
| Type | Use Case | Execution |
|---|---|---|
| HTTP Proxy | Call external APIs | Makes HTTP requests |
| Transform | Data manipulation | JSONata expressions |
| Code | Complex logic | JavaScript in sandbox |
| Chain | Multi-step workflows | Executes tools in sequence |
HTTP Proxy Tools
Call external APIs with authentication:
create_dynamic_tool({
name: "github_create_issue",
description: "Create an issue in a GitHub repository",
tool_type: "http_proxy",
input_schema: {
type: "object",
properties: {
owner: { type: "string" },
repo: { type: "string" },
title: { type: "string" },
body: { type: "string" }
},
required: ["owner", "repo", "title"]
},
http_config: {
method: "POST",
url_template: "https://api.github.com/repos/{{owner}}/{{repo}}/issues",
body_template: {
title: "{{title}}",
body: "{{body}}"
},
connection_id: "my-github-connection"
}
})
See HTTP Proxy Tools for details.
Transform Tools
Manipulate data using JSONata expressions:
create_dynamic_tool({
name: "extract_emails",
description: "Extract email addresses from text",
tool_type: "transform",
input_schema: {
type: "object",
properties: {
text: { type: "string" }
},
required: ["text"]
},
transform_config: {
expression: "$match(input.text, /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g)"
}
})
See Transform Tools for details.
Code Tools
Run JavaScript in isolated containers:
create_code_tool({
name: "calculate_stats",
description: "Calculate statistical measures",
runtime: "javascript",
input_schema: {
type: "object",
properties: {
numbers: { type: "array", items: { type: "number" } }
},
required: ["numbers"]
},
code: `
export default {
async fetch(request) {
const { numbers } = await request.json();
const sum = numbers.reduce((a, b) => a + b, 0);
return Response.json({
sum,
mean: sum / numbers.length,
min: Math.min(...numbers),
max: Math.max(...numbers)
});
}
}
`
})
See Code Tools for details.
Chain Tools
Combine multiple tools into workflows:
create_dynamic_tool({
name: "deploy_and_notify",
description: "Deploy to Cloudflare and post to Slack",
tool_type: "chain",
input_schema: {
type: "object",
properties: {
environment: { type: "string" }
},
required: ["environment"]
},
chain_config: {
steps: [
{
tool_name: "cloudflare_deploy",
input_mapping: { env: "{{environment}}" }
},
{
tool_name: "slack_post",
input_mapping: {
channel: "#deployments",
message: "Deployed to {{environment}}"
}
}
]
}
})
See Chain Tools for details.
Managing Dynamic Tools
List Tools
"list my custom tools"
"list active http_proxy tools"
Get Details
"show details for tool github_create_issue"
Update Tools
"update tool github_create_issue to add labels support"
Delete Tools
"delete tool github_create_issue"
Test Tools
"test tool github_create_issue with owner='me' repo='test' title='Bug'"
Connections
HTTP proxy tools need connections for authentication:
create_connection({
name: "my-github-connection",
provider: "github",
auth_type: "bearer",
api_key_config: {
key: "ghp_xxxxxxxxxxxx",
header_name: "Authorization",
prefix: "Bearer "
}
})
Authentication Types
| Type | Use Case |
|---|---|
api_key | Header or query param API keys |
bearer | Bearer token authentication |
basic | Username/password (base64) |
oauth2 | OAuth 2.0 flows |
Tool Status
Dynamic tools have three statuses:
- draft: Created but not activated
- active: Available for use
- disabled: Temporarily turned off
// Activate immediately
create_dynamic_tool({ ..., activate: true })
// Or activate later
update_dynamic_tool({ tool_id: "...", status: "active" })
Input Schemas
All tools require an input schema defining expected parameters:
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query"
},
"limit": {
"type": "number",
"description": "Max results",
"default": 10
}
},
"required": ["query"]
}
This schema:
- Validates input before execution
- Documents parameters for Claude
- Enables better suggestions
Template Syntax
HTTP and chain tools use {{variable}} templating:
{
"url_template": "https://api.example.com/users/{{userId}}",
"body_template": {
"name": "{{name}}",
"email": "{{email}}"
}
}
Nested access:
{{user.profile.name}}
Best Practices
Name Tools Clearly
# Good
github_create_issue
slack_post_message
# Avoid
doThing
myTool1
Write Descriptions
Good descriptions help Claude choose the right tool:
# Good
"Create a new issue in a GitHub repository with title and optional body"
# Avoid
"GitHub stuff"
Validate Early
Use input schemas to catch errors before execution.
Test Before Activating
Use test_dynamic_tool to verify behavior before making tools active.
Secure Credentials
Never hardcode secrets in templates. Use connections for all authentication.