Discover MCPs & agents
Loading MCPs and agents…
Loading MCPs and agents…
MCP Firefox browser automation extension for Claude Code - screenshots, clicking, typing, page refresh, and AI-powered web interaction
From the repo.
A browser automation system for Claude Code that enables AI-powered interaction with web pages — with built-in safety guards for humans. Take screenshots, click elements, type text, navigate pages, and force refresh browser tabs when launching development servers. Drive your real Firefox through the extension, or run fully headless (Firefox, Chromium, or WebKit) via Playwright.
Author: Andre Watson (@nanogenomic) - dre@ligandal.com Organization: Ligandal Inc. License: MIT Copyright: 2025 Ligandal Inc.
| Browser | Attended (extension) | Headless (Playwright) |
|---|---|---|
| Firefox | ✅ Primary target (Manifest V2, AMO-signable) | ✅ CLAUDE_BROWSER_ENGINE=firefox (default) |
| Chromium / Chrome | 🧪 Experimental build via scripts/build-chrome.sh (MV3) | ✅ CLAUDE_BROWSER_ENGINE=chromium |
| WebKit (Safari engine) | — | ✅ CLAUDE_BROWSER_ENGINE=webkit |
Attended mode drives your real browser with your logged-in sessions. Headless mode launches a fresh, isolated browser — best for CI, servers, and unattended tasks. See Headless Mode.
ClaudeCodeBrowser consists of four main components:
ClaudeCodeBrowser uses a dual-server architecture for maximum reliability and flexibility:
| Server | Port | Protocol | Purpose |
|---|---|---|---|
| HTTP Server | 8765 | HTTP REST | MCP tool calls, health checks, command polling, screenshot retrieval |
| WebSocket Server | 8766 | WebSocket | Real-time browser communication (reserved for future use) |
Why Two Servers?
flowchart TB
CC["Claude Code<br/>(MCP client)"] -->|"stdio (MCP)"| SW["stdio_wrapper.py"]
SW -->|"HTTP + X-API-Key"| SRV["MCP Server<br/>HTTP :8765 / WebSocket :8766"]
SRV --> GUARD{{"Safety Guard<br/>URL rules · confirm tokens · rate limit · audit log"}}
GUARD -->|attended| QUEUE["Command queue<br/>(in-memory)"]
GUARD -->|"headless mode"| PW["Playwright<br/>Firefox / Chromium / WebKit"]
QUEUE <-->|"500ms polling"| NH["Native Host<br/>(stdio)"]
NH <--> EXT["Firefox Extension<br/>(background + content scripts)"]
EXT --> PAGE["Web Page"]
PW --> PAGE2["Web Page (headless)"]
localhost:8765/mcp/calllocalhost:8765/browser/poll every 500mslocalhost:8765/browser/responseThe native messaging host (claudecodebrowser_host.py) provides an alternative communication path:
/tmp/claudecodebrowser/screenshots/System Python websockets (required for WebSocket server on port 8766):
sudo apt install python3-websockets # Linux
pip3 install websockets # macOS
Without this, the server runs in HTTP-only mode and browsers_connected will always show 0. Everything else still works over HTTP.
cd ClaudeCodeBrowser
./scripts/install.sh
The install script handles these automatically, but if you are installing manually:
~/Library/Application Support/Mozilla/NativeMessagingHosts/ (not ~/.mozilla/).~/Documents, ~/Desktop, ~/Downloads). Firefox is not allowed to execute anything there and fails with Operation not permitted. The default install location ~/.claudecodebrowser is fine.python3 path. Firefox launches native hosts with a minimal PATH, so #!/usr/bin/env python3 may not resolve (e.g. Homebrew installs).Install the MCP server and agent:
mkdir -p ~/.claudecodebrowser/{native-host,mcp-server,agent,screenshots,logs}
cp native-host/* ~/.claudecodebrowser/native-host/
cp mcp-server/* ~/.claudecodebrowser/mcp-server/
cp agent/* ~/.claudecodebrowser/agent/
chmod +x ~/.claudecodebrowser/**/*.py
Install native messaging manifest for Firefox:
# Linux
mkdir -p ~/.mozilla/native-messaging-hosts
cp native-host/claudecodebrowser.json ~/.mozilla/native-messaging-hosts/
# macOS
mkdir -p ~/Library/Application\ Support/Mozilla/NativeMessagingHosts
cp native-host/claudecodebrowser.json ~/Library/Application\ Support/Mozilla/NativeMessagingHosts/
# Update the path in the JSON file to point to your installation
Install the Firefox extension:
about:debuggingextension/manifest.jsonConfigure Claude Code MCP:
Add to ~/.claude/settings.json:
{
"mcpServers": {
"claudecodebrowser": {
"command": "python3",
"args": ["/home/YOUR_USER/.claudecodebrowser/mcp-server/stdio_wrapper.py"]
}
}
}
Quick install (PowerShell):
powershell -ExecutionPolicy Bypass -File scripts\install.ps1
This copies the components to %USERPROFILE%\.claudecodebrowser, generates the
.bat native-host wrapper with your Python path baked in, writes the native
messaging manifest, and registers it in the Windows registry. Then load the
extension (step 1 below) and add the printed MCP config to Claude Code.
Manual steps:
Install the Firefox extension:
about:debuggingextension/manifest.jsonRegister the native messaging host:
Update the path in native-host/claudecodebrowser.json to point to the .bat wrapper:
{
"path": "C:\\path\\to\\ClaudeCodeBrowser\\native-host\\claudecodebrowser_host.bat"
}
Then register it in the Registry:
New-Item -Path 'HKCU:\Software\Mozilla\NativeMessagingHosts\claudecodebrowser' -Force | Out-Null
Set-ItemProperty -Path 'HKCU:\Software\Mozilla\NativeMessagingHosts\claudecodebrowser' -Name '(Default)' -Value 'C:\path\to\ClaudeCodeBrowser\native-host\claudecodebrowser.json'
Configure Claude Code MCP:
Add to %USERPROFILE%\.claude\settings.json:
{
"mcpServers": {
"claudecodebrowser": {
"command": "python",
"args": ["C:/path/to/ClaudeCodeBrowser/mcp-server/stdio_wrapper.py"]
}
}
}
The MCP server and native host are plain Python — pull the repo and restart
them and you're current. The browser extension is separate: it runs
inside Firefox and does not update from a git pull. How you update it
depends on how it was installed.
Build a versioned package (both scripts also emit dist/updates.json for
auto-update — see below):
# Linux / macOS
./scripts/package-extension.sh # dist/claudecodebrowser-<version>.xpi
./scripts/package-extension.sh --sign # signed via AMO (see below)
# Windows
powershell -ExecutionPolicy Bypass -File scripts\package-extension.ps1
powershell -ExecutionPolicy Bypass -File scripts\package-extension.ps1 -Sign
1. Temporary add-on (development). If you loaded it through
about:debugging → Load Temporary Add-on, it is not persistent and does
not auto-update:
about:debugging#/runtime/this-firefoxmanifest.json/.xpi againThis is the quickest loop while developing, and it's where you are if you've
been "reloading the plugin" after each change. When the manifest gains a new
permission (v1.3.0 added notifications), a reload picks it up.
2. Signed, self-distributed .xpi (recommended for real use). A signed
extension installs permanently and can auto-update. Sign it through
Mozilla without a public listing:
export AMO_JWT_ISSUER=user:xxxx
export AMO_JWT_SECRET=yyyy
npm install -g web-ext # one-time
./scripts/package-extension.sh --sign
(this uploads to AMO's signer with --channel=unlisted and writes a
signed .xpi to dist/)..xpi by opening it in Firefox (drag it onto the
window, or about:addons → gear → Install Add-on From File).Auto-update is already wired to GitHub Releases. The manifest carries:
"update_url": "https://github.com/nanogenomic/ClaudeCodeBrowser/releases/latest/download/updates.json"
That's a stable URL — it always resolves to the newest release's
updates.json — and the packaging scripts generate that updates.json
pointing at the matching versioned .xpi. So each new plugin version is just:
Bump version in extension/manifest.json.
./scripts/package-extension.sh --sign (or the .ps1 on Windows) — writes
the signed claudecodebrowser-<version>.xpi and updates.json into
dist/.
Publish the release with both assets — one command:
./scripts/publish-release.sh # or --draft to review before publishing
It reads the version from the manifest, creates the v<version> release,
and uploads the .xpi + updates.json. It uses the gh CLI if present
(gh auth login), otherwise falls back to the GitHub API with
GITHUB_TOKEN (needs repo scope).
With the gh CLI:
VER=$(python3 -c "import json;print(json.load(open('extension/manifest.json'))['version'])")
gh release create "v$VER" \
"dist/claudecodebrowser-$VER.xpi" "dist/updates.json" \
--title "v$VER" --notes "ClaudeCodeBrowser v$VER"
With curl (set GITHUB_TOKEN):
VER=$(python3 -c "import json;print(json.load(open('extension/manifest.json'))['version'])")
REPO=nanogenomic/ClaudeCodeBrowser
ID=$(curl -sS -X POST "https://api.github.com/repos/$REPO/releases" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-d "{\"tag_name\":\"v$VER\",\"name\":\"v$VER\"}" | python3 -c "import json,sys;print(json.load(sys.stdin)['id'])")
curl -sS -X POST "https://uploads.github.com/repos/$REPO/releases/$ID/assets?name=claudecodebrowser-$VER.xpi" \
-H "Authorization: Bearer $GITHUB_TOKEN" -H "Content-Type: application/octet-stream" \
--data-binary @"dist/claudecodebrowser-$VER.xpi"
curl -sS -X POST "https://uploads.github.com/repos/$REPO/releases/$ID/assets?name=updates.json" \
-H "Authorization: Bearer $GITHUB_TOKEN" -H "Content-Type: application/json" \
--data-binary @"dist/updates.json"
Installed copies check releases/latest/download/updates.json, see the higher
version, and update themselves within ~24h — or immediately via Check for
Updates in about:addons. (Format reference: Mozilla's
updateURL manifest.)
Forking? Set
CCB_REPO_SLUG=youruser/yourrepowhen packaging so the generatedupdate_linkpoints at your releases, and change theupdate_urlin the manifest to match.
3. Public AMO listing. To distribute on
addons.mozilla.org, run
web-ext sign --channel=listed (or submit the .xpi in the Developer Hub)
and go through Mozilla's review. Users then install and update like any store
add-on. Best when you want the extension discoverable; heavier because each
version is reviewed.
Whichever route: bump
versioninextension/manifest.jsonfirst (it must increase for Firefox to treat a build as an update), keep it in step with the server version, then repackage.
~/.claudecodebrowser/start-server.sh
Or directly:
python3 ~/.claudecodebrowser/mcp-server/stdio_wrapper.py
The server runs on:
Run without any visible browser — ideal for CI, servers, and unattended tasks:
pip install playwright
playwright install firefox # or: chromium / webkit
CLAUDE_BROWSER_HEADLESS=1 python3 mcp-server/server.py
Pick the engine with CLAUDE_BROWSER_ENGINE:
CLAUDE_BROWSER_ENGINE=chromium CLAUDE_BROWSER_HEADLESS=1 python3 mcp-server/server.py
CLAUDE_BROWSER_ENGINE=webkit CLAUDE_BROWSER_HEADLESS=1 python3 mcp-server/server.py
To use a browser you already have (a system install, or a Playwright build at
a different revision) instead of running playwright install, point
CLAUDE_BROWSER_EXECUTABLE at the binary:
CLAUDE_BROWSER_ENGINE=chromium CLAUDE_BROWSER_EXECUTABLE=/usr/bin/chromium \
CLAUDE_BROWSER_HEADLESS=1 python3 mcp-server/server.py
Headless mode supports the core toolset (navigate, screenshot, click, type,
scroll, element queries, script execution, eval chains, waiting, history,
keyboard, text extraction) with real multi-tab management — browser_create_tab
returns a tabId usable with tab_id on every other tool. The same safety
guards apply. Startup takes ~15 seconds; the server holds the first command
until the browser is ready (tunable via
CLAUDE_BROWSER_HEADLESS_STARTUP_TIMEOUT, default 45s).
python3 ~/.claudecodebrowser/agent/browser_agent.py -i
# Take a screenshot
browser-agent --screenshot
# Navigate to a URL
browser-agent --navigate https://example.com
# Get page info
browser-agent --info
# Check server status
browser-agent --check
from browser_agent import BrowserAutomationAgent
agent = BrowserAutomationAgent(verbose=True)
# Navigate to a page
agent.navigate("https://example.com")
# Take a screenshot
agent.screenshot("example.png")
# Click an element
agent.click(selector="button.submit")
# Type text
agent.type_text("Hello, World!", selector="#search-input")
# Fill a form
agent.fill_form({
"username": "myuser",
"password": "mypass"
}, submit=True)
| Tool | Description |
|---|---|
browser_screenshot | Take a screenshot (visible area or full page) |
browser_navigate | Navigate to a URL, optionally in new tab |
browser_go_back | Navigate back in tab history |
browser_go_forward | Navigate forward in tab history |
browser_refresh | Refresh current page |
browser_hard_refresh | Force refresh bypassing cache (Ctrl+Shift+R) |
browser_reload_all | Reload all browser tabs |
browser_reload_by_url | Reload tabs matching URL pattern |
| Tool | Description |
|---|---|
browser_click | Click element by selector, XPath, text, or coordinates |
browser_type | Type text into an input field |
browser_scroll | Scroll page or element (up/down/left/right/top/bottom) |
browser_hover | Hover over an element to trigger hover effects |
browser_get_value | Get the value of an input element |
browser_set_value | Set input value directly (no typing simulation) |
browser_select_option | Select an option in a dropdown |
browser_press_key | Press a keyboard key (Enter, Escape, arrows, shortcuts) |
| Tool | Description |
|---|---|
browser_get_page_info | Get URL, title, forms, headings, interactive elements |
browser_get_text | Extract visible text of the page or an element |
browser_get_elements | Find elements matching a CSS selector |
browser_highlight | Highlight an element for visual debugging |
browser_execute_script | Execute JavaScript in browser context |
| Tool | Description |
|---|---|
browser_get_tabs | List all open browser tabs |
browser_create_tab | Create a new tab |
browser_close_tab | Close a tab by ID |
browser_focus_tab | Focus/activate a tab by ID |
| Tool | Description |
|---|---|
browser_wait_for_element | Wait for element to appear on page |
browser_wait_for_change | Wait for DOM changes (useful after clicks) |
browser_wait_for_network_idle | Wait for fetch/XHR requests to settle |
browser_click_and_wait | Click element and wait for DOM changes |
| Tool | Description |
|---|---|
browser_observe_element | Start observing element for changes |
browser_stop_observing | Stop observing and get accumulated changes |
browser_scroll_and_capture | Scroll through page capturing element info |
| Tool | Description |
|---|---|
browser_start_logging | Start capturing console logs and network requests |
browser_stop_logging | Stop capturing logs (logs are preserved) |
browser_get_console_logs | Retrieve captured console.log/error/warn/info/debug |
browser_get_network_logs | Retrieve captured fetch/XHR requests and responses |
browser_clear_logs | Clear all captured logs |
| Tool | Description |
|---|---|
browser_request_approval | Ask the human at the browser to Approve/Deny an action (in-page banner + OS notification) |
browser_solve_captcha | Detect a captcha and hand it to the human to solve, then continue (never auto-solves) |
browser_run_workflow | Run a declarative multi-step workflow with assertions — an end-to-end test runner for web apps |
browser_audit_page | One-call page audit: headings, missing alt text, unlabeled inputs, meta info + screenshot for visual critique |
| Tool | Description |
|---|---|
browser_safety_status | Show active safety policy, rate-limit state, and audit log location |
Essential for debugging AI chat interfaces and monitoring API communications:
# Start logging before performing actions
browser-agent --start-logging
# Perform actions that you want to monitor...
# Get console logs (errors, warnings, debug output)
browser-agent --get-console-logs
# Get network logs (API requests and responses)
browser-agent --get-network-logs
# Filter console logs by level
browser-agent --get-console-logs --level error
# Filter network logs by URL pattern
browser-agent --get-network-logs --url-pattern "api/chat"
# Stop logging
browser-agent --stop-logging
agent = BrowserAutomationAgent()
# Start logging
agent.start_logging(clear_existing=True)
# Perform actions...
agent.navigate("https://example.com/chat")
agent.type_text("Hello!", selector="#chat-input")
agent.click(selector="#send-button")
# Get console logs
console_logs = agent.get_console_logs(level="error") # Filter by level
for log in console_logs['logs']:
print(f"[{log['level']}] {log['message']}")
# Get network logs
network_logs = agent.get_network_logs(url_pattern="api/chat")
for req in network_logs['logs']:
print(f"{req['method']} {req['url']} -> {req['status']}")
print(f"Response: {req['responseBody'][:200]}...")
# Stop logging
agent.stop_logging()
Essential for development workflows - refresh browser tabs after server restarts:
# Refresh current tab
browser-agent --refresh
# Hard refresh (bypass cache) - like Ctrl+Shift+R
browser-agent --hard-refresh
# Reload all browser tabs
browser-agent --reload-all
# Reload all localhost tabs
browser-agent --reload-localhost
# Reload localhost on specific port
browser-agent --reload-localhost 5000
# Reload all dev server tabs (localhost, 127.0.0.1, *.local, *.dev)
browser-agent --reload-dev
# Reload tabs matching URL pattern
browser-agent --reload-url "ligandal"
agent = BrowserAutomationAgent()
# Refresh current page
agent.refresh()
# Hard refresh (bypass cache)
agent.hard_refresh()
# Reload all localhost tabs
agent.reload_localhost()
# Reload localhost:5000 specifically
agent.reload_localhost(port=5000)
# Reload all dev server tabs
agent.reload_dev_servers()
# Reload tabs matching pattern
agent.reload_by_url(url_pattern=r"localhost:500[0-9]")
{
"selector": "CSS selector",
"xpath": "XPath expression",
"text": "Text to find and click",
"x": 100,
"y": 200,
"double_click": false,
"right_click": false
}
{
"text": "Text to type",
"selector": "CSS selector",
"placeholder": "Placeholder text",
"name": "Input name",
"clear": true,
"press_enter": true,
"delay": 50
}
{
"direction": "down",
"amount": 300,
"to_element": "CSS selector"
}
| Endpoint | Method | Description |
|---|---|---|
/health | GET | Server health check |
/mcp/tools | GET | List available MCP tools |
/mcp/call | POST | Execute an MCP tool |
/screenshots | GET | List saved screenshots |
/browser/command | POST | Send direct browser command |
/browser/response | POST | Receive browser response |
# Health check
curl http://localhost:8765/health
# List tools
curl http://localhost:8765/mcp/tools
# Take screenshot
curl -X POST http://localhost:8765/mcp/call \
-H "Content-Type: application/json" \
-d '{"name": "browser_screenshot", "arguments": {}}'
# Click element
curl -X POST http://localhost:8765/mcp/call \
-H "Content-Type: application/json" \
-d '{"name": "browser_click", "arguments": {"selector": "button.login"}}'
| Path | Description |
|---|---|
~/.claudecodebrowser/ | Main installation directory |
~/.claudecodebrowser/screenshots/ | Saved screenshots |
~/.claudecodebrowser/logs/ | Log files |
~/.mozilla/native-messaging-hosts/ | Firefox native messaging manifests |
claudecodebrowser.json is correct~/.claudecodebrowser/logs/native_host.logcurl http://localhost:8765/health~/.claudecodebrowser/logs/mcp_server.log~/.claudecodebrowser/screenshots/Start the MCP server with debug logging:
python3 mcp-server/server.py
Load the extension temporarily in Firefox
Use the browser agent in verbose mode:
python3 agent/browser_agent.py -i -v
Two tools turn the browser into a lightweight QA rig for building websites:
browser_run_workflow executes a declarative sequence of tool steps with
assertions — click through a signup flow, submit a form, verify the result —
and reports pass/fail per step with a screenshot captured at the point of
failure:
{
"steps": [
{ "label": "open app", "tool": "browser_navigate",
"arguments": { "url": "http://localhost:3000" },
"assert": { "selector_exists": "#login-form" } },
{ "label": "fill email", "tool": "browser_type",
"arguments": { "selector": "#email", "text": "test@example.com" } },
{ "label": "submit", "tool": "browser_click",
"arguments": { "selector": "button[type=submit]" },
"assert": { "url_contains": "/dashboard", "text_contains": "Welcome" } }
]
}
Every step passes through the safety guard individually, and failing steps
capture workflow_fail_<label>.png automatically.
browser_audit_page gathers everything needed for a structural and visual
critique in one call: heading hierarchy, images missing alt text, unlabeled
form inputs, empty links/buttons, meta description and viewport info, page
dimensions — plus a screenshot. Point Claude at a page and ask for a critique;
this tool is the evidence-gathering step.
Every tool call passes through a safety guard before it reaches the browser.
The guard is designed to keep an automated agent from doing things the human
operating it would not expect, while staying out of the way for normal
development workflows. Policy lives in ~/.claudecodebrowser/safety.json
(created with safe defaults on first run) and can be inspected at runtime with
the browser_safety_status tool.
| Guard | Behavior |
|---|---|
| URL scheme guard | Navigation is limited to http://, https://, and about:blank. file:, javascript:, data:, chrome:, resource:, and moz-extension: targets are always refused. |
| Blocklist / allowlist | blocked_url_patterns refuses matching URLs; a non-empty allowed_url_patterns switches to allowlist mode where only matching URLs may be visited. |
| Protected sites | State-changing actions (click, type, navigate, script execution) on banking, payment, health, and government sites require explicit confirmation — by default from the human at the browser (see below), with an agent-side confirm_token round trip as the fallback. Read-only actions (screenshots, inspection) are unaffected. |
| Password fields | Typing into <input type="password"> (or autocomplete="current-password"/"new-password") is refused by default in both attended and headless modes. Credentials belong in the browser's own password manager. Set "allow_password_typing": true to override. |
| Human approval (Duo-style) | With protected_approval set to "auto" (default) or "human", a protected action triggers an OS notification plus an Approve/Deny banner on the current page. The action proceeds only if the person clicks Approve (60s timeout = deny). "token" forces the agent-side flow; headless mode always uses tokens since no human is present. |
| Read-only mode | Set "read_only": true or CLAUDE_BROWSER_READ_ONLY=1 to block every state-changing tool while keeping screenshots, page inspection, and log reading available. Useful for "look but don't touch" sessions. |
| Script toggle | Set "allow_script_execution": false or CLAUDE_BROWSER_ALLOW_SCRIPTS=0 to disable browser_execute_script, browser_eval_chain, browser_wait_and_act, and browser_inject_observer entirely. |
| Rate limiting | A sliding-window cap (max_actions_per_minute, default 120) prevents runaway automation loops. |
| Audit log | Every decision (allowed, denied, confirmation requested) is appended to ~/.claudecodebrowser/logs/audit.jsonl with sensitive argument values (typed text, scripts, passwords) redacted. |
safety.json{
"enabled": true,
"read_only": false,
"allow_script_execution": true,
"confirm_protected_actions": true,
"max_actions_per_minute": 120,
"audit_log": true,
"blocked_url_patterns": ["internal-admin\\.mycompany\\.com"],
"allowed_url_patterns": [],
"protected_url_patterns": ["paypal\\.com", "chase\\.com", "\\.gov(/|$)"]
}
The defaults include a starter set of protected patterns for common banking,
payment, brokerage, government, and health domains — edit the file to match
your own risk tolerance. Setting "enabled": false turns the guard off
entirely (not recommended).
browser_request_approval to
ping you), you complete the login/2FA yourself in the same tab, then
automation continues in the authenticated session.The Duo-style pattern this project does implement is pointed the other way: you are the second factor for Claude's actions. Sensitive operations push a notification to you and wait for your explicit Approve click in the browser.
browser_solve_captcha follows the same human-in-the-loop principle.
Captchas exist to tell humans from bots, so auto-solving them (via OCR or
third-party solver farms) is explicitly not something this project does.
Instead:
detect_only: true just reports what's present without
waiting.In headless mode there is no human, so it reports what it detected and that a human is required — re-run that step in attended mode (the Firefox extension) so you can complete the challenge.
ClaudeCodeBrowser is the browser hands of a Claude Code setup. For secretary-style workflows, combine it with purpose-built MCP connectors rather than screen-driving web apps: Gmail/Calendar MCP connectors handle email triage and scheduling far more reliably than clicking through webmail, while this project covers the parts that genuinely need a browser — visual review of what you're building, workflow testing, form filling, and anything without an API.
about:addons in Firefox (or menu → Add-ons and themes)… menu next to it and choose RemoveIf the extension was loaded temporarily via about:debugging, it disappears
on its own the next time Firefox restarts — or click Remove on the
about:debugging#/runtime/this-firefox page.
./scripts/uninstall.sh
This removes the native messaging manifest, the ~/.claudecodebrowser
install directory, and any symlinks. If you registered the MCP server with
Claude Code, also run:
claude mcp remove claudecodebrowser
/health require the X-API-Key token
(auto-generated at ~/.claudecodebrowser/api_token, mode 0600)runtime.onMessageExternal messages, so co-installed
extensions cannot issue automation commands through itMIT License - Copyright (c) 2025 Andre Watson (nanogenomic), Ligandal Inc.
See LICENSE for full details.
Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.
Tool
OS
Config file: ~/.cursor/mcp.json
{
"mcpServers": {
"mcp-server": {
"url": "{MCP_ENDPOINT_URL}"
}
}
}Paste into mcpServers in the config file. Restart Cursor after saving.
If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.