Back to docs

MCP Server

Run CBrowser as an MCP server for Claude Desktop integration.

Looking for Remote MCP? See Remote MCP Server for deploying CBrowser as a remote MCP server for claude.ai custom connectors. No local installation required!


What is MCP?

MCP (Model Context Protocol) is Anthropic's standard for connecting AI assistants to external tools. CBrowser implements an MCP server that gives Claude direct browser automation capabilities.


Why Use MCP?

Without MCP With MCP
Copy-paste commands manually Claude executes directly
View results separately Results inline in conversation
No context awareness Claude sees page state
Manual iteration Autonomous workflows

Setup

1. Install CBrowser

npm install -g cbrowser

2. Configure Claude Desktop

Edit claude_desktop_config.json at the path for your OS:

Platform Config Path
macOS ~/Library/Application Support/Claude/claude_desktop_config.json
Windows %APPDATA%\Claude\claude_desktop_config.json
Linux ~/.config/Claude/claude_desktop_config.json

Tip: You can also open this file via Settings > Developer > Edit Config in Claude Desktop.

Note: If the folder or file doesn't exist, create it. On Windows, use double backslashes (\\) in paths.

Add the CBrowser MCP server:

{
  "mcpServers": {
    "cbrowser": {
      "command": "npx",
      "args": ["cbrowser", "mcp-server"]
    }
  }
}

3. Restart Claude Desktop

The CBrowser tools will appear in Claude's tool list.


Available Tools

Once configured, Claude can use these tools:

Navigation

Tool Description
navigate Navigate to URL and screenshot
screenshot Take screenshot of current page

Interaction

Tool Description
click Click element by selector
smart_click AI-powered click with retry
fill Fill form field

Analysis

Tool Description
assert Natural language assertion
analyze_page Analyze page structure
generate_tests Generate test scenarios
extract Extract data from page

Sessions

Tool Description
save_session Save browser session
load_session Load saved session

Self-Healing

Tool Description
heal_stats Selector cache stats

Security

Tool Description
security_audit Scan MCP tools for prompt injection patterns

Screen Capture

Tool Description
capture_start Start recording the screen to GIF/WebP/video
capture_stop Stop the recording, encode the formats, return paths and a contact sheet
capture_status Report the running or most recent capture

Session Continuity

Browser tools accept an optional _browserToken. It is how one tool call reaches the page a previous call left behind.

The remote MCP servers issue a short token (cb_ plus a random suffix) and echo it in the tool response. Pass that value back on the next call and you get the same browser β€” same cookies, same scroll position, same running capture. Omit it and you get a blank new browser.

Three things to know about the token:

  • It is good for 10 minutes from when it is issued β€” an absolute lifetime, not a sliding window reset by reuse β€” and the browser behind it is dropped after 5 minutes with no calls. Continuity ends at whichever comes first, after which the same token quietly starts a fresh browser.
  • An unknown or expired token is not an error. The server quietly creates a new session, so a call that should have continued starts over on a blank page instead.
  • The local stdio server (npx cbrowser mcp-server) keeps one browser for the whole conversation and issues no tokens. _browserToken is accepted and ignored there.

Screen capture is keyed by the same token. Two tokens are two independent captures, and capture_stop only finds the capture started under the token you pass it. If a capture is running somewhere else β€” another token on the same server, or the CLI in another process β€” capture_status reports it under also_running_elsewhere rather than pretending nothing is recording.


Screen Capture Tools

capture_start, capture_stop and capture_status record PIXELS over time. They are distinct from the record command family, which records user ACTIONS for test generation; the two share no output format.

Capture runs in the background. Call capture_start, drive the page with the ordinary tools (navigate, click, fill, scroll), then call capture_stop.

capture_start

Parameter Type Required Default Description
url string No β€” URL to navigate to before capturing. Omit to capture the current page.
fps number No 10 Target frames per second
duration string No β€” Auto-stop after this long: 5s, 2m, 1500ms. Omit for an open-ended capture stopped by capture_stop.
viewport string No β€” WIDTHxHEIGHT (e.g. 1280x720) or a preset name β€” mobile, tablet, desktop, desktop-lg and more; an unknown name lists them all in the error
region string No β€” Fixed region as x,y,width,height. Clamped to the viewport.
element string No β€” CSS selector to capture. Resolved to the element's bounding box once at start; the region does not follow the element if it moves.
padding number No 0 Padding in pixels around the element region
format string No gif Comma-separated output formats: gif,webp,mp4,webm
quality number No 80 JPEG quality for captured frames, 1-100
max_frames number No 3000 Hard cap on retained frames
name string No β€” Capture name / slug
out_dir string No ~/.cbrowser/videos/<session>/<slug> Output directory
_browserToken string No β€” Browser session token from a previous tool call

