- Mcp Selenium Haskell
Mcp Selenium Haskell
mcp-selenium-haskell
A Haskell implementation of MCP Selenium Server using WebDriver, enabling browser automation through standardized MCP clients like Claude.
Credits
This implementation is inspired by the mcp-selenium project developed by Angie Jones. We thank the original contributors for their foundational work in MCP Selenium automation.
Comparison with mcp-selenium (Node.js)
This project is a Haskell reimplementation of the original JavaScript mcp-selenium project. Here's an honest comparison between the two implementations:
Target Audience & Architecture
- Node.js: Direct WebDriver integration, single-session model
- Haskell: Multi-session support with UUID-based session management, connects to Selenium Grid
Installation & Dependencies
- Node.js: Published to npm with
npxsupport, includes browser management - Haskell: Statically-linked executable, requires separate Selenium server
Features & API
Both implementations provide identical MCP tool interfaces with these differences:
- Node.js: Implicit session management (one session per server instance)
- Haskell: Explicit session management with concurrent sessions
Additional Tools (Haskell-only):
- Console Logging Suite:
get_console_logs,inject_console_logger,get_injected_console_logs,get_available_log_types- comprehensive JavaScript console monitoring - Page Source:
get_source- retrieve current page HTML - Session Management: UUID-based session IDs with proper multi-session isolation
Testing & Reliability
- Node.js: Basic test coverage
- Haskell: 90+ integration tests with comprehensive validation
When to Choose Which
Choose Node.js mcp-selenium if you:
- Want the quickest setup with built-in browser management
- Prefer the JavaScript ecosystem
- Need a single browser session
Choose Haskell mcp-selenium if you:
- Need multiple concurrent browser sessions
- Want type safety and compile-time error checking
- Have existing Selenium Grid infrastructure
- Prefer zero-dependency executables
Current Status
Both implementations are production-ready with different strengths:
- Node.js: Faster setup, mature ecosystem, simpler deployment
- Haskell: Multi-session support, type safety, extensive test coverage
Choose based on your technical requirements and ecosystem preferences.
Features
- Multi-session browser management with UUID-based session IDs
- Element interaction: click, type, hover, drag & drop, double-click, right-click
- Element location using CSS selectors, XPath, ID, name, class, tag
- JavaScript console logging with injection and monitoring capabilities
- Screenshot capture and page source retrieval
- File upload support
- Keyboard input simulation
- Chrome and Firefox browser support
- Headless mode operation
- Statically-linked executable with zero runtime dependencies
API Documentation
For comprehensive documentation of all available tools and their parameters, see API.md.
Building
nix develop
# inside the shell that will open...
cabal build
Running
From the flake
nix run github:albertov/mcp-selenium-haskell
From the release
mcp-selenium-hs
Claude Desktop Configuration
To use this MCP server with Claude Desktop, add the following configuration to your claude_desktop_config.json file:
{
"mcpServers": {
"selenium": {
"command": "mcp-selenium-hs",
"args": [],
"env": {
"SELENIUM_HOST": "some.tailscale.host",
"SELENIUM_PORT": "1234",
}
}
}
}
Or from a flake
{
"mcpServers": {
"selenium": {
"command": "nix",
"args": ["run", "github:albertov/mcp-selenium-haskell"],
"env": {
"SELENIUM_HOST": "some.tailscale.host",
"SELENIUM_PORT": "1234",
}
}
}
}
The configuration file is typically located at:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
After adding this configuration, restart Claude Desktop to enable the Selenium MCP server.
Using with mcp-proxy
mcp-proxy allows you to expose the mcp-selenium server over HTTP/SSE for remote access or to connect to remote MCP servers. This is useful when you want to make the mcp-selenium proxy accessible through the network to MCP clients running on different machines. The underlying Selenium server can be located anywhere as long as the proper environment variables (SELENIUM_HOST, SELENIUM_PORT, etc.) are configured to reach it.
⚠️ SECURITY WARNING
NEVER bind mcp-proxy to
0.0.0.0on production systems or networks you don't fully control! This exposes your MCP server to the entire internet, potentially allowing unauthorized access to browser automation capabilities.Safe alternatives:
- Tailscale/VPN: Bind to your Tailscale interface IP (e.g.,
--host=100.x.x.x)- Local + SSH: Use
--host=127.0.0.1and SSH port forwarding (ssh -L 8080:localhost:8080 user@server)- Private networks: Only bind to private network interfaces you control
- Firewall: If you must use
0.0.0.0, ensure proper firewall rules restrict access
Exposing mcp-selenium over SSE (Local to Remote)
To run mcp-selenium behind mcp-proxy and expose it over SSE for remote access:
# Install mcp-proxy
uv tool install mcp-proxy
# Run mcp-selenium behind the proxy on localhost (safe for local development)
mcp-proxy --port=8080 mcp-selenium-hs
# For network access, bind to a specific interface (replace with your Tailscale IP)
mcp-proxy --host=100.64.1.100 --port=8080 mcp-selenium-hs
# Or use SSH port forwarding for remote access
# On the server:
mcp-proxy --host=127.0.0.1 --port=8080 mcp-selenium-hs
# On the client:
# ssh -L 8080:localhost:8080 user@your-server
The server will be accessible at:
- SSE endpoint:
http://localhost:8080/sse - Status endpoint:
http://localhost:8080/status
You can then configure Claude Desktop to connect to the proxy instead of directly to the server:
{
"mcpServers": {
"selenium-proxy": {
"command": "mcp-proxy",
"args": ["http://your-server:8080/sse"],
"env": {}
}
}
}
Multiple Named Servers
You can run multiple instances of mcp-selenium with different configurations:
# Run multiple selenium instances with different headless settings
mcp-proxy --port=8080 \
--named-server selenium-headless 'mcp-selenium-hs' \
--named-server selenium-desktop 'mcp-selenium-hs'
This exposes:
- Headless instance:
http://localhost:8080/servers/selenium-headless/sse - Desktop instance:
http://localhost:8080/servers/selenium-desktop/sse
Note: Browser type (Chrome/Firefox) and other options are specified through the MCP tool parameters, not environment variables.
Using Configuration Files
For complex setups, use a JSON configuration file:
{
"mcpServers": {
"selenium-default": {
"command": "mcp-selenium-hs",
"args": [],
"transportType": "stdio"
},
"selenium-remote": {
"command": "mcp-selenium-hs",
"args": [],
"env": {
"SELENIUM_HOST": "selenium.example.com",
"SELENIUM_PORT": "4444"
},
"transportType": "stdio"
}
}
}
Then run:
mcp-proxy --port=8080 --named-server-config ./selenium-servers.json
Docker Deployment
For containerized deployments, you can use mcp-proxy with Docker. Always use specific interface binding for security:
FROM ghcr.io/sparfenyuk/mcp-proxy:latest
# Install dependencies and copy mcp-selenium-hs binary
RUN wget -O /usr/local/bin/mcp-selenium-hs https://github.com/albertov/mcp-selenium-haskell/releases/latest/download/mcp-selenium-hs
RUN chmod +x /usr/local/bin/mcp-selenium-hs
EXPOSE 8080
# Use a specific interface IP instead of 0.0.0.0
ENTRYPOINT ["mcp-proxy", "--host=127.0.0.1", "--port=8080", "mcp-selenium-hs"]
For Tailscale integration in Docker:
# Run with Tailscale network access
docker run -d \
--name mcp-selenium-proxy \
--network=host \
-e TAILSCALE_HOSTNAME=$(tailscale ip -4) \
your-mcp-proxy-image \
mcp-proxy --host=$(tailscale ip -4) --port=8080 mcp-selenium-hs
Secure Network Access with Tailscale
For the safest remote access, use Tailscale to create a secure network:
- Install Tailscale on both server and client machines
- Get your server's Tailscale IP:
tailscale ip -4 - Run mcp-proxy bound to the Tailscale interface:
# Replace 100.64.1.100 with your actual Tailscale IP
mcp-proxy --host=100.64.1.100 --port=8080 mcp-selenium-hs
- Configure Claude Desktop to connect using the Tailscale IP:
{
"mcpServers": {
"selenium-proxy": {
"command": "mcp-proxy",
"args": ["http://100.64.1.100:8080/sse"],
"env": {}
}
}
}
Environment Variables
When using mcp-proxy, you can pass environment variables to configure the Selenium connection:
# Pass custom Selenium server configuration
mcp-proxy --port=8080 \
--env SELENIUM_HOST selenium.example.com \
--env SELENIUM_PORT 4444 \
mcp-selenium-hs
Complete list of supported environment variables:
| Variable | Default | Description | Example |
|---|---|---|---|
SELENIUM_HOST | 127.0.0.1 | Hostname or IP address of the Selenium WebDriver server | selenium.example.com |
SELENIUM_PORT | 4444 | Port number of the Selenium WebDriver server | 4444 |
Configuration Examples:
For local Selenium server (default):
# These are the defaults, no configuration needed
export SELENIUM_HOST=127.0.0.1
export SELENIUM_PORT=4444
For remote Selenium Grid:
export SELENIUM_HOST=selenium-grid.company.com
export SELENIUM_PORT=4444
For Docker-based Selenium:
export SELENIUM_HOST=selenium-container
export SELENIUM_PORT=4444
For Selenium running on different port:
export SELENIUM_HOST=localhost
export SELENIUM_PORT=8080
CORS Configuration
To allow browser-based clients to connect, you can enable CORS. Be careful with wildcard origins:
# ⚠️ Only use '*' for development/testing - NEVER in production!
mcp-proxy --port=8080 --allow-origin='*' mcp-selenium-hs
For production, always specify exact origins:
# Safe: specify exact origins you trust
mcp-proxy --port=8080 \
--allow-origin='https://claude.ai' \
--allow-origin='https://your-app.com' \
mcp-selenium-hs
Integration Testing
The project includes comprehensive black-box integration tests that validate the MCP server functionality through its external interface.
Quick Start
Run all integration tests:
./run_integration_tests.sh
This automatically:
- Starts selenium-server daemon
- Starts HTTP server for test fixtures
- Builds the mcp-selenium-hs executable
- Runs the integration test suite
- Stops all services
Documentation
For detailed information about the integration testing setup, see integration_tests/README.md.
Dependencies
The project uses the following key dependencies:
webdriver- Selenium WebDriver bindings for Haskellhs-mcp- Model Context Protocol implementationaeson- JSON parsing and encoding
Development
Prerequisites
- GHC 9.10.2 or compatible
- Cabal 3.0+
- For integration tests: Python 3, pytest, selenium-server-standalone, chromium
Nix Environment
The project provides a Nix environment with all dependencies:
nix-shell
Or with flakes:
nix develop
Testing
Unit tests:
cabal test
Integration tests:
./run_integration_tests.sh
Code Quality
Format code:
nix fmt
Check code quality and run linting:
nix check
License
BSD-3-Clause - see LICENSE file for details.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Run the test suite
- Submit a pull request
Please ensure all tests pass and code follows the project style guidelines.
Server Config
{
"mcpServers": {
"selenium": {
"command": "mcp-selenium-hs",
"args": [],
"env": {
"SELENIUM_HOST": "some.tailscale.host",
"SELENIUM_PORT": "1234"
}
}
}
}