AgentKit Integration
AgentKit is a TypeScript framework by Inngest for building fault-tolerant AI agents with tools, state, and multi-agent networks. By connecting AgentKit to Browserless, your agents can browse the web with stealth capabilities, CAPTCHA solving, and residential proxies without managing browser infrastructure.
Prerequisites
- Node.js 18 or higher
- Browserless API token (available in your account dashboard)
- An LLM API key (Anthropic, OpenAI, etc.), required for the agent to reason and call tools
Step-by-Step Setup
1. Get your API keys
Go to your Browserless Account Dashboard and copy your API token.
Then set your environment variables:
- .env file
- Command line
BROWSERLESS_API_KEY=your-browserless-token
ANTHROPIC_API_KEY=your-anthropic-key
export BROWSERLESS_API_KEY=your-browserless-token
export ANTHROPIC_API_KEY=your-anthropic-key
2. Install dependencies
AgentKit requires inngest as a peer dependency. Install both alongside Playwright and Zod:
- npm
- yarn
- pnpm
npm install @inngest/agent-kit inngest playwright-core zod
yarn add @inngest/agent-kit inngest playwright-core zod
pnpm add @inngest/agent-kit inngest playwright-core zod
3. Create a Browserless tool
Create a file called index.ts. Start by defining a tool that connects to Browserless using Playwright's connectOverCDP method:
import { createTool } from "@inngest/agent-kit";
import { z } from "zod";
import { chromium } from "playwright-core";
const scrapeHackerNews = createTool({
name: "scrape_hackernews",
description: "Get the top stories from Hacker News",
parameters: z.object({
limit: z.number().describe("Number of stories to fetch").default(5),
}),
handler: async ({ limit }, { step }) => {
const scrape = async () => {
const browser = await chromium.connectOverCDP(
`wss://production-sfo.browserless.io?token=${process.env.BROWSERLESS_API_KEY}`
);
try {
const page = await browser.newPage();
await page.goto("https://news.ycombinator.com");
const stories = await page.evaluate((limit) => {
const items = document.querySelectorAll(".athing");
return Array.from(items)
.slice(0, limit)
.map((item) => {
const titleEl = item.querySelector(".titleline > a");
const subtext = item.nextElementSibling;
const scoreEl = subtext?.querySelector(".score");
return {
title: titleEl?.textContent,
url: titleEl?.getAttribute("href"),
points: scoreEl?.textContent || "0 points",
};
});
}, limit);
return stories;
} finally {
await browser.close();
}
};
return await step?.run("scrape-hn", scrape) ?? await scrape();
},
});
When running inside an Inngest function, step.run() ensures the operation only executes once, even if the agent retries. The ?? await scrape() fallback lets the same tool work in standalone mode without Inngest.
4. Create an agent and network
Add the agent and network definitions to the same file. Pass the tool directly to the agent's tools array:
import {
anthropic,
createAgent,
createNetwork,
} from "@inngest/agent-kit";
const newsAgent = createAgent({
name: "hackernews_agent",
description: "Fetches and summarizes Hacker News stories",
system: "You fetch top stories from Hacker News and provide summaries.",
tools: [scrapeHackerNews],
});
const network = createNetwork({
name: "news_network",
agents: [newsAgent],
maxIter: 3,
defaultModel: anthropic({
model: "claude-sonnet-4-20250514",
defaultParameters: {
max_tokens: 4096,
},
}),
});
5. Run the agent
Add the following to the same file to run the network with a prompt:
const result = await network.run(
"Get the top 5 stories from Hacker News and summarize them"
);
console.log(result);
Run the script:
npx tsx ./index.ts
You should see the agent fetch and summarize the top Hacker News stories.
How It Works
- Connection: Playwright connects to Browserless via WebSocket using
connectOverCDP - Tool execution: The agent calls your tool, which runs browser operations through Browserless
- Cleanup: The browser closes in a
finallyblock to prevent session leaks
Advanced Configuration
Stealth mode
For sites with bot detection, use a stealth route:
const browser = await chromium.connectOverCDP(
`wss://production-sfo.browserless.io/stealth?token=${process.env.BROWSERLESS_API_KEY}`
);
Residential proxies
Route traffic through residential IPs for geo-targeting and rate-limit avoidance:
const browser = await chromium.connectOverCDP(
`wss://production-sfo.browserless.io?token=${process.env.BROWSERLESS_API_KEY}&proxy=residential&proxyCountry=us`
);
Regional endpoints
Pick the region closest to your users or target sites:
| Region | Endpoint |
|---|---|
| US West (San Francisco) | wss://production-sfo.browserless.io |
| Europe (London) | wss://production-lon.browserless.io |
| Europe (Amsterdam) | wss://production-ams.browserless.io |