The agent platform powering BrowserOS — contains the MCP server, agent UI, CLI, and shared packages.
apps/
server/ # Bun server - MCP endpoints + agent loop
app/ # BrowserOS app UI (Chrome extension)
cli/ # Go CLI for controlling BrowserOS from the terminal
packages/
cdp-protocol/ # Type-safe Chrome DevTools Protocol bindings
shared/ # Shared constants (ports, timeouts, limits)
| Package | Description |
|---|---|
apps/server |
Bun server exposing MCP tools and running the agent loop |
apps/app |
BrowserOS app UI — Chrome extension for the chat interface |
apps/cli |
Go CLI — control BrowserOS from the terminal or AI coding agents |
packages/cdp-protocol |
Auto-generated CDP type bindings used by the server |
packages/shared |
Shared constants used across packages |
apps/server: Bun server which contains the agent loop and tools.apps/app: BrowserOS app UI (Chrome extension).
┌──────────────────────────────────────────────────────────────────────────┐
│ MCP Clients │
│ (Agent UI, claude-code via MCP) │
└──────────────────────────────────────────────────────────────────────────┘
│
│ HTTP/SSE
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ BrowserOS Server (serverPort: 9100) │
│ │
│ /mcp ─────── MCP tool endpoints │
│ /chat ────── Agent streaming │
│ /system/health ─ Health check │
│ │
│ Tools: │
│ └── CDP-backed browser tools (tabs, navigation, input, screenshots, │
│ bookmarks, history, console, DOM, tab groups, windows, ...) │
└──────────────────────────────────────────────────────────────────────────┘
│
│ CDP (client)
▼
┌─────────────────────┐
│ Chromium CDP │
│ (cdpPort: 9000) │
│ │
│ Server connects │
│ TO this as client │
└─────────────────────┘
| Port | Sidecar Field | Purpose |
|---|---|---|
| 9100 | ports.server |
HTTP server - MCP endpoints, agent chat, health |
| 9000 | ports.cdp |
Chromium CDP server (BrowserOS Server connects as client) |
| 9100 | ports.proxy |
Browser proxy port emitted by Chromium for managed sidecars |
# Copy the root development environment file
cp .env.development.example .env.development
# Install deps and generate agent code
bun run dev:setup
# Start the full dev environment
bun run dev:watchdev:watch starts the server and app UI immediately.
Existing checkouts with old per-app env files should run bun run env:migrate to merge those values into the root files.
For release builds, copy .env.production.example to .env.production and fill the production-only secrets before running build or upload scripts.
The monorepo has two root env files:
.env.development- local development, tests, app/server runs, and codegen inputs..env.production- release builds and upload scripts.
Both are gitignored. Their tracked templates, .env.development.example and .env.production.example, are generated from @browseros/shared/env/registry; run bun run env:examples after changing the registry. CI drift-checks the generated examples.
Fresh clone setup is: copy .env.development.example to .env.development, fill any secrets needed for the workflow, then run bun run dev:*. Existing checkouts can run bun run env:migrate to merge old per-app values into the root files.
Server Sidecar Config (--config <path>)
The server and Claw server read startup ports, resource directories, execution directories, and instance metadata from a sidecar JSON file. tools/dev, dogfood, and Chromium-managed sidecar launches generate this file and pass it with --config.
| Field | Description |
|---|---|
ports.server |
HTTP server port (MCP, chat, health) |
ports.cdp |
Chromium CDP port (server connects as client) |
ports.proxy |
Browser proxy port emitted by Chromium |
directories.resources |
Packaged resources root |
directories.execution |
Runtime execution/log/config directory |
instance.* |
Optional browser/client metadata |
Root Env Sections
| Section | File | Purpose |
|---|---|---|
dev-tools |
.env.development |
Optional codegen and local tooling inputs such as CDP_PROTOCOL_JSON and BROWSEROS_BINARY. |
app |
.env.development |
Browser extension and local BrowserOS launch settings, including dev ports, public Vite values, source-map upload settings, and optional GraphQL schema path. |
claw |
.env.development |
Optional Claw app/server overrides such as Claw API URL, user-data dir, CDP port, and BROWSERCLAW_DIR. |
server |
.env.development, .env.production |
Server config URL, telemetry, Sentry, NODE_ENV, log level, and local server test settings. |
upload |
.env.production |
Cloudflare R2 credentials and bucket for production artifact uploads. |
Production build and upload scripts read root .env.production plus exported process env through the shared loader in @browseros/shared/env/*; exported process env takes precedence. Missing required values fail with an error naming the key, section, and root file.
# Start
bun run dev:watch # Start server and app with generated sidecar config
bun run start:server # Start the server from the repo root
cd apps/server && bun --env-file=../../.env.development src/index.ts --config ../../config.dev.json
# Build
bun run build # Build server and agent
bun run build:server # Build production server resource artifacts and upload zips to R2
bun run build:claw-server # Build five-platform BrowserClaw Rust resources and upload zips to R2
bun run build:agent # Build agent extension
# Test
bun run test # Run all tests
bun run test:all # Run all tests
bun run test:main # Run key server tools and integration tests
# App-specific test groups (from packages/browseros-agent)
cd apps/server && bun run test:tools
cd apps/server && bun run test:cdp
cd apps/server && bun run test:integration
# Quality
bun run lint # Check with Biome
bun run lint:fix # Auto-fix
bun run typecheck # TypeScript checkbun run typecheck runs the native TypeScript 7 compiler (tsc from typescript@7, the Go-native build). Unlike an editor's bundled classic TypeScript, the native compiler does not implicitly include every @types/* package it finds — each tsconfig must list its ambient type packages in compilerOptions.types (the root tsconfig defaults to ["node", "bun"]). A new package that omits this may look green in the editor but fail bun run typecheck in CI with "Cannot find name 'Bun' / 'process'"; add the needed names to its types array. For editor parity with CI, install your editor's native TypeScript 7 support.
build:server now emits artifacts under dist/prod/server/<target>/ and zip files under dist/prod/server/.
Direct server build script options:
bun scripts/build/server.ts --target=all
bun scripts/build/server.ts --target=darwin-arm64,linux-x64
bun scripts/build/server.ts --target=all --manifest=scripts/build/config/server-prod-resources.json
bun scripts/build/server.ts --target=all --no-uploadThe BrowserClaw Rust builder runs on macOS and produces the same five resource
ZIPs as release-claw-server.yml: macOS ARM64/x64, Linux ARM64/x64, and Windows
x64. Darwin targets use Cargo and Xcode, Linux targets use Zig with a glibc 2.17
floor, and Windows uses the MSVC ABI through cargo-xwin.
Install the one-time host toolchain:
xcrun --find clang || xcode-select --install
brew install rustup zig llvm cmake nasm
rustup-init
export PATH="$(brew --prefix llvm)/bin:$PATH"
cargo install --locked cargo-zigbuild --version 0.23.0
cargo install --locked cargo-xwin --version 0.23.0
rustup target add \
aarch64-apple-darwin \
x86_64-apple-darwin \
aarch64-unknown-linux-gnu \
x86_64-unknown-linux-gnu \
x86_64-pc-windows-msvcThe build command preflights every selected target before compiling and repeats
the relevant install command for anything missing. cargo-xwin downloads and
caches the Microsoft CRT and Windows SDK on its first build.
# Build and package all five targets without R2 credentials
bun scripts/build/claw-server-rust.ts --target=all --ci
# Use production telemetry configuration but keep every artifact local
bun scripts/build/claw-server-rust.ts --target=all --no-upload
# Build selected targets
bun scripts/build/claw-server-rust.ts --target=darwin-arm64,linux-x64 --no-upload
# Upload immutable version keys without moving latest
RELEASE_SHA="$(git rev-parse HEAD)" \
bun scripts/build/claw-server-rust.ts --target=all --upload --versioned-onlyNormal builds read CLAW_POSTHOG_KEY, optional CLAW_POSTHOG_HOST, and R2
credentials from the root .env.production plus exported environment values.
--ci always embeds a non-production placeholder and never uploads. Output
directories and ZIPs live under dist/prod/claw-server-rust/.
The artifact version comes from apps/claw-server-rust/Cargo.toml. When
replacing the build stage of a prepared release, stamp that version in a clean,
disposable checkout before building:
VERSION=0.0.27
(cd ../browseros && uv run browseros release component stamp \
--component claw-server-rust --version "$VERSION")AGPL-3.0