BROWSER BRIDGE / MCP SERVER

Causeway

AI meets browser. Data flows between.

Three layers. One direction.

01

Claude Code

AI sends tool calls over stdio. Navigate, click, screenshot, read — structured MCP, not natural language.

stdio
02

Causeway

Rust binary translates MCP tool calls into CDP commands. Pure functions: data in, JSON pair out. No runtime.

WebSocket
03

Browser

Chromium executes via Chrome DevTools Protocol. Real browser, real rendering, real JavaScript. Not a simulation.

CDP

Browser automation is broken.

Framework Theatre

Selenium. Playwright. Puppeteer. Install Node. Install the framework. Install the browser driver. Configure timeouts. Handle race conditions. Your test is three lines. Your infrastructure is three hundred.

Headless Hallucinations

Headless browsers render pages that real browsers don't. Missing fonts, broken layouts, phantom elements. You're testing a simulation. When it passes in CI and fails in production, the headless layer is the ghost.

Extension Parasites

Extensions that "add AI to browsing" want your profile, your cookies, your history. They ship bundled Chromium or inject scripts into every page. The AI sees what the extension allows.

AI-Blind

An AI told to "check the website" has no browser. It can fetch HTML, but it can't execute JavaScript, render CSS, click buttons, or see what a human sees. The gap between HTTP and browsing is immense.

What if AI could just use a browser?

Causeway is a Rust binary. Not a framework, not an extension, not a library — a standalone executable. It speaks MCP over stdio to your AI, and CDP over WebSocket to your browser.

One binary. Two protocols. Complete browser control.

Causeway doesn't simulate a browser. It drives the real one you're already using — your tabs, your bookmarks, your session. The AI sees exactly what you see.

Everything an AI needs to browse.

Navigation

navigate

Go to any URL. Returns the page title.

back

Navigate back in history.

forward

Navigate forward in history.

get_url

Get current page URL and title.

wait_for_navigation

SPA-aware. Three detection layers.

Tabs

list_tabs

Enumerate all open tabs with IDs.

switch_tab

Activate any tab by target ID.

new_tab

Open a new tab, optionally with a URL.

close_tab

Close a tab by its target ID.

Interaction

click

Click any element by CSS selector.

click_text

Click an element by its visible text.

double_click

Double-click to select or trigger.

type_text

Type into inputs character by character.

fill_form

Fill multiple form fields at once.

select_option

Choose a dropdown value.

submit_form

Submit a form element.

hover

Hover to reveal menus and tooltips.

press_key

Press keyboard keys like Enter or Tab.

keyboard_chord

Press shortcuts with modifier keys.

drag

Drag between selectors or coordinates.

upload_file

Set files on an input. No OS picker.

handle_dialog

Respond to alerts, confirms, prompts.

Reading

screenshot

Capture the visible page as PNG.

element_screenshot

Screenshot a specific element.

read_page

Extract all visible text content.

read_text

Read text from a specific element.

inspect

Structural DOM tree at configurable depth.

query_elements

Find matching elements with metadata.

get_attribute

Read any attribute from an element.

accessibility_snapshot

Page accessibility tree snapshot.

Waiting

wait_for

Block until an element appears in DOM.

wait_for_text

Wait until specific text appears.

Browser Control

scroll

Scroll the page by pixel coordinates.

set_viewport

Set browser viewport dimensions.

emulate_device

Emulate mobile devices or viewports.

save_pdf

Save the page as a PDF file.

download_file

Download any file to a local path.

clear_storage

Clear cache, cookies, localStorage.

Data & Debug

evaluate_js

Run JavaScript in the page context.

get_cookies

Get browser cookies with full details.

set_cookie

Set a browser cookie by URL or domain.

get_console_messages

Read buffered console output.

list_network_requests

List captured network requests.

get_page_metrics

DOM count, heap size, layout stats.

discover_webmcp_tools

Find tools declared by the page itself.

Data in. JSON pair out.

commands.rs — Pure data functions
/// Navigate to a URL.
pub fn navigate(url: &str) -> (&'static str, Value) {
    ("Page.navigate", json!({ "url": url }))
}

/// Capture a screenshot as base64 PNG.
pub fn screenshot() -> (&'static str, Value) {
    ("Page.captureScreenshot", json!({ "format": "png" }))
}
cdp.rs — The bridge function
/// Send a CDP command and await the response.
pub async fn execute(
    conn: &CdpConnection,
    command: (&str, Value),
) -> Result<Value, CdpError> {
    let (method, params) = command;
    send(conn, method, params).await
}
server.rs — MCP tool handler
async fn navigate(
    &self,
    Parameters(NavigateParams { url }): Parameters<NavigateParams>,
) -> Result<CallToolResult, McpError> {
    cdp::execute(&self.conn, commands::navigate(&url))
        .await
        .map_err(|e| McpError::internal_error(
            format!("Navigate failed: {e}"), None
        ))?;
    // ...
}
causeway.toml — Configuration
[browser]
executable = "C:\\...\\brave.exe"
port = 9222
restore_session = true
dedicated_profile = false

No objects. No state. Just data.

Traditional Automation

  • Browser driver object
  • Session manager
  • Wait strategy classes
  • Page object model
  • Element wrapper classes
  • Configuration objects
  • Test runner framework

7+ layers between you and the browser.

Causeway

  • Functions return (&str, Value)
  • execute() sends over WebSocket

Data in. JSON pair out.

0 Source Files
0 MCP Tools
0 Node Dependencies
0 Lines of Rust

No framework. No runtime. No abstractions between you and the protocol.

Rust Tokio RMCP CDP WebSocket Serde

Sovereign software.

Causeway is free to use. Connect it to Claude Code, Cursor, or any MCP client. Your browser, your automation, your rules.

Get in Touch