demo.mp4
Talk to an AI agent in Slack threads. It can browse the web with a real Chromium browser you can watch live through VNC, run scheduled tasks on a cron, and keep persistent sessions across conversations. BrowserBird is the orchestration layer; the agent CLI (claude, opencode) handles reasoning, memory, tools, and sub-agents.
Built by Owloops, who have been building browser automation tools since 2020 (flybird, chrome-recorder, extension). BrowserBird is written from scratch with lessons learned from those projects.
On first run, open the web UI and complete the onboarding wizard. It walks through Slack tokens, agent config, and API keys.
curl -fsSL https://raw.githubusercontent.com/Owloops/browserbird/main/compose.yml -o compose.yml
docker compose up -dEverything is included: agent CLI, Chromium browser, VNC, and Playwright MCP. Open http://<host>:18800 to begin onboarding.
The browser runs in persistent mode by default: logins and cookies are saved across sessions, one agent at a time. Set BROWSER_MODE=isolated in .env for parallel sessions with fresh contexts (requires container restart).
npm install -g @owloops/browserbird
browserbirdRequires Node.js 22.21+ and at least one agent CLI installed (claude or opencode). Open http://localhost:18800 to begin onboarding.
- Create a new Slack app at api.slack.com/apps using the manifest.json from this repo
- Go to OAuth & Permissions, install the app to your workspace, copy the Bot User OAuth Token (
xoxb-...) - Go to Basic Information, create an app-level token with the
connections:writescope, copy the token (xapp-...)
Once the app is installed, /bird is available in any channel:
/bird list Show all configured birds
/bird fly <name> Trigger a bird immediately
/bird logs <name> Show recent flights
/bird enable <name> Enable a bird
/bird disable <name> Disable a bird
/bird create Create a new bird (opens modal form)
/bird status Show daemon status
The onboarding wizard handles initial setup. For manual configuration, copy the example config:
cp browserbird.example.json browserbird.jsonSee browserbird.example.json for the full config with defaults.
Any string value can reference an environment variable with "env:VAR_NAME" syntax (e.g. "env:SLACK_BOT_TOKEN").
The top-level timezone field (IANA format, default "UTC") is used for cron scheduling and quiet hours.
slack - Slack connection and behavior
"slack": {
"botToken": "env:SLACK_BOT_TOKEN",
"appToken": "env:SLACK_APP_TOKEN",
"requireMention": true,
"coalesce": { "debounceMs": 3000, "bypassDms": true },
"channels": ["*"],
"quietHours": { "enabled": false, "start": "23:00", "end": "08:00", "timezone": "UTC" }
}botToken,appToken: Required. Bot user OAuth token and app-level token for Socket ModerequireMention: Only respond in channels when@mentioned; DMs always respondcoalesce.debounceMs: Wait N ms after last message before dispatching (groups rapid messages)coalesce.bypassDms: Skip debouncing for DMschannels: Channel names or IDs to listen in, or"*"for allquietHours: Silence the bot during specified hours. Start/end in HH:MM format, can wrap midnight
agents - Agent routing and model config
"agents": [
{
"id": "default",
"name": "BrowserBird",
"provider": "claude",
"model": "sonnet",
"fallbackModel": "haiku",
"maxTurns": 50,
"systemPrompt": "You are responding in a Slack workspace. Be concise, helpful, and natural.",
"channels": ["*"]
}
]Each agent is scoped to specific channels. Multiple agents are matched in order, first match wins.
id,name: Required. Unique identifier and display nameprovider:"claude"or"opencode"model: Claude uses short names (sonnet,haiku). OpenCode usesprovider/modelformat (anthropic/claude-sonnet-4-20250514)fallbackModel: Fallback when primary is unavailable (claude only)maxTurns: Max conversation turns per sessionsystemPrompt: Instructions prepended to every sessionchannels: Channel names or IDs this agent handles, or"*"for allprocessTimeoutMs: Per-agent subprocess timeout override (inherits fromsessionsif not set)
sessions - Session lifecycle
"sessions": {
"ttlHours": 24,
"maxConcurrent": 5,
"processTimeoutMs": 300000
}ttlHours: Session lifetime in hours (resets on each message)maxConcurrent: Max simultaneous agent processesprocessTimeoutMs: Per-request timeout in milliseconds
browser - Playwright MCP and VNC
"browser": {
"enabled": false,
"mcpConfigPath": null,
"vncPort": 5900,
"novncPort": 6080,
"novncHost": "localhost"
}enabled: Enable Playwright MCP for the agentmcpConfigPath: Path to your MCP config (relative or absolute)vncPort: VNC server portnovncPort: Upstream noVNC WebSocket portnovncHost: Upstream noVNC host (e.g."vm"in Docker)
Browser mode (persistent or isolated) is controlled by the BROWSER_MODE environment variable, not the config file.
birds - Scheduled task settings
"birds": {
"maxAttempts": 3
}maxAttempts: Max job attempts before a bird stops retrying
Each bird supports per-bird active hours set via CLI --active-hours 09:00-17:00 or the API. Wrap-around windows (e.g. 22:00-06:00) are supported.
database - Retention policy
"database": {
"retentionDays": 30
}retentionDays: How long to keep messages, flight logs, jobs, and logs
web - Dashboard and API server
"web": {
"enabled": true,
"host": "127.0.0.1",
"port": 18800,
"corsOrigin": ""
}enabled: Enable the web dashboard and APIhost: Bind address (0.0.0.0for Docker/remote)port: Web UI and REST API portcorsOrigin: Allowed origin for CORS headers (for cross-origin SPA hosting)
Authentication is handled via the web UI. On first visit, you create an account. All subsequent visits require login.
| Variable | Description |
|---|---|
SLACK_BOT_TOKEN |
Bot user OAuth token |
SLACK_APP_TOKEN |
App-level token for Socket Mode |
ANTHROPIC_API_KEY |
Anthropic API key (pay-per-token). Used by both claude and opencode providers |
CLAUDE_CODE_OAUTH_TOKEN |
OAuth token for claude provider only (uses your Claude Pro/Max subscription) |
BROWSER_MODE |
persistent (default) or isolated. Requires container restart |
BROWSERBIRD_CONFIG |
Path to browserbird.json. Overridden by --config flag |
BROWSERBIRD_DB |
Path to SQLite database file. Overridden by --db flag |
NO_COLOR |
Disable colored output |
The opencode provider inherits standard env vars per model provider: OPENAI_API_KEY, GEMINI_API_KEY, OPENROUTER_API_KEY, etc. See the full list at models.dev.
Note
Agent authentication: ANTHROPIC_API_KEY (pay-per-token) is required for shared or commercial deployments per Anthropic's Consumer ToS. CLAUDE_CODE_OAUTH_TOKEN is fine for personal self-hosted use (claude provider only). When both are set, the claude provider uses OAuth and the opencode provider uses the API key.
$ browserbird --help
.__.
( ^>
/ )\
<_/_/
" "
usage: browserbird [command] [options]
commands:
sessions manage sessions
birds manage scheduled birds
config view configuration
logs show recent log entries
jobs inspect and manage the job queue
doctor check system dependencies
options:
-h, --help show this help
-v, --version show version
--verbose enable debug logging
--config config file path (env: BROWSERBIRD_CONFIG)
--db database file path (env: BROWSERBIRD_DB)
run 'browserbird <command> --help' for command-specific options.
Runs at http://localhost:18800 by default.
| Page | Description |
|---|---|
| Status | System overview, failing birds, upcoming runs, active sessions |
| Sessions | Session list with message history, token usage, and conversation detail |
| Birds | Scheduled birds: create, edit, enable/disable, trigger, inline flight history |
| Browser | Live noVNC viewer (Docker only) |
| Settings | Config editor, agent management, secrets, system birds, job queue, and log viewer |
git clone https://github.com/Owloops/browserbird.git
cd browserbird
npm cicd web && npm ci && npm run build && cd ..
./bin/browserbirdcp .env.example .env
docker compose -f oci/compose.yml up -d --buildnpm run typecheck # tsc --noEmit
npm run lint # eslint
npm run format:check # prettier
npm test # node --testWeb UI (from web/):
npm run check # svelte-check
npm run format:check # prettierFSL-1.1-MIT, source available, converts to MIT after two years.
Note
This project was built with assistance from LLMs. Human review and guidance provided throughout.