Pass region or element, not both. Starting a second capture under the same token fails with A capture is already running (<slug>). Call capture_stop before starting another.

The response confirms the recording is live:

{
  "success": true,
  "state": "recording",
  "slug": "mcpprobe",
  "out_dir": "/home/you/.cbrowser/videos/<session>/mcpprobe",
  "capture_method": "cdp-screencast",
  "engine": "chromium",
  "note": "Capture is event-driven: a page that never repaints emits no frames, and still stretches are reported as frame_gaps rather than padded out. Interact with the page (navigate, click, scroll) to produce frames, then call capture_stop."
}

An element capture adds an element_note saying the region was resolved once and is fixed for the run. The CLI's capture start --element tracks a moving element; the MCP element parameter does not.

capture_stop and capture_status

Parameter Type Required Default Description
_browserToken string No β€” Browser session token from a previous tool call

capture_stop on a session with no capture returns {"success": false, "error": "No capture has been started on this browser session. Call capture_start first."}. capture_status on a fresh session returns state: "idle"; after a stop it returns state: "stopped" with the most recent completed capture, so a finished recording never reads as one that never happened.

Response Shape

A recording is hundreds of frames and tens of megabytes of video, and none of that can cross an MCP boundary. capture_stop returns paths plus one inlined contact sheet β€” an evenly spaced visual sample of the whole run β€” so the response is the same small size whether you recorded three seconds or ten minutes.

Real capture_stop response from a 27-frame capture:

{
  "success": true,
  "slug": "mcpprobe",
  "manifest_path": "/home/you/.cbrowser/videos/<session>/mcpprobe/manifest.json",
  "out_dir": "/home/you/.cbrowser/videos/<session>/mcpprobe",
  "frames": 27,
  "target_fps": 10,
  "actual_fps": 10.526315789473685,
  "duration_ms": 2565,
  "capture_method": "cdp-screencast",
  "engine": "chromium",
  "output_dims": { "width": 1280, "height": 800 },
  "target": { "kind": "viewport" },
  "region_clamped": false,
  "artifacts": { "gif": "mcpprobe.gif" },
  "change_points": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26],
  "change_points_total": 26,
  "frame_gaps": [],
  "frame_gaps_total": 0,
  "console_errors": [],
  "console_errors_total": 0,
  "network_requests_total": 0,
  "frames_dir": "/home/you/.cbrowser/videos/<session>/mcpprobe/frames",
  "contact_sheet": "/home/you/.cbrowser/videos/<session>/mcpprobe/contact-sheet.jpg",
  "note": "Individual frames and video artifacts are on disk, not inlined β€” read them by path. The contact sheet is an evenly spaced visual sample of the recording."
}

What the shape does:

  • The frame array is excluded. frames is a count and frames_dir names the directory; the per-frame paths, crops, SSIM scores and console/network records stay in manifest.json on disk.
  • Unbounded lists are truncated with their true totals alongside. change_points caps at 200, frame_gaps at 50, console_errors at 20 β€” so you can tell "3 change points" from "200 shown of 4,812" by reading change_points_total.
  • Encoded video is a path. artifacts maps each requested format to its filename inside out_dir. A format that fails to encode appears in encode_errors while the formats that did encode still ship.
  • Only the contact sheet is inlined. It is built to whatever is left of the 150 KB response target after the JSON payload is measured, and it is skipped entirely if that leaves less than roughly 12 KB β€” in which case contact_sheet_note says why.
  • The budget is enforced, not assumed. Before returning, the server measures the serialized content blocks and sheds the image first, then the text, rather than emitting an over-budget response.

The remote servers (demo.cbrowser.ai, enterprise.cbrowser.ai) inline the contact sheet as an image block, because claude.ai cannot read the server's filesystem. The local stdio server returns the contact_sheet path only β€” open it yourself.


Example Conversations

Basic Navigation

You: "Go to github.com and take a screenshot"

Claude: Uses navigate tool

