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.