Browsing
Lightweight, headless-first MCP/API for browser automation
A concise MCP server and Rust library: navigate, get_links, follow_link, list_content (links+images), get_content, get_image, save_content, screenshot (full or element). Lazy browser init. Parallel reads via RwLock. Runs headless by default with 17+ lightweight Chrome flags for fast, minimal operation. No LLM or AI dependencies.
π― Usage Modes
- π MCP Server (primary) -
navigate,get_links,follow_link,list_content,get_content,get_image,save_content,screenshot,generate_sitemaptools - β¨οΈ CLI - Browser automation tasks
- π¦ Library - Browser automation via CDP
β¨ Why Browsing?
Browser automation is challenging. You need to:
- Extract structured data from unstructured HTML - Parse complex DOM trees into usable representations
- Handle browser automation reliably - Manage browser lifecycle, CDP connections, and process management
- Maintain testability - Mock components for unit testing without real browsers
- Support extensibility - Add custom actions and browser backends
Browsing solves all of this with a clean, modular, and well-tested architecture.
π§ Why Better Than Chrome DevTools?
Chrome DevTools Protocol (CDP) is an engine β it gives you raw browser control, but you must build all intelligence yourself. Most "headless browsing" tools are just CDP wrappers with slightly nicer APIs.
Browsing is a self-driving car on top of that engine. It adds five intelligence layers that are hard to replicate by simply wrapping CDP:
| Layer | CDP (Raw Protocol) | Browsing (Browser Automation) |
|---|---|---|
| Perception | Raw DOM tree | Semantic understanding: page intent, form schemas, action affordances |
| Action | Brittle backend_node_id/XPath |
Self-healing element resolution: index β text β semantic fallback |
| Memory | Nothing persists | Session history, site-specific strategies |
| Observability | Protocol logs | DOM state snapshots and action traces |
The goal: CDP becomes invisible. Users think about tasks, not WebSocket messages or element IDs.
π― Key Features
ποΈ Trait-Based Architecture
- BrowserClient trait - Abstract browser operations for easy mocking and alternative backends
- DOMProcessor trait - Pluggable DOM processing implementations
- ActionHandler trait - Extensible action system for custom behaviors
π Full Browser Automation
- Headless by default β
BrowserProfile::default()runs headless with--headless=new - 17+ lightweight flags β disables extensions, sync, background networking, logging, and more
- Cross-platform support (macOS, Linux, Windows)
- Automatic browser detection
- Chrome DevTools Protocol (CDP) integration
- Tab management (create, switch, close)
- Screenshot capture (page and element-level)
π Advanced DOM Processing
- Full CDP integration (DOM, AX tree, Snapshot)
- Text serialization with interactive element indices
- Accessibility tree support for better semantic understanding
π§ Extensible & Maintainable
- Manager-based architecture (TabManager, NavigationManager, ScreenshotManager)
- Custom action registration
- Utility traits for reduced code duplication
- Comprehensive test coverage (350+ tests)
π¦ Installation
As a Library
[]
= "0.1"
= { = "1.40", = ["full"] }
As a CLI Tool
As an MCP Server
π οΏ½ Quick Start## οΏ½ Quick Start
1οΈβ£ CLI Usage
# Run a browser automation task (headless by default)
# Run with visible browser
# Launch a headless browser and get CDP URL (headless by default)
# Launch with visible browser
# Connect to existing browser
2οΈβ£ MCP Server Usage
Configure in Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
Then ask Claude:
"Navigate to rust-lang.org, get the links, follow the second link, and screenshot the main content area"
3οΈβ£ Library Usage
use Result;
use Browser;
use BrowserProfile;
async
π Full Library Documentation
Browser Launch Options
use ;
// Option 1: Auto-launch headless browser (default)
let profile = default; // headless = true by default
let browser = new;
// Option 2: Launch with visible browser
let profile = default.with_headless;
let browser = new;
// Option 3: Connect to existing browser
let browser = new
.with_cdp_url;
// Option 4: Custom browser executable
use BrowserLauncher;
let launcher = new
.with_executable_path;
Using Traits for Testing
Standalone Browser Testing (no AI required)
use ;
use Arc;
// Test your browser automation logic directly
π Usage Examples
Content Download
use ;
use DOMProcessorImpl;
use DOMProcessor;
async
Run this example:
Screenshot Capture
use Browser;
let browser = new;
browser.start.await?;
// Full page screenshot
let screenshot_data = browser.take_screenshot.await?;
// Viewport only
let viewport = browser.take_screenshot.await?;
Direct Browser Control
use ;
async
Custom Actions
use ;
use Result;
use Tools;
;
// Register custom action
let mut tools = default;
tools.register_custom_action;
ποΈ Architecture
Browsing follows SOLID principles with a focus on separation of concerns, testability, and maintainability.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Browser Automation β
β βββββββββββββββ¬βββββββββββββββ¬ββββββββββββββββββββββββββ β
β β Browser β DOMProcessor β Tools β β
β β (trait) β (trait) β β β
β ββββββββ¬βββββββ΄βββββββ¬ββββββββ΄βββββββββββββββββ¬βββββββββ β
β β β β β
βββββββββββΌββββββββββββββΌβββββββββββββββββββββββΌββββββββββββ
β β β
βββββββΌβββββββ βββββΌβββββ ββββββββββΌββββββ
β Browser β βDomSvc β β Handlers β
β β β β β β
βTabManager β βCDP β βNavigation β
βNavManager β βHTML β βInteraction β
βScreenshot β βTree β βTabs β
β β βBuilder β βContent β
ββββββββββββββ ββββββββββ ββββββββββββββββ
Key Components
| Component | Responsibility | Trait-Based |
|---|---|---|
| Browser | Manages browser session and lifecycle | Implements BrowserClient |
| DOMProcessor | Extracts and serializes DOM | Implements DOMProcessor |
| Tools | Action registry and execution | Uses BrowserClient trait |
| Handlers | Specific action implementations | Use ActionHandler trait |
π Project Structure
browsing/
βββ src/
β βββ agent/ # Agent view types (used by tools layer)
β β βββ views.rs # Data types
β β βββ memory.rs # Session memory types
β βββ browser/ # Browser management
β β βββ session.rs # Browser session (BrowserClient impl)
β β βββ tab_manager.rs # Tab operations
β β βββ navigation.rs # Navigation operations
β β βββ screenshot.rs # Screenshot operations
β β βββ cdp.rs # CDP WebSocket client
β β βββ launcher.rs # Browser launcher
β β βββ profile.rs # Browser configuration
β βββ dom/ # DOM processing
β β βββ processor.rs # DOMProcessor trait impl
β β βββ serializer.rs # Text serialization
β β βββ tree_builder.rs # DOM tree construction
β β βββ cdp_client.rs # CDP wrapper for DOM
β β βββ html_converter.rs # HTML to markdown
β βββ tools/ # Action system
β β βββ service.rs # Tools registry
β β βββ handlers/ # Action handlers
β β β βββ navigation.rs
β β β βββ interaction.rs
β β β βββ tabs.rs
β β β βββ content.rs
β β β βββ advanced.rs
β β βββ params.rs # Parameter extraction
β βββ traits/ # Core trait abstractions
β β βββ browser_client.rs # BrowserClient trait
β β βββ dom_processor.rs # DOMProcessor trait
β βββ actor/ # Low-level interactions
β β βββ page.rs # Page operations
β β βββ element.rs # Element operations
β β βββ mouse.rs # Mouse interactions
β β βββ keyboard.rs # Keyboard input
β βββ config.rs # Configuration
β βββ error.rs # Error types
β βββ logging.rs # Logging setup
β βββ metrics.rs # Metrics collection
β βββ utils.rs # Utilities
β βββ views.rs # Shared data types
βββ Cargo.toml
π¨ Design Principles
Trait-Facing Design
- BrowserClient - Abstract browser operations for testing and alternative backends
- DOMProcessor - Pluggable DOM processing implementations
- ActionHandler - Extensible action system
Separation of Concerns
- TabManager - Tab operations (create, switch, close)
- NavigationManager - Navigation logic
- ScreenshotManager - Screenshot capture
- Handlers - Focused action implementations
DRY (Don't Repeat Yourself)
- ActionParams - Reusable parameter extraction
- JSONExtractor - Centralized JSON parsing
- SessionGuard - Unified session access
KISS (Keep It Simple, Stupid)
- Split complex methods into focused helpers
- Clear naming and single responsibility
- Minimal dependencies between modules
π§ͺ Testing
# Run all tests
# Run with output
# Run specific test
# Run integration tests only
Test Coverage
- 350+ tests across all modules (all passing, 0 ignored)
- Test files:
- actor_test.rs - Page, Element, Mouse, Keyboard operations
- browser_lifecycle_test.rs - Browser start/stop lifecycle
- browser_managers_test.rs - Navigation, Screenshot, Tab managers
- browser_test.rs - Browser integration
- cdp_enhancements_test.rs - CDP client features
- dom_extraction_test.rs - DOM extraction
- dom_test.rs - DOM state and serialization
- error_handling_test.rs - Error variants and propagation
- error_recovery_test.rs - Config validation and recovery
- integration_test.rs - Action models, URL extraction, tools
- integration_workflow_test.rs - Full workflow
- security_test.rs - Security validation
- tools_handlers_test.rs - All action handlers
- tools_test.rs - Tools registry
- traits_test.rs - BrowserClient, DOMProcessor traits
- utils_test.rs - URL extraction, signal handling
- agent_test.rs - Agent view types
- agent_service_test.rs - Agent state and history
- Mock implementations for deterministic testing
- Trait-based mocking for browser/DOM components
β οΈ Data Retention Policy
Browser Data is NEVER Deleted
IMPORTANT: The browsing library never deletes browser data for safety reasons.
What This Means:
| Data Type | Behavior |
|---|---|
| Bookmarks | Never deleted |
| History | Never deleted |
| Cookies | Never deleted |
| Passwords | Never deleted |
| Extensions | Never deleted |
| Cache | Never deleted |
| Temp Directories | Never deleted (left in /tmp/) |
Why This Policy Exists:
- User Safety: Users may specify a custom
user_data_dirpointing to their real browser profile - Catastrophe Prevention: Accidentally deleting a user's real browser data (bookmarks, history, passwords) would be devastating
- Debugging: Leaving temp directories allows inspection after crashes or failures
- User Control: Users are responsible for managing their own browser data
How It Works:
When no user_data_dir is specified:
let profile = BrowserProfile ;
When browser.stop() is called:
- β Browser process is killed
- β In-memory state is cleared
- β User data directory is NOT deleted
Managing Temporary Data:
Users are responsible for cleanup:
# List browser temp directories
# Delete old temp directories (optional, manual cleanup)
Using a Custom Data Directory:
let profile = BrowserProfile ;
Warning: If you point to your real browser profile, the library will NOT protect it. You're responsible for that directory.
π§ Configuration
Browser Profile
use BrowserProfile;
// Default: headless mode with lightweight flags
let profile = default;
// Explicit headless
let profile = default.with_headless;
// Visible browser for debugging
let profile = default.with_headless;
// With custom data directory
let profile = BrowserProfile ;
π API Documentation
Generate and view API docs: