Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Cursor Browser CLINew to Visual Studio Code? Get it now.
Cursor Browser CLI

Cursor Browser CLI

bcharleson

| (0) | Free
Drive Cursor's Browser Tab from any CLI or MCP
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Cursor Browser CLI

Cursor Browser CLI

B. Charleson

This is the extension, CLI, and MCP server that let an agent drive the Browser Tab already open in Cursor. Grok Build, Claude Code, Codex, OpenCode, or a shell can navigate, snapshot, click, and type on that same tab. The bridge listens on your machine only.

Author B. Charleson
Extension id bcharleson.cursor-browser-cli
License MIT
Requires Cursor, with its Browser Tab
Does not run in Visual Studio Code
Network 127.0.0.1 only. No account, no telemetry.

Unofficial. Not affiliated with Cursor or Anysphere.

Drive Cursor IDE’s built-in Browser Tab from any CLI agent or shell — without leaving Cursor and without spinning up a separate Chrome/Playwright stack.

Stay in a long chat in Cursor’s integrated terminal. Navigate, take accessibility snapshots with refs, click/type/fill by ref, wait for page state, lock the tab, screenshot, and inspect console/network/DOM — all on the same Browser Tab you already see in the IDE.

Grok Build · Claude Code · Codex · OpenCode · shell
              │
              │  CLI  (cursor-browser)
              │  or MCP stdio  (mcp/server.mjs)
              ▼
     localhost HTTP  127.0.0.1:<port>
              │
              ▼
   Cursor extension (workspace host)
              │  cursor.browserView.*
              ▼
     Cursor Browser Tab  (this project window)

Why this exists

The problem

Cursor ships Browser Automation for its own Cursor Agent (chat/composer with built-in browser tools). That is great when you stay inside Cursor Agent.

Many people do not stay there. A common workflow is:

  1. Open a project in Cursor
  2. Run Grok Build, Claude Code, Codex, or another CLI agent in the integrated terminal
  3. Still want to use the in-IDE Browser Tab for UI checks, local apps, auth flows, visual verification, etc.

Those CLI agents cannot call Cursor Agent’s built-in browser tools. Without something else, you end up:

  • Opening extra Chrome windows and tabs
  • Re-explaining context across tools
  • Running a separate Playwright/CDP stack just to “see” the app
  • Or bouncing back into Cursor Agent only for browser steps

That breaks the flow: you wanted one IDE window, one Browser Tab, and multiple agents that can share it.

The solution

cursor-browser-cli is a small local stack that lets any agent (or script) control Cursor’s Browser Tab the same way Cursor Agent does — via:

Surface Best for
cursor-browser CLI Fast, scriptable loops; agents that shell out; one-off commands
MCP server (mcp/server.mjs) Claude Code, Codex, Grok, and any stdio MCP client with native tool calling
Agent skill (skill/SKILL.md) Teaches agents the snapshot → ref → wait loop and multi-window routing

You keep working in the CLI agent. The Browser Tab stays inside Cursor. No second browser product required for day-to-day agent work.

What this is not

Need Use instead
Cursor’s own Agent chat/composer Built-in browser tools (no extra install)
External desktop browser / cookie sessions / full profile A separate external-browser tool of your choice
Headless CI / pure automation outside Cursor Playwright, Puppeteer, or a headless browser MCP
Native macOS UI outside the Browser Tab Other OS automation tools

This project targets one job: multi-agent access to Cursor’s Browser Tab from CLI/MCP while you work inside Cursor. It is intentionally independent of any external-browser stack so both can coexist without coupling.


Bridge recovery (agents / post-reboot)

The CLI talks to a localhost HTTP bridge started by the Cursor extension. The in-IDE Browser Tab can work while that bridge is down.

cursor-browser ensure            # setup + doctor + heal + verify (preferred)
cursor-browser ensure --reload   # after upgrades — multi-window extension code reload
cursor-browser doctor            # ports, extension, version skew, stale state
cursor-browser recover           # self-heal: multi-window restart tokens + wait
cursor-browser recover --reload  # force all windows to reload extension code
cursor-browser windows           # must list live project ports + versions

