Tutorials
Extend with Tools
This tutorial walks through building a custom tool for Autohand Code. The tool queries an internal API and returns structured JSON that the agent can reason about.
What you will build
- A custom tool definition with a JSON Schema.
- A handler that calls an internal API in the language your agent service uses.
- An Autohand agent configured to use the tool.
Prerequisites
- An Autohand SDK package for your runtime.
- An internal API endpoint and an API key.
Step 1: define the tool
JavaScript
import { defineTool } from '@autohandai/agent-sdk';
export const fetchCustomer = defineTool({
name: 'fetch_customer',
description: 'Fetch a customer record by ID',
parameters: {
type: 'object',
properties: { id: { type: 'string' } },
required: ['id']
},
handler: async ({ id }) => {
const res = await fetch(`${process.env.API_URL}/customers/${id}`, {
headers: { Authorization: `Bearer ${process.env.API_KEY}` }
});
return res.json();
}
});
TypeScript
import { defineTool } from '@autohandai/agent-sdk';
export const fetchCustomer = defineTool<{ id: string }>({
name: 'fetch_customer',
description: 'Fetch a customer record by ID',
parameters: {
type: 'object',
properties: { id: { type: 'string', description: 'Customer ID' } },
required: ['id']
},
handler: async ({ id }) => {
const res = await fetch(`${process.env.API_URL}/customers/${id}`);
if (!res.ok) throw new Error(`Customer ${id} not found`);
return res.json();
}
});
Python
from autohand_sdk import define_tool
import httpx
import os
@define_tool(
name="fetch_customer",
description="Fetch a customer record by ID",
parameters={
"type": "object",
"properties": {"id": {"type": "string"}},
"required": ["id"],
},
)
async def fetch_customer(id: str):
async with httpx.AsyncClient() as client:
response = await client.get(
f"{os.environ['API_URL']}/customers/{id}",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
)
response.raise_for_status()
return response.json()
Go
fetchCustomer := autohand.Tool{
Name: "fetch_customer",
Description: "Fetch a customer record by ID",
Parameters: autohand.Schema{
Type: "object",
Properties: map[string]autohand.Schema{
"id": {Type: "string"},
},
Required: []string{"id"},
},
Handler: func(ctx context.Context, args map[string]any) (any, error) {
id := args["id"].(string)
return fetchCustomerRecord(ctx, id)
},
}
Java
Tool fetchCustomer = Tool.builder()
.name("fetch_customer")
.description("Fetch a customer record by ID")
.parameter("id", JsonSchema.string().description("Customer ID"))
.handler(args -> {
String id = args.getString("id");
return customersApi.fetchCustomer(id);
})
.build();
Swift
let fetchCustomer = Tool(
name: "fetch_customer",
description: "Fetch a customer record by ID",
parameters: [
"id": .string(description: "Customer ID")
]
) { args in
let id = try args.requireString("id")
return try await customersAPI.fetchCustomer(id: id)
}
curl
curl -X POST "$API_URL/customers/CUST-1234" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"include":["plan","usage","owner"]}'Step 2: register the tool
JavaScript
import { Agent } from '@autohandai/agent-sdk';
import { fetchCustomer } from './tools/fetch-customer.js';
const agent = await Agent.create({
cwd: '.',
instructions: 'Use fetch_customer when users ask about customer data.',
tools: [fetchCustomer]
});
const result = await agent.run('What is the plan for customer CUST-1234?');
console.log(result.text);
TypeScript
import { Agent } from '@autohandai/agent-sdk';
import { fetchCustomer } from './tools/fetch-customer';
const agent = await Agent.create({
cwd: '.',
instructions: 'Use fetch_customer when users ask about customer data.',
tools: [fetchCustomer]
});
const result = await agent.run('What is the plan for customer CUST-1234?');
console.log(result.text);
Python
from autohand_sdk import Agent
from tools import fetch_customer
agent = await Agent.create(
cwd=".",
instructions="Use fetch_customer when users ask about customer data.",
tools=[fetch_customer],
)
result = await agent.run("What is the plan for customer CUST-1234?")
print(result.text)
Go
agent, _ := autohand.NewAgent(ctx, autohand.AgentConfig{
Cwd: ".",
Instructions: "Use fetch_customer when users ask about customer data.",
Tools: []autohand.Tool{fetchCustomer},
})
result, _ := agent.Run(ctx, "What is the plan for customer CUST-1234?")
fmt.Println(result.Text)
Java
Agent agent = Agent.create(AgentConfig.builder()
.cwd(".")
.instructions("Use fetch_customer when users ask about customer data.")
.tools(List.of(fetchCustomer))
.build());
AgentResult result = agent.run("What is the plan for customer CUST-1234?");
System.out.println(result.text());
Swift
let agent = try await Agent.create(
cwd: ".",
instructions: "Use fetch_customer when users ask about customer data.",
tools: [fetchCustomer]
)
let result = try await agent.run("What is the plan for customer CUST-1234?")
print(result.text)Step 3: test the agent
Run the script and verify the agent calls the tool and returns the correct email. If the API is unavailable, the agent should report the error from the handler.
Next steps
Add more tools, expose them through MCP, or deploy the agent as a service.