"I've navigated to GitHub. Here's what I see: [screenshot] The page shows the GitHub homepage with trending repositories and a search bar."

Form Filling

You: "Fill out the contact form on example.com/contact with my info"

Claude: Uses navigate, fill, smart_click tools

"I've filled out the contact form:

  • Name: [your name]
  • Email: [your email]
  • Message: [your message]

Should I submit it?"

Page Analysis

You: "Analyze the login page at myapp.com/login"

Claude: Uses analyze_page tool

"Here's my analysis of the login page:

  • 1 form with 3 fields (email, password, remember me)
  • Login button labeled 'Sign In'
  • 'Forgot Password' link present
  • Social login options: Google, GitHub
  • No CAPTCHA detected

I can generate test scenarios for this page if you'd like."

Test Generation

You: "Generate tests for the checkout flow"

Claude: Uses navigate, analyze_page, generate_tests tools

"I've analyzed the checkout flow and generated these test scenarios:

# Test: Guest Checkout
go to https://myapp.com/cart
click 'Proceed to Checkout'
fill email with '[email protected]'
click 'Continue as Guest'
verify url contains '/shipping'
...

Want me to run these tests?"

Capturing an Animation

You: "Record the menu animation on myapp.com as a GIF"

Claude: Uses capture_start, click, capture_stop tools

"Recorded 27 frames over 2.6s (10.5 fps actual vs 10 requested), 26 change points β€” the menu repainted on almost every frame.

  • GIF: ~/.cbrowser/videos/<session>/menu/menu.gif
  • Manifest: ~/.cbrowser/videos/<session>/menu/manifest.json
  • Frames: ~/.cbrowser/videos/<session>/menu/frames/

Here's the contact sheet so you can see the motion without opening the GIF: [contact sheet]"


Session Persistence

MCP sessions can persist browser state:

You: "Log into my GitHub account and save the session"

Claude: Uses navigate, fill, smart_click, save_session tools

"I've logged into GitHub. Session saved as 'github-logged-in'.

In future conversations, I can load this session to skip the login step."

Later...

You: "Load my GitHub session and check my notifications"

Claude: Uses load_session, navigate, extract tools

"Loaded your GitHub session. You have 3 unread notifications:

  1. New PR review on repo/project
  2. Issue mention in org/repo
  3. Release published for lib/package"

Safety in MCP

Constitutional safety applies to all MCP operations:

You: "Delete all my GitHub repositories"

Claude: "I can't do that. Deleting repositories is a Red Zone action that could cause irreversible data loss.

If you're certain, you can use the --force flag, but I recommend:

  1. First listing what would be deleted
  2. Creating backups
  3. Confirming each deletion individually

Would you like me to list your repositories instead?"


Configuration

Environment Variables

Set in Claude Desktop config:

{
  "mcpServers": {
    "cbrowser": {
      "command": "npx",
      "args": ["cbrowser", "mcp-server"],
      "env": {
        "CBROWSER_HEADLESS": "true",
        "CBROWSER_TIMEOUT": "60000"
      }
    }
  }
}

Persistent Context

Keep browser open between tool calls:

{
  "mcpServers": {
    "cbrowser": {
      "command": "npx",
      "args": ["cbrowser", "mcp-server", "--persistent"]
    }
  }
}

Troubleshooting

Tools Not Appearing

  1. Check Claude Desktop config syntax (valid JSON)
  2. Restart Claude Desktop completely
  3. Check CBrowser is installed: npx cbrowser --version

"Browser not starting"

  1. Install Playwright browsers: npx playwright install chromium
  2. Check for display issues (Linux): Set DISPLAY environment variable

Timeout Errors

Increase timeout in config:

{
  "env": {
    "CBROWSER_TIMEOUT": "120000"
  }
}

Permission Errors

If running on Linux without display:

{
  "env": {
    "CBROWSER_HEADLESS": "true"
  }
}

Comparison to Other Browser MCPs

Feature CBrowser MCP Playwright MCP Browser-Use
Self-healing selectors βœ… ❌ βœ…
Constitutional safety βœ… ❌ ❌
Session persistence βœ… ⚠️ ⚠️
Persona simulation βœ… ❌ ❌
Test generation βœ… ❌ ❌
Natural language assertions βœ… ❌ βœ…

Related


Copyright: (c) 2026 Alexa Eden.

License: MIT License

Contact: [email protected]

From the Blog