You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# why
We didn't have docs for passing custom tools to stagehand agent or
examples, only MCP integrations. Under the hood, stagehand treats both
the same, and passing custom tools directly is (most times) more
convenient and performant.
# what changed
Added an example `agent-custom-tools.ts` as well as docs under the
basics > agent section
# test plan
Copy file name to clipboardExpand all lines: packages/docs/v3/basics/agent.mdx
+136-3Lines changed: 136 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -142,6 +142,139 @@ When you use `agent()`, Stagehand will return a `Promise<AgentResult>` with the
142
142
}
143
143
```
144
144
145
+
## Custom Tools
146
+
147
+
Agents can be enhanced with custom tools for more granular control and better performance. Unlike MCP integrations, custom tools are defined inline and execute directly within your application.
148
+
149
+
<Note>Custom tools provide a cleaner, more performant alternative to MCP integrations when you need specific functionality.</Note>
150
+
151
+
### Defining Custom Tools
152
+
153
+
Use the `tool` helper from the [Vercel AI SDK](https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling) to define custom tools:
154
+
155
+
<CodeGroup>
156
+
```typescript Basic Tool
157
+
import { tool } from"ai";
158
+
import { z } from"zod/v3";
159
+
160
+
const agent =stagehand.agent({
161
+
model: "openai/gpt-5",
162
+
tools: {
163
+
getWeather: tool({
164
+
description: 'Get the current weather in a location',
165
+
inputSchema: z.object({
166
+
location: z.string().describe('The location to get weather for'),
167
+
}),
168
+
execute: async ({ location }) => {
169
+
// Your custom logic here
170
+
const weather =awaitfetchWeatherAPI(location);
171
+
return {
172
+
location,
173
+
temperature: weather.temp,
174
+
conditions: weather.conditions,
175
+
};
176
+
},
177
+
}),
178
+
},
179
+
systemPrompt: 'You are a helpful assistant with access to weather data.',
180
+
});
181
+
182
+
awaitagent.execute("What's the weather in San Francisco and should I bring an umbrella?");
183
+
```
184
+
185
+
```typescript Multiple Tools
186
+
import { tool } from"ai";
187
+
import { z } from"zod/v3";
188
+
189
+
const agent =stagehand.agent({
190
+
cua: true,
191
+
model: "anthropic/claude-sonnet-4-20250514",
192
+
tools: {
193
+
searchDatabase: tool({
194
+
description: 'Search for records in the database',
195
+
inputSchema: z.object({
196
+
query: z.string().describe('The search query'),
197
+
limit: z.number().optional().describe('Max results to return'),
198
+
}),
199
+
execute: async ({ query, limit=10 }) => {
200
+
const results =awaitdb.search(query, limit);
201
+
return { results };
202
+
},
203
+
}),
204
+
205
+
calculatePrice: tool({
206
+
description: 'Calculate the total price with tax',
207
+
inputSchema: z.object({
208
+
amount: z.number().describe('The base amount'),
209
+
taxRate: z.number().describe('Tax rate as decimal (e.g., 0.08 for 8%)'),
210
+
}),
211
+
execute: async ({ amount, taxRate }) => {
212
+
const total =amount* (1+taxRate);
213
+
return { total: total.toFixed(2) };
214
+
},
215
+
}),
216
+
},
217
+
});
218
+
219
+
awaitagent.execute("Find products under $50 and calculate the total with 8% tax");
220
+
```
221
+
222
+
```typescript Tool with API Integration
223
+
import { tool } from"ai";
224
+
import { z } from"zod/v3";
225
+
226
+
const agent =stagehand.agent({
227
+
model: "google/gemini-2.0-flash",
228
+
tools: {
229
+
sendEmail: tool({
230
+
description: 'Send an email via SendGrid',
231
+
inputSchema: z.object({
232
+
to: z.string().email().describe('Recipient email address'),
| Type-safe with TypeScript | Access to pre-built integrations |
272
+
| Granular control | Network-based communication |
273
+
274
+
<Tip>
275
+
Use custom tools when you need specific functionality within your application. Use MCP integrations when connecting to external services or when you need standardized cross-application tools.
276
+
</Tip>
277
+
145
278
## MCP Integrations
146
279
147
280
Agents can be enhanced with external tools and services through MCP (Model Context Protocol) integrations. This allows your agent to access external APIs and data sources beyond just browser interactions.
@@ -188,12 +321,12 @@ await agent.execute("Search for restaurants and save the first result to the dat
188
321
MCP integrations enable agents to be more powerful by combining browser automation with external APIs, databases, and services. The agent can intelligently decide when to use browser actions versus external tools.
189
322
</Tip>
190
323
324
+
## Agent Execution Configuration
325
+
191
326
<Warning>
192
-
Stagehand uses a 1288x711 viewport by default (the optimal size for Computer Use Agents). Other viewport sizes may reduce performance. If you need to modify the viewport, you can edit in the [Browser Configuration](/v3/configuration/browser).
327
+
Stagehand uses a 1288x711 viewport by default. Other viewport sizes may reduce performance. If you need to modify the viewport, you can edit in the [Browser Configuration](/v3/configuration/browser).
193
328
</Warning>
194
329
195
-
## Agent Execution Configuration
196
-
197
330
Control the maximum number of steps the agent can take to complete the task using the `maxSteps` parameter.
0 commit comments