fgp-browser

Crates.iofgp-browser
lib.rsfgp-browser
version0.1.0
created_at2026-01-14 07:48:54.872961+00
updated_at2026-01-14 07:48:54.872961+00
descriptionFGP daemon for browser automation via Chrome DevTools Protocol - 292x faster than Playwright MCP
homepage
repositoryhttps://github.com/wolfiesch/fgp-browser
max_upload_size
id2042383
size149,832
Wolfie (wolfiesch)

documentation

README

FGP Browser Gateway

Fast browser automation daemon using Chrome DevTools Protocol directly. 292x faster than Playwright MCP, 2.8x faster than Vercel's agent-browser.

Why?

MCP stdio tools spawn a new process for every call (~2.3s overhead). FGP Browser keeps Chrome warm and ready:

Operation FGP Browser Playwright MCP agent-browser
Navigate 8ms 2,328ms 22ms
Snapshot 9ms 2,484ms 31ms
Screenshot 30ms 1,635ms 34ms

Multi-step workflows show even bigger gains:

Workflow Steps FGP MCP Estimate Speedup
Login flow 5 659ms 11.5s 17x
Form submit 7 304ms 16.1s 53x
Pagination 10 1,087ms 23s 21x

Installation

# Clone and build
git clone https://github.com/wolfiesch/fgp-browser.git
cd fgp-browser
cargo build --release

# Add to PATH (optional)
cp target/release/browser-gateway ~/.local/bin/

Requirements:

  • Rust 1.70+
  • Chrome/Chromium installed

Quick Start

# Start the daemon
browser-gateway start

# Navigate to a page
browser-gateway open "https://example.com"

# Get ARIA accessibility tree (for LLM consumption)
browser-gateway snapshot

# Fill a form
browser-gateway fill "input#email" "user@example.com"
browser-gateway fill "input#password" "secret"
browser-gateway click "button[type=submit]"

# Take a screenshot
browser-gateway screenshot /tmp/page.png

# Stop the daemon
browser-gateway stop

CLI Commands

Core Operations

browser-gateway open <url>              # Navigate to URL
browser-gateway snapshot                # Get ARIA tree with element refs (@e1, @e2...)
browser-gateway screenshot [path]       # Capture PNG (default: /tmp/screenshot.png)
browser-gateway click <selector>        # Click element (CSS selector or @ref)
browser-gateway fill <selector> <text>  # Fill input field
browser-gateway press <key>             # Press key (Enter, Tab, Escape, etc.)

Form Interactions

browser-gateway select <selector> <value>    # Select dropdown option
browser-gateway check <selector>             # Check checkbox
browser-gateway check <selector> --uncheck   # Uncheck checkbox
browser-gateway hover <selector>             # Hover over element
browser-gateway scroll <selector>            # Scroll element into view
browser-gateway scroll --y 500               # Scroll down 500px
browser-gateway upload <selector> <path>     # Upload file
browser-gateway press-combo --modifiers Ctrl --key a  # Ctrl+A

Session Management

Multiple isolated browser sessions for parallel workflows:

browser-gateway session new --id gmail       # Create session
browser-gateway session list                 # List sessions
browser-gateway --session gmail open "https://gmail.com"
browser-gateway --session gmail snapshot
browser-gateway session close --id gmail     # Close session

Daemon Control

browser-gateway start                  # Start daemon (headless)
browser-gateway start --no-headless    # Start with visible browser
browser-gateway status                 # Check if running
browser-gateway health                 # Detailed health check
browser-gateway stop                   # Graceful shutdown

FGP Protocol

The daemon listens on a UNIX socket at ~/.fgp/services/browser/daemon.sock.

Request format (NDJSON):

{"id": "uuid", "v": 1, "method": "browser.open", "params": {"url": "https://example.com"}}

Response format:

{"id": "uuid", "ok": true, "result": {"title": "Example"}, "meta": {"server_ms": 8.2}}

Available Methods

Method Params Description
browser.open {url} Navigate to URL
browser.snapshot {} Get ARIA accessibility tree
browser.screenshot {path?} Capture PNG screenshot
browser.click {selector} Click element
browser.fill {selector, value} Fill input field
browser.press {key} Press keyboard key
browser.select {selector, value} Select dropdown option
browser.check {selector, checked?} Set checkbox state
browser.hover {selector} Hover over element
browser.scroll {selector?, x?, y?} Scroll page/element
browser.press_combo {key, modifiers[]} Key with modifiers
browser.upload {selector, path} Upload file
session.new {id} Create isolated session
session.list {} List active sessions
session.close {id} Close session

Architecture

┌─────────────────────────────────────────────────────────┐
│                    browser-gateway                       │
├─────────────────────────────────────────────────────────┤
│  FGP Server (concurrent, thread-per-connection)         │
│  └── UNIX Socket: ~/.fgp/services/browser/daemon.sock   │
├─────────────────────────────────────────────────────────┤
│  BrowserService                                          │
│  └── BrowserClient (chromiumoxide)                      │
│      ├── Default Session (shared page)                  │
│      └── Named Sessions (isolated BrowserContext each)  │
├─────────────────────────────────────────────────────────┤
│  Chrome DevTools Protocol (CDP)                         │
│  └── Headless Chrome/Chromium                           │
└─────────────────────────────────────────────────────────┘

Key design decisions:

  • Direct CDP (no Playwright abstraction) = minimal latency
  • Single-pass ARIA extraction = fast accessibility tree
  • BrowserContext isolation = parallel sessions without interference
  • Thread-per-connection = concurrent request handling

Integration with Claude Code

Add to your Claude Code skill or use directly:

# In your skill's run script
browser-gateway open "$URL"
SNAPSHOT=$(browser-gateway snapshot --json)
# Pass $SNAPSHOT to Claude for element selection
browser-gateway click "@e5"  # Click element ref from snapshot

Performance Tips

  1. Reuse sessions - Creating sessions has overhead; reuse for related operations
  2. Use element refs - @e5 from snapshot is faster than CSS selector lookup
  3. Batch operations - Chain commands without waiting for Claude between each
  4. Headless mode - Default; 10-20% faster than visible browser

Development

# Build debug
cargo build

# Build release
cargo build --release

# Run tests
cargo test

# Run with debug logging
RUST_LOG=debug ./target/release/browser-gateway start

Dependencies

License

MIT

Related

Commit count: 13

cargo fmt