@owloops/browserbird
v1.2.2
Published
Self-hosted AI agent for Slack with a real browser, a scheduler, and a web dashboard
Maintainers
Readme
BrowserBird
Self-hosted AI agent for Slack with a real browser, a scheduler, and a web dashboard.
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, building browser automation tools since 2020.
Installation
On first run, open the web UI and complete the onboarding wizard. It walks through Slack tokens, agent config, and API keys.
Docker (recommended)
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).
Railway
Slack
The manifest pre-configures all scopes, events, and slash commands. After creating the app, install it to your workspace and grab two tokens: the Bot User OAuth Token (xoxb-...) from OAuth & Permissions, and an app-level token (xapp-...) with connections:write scope from Basic Information.
Slash Commands
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[!TIP] If
/birdfails or routes to the wrong app, you may have another Slack app in the workspace with the same slash command. Remove or rename the duplicate from api.slack.com/apps.
Configuration
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": {
"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": [
{
"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": {
"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": {
"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": {
"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": {
"retentionDays": 30
}retentionDays: How long to keep messages, flight logs, jobs, and logs
"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.
Environment Variables
| 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_TOKENis 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.
CLI
Available on npm: npx @owloops/browserbird
$ 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.Web UI
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 |
Development
git clone https://github.com/Owloops/browserbird.git
cd browserbird
npm ciRun locally
cd web && npm ci && npm run build && cd ..
./bin/browserbirdDocker (build locally)
cp .env.example .env
docker compose -f oci/compose.yml up -d --buildChecks
npm 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 # prettierLicense
FSL-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.
