How to add and configure tools
mainTools are defined in the tools object within server.ts. There are three distinct patterns for implementing tools depending on where the execution logic resides and whether user interaction is required:
1. Auto-execute (Server-side)
Runs automatically on the server without user interaction. Use this for API calls or database queries.
myTool: tool({
description: "...",
inputSchema: z.object({ /* ... */ }),
execute: async (input) => { /* return result */ }
}),2. Client-side (Browser-side)
Does not include an execute function. The browser provides the result, which you must handle in app.tsx via the onToolCall callback. This is useful for accessing browser-specific APIs like geolocation.
browserTool: tool({
description: "...",
inputSchema: z.object({ /* ... */ })
}),3. Approval (Human-in-the-loop)
Gated execution that requires user permission before the execute function runs. Use the needsApproval property to define the gating logic.
sensitiveTool: tool({
description: "...",
inputSchema: z.object({ /* ... */ }),
needsApproval: async (input) => true, // or conditional logic
execute: async (input) => { /* runs after approval */ }
}),// Auto-execute example
getWeather: tool({
description: "Get the current weather for a city",
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => {
const res = await fetch(`https://api.weather.example/${city}`);
return res.json();
}
}),