Server Tools
What are Server Tools?
Server tools are functions that run on your backend that the Built-in Agent can invoke. They're defined using defineTool() with Zod schemas for type-safe parameters.
When should I use this?
- Your agent needs to access databases, APIs, or other backend services
- You want type-safe tool parameters with validation
- The tool logic requires server-side secrets or resources
Defining a tool
const getWeather = defineTool({
name: "getWeather",
description: "Get the current weather for a city",
parameters: z.object({
city: z.string().describe("The city name"),
}),
execute: async ({ city }) => {
// Your implementation here
return { temperature: 72, condition: "sunny", city };
},
});
const builtInAgent = new BuiltInAgent({
model: "openai:gpt-5.2",
tools: [getWeather],
});
Tool response
Tools can return any JSON-serializable value. The agent uses the response to continue the conversation.
Multiple tools
Pass an array of tools — the agent chooses which to call based on the user's request:
const searchDocs = defineTool({
name: "searchDocs",
description: "Search the documentation for relevant articles",
parameters: z.object({
query: z.string().describe("The search query"),
}),
execute: async ({ query }) => {
const results = await search(query);
return { results, count: results.length };
},
});
const createTicket = defineTool({
name: "createTicket",
description: "Create a support ticket",
parameters: z.object({
title: z.string().describe("Ticket title"),
priority: z.enum(["low", "medium", "high"]).describe("Ticket priority"),
description: z.string().describe("Detailed description of the issue"),
}),
execute: async ({ title, priority, description }) => {
const ticket = await db.tickets.create({ title, priority, description });
return { ticketId: ticket.id, status: "created" };
},
});
const builtInAgent = new BuiltInAgent({
model: "openai:gpt-5.2",
tools: [searchDocs, createTicket], // [!code highlight]
});
Complex Zod schemas
Use nested objects, arrays, enums, and optional fields for sophisticated tool parameters:
const bookFlight = defineTool({
name: "bookFlight",
description: "Search for and book flights",
parameters: z.object({
trip: z.object({
origin: z.string().describe("Origin airport code (e.g., SFO)"),
destination: z.string().describe("Destination airport code (e.g., JFK)"),
date: z.string().describe("Departure date in YYYY-MM-DD format"),
}),
passengers: z
.array(
z.object({
name: z.string(),
seatPreference: z.enum(["window", "middle", "aisle"]).optional(),
}),
)
.describe("List of passengers"),
class: z.enum(["economy", "business", "first"]).default("economy"),
}),
execute: async ({ trip, passengers, class: seatClass }) => {
const flights = await searchFlights(trip, seatClass);
return { flights, passengerCount: passengers.length };
},
});
Error handling
Throw errors or return error objects from your tool — the agent will see the error and can inform the user or try a different approach:
const getUser = defineTool({
name: "getUser",
description: "Look up a user by email",
parameters: z.object({
email: z.string().email().describe("The user's email address"),
}),
execute: async ({ email }) => {
const user = await db.users.findByEmail(email);
if (!user) {
throw new Error(`No user found with email: ${email}`); // [!code highlight]
}
return { id: user.id, name: user.name, role: user.role };
},
});
Multi-step tool calling
By default, the agent performs a single step. If your agent needs to chain tool calls (e.g., search first, then create a ticket), set maxSteps:
const builtInAgent = new BuiltInAgent({
model: "openai:gpt-5.2",
maxSteps: 5, // [!code highlight]
tools: [searchDocs, createTicket, getUser],
});
With maxSteps: 5, the agent can:
- Call
searchDocsto find relevant info - Process the result
- Call
createTicketwith details from the search - Continue until done (up to 5 iterations)
See Advanced Configuration for more
options like toolChoice, temperature, and providerOptions.