浏览器工具包
一个开源框架,用于构建特定于站点的MCP服务器,这些服务器在真实的、经过身份验证的用户浏览器会话上运行,在您的机器上本地运行。
将您登录的浏览器会话转化为可组合、可测试的AI工具。
______________________________________________________________________
为什么是地方会议?
云浏览器自动化服务通过在服务器上运行浏览器并要求您在那里重新进行身份验证来工作。这种模式适用于匿名或公司所有的账户,但也适用于个人账户——你不会把你的领英、Gmail或银行凭证交给第三方服务器。
browserkit采取了相反的方法: 你的机器已经在所有地方进行了身份验证。 它重用你笔记本电脑上现有的会话,在本地运行所有浏览器,从不通过网络发送Cookie或凭据。人工智能可以在网络上访问你的真实身份;没有什么离开本地主机。
这种权衡是有意的——browserkit是单用户的,并且仅在设计上是本地的。如果你需要云舰队或多租户访问,这不是那个工具。
______________________________________________________________________
快速开始
# Install core + adapters
pnpm add @browserkit-dev/core @browserkit-dev/adapter-hackernews @browserkit-dev/adapter-linkedin
# Log in once per authenticated site (opens a browser window)
browserkit login linkedin
# Start the daemon
browserkit start --config browserkit.config.js配置您的MCP客户端(Cursor、Claude Desktop等):
{
"mcpServers": {
"browserkit-hackernews": { "url": "http://localhost:3847/mcp" },
"browserkit-linkedin": { "url": "http://localhost:3848/mcp" }
}
}______________________________________________________________________
可用适配器
| 包 | 站点 | 身份验证 | 工具 |
|---|---|---|---|
@browserkit-dev/adapter-hackernews | 黑客新闻 | 无 | get_top, get_new, get_ask, get_show, get_comments |
@browserkit-dev/adapter-linkedin | 必填 | get_person_profile, get_company_profile, get_company_posts, search_people, search_jobs, get_job_details, get_feed | |
@browserkit-dev/adapter-reddit | 无 | get_subreddit, get_thread, search, get_user |
______________________________________________________________________
运作原理
每个适配器都作为 专用MCP HTTP服务器 多个AI代理可以同时连接——每个适配器对请求进行序列化,以保护浏览器会话。
AI Agent (Cursor / Claude / custom)
↓ HTTP MCP
browserkit daemon
├── hackernews :3847 headless Chromium (public, no auth needed)
├── linkedin :3848 headless Chrome (authenticated, uses real Chrome)
└── ...浏览器运行 默认情况下完全无头 --没有窗口,没有Dock图标。它们仅在登录时可见(browserkit login)或者当您明确切换到 watch 或 pause 模式。
______________________________________________________________________
配置
// browserkit.config.js
export default {
host: "127.0.0.1", // bind address (non-localhost requires bearerToken)
basePort: 3847, // first adapter auto-assigns from here
bearerToken: process.env.BROWSERKIT_TOKEN, // optional auth
adapters: {
// key = npm package name (no naming convention required)
"@browserkit-dev/adapter-hackernews": {
port: 3847,
},
"@browserkit-dev/adapter-linkedin": {
port: 3848,
channel: "chrome", // use real Chrome — avoids bot detection on login
},
"@someone/my-custom-adapter": {
port: 3849,
debugPort: 4849, // optional: enables raw Playwright access via CDP
authStrategy: "persistent", // "persistent" | "storage-state" | "cdp-attach" | "extension"
rateLimit: { minDelayMs: 3000 },
},
},
};______________________________________________________________________
命令行界面
browserkit start [--adapter
] [--port ] [--config
]
browserkit login # one-time login (opens browser)
browserkit status # show running adapters
browserkit config cursor # generate Cursor MCP settings JSON
browserkit create-adapter # scaffold a new adapter package______________________________________________________________________
每个适配器服务器上的工具
每个适配器都公开了自己的域工具以及这些自动注册的工具:
域工具(特定于适配器)
无论适配器声明什么——例如。 get_feed, search_people, get_top.
浏览器控制(自动注册,旁路锁定)
| 工具 | 说明 |
|---|---|
set_mode | 切换 headless, watch (可见), paused (用户控制) |
take_screenshot | 将当前页面捕获为内联图像——AI可以直接看到它 |
get_page_state | 原始访问的URL、标题、模式、CDP端点 |
navigate | 导航到URL(锁内) |
health_check | 浏览器活动、登录状态、选择器验证报告 |
______________________________________________________________________
浏览器模式
headless → fully invisible, automation runs normally (default)
watch → browser becomes visible, automation continues (optional slowMoMs)
paused → browser visible, tool calls queue — user has manual control通过以下方式切换模式 set_mode 来自任何AI代理的MCP工具。
______________________________________________________________________
扩展模式(Chrome通过Playwriter)
一些网站积极屏蔽自动浏览器——谷歌、领英和其他网站检测到Playwright的Chromium并拒绝登录。 扩展模式 通过直接在真实的登录Chrome浏览器中运行适配器工具来解决这个问题,而不是启动单独的Patchright实例。
AI Agent (Cursor / Claude)
↓ HTTP MCP
browserkit daemon
├── hackernews :3847 headless Patchright (default — no login needed)
└── linkedin :3848 your Chrome (extension mode — inherits your session)
└── Playwriter relay → Chrome extension → authenticated tab设置
1.安装Playwriter Chrome扩展程序 从 Chrome网络商店.
2.安装playwriter npm包:
pnpm add playwriter3.单击Playwriter扩展图标 在您希望browserkit使用的选项卡上。图标激活后变为绿色。
4.配置适配器 要使用扩展模式:
// browserkit.config.js
export default {
adapters: {
"@browserkit-dev/adapter-linkedin": {
authStrategy: "extension", // use Chrome extension backend
// extensionPort: 19988, // optional — Playwriter's default
},
"@browserkit-dev/adapter-hackernews": {
// defaults to "persistent" — headless Patchright as normal
},
},
};5.启动守护进程 --没有 browserkit login 需要:
browserkit start运作原理
browserkit启动Playwriter的本地WebSocket中继服务器,并通过以下方式将Patchright连接到该服务器 connectOverCDP()Chrome扩展程序使用 chrome.debugger 将CDP命令转发到活动的Chrome选项卡。适配器工具将收到完整的Playwright Page 对象-- page.goto(), page.evaluate(), page.route()、截图、定位器——一切正常。
Playwriter扩展会自动创建 标签分组 为自动化选项卡命名为“playwriter”,所有新选项卡都在后台打开(active: false)因此,您当前的选项卡永远不会中断。
与默认模式相比有什么变化
默认值(persistent) | 扩展模式 | |
|---|---|---|
| 浏览器 | 无头补丁 | 你真正的Chrome |
| 认证 | browserkit login | 已登录 |
| 机器人检测 | Patchright反检测 | 无需(真正的Chrome) |
| 无头 | 是 | 否 |
| 选项卡组 | N/A | 绿色“编剧”组 |
set_mode | 无头/观察/暂停 | 不适用 |
可接受的权衡
- 仅限Chrome(不包括Brave、Arc、Firefox)
chrome.debugger在附加标签上显示“Chrome由自动测试软件控制”横幅- 需要打开Chrome浏览器并激活Playwriter扩展程序
- 共享浏览器:自动化在您的Chrome中运行(CPU/内存与您的浏览共享)
______________________________________________________________________
原始剧作家访问(通过CDP)
当 debugPort 已配置, get_page_state 返回a cdpUrl外部代理——Claude Code、Cursor、自定义脚本——可以附加到 已通过身份验证 浏览器会话并运行任意Playwright代码:
// Script written by Claude Code, executed via shell
const { chromium } = require('playwright');
// Attach to the running session — already logged in, no auth needed
const browser = await chromium.connectOverCDP("http://127.0.0.1:4848");
const context = browser.contexts()[0];
const page = context.pages()[0];
// Full Playwright API — write any automation
await page.goto("https://my-site.com/data");
const results = await page.$$eval(".row", (els) => els.map((el) => el.textContent?.trim()));
console.log(JSON.stringify(results));
await browser.disconnect(); // disconnect only — session stays alive模式:AI编写脚本 /tmp/script.js,通过shell运行它,读取stdout。
在配置中启用: debugPort: adapterPort + 1000 (例如3848上的适配器→ debugPort 4848)。
______________________________________________________________________
构建适配器
实施参考
browserkit-dev/adapter-hackernews--公共站点,无身份验证,5个工具,完整的4层测试套件。最简单的起点。browserkit-dev/adapter-linkedin--认证站点、7个工具,innerText提取策略+ARI锚点抓取。对于需要登录并与DOM混淆的JS应用程序配合使用的适配器来说,这是一个很好的参考。
脚手架
npx @browserkit-dev/core create-adapter my-site
cd adapter-my-site
pnpm install这将生成完整的包结构: src/index.ts, src/selectors.ts, vitest.config.ts, package.json, README.md.
SiteAdapter接口
import { defineAdapter } from "@browserkit-dev/core";
import { z } from "zod";
import type { Page } from "playwright";
export default defineAdapter({
// ── Required ────────────────────────────────────────────────────────────
site: "my-site", // unique ID, becomes the MCP server name
domain: "my-site.com", // used for profile scoping
loginUrl: "https://my-site.com/login", // where to navigate for login flow
async isLoggedIn(page: Page): Promise {
// Return true when the page shows an authenticated state.
// Called before every tool call. If it returns false, browserkit
// triggers the human handoff flow (opens browser, waits for login).
// For public sites (no auth), always return true.
return page.getByRole("navigation", { name: "user menu" }).isVisible({ timeout: 3000 });
},
tools: () => [ /* see below */ ],
// ── Optional ────────────────────────────────────────────────────────────
rateLimit: { minDelayMs: 2000 }, // min delay between consecutive tool calls
selectors: { // exported CSS selectors for health_check reporting
mainContent: ".main-content", // health_check validates these on the live page
loginButton: "button[data-testid=login]",
},
});工具定义
tools: () => [
{
name: "get_data",
description: "Get data from my-site",
// Zod schema — validated before handler is called
inputSchema: z.object({
query: z.string().describe("Search query"),
limit: z.number().int().min(1).max(50).default(10),
}),
// handler receives: the live authenticated Page + validated input
async handler(page: Page, input: unknown) {
const { query, limit } = mySchema.parse(input); // use schema.parse for type safety
await page.goto(`https://my-site.com/search?q=${encodeURIComponent(query)}`);
await page.waitForSelector(".result", { timeout: 10_000 });
const results = await page.evaluate(({ sel, n }) => {
return Array.from(document.querySelectorAll(sel))
.slice(0, n)
.map((el) => el.textContent?.trim() ?? "");
}, { sel: ".result", n: limit });
// Return value must have this shape:
return {
content: [{ type: "text" as const, text: JSON.stringify(results, null, 2) }],
// isError: true — set this if the tool failed but you want to return a message
};
},
},
],工具操作员合同:
page是一位现场剧作家Page--已导航,已验证input是Zod模式的验证结果——始终在处理程序内解析它以确保类型安全- 返回
{ content: [{ type: "text", text: string }] }对于文本结果 - 返回
{ content: [{ type: "image", data: base64, mimeType: "image/png" }] }对于图像 - 返回
{ content: [...], isError: true }在不崩溃的情况下发出刀具液位错误信号
测试适配器
使用 @browserkit-dev/core/testing 编写测试来启动一个真正的进程内服务器:
// tests/mcp-protocol.test.ts
import { describe, it, expect, beforeAll, afterAll } from "vitest";
import myAdapter from "../src/index.js";
import { createTestAdapterServer, createTestMcpClient } from "@browserkit-dev/core/testing";
let server, client;
beforeAll(async () => {
server = await createTestAdapterServer(myAdapter);
client = await createTestMcpClient(server.url);
}, 30_000);
afterAll(async () => {
await client.close();
await server.stop();
});
it("get_data returns results", async () => {
const result = await client.callTool("get_data", { query: "test" });
expect(result.isError).toBeFalsy();
const data = JSON.parse(result.content[0].text);
expect(Array.isArray(data)).toBe(true);
});createTestAdapterServer 使用隔离的临时数据目录启动适配器(避免pidfile与正在运行的守护进程冲突)。 createTestMcpClient 通过真正的MCP HTTP传输进行连接——与Cursor和Claude Desktop使用的路径相同。
有关完整的4层示例,请参见 browserkit-dev/adapter-hackernews/tests/.
发布
pnpm build
npm publish --access public用户将包名称添加到 browserkit.config.js --不需要命名约定。任何npm包名称都可以使用。
______________________________________________________________________
计划适配器
欢迎社区捐款--使用 browserkit create-adapter 关于脚手架,请参见 构建适配器 上面。
| 网站 | 为什么选择browserkit | 建议的工具 | 状态 |
|---|---|---|---|
| 推特/X | API为100美元/月+;大多数个人帐户没有API访问权限 | get_feed, search, get_thread, get_bookmarks, get_dms, get_lists | 打开 |
| 亚马逊 | 完全没有消费者API | get_orders, search_products, get_product, get_wishlist, track_price | 打开 |
| Airbnb | 没有公开的API;对旅行计划代理有用 | search_listings, get_listing, get_bookings, get_messages | 打开 |
| 谷歌地图 | 地方API是昂贵的人均;浏览器是免费的 | search_nearby, get_place, get_reviews, get_directions | 打开 |
如果您有兴趣构建一个,请在 浏览器开发/浏览器工具包 协调。
______________________________________________________________________
建筑
看 ARCH.md 了解完整的架构细节。
关键属性:
- 会话持续:跨工具调用和进程重启维护身份验证
- 位点特异性:基于确定性选择器的工具,而不是DOM猜测代理
- MCP本地:每个适配器都是一个标准的HTTP MCP服务器
- 循环中的人类:打开浏览器登录,2FA,验证码
- 多客户端:多个AI代理可以同时连接到同一适配器
______________________________________________________________________
许可证
麻省理工学院
