Skip to main content

Production-ready MCP server integrating Selenium 4 (BiDi) for browser automation

Project description

selenium-mcp

A production-ready MCP (Model Context Protocol) server that exposes Selenium 4 browser automation as MCP tools. Supports Chrome and Firefox with full BiDi (Bidirectional API) event streaming.


Architecture

selenium-mcp/
├── server.py               # MCP entrypoint (JSON-RPC 2.0 over stdio)
├── config/
│   ├── settings.py         # ENV + YAML config loader (singleton)
│   ├── default.yaml        # Default configuration values
│   └── logging_config.py   # Structured logging setup
├── driver/
│   ├── factory.py          # WebDriver factory (Chrome / Firefox + BiDi)
│   ├── session.py          # BrowserSession – wraps a single WebDriver
│   └── session_manager.py  # Registry of all active sessions
├── events/
│   ├── dispatcher.py       # Async pub/sub event dispatcher (asyncio.Queue)
│   ├── bidi_listeners.py   # BiDi WebSocket event listeners
│   └── network_interceptor.py  # CDP/BiDi network interception
├── tools/
│   ├── base.py             # BaseTool + error-screenshot decorator
│   ├── navigation_tools.py # open_page, navigate_back/forward, get_dom
│   ├── interaction_tools.py# click, type_text, get_text, wait_for
│   ├── script_tools.py     # execute_js, screenshot
│   ├── log_tools.py        # get_console_logs, get_network_logs, intercept_requests
│   ├── session_tools.py    # create_session, close_session, list_sessions
│   └── registry.py         # Tool name → callable map + MCP descriptors
└── models/
    ├── session.py          # SessionInfo, BrowserType, SessionStatus
    ├── events.py           # BrowserEvent, ConsoleLogEvent, NetworkRequestEvent, …
    ├── network.py          # NetworkLog, ConsoleLog, InterceptRule, PerformanceMetrics
    └── exceptions.py       # Custom exception hierarchy

Layered design