recover / ensure are safe to run from Grok/Claude/Codex when you see ECONNREFUSED. They self-heal with file triggers only:

  1. Prunes dead instances.json / port files
  2. Writes ~/.cursor-browser-cli/request-restart (extension watches + polls → restartServer())
  3. If still down and Cursor hosts are running: writes request-reload (extension reloads window → re-activate)
  4. Waits until a bridge port answers

If the extension is not loaded at all, recover cannot start the server from outside Cursor — run once:

Cmd+Shift+P → Cursor Browser CLI: Restart Server (or Reload Window).

The extension also self-heals on a heartbeat: if activePort is set but TCP is dead, it restarts the HTTP server without any CLI call.

Optional env: CURSOR_BROWSER_NO_AUTO_RECOVER=1 disables auto-recover on connection errors.

Features

Multi-agent by design

  • Same Browser Tab for Grok Build, Claude Code, Codex, OpenCode, shell scripts, and humans
  • CLI and MCP share the same extension HTTP API
  • Workspace routing so multiple Cursor windows do not step on each other
  • Optional skill files for Grok / Claude / agents that load SKILL.md

Agent-grade interaction (ref model)

  • Accessibility snapshot with refs (e1, e5, …) — YAML-style tree agents can read and act on
  • Click / double-click / right-click / type / fill / hover by ref (CSS selector fallback)
  • scroll window or element; select-option for <select>
  • wait for URL substring, visible text, ref, or CSS selector (reduces agent races)
  • --wait-nav after click to wait for URL change; --snap to attach a fresh snapshot after interact
  • Lock / unlock the tab during automation so accidental human input does not fight the agent
  • Resize viewport
  • open / nav print snapshot text by default (use --json for full payload)

Fast, CLI-first

  • Single binary-style script on your PATH: cursor-browser
  • Low overhead: Node built-ins only, loopback HTTP, no runtime npm deps
  • Multi-window: --workspace <folder> or match cwd
  • Single-tab policy: reuse one tab; close extras for predictable automation

Under the hood (debug like DevTools)

  • Screenshot (PNG path; MCP can return image content when available)
  • inspect — meta, counts, headings, links, inputs, body text
  • console / network via Cursor getConsoleLogs / getNetworkRequests
  • eval — run page JavaScript

Local and contained

  • Listens on 127.0.0.1 only
  • Per-window port (default base 17373, auto-increments if busy)
  • State under ~/.cursor-browser-cli/
  • Status bar shows project :port so you know which window is listening

Requirements

  • Cursor IDE with Browser Tab / cursor.browserView.* APIs available
  • Node.js ≥ 18 (CLI + MCP; no production npm dependencies)
  • macOS / Linux / Windows (where Cursor runs)

Visual Studio Code does not have Cursor’s Browser Tab API. Installed there, the extension shows a status-bar notice and does not start the bridge.


Install (recommended: npm)

npm install -g cursor-browser-cli

That installs:

Piece What you get
CLI cursor-browser on your PATH
MCP cursor-browser-mcp on your PATH
Extension Copied into ~/.cursor/extensions/ (via postinstall)
Skills Agent skill templates when those skill roots exist

If the extension step was skipped (e.g. npm i --ignore-scripts), run:

cursor-browser setup

Then reload each Cursor window you use:

Cmd+Shift+P (or Ctrl+Shift+P) → Developer: Reload Window

Confirm the status bar shows something like your-project :17375, then:

cursor-browser windows
cursor-browser --workspace <project-folder> open https://example.com
cursor-browser --workspace <project-folder> snapshot

Skip automatic setup

CURSOR_BROWSER_SKIP_SETUP=1 npm install -g cursor-browser-cli
cursor-browser setup   # when ready

From source (optional)

git clone https://github.com/bcharleson/cursor-browser-cli.git
cd cursor-browser-cli
npm install          # runs setup
# or: ./scripts/install.sh

Extension commands (inside Cursor)

Command palette Purpose
Cursor Browser CLI: Show Status Health + workspace/port
Cursor Browser CLI: Restart Server Restart the localhost HTTP server

Extension id: bcharleson.cursor-browser-cli.

Settings

