@ricardochen1996/browser-use-mcp 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,425 @@
1
+ # Client wiring
2
+
3
+ `browser-use-mcp` speaks the Model Context Protocol. This page has copy-pasteable configuration for
4
+ the clients people actually use: **[Claude Code](#claude-code)**, **[Claude Desktop](#claude-desktop)**,
5
+ **[Cursor](#cursor)**, **[Codex](#codex)**, **[DSH](#dsh)**, and a plain
6
+ **[`mcpServers` JSON](#generic-mcpservers-json)** any MCP host understands. Every stdio snippet
7
+ starts `node` with the server's absolute path and runs from any working directory.
8
+
9
+ ## Before you paste: three things
10
+
11
+ 1. **Use your own absolute path.** The snippets below use this checkout's path,
12
+ `/Users/ricardo.chen/PersonalGit/browser-use-mcp`. Replace it with wherever you cloned the
13
+ repository. Do not rely on a relative path: GUI applications do not start in the directory you
14
+ ran a shell command from.
15
+ 2. **Make sure `node` is the Node 22+ you expect.** The server needs Node `^22.19.0 || >=24.0.0`.
16
+ A GUI-launched client often has a shorter `PATH` than your shell. If it cannot find `node`, run
17
+ `which node` in your shell and put that absolute path in `command` instead — for example
18
+ `/opt/homebrew/bin/node`.
19
+ 3. **stdout is the protocol; logs are stderr.** While serving MCP, stdout carries JSON-RPC frames
20
+ and every log line goes to stderr. When a client shows nothing, run the exact command in a
21
+ terminal: the JSON-RPC traffic appears on stdout and `browser-use-mcp …` log lines on stderr,
22
+ which is where startup and engine-install problems are explained.
23
+
24
+ The package is **not published to npm yet**. Install from the checkout:
25
+
26
+ ```bash
27
+ cd /Users/ricardo.chen/PersonalGit/browser-use-mcp
28
+ npm install
29
+ ```
30
+
31
+ That is enough — the server itself is plain ESM. The Python side (the engine and `browser-harness`)
32
+ is provisioned automatically on first use, or ahead of time:
33
+
34
+ ```bash
35
+ node /Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs install
36
+ node /Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs doctor
37
+ ```
38
+
39
+ If you prefer a command name over an absolute path, `npm link` in the checkout puts
40
+ `browser-use-mcp` on your `PATH`; GUI clients may still not see that `PATH`, so the absolute path is
41
+ the reliable form. Every snippet below is **stdio** unless it says otherwise; the server's default
42
+ transport is stdio, one browser per server process.
43
+
44
+ Two defaults decide what the agent sees:
45
+
46
+ - **Transport stdio** — the client starts its own server process, and only that client uses it.
47
+ - **Mode attach** — the server drives the Chrome you already use, so the agent sees your logins and
48
+ tabs. Enable remote debugging once in that Chrome (`chrome://inspect/#remote-debugging` → allow);
49
+ on macOS the application running the server also needs Full Disk Access. If you would rather give
50
+ the agent a dedicated browser, add `BROWSER_USE_MCP_MODE=launch` (and `BROWSER_USE_MCP_HEADLESS=1`
51
+ for no window). `BROWSER_USE_MCP_PROFILE` and `BROWSER_USE_MCP_HEADLESS` only mean something in
52
+ launch mode — the snippets below set `launch` where they use them.
53
+
54
+ ---
55
+
56
+ ## Claude Code
57
+
58
+ Two equivalent ways to wire it.
59
+
60
+ ### CLI
61
+
62
+ ```bash
63
+ # Attach mode (the default): use the Chrome you browse with.
64
+ claude mcp add --scope user browser-use \
65
+ -- node /Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs
66
+
67
+ # Launch mode: a dedicated headless browser with its own profile.
68
+ claude mcp add --scope user browser-use \
69
+ --env BROWSER_USE_MCP_MODE=launch \
70
+ --env BROWSER_USE_MCP_HEADLESS=1 \
71
+ --env BROWSER_USE_MCP_PROFILE=claude-code \
72
+ -- node /Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs
73
+ ```
74
+
75
+ - `--scope user` makes it available in every project. Use `--scope project` to write a `.mcp.json`
76
+ in the current repository instead, or omit it for local-only.
77
+ - Add `--env TYPESAFE_API_KEY=…` (or the `TEXT_MODEL_*` group) to enable `browser_goal` and
78
+ `browser_act` intents; see [Jev credentials](#jev-credentials).
79
+ - Check it with `claude mcp list`, then ask Claude to call `browser_doctor`.
80
+
81
+ ### Project `.mcp.json`
82
+
83
+ ```json
84
+ {
85
+ "mcpServers": {
86
+ "browser-use": {
87
+ "command": "node",
88
+ "args": ["/Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs"],
89
+ "env": {
90
+ "BROWSER_USE_MCP_MODE": "launch",
91
+ "BROWSER_USE_MCP_HEADLESS": "1",
92
+ "BROWSER_USE_MCP_PROFILE": "claude-code"
93
+ }
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Claude Desktop
102
+
103
+ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, or
104
+ `%APPDATA%\Claude\claude_desktop_config.json` on Windows. The file is plain JSON (no comments, no
105
+ trailing commas):
106
+
107
+ ```json
108
+ {
109
+ "mcpServers": {
110
+ "browser-use": {
111
+ "command": "node",
112
+ "args": ["/Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs"],
113
+ "env": {
114
+ "BROWSER_USE_MCP_MODE": "launch",
115
+ "BROWSER_USE_MCP_PROFILE": "claude-desktop"
116
+ }
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ Fully quit and restart Claude Desktop after saving. In launch mode the browser window appears when
123
+ the model calls `browser_open`, not at startup; in attach mode it is already the Chrome you use.
124
+ `BROWSER_USE_MCP_MODE=launch` is what makes this client use a dedicated profile — give each client
125
+ its own `BROWSER_USE_MCP_PROFILE` if several clients will launch at once (two servers on one profile
126
+ are refused by design).
127
+
128
+ ---
129
+
130
+ ## Cursor
131
+
132
+ Project configuration goes in `.cursor/mcp.json`; to make it available everywhere, use
133
+ `~/.cursor/mcp.json`:
134
+
135
+ ```json
136
+ {
137
+ "mcpServers": {
138
+ "browser-use": {
139
+ "command": "node",
140
+ "args": ["/Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs"],
141
+ "env": {
142
+ "BROWSER_USE_MCP_MODE": "launch",
143
+ "BROWSER_USE_MCP_HEADLESS": "1",
144
+ "BROWSER_USE_MCP_PROFILE": "cursor"
145
+ }
146
+ }
147
+ }
148
+ }
149
+ ```
150
+
151
+ Reload the window (or restart Cursor) after editing. The tools appear in **Settings → MCP** once the
152
+ server answers an `initialize`.
153
+
154
+ ---
155
+
156
+ ## Codex
157
+
158
+ Add the server to `~/.codex/config.toml`:
159
+
160
+ ```toml
161
+ [mcp_servers.browser-use]
162
+ command = "node"
163
+ args = ["/Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs"]
164
+ startup_timeout_sec = 120
165
+
166
+ [mcp_servers.browser-use.env]
167
+ BROWSER_USE_MCP_MODE = "launch"
168
+ BROWSER_USE_MCP_HEADLESS = "1"
169
+ BROWSER_USE_MCP_PROFILE = "codex"
170
+ ```
171
+
172
+ `startup_timeout_sec` is optional; a first run that has to provision the Python environment can take
173
+ a minute or two, so raise it if your Codex build gives up before the server answers. Restart Codex
174
+ after saving, then check that `browser_doctor` is in its tool list.
175
+
176
+ ---
177
+
178
+ ## DSH
179
+
180
+ DSH loads MCP servers through its `@deepseek-ai/dsh-mcp-client` plugin, configured in the profile's
181
+ `cordis.patch.yml` (`$DSH_HOME/profiles/<profile>/cordis.patch.yml`; `DSH_HOME` defaults to
182
+ `~/.dsh`, and the standard Web UI profile is `web`). The row is namespaced: its tools appear as
183
+ `mcp__browser-use__browser_open` and so on.
184
+
185
+ **stdio** — DSH starts the server itself:
186
+
187
+ ```yaml
188
+ - insert:
189
+ - id: browser-use-mcp
190
+ name: '@deepseek-ai/dsh-mcp-client'
191
+ config:
192
+ serverName: browser-use
193
+ transport: stdio
194
+ command: node
195
+ args:
196
+ - /Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs
197
+ env:
198
+ BROWSER_USE_MCP_MODE: launch
199
+ BROWSER_USE_MCP_HEADLESS: '1'
200
+ BROWSER_USE_MCP_PROFILE: dsh
201
+ failOnStartupError: true
202
+ ```
203
+
204
+ **Streamable HTTP** — point at a server you started yourself (see
205
+ [one shared HTTP server](#one-shared-http-server)):
206
+
207
+ ```yaml
208
+ - insert:
209
+ - id: browser-use-mcp
210
+ name: '@deepseek-ai/dsh-mcp-client'
211
+ config:
212
+ serverName: browser-use
213
+ transport: streamable-http
214
+ url: http://127.0.0.1:7331/mcp
215
+ failOnStartupError: true
216
+ ```
217
+
218
+ A DSH detail worth knowing: the stdio transport merges the configured `env` over a **scrubbed**
219
+ ambient environment, and ambient names matching `KEY`, `PASSWORD`, `SECRET` or `TOKEN` are dropped.
220
+ So Jev credentials must be listed explicitly in `env` — they do not leak in from the shell:
221
+
222
+ ```yaml
223
+ # Jev credentials must be repeated in env: ambient names matching KEY/TOKEN are scrubbed.
224
+ env:
225
+ BROWSER_USE_MCP_MODE: launch
226
+ BROWSER_USE_MCP_HEADLESS: '1'
227
+ TYPESAFE_API_KEY: !!js process.env.TYPESAFE_API_KEY
228
+ ```
229
+
230
+ Restart the harness if the row is new. Both variants accept the same other `config` fields as any
231
+ `dsh-mcp-client` entry (`reconnect`, `toolCallTimeoutMs`, …).
232
+
233
+ ---
234
+
235
+ ## Generic `mcpServers` JSON
236
+
237
+ Most MCP hosts read a JSON object with one entry per server. This is the same shape as the Claude
238
+ Desktop and Cursor snippets, with the most common knobs shown:
239
+
240
+ ```json
241
+ {
242
+ "mcpServers": {
243
+ "browser-use": {
244
+ "command": "node",
245
+ "args": [
246
+ "/Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs",
247
+ "--mode", "launch",
248
+ "--headless",
249
+ "--profile", "my-agent"
250
+ ],
251
+ "env": {
252
+ "BROWSER_USE_MCP_HEADLESS": "1",
253
+ "BROWSER_USE_MCP_PROFILE": "my-agent",
254
+ "BROWSER_USE_MCP_HOME": "/Users/me/.browser-use-mcp"
255
+ }
256
+ }
257
+ }
258
+ }
259
+ ```
260
+
261
+ Server flags go in `args`; environment variables go in `env`. `--headless` and
262
+ `BROWSER_USE_MCP_HEADLESS=1` mean the same thing — either spelling is fine, and a flag wins if both
263
+ are present. The full list is in the [configuration reference](config.md).
264
+
265
+ Mutually equivalent spellings for the same settings:
266
+
267
+ | Setting | Flag | Env |
268
+ | --- | --- | --- |
269
+ | Headless | `--headless` | `BROWSER_USE_MCP_HEADLESS=1` |
270
+ | Profile | `--profile my-agent` | `BROWSER_USE_MCP_PROFILE=my-agent` |
271
+ | State root | `--home /path` | `BROWSER_USE_MCP_HOME=/path` |
272
+ | No `browser_eval` | `--no-eval` | `BROWSER_USE_MCP_NO_EVAL=1` |
273
+ | Attach to a debug browser | `--mode attach --cdp-endpoint http://127.0.0.1:9333` | `BROWSER_USE_MCP_MODE=attach`, `BROWSER_USE_MCP_CDP_ENDPOINT=http://127.0.0.1:9333` |
274
+
275
+ ### Environment examples
276
+
277
+ Headless, separate profile, explicit state root:
278
+
279
+ ```json
280
+ "env": {
281
+ "BROWSER_USE_MCP_HEADLESS": "1",
282
+ "BROWSER_USE_MCP_PROFILE": "agent-a",
283
+ "BROWSER_USE_MCP_HOME": "/Users/me/.browser-use-mcp"
284
+ }
285
+ ```
286
+
287
+ Jev credentials belong in `env`, never in `args` (arguments are visible in process listings):
288
+ see the next section.
289
+
290
+ ---
291
+
292
+ ## Jev credentials
293
+
294
+ `browser_goal` and `browser_act`'s `intent` are optional; the rest of the tool surface never spends
295
+ model quota. Two ways to make the policy work:
296
+
297
+ **TypeSafe decider** (default) — Jev answers the policy questions:
298
+
299
+ ```json
300
+ "env": {
301
+ "TYPESAFE_API_KEY": "your-key",
302
+ "TYPESAFE_BASE_URL": "https://…",
303
+ "TYPESAFE_MODEL": "…"
304
+ }
305
+ ```
306
+
307
+ Only `TYPESAFE_API_KEY` is required; the other two have engine defaults. `TEXT_MODEL_*` is still
308
+ wanted if the policy should write `TYPE_TEXT` values.
309
+
310
+ **Chat decider** — a text model answers instead:
311
+
312
+ ```json
313
+ "env": {
314
+ "JEV_DECIDER": "chat",
315
+ "TEXT_MODEL_BASE_URL": "https://your-endpoint/v1",
316
+ "TEXT_MODEL": "your-model",
317
+ "TEXT_MODEL_API_KEY": "your-key"
318
+ }
319
+ ```
320
+
321
+ `--jev-decider chat` in `args` is equivalent to `JEV_DECIDER=chat`. To keep the surface entirely
322
+ policy-free, pass `--no-jev` (or `BROWSER_USE_MCP_NO_JEV=1`).
323
+
324
+ The doctor reports only `set`/`unset` for keys, never a value, and a missing key is a refusal that
325
+ names the variable, not a crash.
326
+
327
+ ---
328
+
329
+ ## One shared HTTP server
330
+
331
+ Running a long-lived HTTP endpoint is how several agents share one installed server instead of each
332
+ starting a stdio process. Each MCP session still gets its own browser session, sidecar and tab, so
333
+ two agents never click on one page by accident.
334
+
335
+ Start it once:
336
+
337
+ ```bash
338
+ # Default: every session drives the Chrome you already use (attach, shared by default).
339
+ node /Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs \
340
+ --transport http --host 127.0.0.1 --port 7331 --path /mcp
341
+
342
+ # Or: every session gets a tab in one dedicated browser this server launches.
343
+ node /Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs \
344
+ --transport http --host 127.0.0.1 --port 7331 --path /mcp \
345
+ --mode launch --headless
346
+ ```
347
+
348
+ The endpoint is then `http://127.0.0.1:7331/mcp`. Flags given here apply to every session; clients
349
+ only supply the URL.
350
+
351
+ **Persistent per-agent profiles (launch mode).** An anonymous session's profile is deleted when the
352
+ session ends. To keep logins across reconnects, the client names its profile on the initialize
353
+ request — in the URL, `http://127.0.0.1:7331/mcp?profile=claude`, or with the header
354
+ `X-Browser-Use-Profile: claude`. Different names run at once on different profiles; two live
355
+ sessions with the same name are refused (the profile is one browser's at a time). The snippets below
356
+ show the URL form.
357
+
358
+ - **Claude Code**
359
+
360
+ ```bash
361
+ claude mcp add --transport http --scope user browser-use \
362
+ "http://127.0.0.1:7331/mcp?profile=claude"
363
+ ```
364
+
365
+ - **Claude Code project config**
366
+
367
+ ```json
368
+ {
369
+ "mcpServers": {
370
+ "browser-use": { "type": "http", "url": "http://127.0.0.1:7331/mcp?profile=claude" }
371
+ }
372
+ }
373
+ ```
374
+
375
+ - **Cursor** (`~/.cursor/mcp.json`)
376
+
377
+ ```json
378
+ {
379
+ "mcpServers": {
380
+ "browser-use": { "url": "http://127.0.0.1:7331/mcp?profile=cursor" }
381
+ }
382
+ }
383
+ ```
384
+
385
+ - **Codex** (`~/.codex/config.toml`)
386
+
387
+ ```toml
388
+ [mcp_servers.browser-use]
389
+ url = "http://127.0.0.1:7331/mcp"
390
+ ```
391
+
392
+ - **DSH** — use the `streamable-http` row [above](#dsh).
393
+
394
+ - **Any client that only says "URL"** — use `http://127.0.0.1:7331/mcp`, or add
395
+ `?profile=<name>` for a persistent per-agent profile in launch mode.
396
+
397
+ Notes:
398
+
399
+ - There is **no authentication**. Keep the bind on `127.0.0.1`; if it must be reachable from
400
+ elsewhere, put it behind a tunnel or reverse proxy you control.
401
+ - An idle session's browser is closed after 15 minutes; raise or lower that with
402
+ `BROWSER_USE_MCP_HTTP_IDLE_MS` (milliseconds, positive) in the server's environment.
403
+ - A client that disappears without terminating its session is cleaned up by the same idle sweep; an
404
+ explicit terminate cleans up at once.
405
+ - In launch mode browsers are launched per session with a profile directory under the state root:
406
+ anonymous ones are removed when the session ends, a `?profile=<name>` one is kept. In attach mode
407
+ (the default) every session drives the same already-running browser, shared by default — see
408
+ `--attach-sharing` in the [configuration reference](config.md).
409
+
410
+ ---
411
+
412
+ ## If a client shows no tools
413
+
414
+ | Symptom | Likely cause | Fix |
415
+ | --- | --- | --- |
416
+ | Client says the server exited immediately | `node` not found, or a bad flag value | Run the same command in a terminal and read stderr; a configuration error exits with code `2` and names the field. |
417
+ | Server starts but no tools appear | Wrong config file, or the client was not restarted | Use the client's MCP list/log view; restart the client after editing its config. |
418
+ | First call takes minutes, then works | First run is provisioning the Python environment | Wait, or run `node /Users/ricardo.chen/PersonalGit/browser-use-mcp/bin/browser-use-mcp.mjs install` first. Behind a proxy, set `HTTPS_PROXY`. |
419
+ | `browser_doctor` reports `Status: ready` but calls fail | The profile is held by another server, or the browser process died | Read the failure text — a profile collision names `--profile`; a dead browser is rebuilt on the next `browser_open`. |
420
+ | Profile lock error naming `--profile` | Two servers on one browser profile | Stop the other server or give this one `--profile <other-name>`. |
421
+ | Attach mode cannot find your Chrome (macOS) | Full Disk Access missing | System Settings → Privacy & Security → Full Disk Access, add the host app, restart it. |
422
+ | Chrome shows "Allow remote debugging?" | A second CDP client is running | Approve the prompt once, never retry; stop the extra client. The session's own tools share one connection. |
423
+
424
+ For the design behind the freshness rule and the one-connection rule, read
425
+ [architecture.md](architecture.md). For every flag and variable, read [config.md](config.md).