MCP Client (Claude / any MCP host)
        ↕  JSON-RPC 2.0 / stdio
    server.py  (MCPServer)
        ↕
    tools/registry.py  →  tools/*.py  (business logic)
        ↕
    driver/session_manager.py  →  driver/session.py
        ↕                               ↕
    driver/factory.py           events/bidi_listeners.py
    (WebDriver creation)        (BiDi / CDP event capture)
        ↕                               ↕
    Selenium 4 WebDriver       events/dispatcher.py
    (Chrome / Firefox)         (async pub/sub)

Quick start

Prerequisites

Requirement Version
Python 3.11+
Chrome / ChromeDriver latest stable
Firefox / GeckoDriver latest stable (optional)

Installation

# 1. Clone / enter the project
git clone <repo> selenium-mcp
cd selenium-mcp

# 2. Create a virtual environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate

# 3. Install dependencies
pip install -r requirements.txt

# 4. (Optional) install as editable package
pip install -e .

Run the server

# Stdio mode (standard MCP transport)
python server.py

# Or via the installed entry-point
selenium-mcp

The server reads JSON-RPC 2.0 messages from stdin and writes responses to stdout.


Configuration

Configuration is loaded in priority order:

  1. Environment variables (SMCP_*)
  2. YAML file (SMCP_CONFIG_FILE env var or config/default.yaml)
  3. Built-in defaults

Key settings

ENV variable YAML key Default Description
SMCP_BROWSER browser.default chrome Default browser (chrome/firefox)
SMCP_HEADLESS browser.headless true Run headless
SMCP_MAX_SESSIONS browser.max_sessions 5 Max concurrent sessions
SMCP_BIDI_ENABLED bidi.enabled true Enable BiDi WebSocket
SMCP_LOG_LEVEL server.log_level INFO Log level
SMCP_DEBUG server.debug false Verbose debug logging
SMCP_SCREENSHOT_ON_ERROR screenshot.on_error true Auto-screenshot on errors
SMCP_SCREENSHOT_DIR screenshot.directory screenshots/ Screenshot output dir

Custom YAML config

SMCP_CONFIG_FILE=/path/to/my-config.yaml python server.py

Example my-config.yaml:

browser:
  default: firefox
  headless: false
  max_sessions: 3
bidi:
  enabled: true
screenshot:
  on_error: true
  directory: /tmp/mcp-screenshots

MCP Tools reference

Session management

Tool Description Key params
create_session Open a new browser browser, headless
close_session Close a session session_id
list_sessions List active sessions
get_session_info Get session metadata session_id

Navigation

Tool Description Key params
open_page Navigate to URL url
navigate_back History back
navigate_forward History forward
get_dom Full page HTML

Element interaction

Tool Description Key params
click Click a CSS selector selector
type_text Type into an input selector, text
get_text Get element text selector
wait_for Wait until visible selector, timeout
wait_for_dom_stable Smart DOM-stability wait timeout

Script & media

Tool Description Key params
execute_js Run JavaScript script
screenshot Capture viewport (base64 PNG)

Logs & network

Tool Description Key params
get_console_logs Browser console entries
get_network_logs Network request/response log
get_performance_metrics Page timing data
intercept_requests Register URL intercept rule pattern, action

Connecting to MCP clients

Via uvx (recommended — zero install)

uvx mcp_selenium

Via pip

pip install mcp_selenium
selenium-mcp

Local development (uv run)

git clone https://github.com/SCV-Consultants/selenium-mcp.git
cd selenium-mcp
uv run selenium-mcp

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "selenium": {
      "command": "uvx",
      "args": ["mcp_selenium"],
      "env": {
        "SMCP_HEADLESS": "false",
        "SMCP_BROWSER": "chrome"
      }
    }
  }
}

Antigravity / Gemini

Add to your MCP config (mcp_config.json):

{
  "mcpServers": {
    "selenium": {
      "command": "uvx",
      "args": ["mcp_selenium"],
      "env": {
        "SMCP_HEADLESS": "false",
        "SMCP_BROWSER": "chrome"
      }
    }
  }
}

For local development, use uv run instead:

{
  "mcpServers": {
    "selenium": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/selenium-mcp", "selenium-mcp"],
      "env": {
        "SMCP_HEADLESS": "false",
        "SMCP_BROWSER": "chrome"
      }
    }
  }
}

Claude CLI

claude mcp add selenium -- uvx mcp_selenium

Install via Smithery

npx -y @smithery/cli install mcp_selenium --client claude

BiDi / Event system

When bidi.enabled: true the server attaches BiDi WebSocket listeners to each session:

  • Console eventsconsole.log, console.error, etc. are captured and stored per-session. Retrieved via get_console_logs.
  • JS errors – JavaScript runtime errors are captured as error-level console entries.
  • Network events – CDP Network.enable (Chrome) captures request/response data. Retrieved via get_network_logs.
  • Event dispatcher – All events flow through an asyncio.Queue-backed pub/sub hub (events/dispatcher.py). Custom async handlers can be registered per event type for real-time streaming use cases.

Error handling

All tools wrap failures in a typed exception hierarchy:

Exception Trigger
SessionNotFoundError Invalid session_id
SessionLimitError Too many concurrent sessions
ElementNotFoundError CSS selector matched nothing
ElementInteractionError Element not clickable/typeable
NavigationError get() / history navigation failed
ScriptExecutionError JavaScript threw or timed out
TimeoutError wait_for condition not met
NetworkInterceptionError CDP interception setup failed
BiDiNotSupportedError BiDi requested but unavailable

When screenshot.on_error: true, a PNG is saved to screenshot.directory automatically on any SeleniumMCPError.


Development

# Lint
ruff check .

# Type check
mypy .

# Tests
pytest tests/ -v

Retry mechanism

All element interactions use an internal _retry() helper that retries on StaleElementReferenceException and transient WebDriverException. Configurable via:

retry:
  max_attempts: 3
  backoff_seconds: 1.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_selenium-1.0.2.tar.gz (40.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_selenium-1.0.2-py3-none-any.whl (42.2 kB view details)

Uploaded Python 3

File details

Details for the file mcp_selenium-1.0.2.tar.gz.

File metadata

  • Download URL: mcp_selenium-1.0.2.tar.gz
  • Upload date:
  • Size: 40.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mcp_selenium-1.0.2.tar.gz
Algorithm Hash digest
SHA256 9831b45adee6b6b8e1c9ea5a2ca8bf99d35205854b267b209b300e422d9a97f9
MD5 b4f35c3b536e951e8d4bc1ad67136ea6
BLAKE2b-256 2d3b76641bc07f01f5fbceddddf71cc69e5fedb7667c930783f1d423b7eb371b

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_selenium-1.0.2.tar.gz:

Publisher: publish.yml on SCV-Consultants/selenium-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_selenium-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: mcp_selenium-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 42.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mcp_selenium-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 832280412f0ed53a9a242f0080070952533e57ba8a966863cef90bba156c3032
MD5 61703a1233c2a7066b1b07fcb0077188
BLAKE2b-256 60cf2cd98ac4d6c22d5c7a6c25b629856a529a04f5c8fa4425035c43e574f025

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_selenium-1.0.2-py3-none-any.whl:

Publisher: publish.yml on SCV-Consultants/selenium-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page