Setting Default Meaning
cursorBrowserCli.port 17373 Preferred port (falls through if busy)
cursorBrowserCli.enabled true Start the HTTP server on activation

Quick start (agent loop)

This is the loop CLI agents should follow:

# 0) Discover this project → bridge port (required with multiple Cursor windows)
cursor-browser windows          # list: project → port
cursor-browser pin              # this cwd's project + port + export lines
eval $(cursor-browser pin --export)
# sets CURSOR_BROWSER_WORKSPACE + CURSOR_BROWSER_CLI_PORT
# prefer workspace name over port (ports can change after recover)

# or pin explicitly:
export WS=my-app   # folder name of the Cursor workspace

# 1) One clean tab + navigate → snapshot with [ref=e…] printed
cursor-browser --workspace $WS close
cursor-browser --workspace $WS open http://localhost:3000

# 2) Interact by ref from the snapshot
cursor-browser --workspace $WS click e5
cursor-browser --workspace $WS fill e3 "hello"
cursor-browser --workspace $WS press Enter

# 3) Wait for navigation / UI (avoid races)
cursor-browser --workspace $WS wait --url /results --timeout 15000
cursor-browser --workspace $WS wait --text "Success"

# 4) Visual / debug
cursor-browser --workspace $WS screenshot /tmp/out.png
cursor-browser --workspace $WS inspect
cursor-browser --workspace $WS console

Rules of thumb

  1. Pin first — windows → pin → env or --workspace (never guess with multi-window).
  2. Take a fresh snapshot after navigation or large DOM changes before using refs.
  3. Prefer ref (e12) over CSS when the snapshot provides one.
  4. Prefer open / nav (they return snapshots) over bare navigate without a follow-up snap.
  5. Use wait after clicks that change URL or content.
  6. Use close if extra tabs pile up; keep one tab for reliability.
  7. With multiple Cursor windows, always pass --workspace (or pin via eval $(cursor-browser pin --export)).

CLI reference

cursor-browser [--workspace NAME|PATH] [--port N] <command> [args]

Global flags

Flag Alias Description
--workspace <name\|path> -w, --project Target Cursor window by workspace folder name or absolute path
--port <n> -p Force a specific bridge port (from pin / windows)
--json Print full JSON (large trees stripped) instead of snapshot text
--export With pin / resolve: print shell exports only (eval $(cursor-browser pin --export))
--snap --snapshot After interact, attach a fresh ref snapshot
--wait-nav --wait-navigation After click, wait for URL change
--help -h Show usage

Environment variables

Variable Purpose
CURSOR_BROWSER_WORKSPACE Default workspace when --workspace is omitted
CURSOR_BROWSER_CLI_PORT Default port when --port is omitted

Legacy env names from earlier package renames may still be read by clients for compatibility.

Routing commands

Command Description
windows List live bridges (project → port)
pin / resolve Discover this project + port; agent pin step (--export for shell)
whoami / status / health Resolved target + health + pin exports
probe Low-level reachability check

Tabs and navigation

Command Description
open <url> Single-tab open/reuse + navigate + snapshot
nav <url> / navigate <url> Navigate active tab + snapshot
tabs List Browser Tab view IDs
close [viewId] Close extras / specific tab (single-tab hygiene)
select <viewId> Select a tab by view ID
lock / unlock Lock tab from human input during automation
back / forward / reload History and reload
url / title Current URL or document title

Interaction (prefer refs from snapshot)

Command Description
snapshot / snap / refs Accessibility tree with refs (e1, …). Interactive by default
click <ref\|css> Click element (--snap, --wait-nav optional)
dblclick <ref\|css> Double-click
rightclick <ref\|css> Right-click / context menu
type <ref\|css> <text> Type (append) into element
fill <ref\|css> <text> Clear and fill element
select-option <ref\|css> <value\|label> Choose a <select> option
scroll [ref\|css] [--y N] [--top N] Scroll window or element
hover <ref> Hover by ref
press <key> Key press (Enter, Tab, Escape, …)

Wait, viewport, capture, debug

