Project

crucible

0.0
A long-lived project that still receives updates
An MCP (Model Context Protocol) server that provides browser automation tools for AI agents using Ferrum and headless Chrome. Features 25 tools covering navigation, screenshots, form interaction, JavaScript evaluation, cookies, file downloads, and multi-session management.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

Runtime

>= 0
>= 0
 Project Readme

Crucible

A Ruby MCP (Model Context Protocol) server for browser automation using Ferrum and headless Chrome. Provides 29 tools that AI agents can use to control browsers, with built-in stealth mode to evade bot detection.

Installation

gem install crucible

Or from source:

git clone https://github.com/joshfng/crucible.git
cd crucible
bundle install

Usage

Running the Server

# Run with defaults (headless, 1280x720 viewport, 30s timeout)
crucible

# Run with visible browser
crucible --no-headless

# Full options
crucible \
  --no-headless \
  --width 1920 \
  --height 1080 \
  --timeout 60 \
  --chrome /usr/bin/chromium \
  --error-level debug

CLI Options

Option Description Default
-c, --config FILE Path to YAML configuration file auto-detect
--[no-]headless Run browser in headless mode true
-w, --width WIDTH Viewport width in pixels 1280
-h, --height HEIGHT Viewport height in pixels 720
--chrome PATH Path to Chrome/Chromium executable auto-detect
-t, --timeout SECONDS Default timeout in seconds 30
--error-level LEVEL Logging level (debug/info/warn/error) warn
--screenshot-format FMT Default screenshot format (png/jpeg/base64) png
--content-format FMT Default content format (html/text) html
--[no-]stealth Enable/disable stealth mode true
--stealth-profile PROFILE Stealth profile (minimal/moderate/maximum) moderate
--stealth-locale LOCALE Browser locale for stealth mode en-US,en

Claude Code Integration

gem install crucible

Add to your Claude Code MCP settings (~/.claude/settings.json):

{
  "mcpServers": {
    "crucible": {
      "command": "crucible",
      "args": ["--config", "~/.config/crucible/config.yml"]
    }
  }
}

Tools

Navigation

Tool Description
navigate Navigate browser to a URL
wait_for Wait for an element to appear
back Navigate back in history
forward Navigate forward in history
refresh Refresh the current page

Interaction

Tool Description
click Click an element (supports double-click, right-click)
type Type text into an input (with optional clear/submit)
fill_form Fill multiple form fields at once
select_option Select option from dropdown
scroll Scroll page or element into view
hover Hover over an element

Extraction

Tool Description
screenshot Take screenshot (viewport, full page, or element); save to file or return base64
get_content Get page content (HTML or text)
pdf Generate PDF of the page; save to file or return base64
evaluate Execute JavaScript and return result
get_url Get current page URL
get_title Get current page title

Cookies

Tool Description
get_cookies Get all cookies or specific cookie
set_cookies Set one or more cookies
clear_cookies Clear all or specific cookies

Sessions

Tool Description
list_sessions List all active browser sessions
close_session Close a session or all sessions

Downloads

Tool Description
set_download_path Set the directory for downloads
wait_for_download Wait for a download to complete
list_downloads List all tracked downloads
clear_downloads Clear tracked downloads (optionally delete files)

Stealth

Tool Description
enable_stealth Enable stealth mode for a session
disable_stealth Disable stealth mode for a session
get_stealth_status Get stealth mode status for a session
set_stealth_profile Change the stealth profile (minimal/moderate/maximum)

Session Management

All tools accept an optional session parameter to manage multiple independent browser instances:

# These run in separate browsers
navigate(session: "login-flow", url: "https://example.com/login")
navigate(session: "signup-flow", url: "https://example.com/signup")

# List active sessions
list_sessions()
# => { "count": 2, "sessions": ["login-flow", "signup-flow"] }

# Close a specific session
close_session(session: "login-flow")

# Close all sessions
close_session(all: true)

Sessions are created automatically on first use and persist until explicitly closed.

Example Workflows

Basic Navigation

navigate(url: "https://example.com")
wait_for(selector: ".content")
get_content(format: "text")

Form Submission

navigate(url: "https://example.com/login")
type(selector: "#email", text: "user@example.com")
type(selector: "#password", text: "secret123")
click(selector: "button[type=submit]")
wait_for(selector: ".dashboard")

Screenshots & PDFs

# Viewport screenshot (returns base64)
screenshot()

# Full page screenshot
screenshot(full_page: true)

