Welcome to the RemoteTriggerTool project! In this tutorial, we will learn how to build a tool that allows an AI (like Claude) to talk to a specific APIβin this case, a system to manage remote code triggers.
Imagine you have a powerful engine (your code logic), a steering wheel (the input rules), and a dashboard (the output display). If you leave them scattered on the floor, you can't drive anywhere. You need a Chassis to bolt them all together into a vehicle.
In our project, Tool Construction is that chassis.
We want to create a tool called "RemoteTrigger" that lets the AI list, create, or run scheduled tasks. Without a proper structure, the AI wouldn't know:
We solve this using a helper called buildTool.
The buildTool function creates a single object (a ToolDef) that acts as the blueprint for our tool. It groups four main components:
Let's look at how we construct the RemoteTriggerTool in RemoteTriggerTool.ts. We will break this large file down into tiny, understandable pieces.
First, we import the builder. Think of this as getting our empty chassis ready.
import { buildTool } from '../../Tool.js'
import { REMOTE_TRIGGER_TOOL_NAME } from './prompt.js'
// We start building the tool definition here
export const RemoteTriggerTool = buildTool({
name: REMOTE_TRIGGER_TOOL_NAME,
// ... more properties follow
})
Explanation: We export a new tool object. The name is crucialβit's how the AI system identifies this specific tool.
The AI needs to know what this tool does so it knows when to pick it.
searchHint: 'manage scheduled remote agent triggers',
async description() {
// Returns a string explaining the tool's purpose
return 'Manage scheduled remote Claude Code agents...'
},
async prompt() {
// Detailed instructions for the AI model
return 'Call the claude.ai remote-trigger API...'
},
Explanation: searchHint helps the system find this tool quickly. description and prompt give the AI the context it needs to use the tool effectively.
We need to tell the tool what kind of data it accepts. This is like installing the steering wheel.
get inputSchema(): InputSchema {
// Links to the validation rules (Zod schema)
return inputSchema()
},
get outputSchema(): OutputSchema {
// Defines what the tool gives back
return outputSchema()
},
Explanation: Here we link to schemas that validate data. We will cover the details of inputSchema in Schema Validation.
Finally, we define the call function. This is where the actual work happens when the tool runs.
async call(input: Input, context: ToolUseContext) {
// 1. Check authentication
// 2. Prepare API headers
// 3. specific logic (like 'list' or 'create')
// 4. Return the result
return { data: { status: 200, json: '{...}' } }
},
Explanation: The call method receives the validated input. This is where we will eventually put our API logic. We will look at how to handle the execution logic in API Action Dispatcher.
What actually happens when the AI tries to use this tool? Here is a high-level view of the flow:
In RemoteTriggerTool.ts, the buildTool function wraps our configuration object. It ensures type safetyβmeaning if we say our tool accepts a "trigger_id", Typescript will force us to handle that ID in our code.
There are also advanced settings like shouldDefer:
shouldDefer: true,
isConcurrencySafe() {
return true
},
When the tool finishes running, it needs to present the data to the user. This is handled by renderToolResultMessage, which we will discuss in UI Presentation.
We have successfully built the "chassis" of our RemoteTriggerTool. We used buildTool to combine the name, description, and execution logic into a single, usable unit.
However, a vehicle needs a steering wheel. How do we ensure the AI only sends us valid data (like a correct action or trigger_id)?
In the next chapter, we will learn how to strictly define these inputs.
Generated by Code IQ