Command Description
wait / wait-for Poll until condition (see flags below)
resize <W> <H> Resize viewport
screenshot [path.png] Capture viewport (default under /tmp)
inspect / dom Structured page summary
console / logs Console messages
network Network requests
eval / evaluate <js> Run JavaScript in the page

wait flags

Flag Meaning
--url <substr> URL contains substring
--text <str> Page/snapshot text contains string
--ref <eN> Ref exists / is available
--selector <css> CSS selector matches (also positional)
--timeout <ms> Max wait (default 30000)

Examples:

cursor-browser --workspace my-app wait --url /dashboard --timeout 15000
cursor-browser --workspace my-app wait --text "Welcome"
cursor-browser --workspace my-app wait --ref e12
cursor-browser --workspace my-app wait --selector "button.save"

Multi-window routing order

When you have several Cursor projects open, the CLI picks a target in this order:

  1. --port / CURSOR_BROWSER_CLI_PORT
  2. --workspace / CURSOR_BROWSER_WORKSPACE / CURSOR_BROWSER_PROJECT
  3. Match current cwd to a registered workspace folder (strong match only)
  4. Single open instance
  5. Fail closed — never silently open another project when multiple bridges are live

Shared ~/.cursor-browser-cli/port is only used when no instances are registered (recovery), not as a multi-window fallback.

cursor-browser windows
cursor-browser pin
eval $(cursor-browser pin --export)
cursor-browser whoami
cursor-browser open http://localhost:3000
# or without env:
cursor-browser --workspace my-app open http://localhost:3000

pin / resolve output (human):

project:  my-app
path:     /Users/you/Developer/my-app
port:     17375
how:      cwd (score 100)
live:     yes

# Pin this project for the rest of the shell/session:
export CURSOR_BROWSER_WORKSPACE='my-app' CURSOR_BROWSER_CLI_PORT=17375

MCP server

Stdio MCP server for agents that prefer tools over shelling out.

After npm install -g cursor-browser-cli, the bin cursor-browser-mcp is on your PATH.

Register

# Grok Build
grok mcp add cursor-browser -- cursor-browser-mcp

# Claude Code
claude mcp add cursor-browser -- cursor-browser-mcp

Any stdio MCP client:

{
  "mcpServers": {
    "cursor-browser": {
      "command": "cursor-browser-mcp"
    }
  }
}

Fallback (from a clone or if the bin is not on PATH):

{
  "mcpServers": {
    "cursor-browser": {
      "command": "node",
      "args": ["/absolute/path/to/cursor-browser-cli/mcp/server.mjs"]
    }
  }
}

Optional env on the server process:

  • CURSOR_BROWSER_WORKSPACE
  • CURSOR_BROWSER_CLI_PORT

Or pass workspace on each tool call. With multiple Cursor projects open, workspace is required (MCP fails closed instead of opening the wrong project).

Agent pin flow (MCP)

  1. browser_windows — list project → port
  2. browser_resolve (or browser_pin) — returns workspace, port, and pin instructions
  3. Pass that workspace on every subsequent browser_* call

Tools

All tools accept optional workspace (project folder name or path) unless noted. With multiple live bridges, pass it every time.

Tool Purpose
browser_windows List live bridges (project → port)
browser_resolve / browser_pin Discover project + port for this agent; pin before open
browser_status Health + workspace for a window
browser_open Open/reuse single tab, navigate, return ref snapshot
browser_navigate Navigate active tab + snapshot
browser_snapshot Accessibility snapshot with refs (interactive optional)
browser_click Click by ref or selector (snapshot, waitNavigation optional)
browser_dblclick Double-click
browser_rightclick Right-click / context menu
browser_type Type (append) by ref or selector
browser_fill Clear + fill by ref or selector
browser_scroll Scroll window or element
browser_select_option Choose a <select> option by value/label/index
browser_hover Hover by ref
browser_press Press key (Enter submits forms)
browser_wait Wait for URL/text/ref/selector (timeoutMs, etc.)
browser_lock / browser_unlock Tab lock
browser_resize Viewport size (width, height)
browser_screenshot PNG (+ image content when data URL is available)
browser_inspect DOM/meta/links/inputs/body summary
browser_console Console log dump
browser_network Network request dump
browser_evaluate Run script in page
browser_tabs List view IDs
browser_url / browser_title Current URL / title
browser_back / browser_forward / browser_reload History / reload