# Element screenshot
screenshot(selector: ".hero-image")

# Save to file
screenshot(path: "/tmp/page.png")
screenshot(format: "jpeg", quality: 90, path: "/tmp/page.jpg")

# PDF generation
pdf()                                    # Returns base64
pdf(path: "/tmp/page.pdf")               # Save to file
pdf(format: "Letter", landscape: true)   # Custom format

JavaScript Execution

# Get page dimensions
evaluate(expression: "[window.innerWidth, window.innerHeight]")

# Scroll to top
evaluate(expression: "window.scrollTo(0, 0)")

# Get element count
evaluate(expression: "document.querySelectorAll('a').length")

File Downloads

# Set download directory
set_download_path(path: "/tmp/downloads")

# Click download link and wait
click(selector: "a.download-btn")
wait_for_download(timeout: 30)

# List tracked downloads (persists across navigation)
list_downloads()

# Clear tracking and delete files
clear_downloads(delete_files: true)

Stealth Mode

Stealth mode applies various evasion techniques to make headless Chrome appear as a regular browser to bot detection systems. It is enabled by default with the "moderate" profile.

Stealth Profiles

Profile Description
minimal Basic evasions (navigator.webdriver, window dimensions)
moderate Common evasions for most use cases (default)
maximum All evasions for strictest bot detection

Evasions Applied

The stealth module includes evasions ported from puppeteer-extra:

  • navigator.webdriver - Remove the webdriver flag
  • chrome.app - Mock the chrome.app object
  • chrome.csi - Mock the chrome.csi function
  • chrome.loadTimes - Mock chrome.loadTimes
  • chrome.runtime - Mock chrome.runtime for extensions
  • navigator.vendor - Override navigator.vendor
  • navigator.languages - Match Accept-Language header
  • navigator.plugins - Mock plugins and mimeTypes
  • navigator.permissions - Fix Notification.permission
  • navigator.hardwareConcurrency - Set realistic core count
  • webgl.vendor - Fix WebGL vendor/renderer
  • media.codecs - Report support for proprietary codecs
  • iframe.contentWindow - Fix iframe detection
  • window.outerdimensions - Fix outerWidth/outerHeight
  • User-Agent override - Strip "Headless" and fix platform

Runtime Control

# Check stealth status
get_stealth_status(session: "default")

# Enable with maximum protection
enable_stealth(session: "default", profile: "maximum")

# Disable stealth (already-applied evasions remain)
disable_stealth(session: "default")

# Change profile
set_stealth_profile(session: "default", profile: "minimal")

Configuration File

Create ~/.config/crucible/config.yml:

browser:
  headless: true
  window_size: [1280, 720]

stealth:
  enabled: true
  profile: moderate
  locale: "en-US,en"

server:
  log_level: info

Project Structure

crucible/
├── exe/crucible                # CLI executable
├── crucible.gemspec            # Gem specification
├── Gemfile                     # Dependencies
├── Rakefile                    # Build tasks
├── lib/
│   ├── crucible.rb             # Main module
│   └── crucible/
│       ├── version.rb          # Version constant
│       ├── configuration.rb    # Config with YAML support
│       ├── session_manager.rb  # Multi-session management
│       ├── server.rb           # MCP server setup
│       ├── stealth.rb          # Stealth mode module
│       ├── stealth/
│       │   ├── utils.js        # Stealth utilities
│       │   └── evasions/       # Individual evasion scripts
│       └── tools/
│           ├── helpers.rb      # Shared utilities
│           ├── navigation.rb   # Navigation tools
│           ├── interaction.rb  # Interaction tools
│           ├── extraction.rb   # Extraction tools
│           ├── cookies.rb      # Cookie tools
│           ├── sessions.rb     # Session tools
│           ├── downloads.rb    # Download tools
│           └── stealth.rb      # Stealth control tools
└── spec/                       # RSpec tests

Development

# Run tests
bundle exec rspec

# Run linter
bundle exec rubocop

# Interactive console
bundle exec rake console

# Run server in development
bundle exec rake server

Releasing

bin/release 0.2.0

This script bumps the version, commits, tags, pushes, creates a GitHub release, builds the gem, and pushes to RubyGems (you'll handle MFA via browser).

Requirements

  • Ruby >= 3.2.0
  • Chrome or Chromium browser
  • Dependencies:
    • ferrum ~> 0.17.1
    • mcp ~> 0.4.0

License

MIT License. See LICENSE for details.