Screenshot note: When the page returns a data URL, the MCP layer can attach an image content block for vision-capable models, plus a text payload with the saved path.


Skills

npm install -g / cursor-browser setup copies skill/SKILL.md to:

  • ~/.grok/skills/cursor-browser/SKILL.md
  • ~/.claude/skills/cursor-browser/SKILL.md
  • ~/.agents/skills/cursor-browser/SKILL.md
  • ~/.cursor/skills/cursor-browser/SKILL.md
  • ~/.codex/skills/cursor-browser/SKILL.md

The skill describes only the Cursor Browser Tab. It does not depend on or install any external-browser stack.

The skill teaches agents:

  • Always route the correct Cursor window (windows / --workspace)
  • Preferred snapshot → ref click/fill → wait loop
  • When to screenshot, inspect, console, network
  • Failure modes (stale refs, wrong project, connection refused)

Architecture

┌─ Cursor window: your-project ──────────────────────────┐
│  Extension host HTTP  127.0.0.1:1737x                   │
│         │                                              │
│         │  cursor.browserView.*                        │
│         ▼                                              │
│  Browser Tab                                           │
│  · refs via data-cursor-ref after snapshot             │
│  · DOM click/type/fill (not raw CDP Input)             │
└────────────────────────────────────────────────────────┘
                    ▲
                    │  loopback only
     CLI  ·  MCP  ·  scripts
   (Grok / Claude Code / Codex / shell)
Piece Role
extension/ VS Code/Cursor extension: HTTP API, workspace registry, status bar, cursor.browserView.*
cli/cursor-browser Multi-window client; resolves port; pretty-prints actions
mcp/server.mjs Stdio MCP → same HTTP actions
skill/SKILL.md Agent instructions for the preferred loop
scripts/install.sh CLI symlink, extension copy, skills, MCP hints

On-disk state (~/.cursor-browser-cli/):

File Purpose
instances.json Registered windows (workspace paths, ports, PIDs)
port Last/default port hint
bridge.log Extension host log

Ports start at 17373 and try up to 32 candidates if the preferred port is taken (one port per Cursor window).


How agents should use it

Typical product/UI session

  1. browser_windows or cursor-browser windows — list project → port
  2. browser_resolve / cursor-browser pin — pin this project (env or workspace arg)
  3. open / browser_open on http://localhost:… or staging URL
  4. Read refs from the snapshot
  5. click / fill / press
  6. wait for URL or text
  7. New snapshot after major UI change
  8. screenshot or inspect when stuck

Multi-project day

Always discover then pin:

cursor-browser windows
cursor-browser pin
eval $(cursor-browser pin --export)

cursor-browser --workspace project-a open http://localhost:3000
cursor-browser --workspace project-b open http://localhost:4000

Or set CURSOR_BROWSER_WORKSPACE in that agent’s shell profile / MCP env.

Switching agents mid-project

The Browser Tab is owned by the Cursor window, not by a single agent process. You can:

  1. Use Cursor Agent for some steps (built-in tools)
  2. Switch to Claude Code / Grok / Codex in the terminal
  3. Continue with cursor-browser or MCP on the same tab

That continuity is the whole point of this tool.


Security

  • The HTTP server binds to loopback only (127.0.0.1).
  • Requests that carry a browser Origin or Referer are refused. CLI and MCP clients do not send those headers, so a website you visit cannot call the bridge.
  • Any other process on your machine can still drive the Browser Tab (navigate, click, run page JS, read console/network).
  • Treat it like a local debugger: do not tunnel or expose the port; do not run on untrusted multi-user machines without isolation.
  • eval / browser_evaluate execute arbitrary page JavaScript — only run code you trust.

Troubleshooting

Symptom Fix
Connection refused / empty windows cursor-browser doctor then cursor-browser recover. Clears stale ports, asks extension to restart (file trigger), optionally reloads Cursor. Browser Tab open ≠ bridge up.
After reboot bridge dead Extension host did not re-bind HTTP. recover → wait → windows. Ensure Cursor Browser CLI extension is Enabled.
Wrong project / wrong app cursor-browser windows → pin → --workspace <name> or eval $(cursor-browser pin --export)
Multiple windows; cannot guess Pass --workspace / MCP workspace; CLI and MCP fail closed
Stale ref / element not found New snapshot / open / nav; never reuse refs across big DOM changes
Race / empty or intermediate page wait --url / --text / --ref / --selector with a higher --timeout
Extra tabs / flaky targeting close, then open or nav to enforce single-tab
MCP tools missing Re-register MCP with absolute path to mcp/server.mjs; restart the agent
CLI not found Ensure ~/.local/bin is on PATH, or call the script by full path
CDP Input blocked Expected — use click / type / fill / press (DOM events), not raw CDP Input

Logs: ~/.cursor-browser-cli/bridge.log


Repo layout

cursor-browser-cli/
├── README.md
├── LICENSE                 # MIT
├── package.json            # npm package (bins + postinstall setup)
├── cli/
│   └── cursor-browser      # CLI entry (Node)
├── extension/
│   ├── package.json        # publisher bcharleson, icon, gallery text
│   ├── extension.js        # HTTP API + cursor.browserView.*
│   ├── snapshot.js         # Accessibility snapshot + refs
│   ├── icon.svg            # source art
│   └── icon.png            # Extensions view + Open VSX icon
├── mcp/
│   └── server.mjs          # MCP stdio server → bin: cursor-browser-mcp
├── scripts/
│   ├── setup.js            # extension + skills install
│   ├── package-vsix.js     # gallery package (does not publish)
│   └── install.sh          # thin wrapper → setup.js
└── skill/
    └── SKILL.md            # Agent skill template

No runtime npm dependencies — Node built-ins only (http, fs, path, os, etc.).


Development notes

  • Extension activation: onStartupFinished
  • Preferred port configurable via cursorBrowserCli.port
  • Clients still understand legacy state dirs / names from earlier renames for smoother upgrades
  • After changing extension code: cursor-browser setup (or npm run setup) and Reload Window
  • npm package: npm publish (requires npm login)
  • Extension gallery package: npm run package:vsix (see below; this does not publish)

Publishing the extension

The Extensions row that says local is a sideload. cursor-browser setup copies the extension into ~/.cursor/extensions/. Cursor did not fetch it from a gallery, so the publisher was the placeholder local and there was no icon.

Cursor’s Extensions search reads Open VSX (Eclipse), through Cursor’s marketplace proxy. It does not read Microsoft’s Visual Studio Marketplace. A Microsoft-only publish will not make this appear for Cursor users. Open VSX is the listing that reaches people in the Extensions panel you are looking at. The same .vsix can also go to the Visual Studio Marketplace later, for people browsing VS Code’s store. That second listing still only works inside Cursor.

Extension id: bcharleson.cursor-browser-cli.

  1. Create an Eclipse account and claim the bcharleson namespace at open-vsx.org. Set the namespace display name to B. Charleson. That name is what Cursor shows under the extension title. The id stays bcharleson.
  2. Create an access token there.
  3. From this repo: npm run package:vsix
  4. Publish that file: npx ovsx publish cursor-browser-cli-1.3.0.vsix -p "$OVSX_PAT"
  5. In Cursor, search Cursor Browser CLI. The row should show this icon and the publisher bcharleson.

The Visual Studio Marketplace is a separate account (publisher id bcharleson, a PAT). Publish there only after Open VSX is live, with the same version. VS Code users still do not get a Browser Tab.

Tagged GitHub releases are the source release. npm (npm publish) and Open VSX (ovsx publish) are separate logins. This repository does not store those tokens.


License

MIT © Brandon Charleson


Contributing / sharing

This repo is intended to be shared as open source so CLI agents in Cursor can share one Browser Tab.

If you publish or fork:

  1. Keep the why clear: multi-agent access to Cursor’s Browser Tab
  2. Document both CLI and MCP equally
  3. Stress workspace routing and the snapshot → ref → wait loop

Issues and PRs that improve multi-window routing, snapshot quality, or agent docs are especially welcome.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft