mcp-browser-extension 0.9.25 → 0.9.27

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.
Files changed (43) hide show
  1. package/README.md +32 -35
  2. package/SETUP.md +20 -20
  3. package/dist/shared/protocol.d.ts +1 -1
  4. package/dist/shared/tab-border.d.ts +1 -1
  5. package/dist/shared/tab-border.js +1 -1
  6. package/dist/src/access.js +2 -1
  7. package/dist/src/auto-update.d.ts +6 -6
  8. package/dist/src/auto-update.js +9 -8
  9. package/dist/src/bridge/auth.d.ts +3 -3
  10. package/dist/src/bridge/auth.js +5 -4
  11. package/dist/src/bridge/datadir.d.ts +1 -1
  12. package/dist/src/bridge/datadir.js +1 -1
  13. package/dist/src/bridge/evict.d.ts +7 -7
  14. package/dist/src/bridge/evict.js +13 -13
  15. package/dist/src/bridge/peer.d.ts +4 -4
  16. package/dist/src/bridge/peer.js +4 -4
  17. package/dist/src/bridge/server.d.ts +6 -6
  18. package/dist/src/bridge/server.js +11 -11
  19. package/dist/src/cli.d.ts +1 -1
  20. package/dist/src/cli.js +13 -12
  21. package/dist/src/compat.d.ts +4 -0
  22. package/dist/src/compat.js +28 -0
  23. package/dist/src/config.d.ts +4 -4
  24. package/dist/src/config.js +27 -26
  25. package/dist/src/executor/types.d.ts +1 -0
  26. package/dist/src/extension-command.js +3 -3
  27. package/dist/src/extension-install.d.ts +4 -4
  28. package/dist/src/extension-install.js +8 -6
  29. package/dist/src/mcp/helpers.d.ts +1 -1
  30. package/dist/src/mcp/helpers.js +83 -13
  31. package/dist/src/mcp/log.js +2 -2
  32. package/dist/src/mcp/server.d.ts +1 -1
  33. package/dist/src/mcp/server.js +1 -1
  34. package/dist/src/mcp/tools.js +5 -4
  35. package/dist/src/native-host.d.ts +1 -1
  36. package/dist/src/native-host.js +1 -1
  37. package/dist/src/telemetry.d.ts +3 -3
  38. package/dist/src/telemetry.js +7 -6
  39. package/docs/BLUEPRINT.md +11 -11
  40. package/extension-dist/background.js +6 -6
  41. package/extension-dist/manifest.json +1 -1
  42. package/extension-dist/options.html +1 -1
  43. package/package.json +26 -6
package/README.md CHANGED
@@ -1,14 +1,12 @@
1
1
  # MCP Browser Extension
2
2
 
3
- The unscoped distribution of `@mehmoodqureshi/chrome-mcp`, with the same implementation and version. Both package names remain supported.
4
-
5
3
  [![CI](https://github.com/Mehmoodqureshi/mcp-browser-extension/actions/workflows/ci.yml/badge.svg)](https://github.com/Mehmoodqureshi/mcp-browser-extension/actions/workflows/ci.yml)
6
4
  [![npm](https://img.shields.io/npm/v/mcp-browser-extension?label=npm)](https://www.npmjs.com/package/mcp-browser-extension)
7
5
  [![license](https://img.shields.io/npm/l/mcp-browser-extension?label=license)](LICENSE)
8
6
 
9
7
  **Website and docs:** [mcp-browser-extension.com](https://mcp-browser-extension.com) ·
10
8
  [Quickstart](https://mcp-browser-extension.com/docs/quickstart) ·
11
- [All 40 tools](https://mcp-browser-extension.com/docs/tools) ·
9
+ [All 42 tools](https://mcp-browser-extension.com/docs/tools) ·
12
10
  [Install the extension from the Chrome Web Store](https://chromewebstore.google.com/detail/mcp-browser-extension/jelfhdlkhbfmlpbghoeaepijllcnplgh)
13
11
 
14
12
  **Let Claude use the Chrome you are already logged into.** Not a fresh
@@ -24,8 +22,7 @@ localhost WebSocket server and drives the browser you already have open, through
24
22
  other MCP host.
25
23
 
26
24
  MCP Browser Extension has two parts: the extension, and a small MCP server you run
27
- with `npx` (npm package `mcp-browser-extension`, command `chrome-mcp`; the
28
- names predate the rename and stay so existing setups keep working). The extension
25
+ with `npx` (npm package and command: `mcp-browser-extension`). The extension
29
26
  comes from the
30
27
  [Chrome Web Store](https://chromewebstore.google.com/detail/mcp-browser-extension/jelfhdlkhbfmlpbghoeaepijllcnplgh)
31
28
  or loaded unpacked.
@@ -103,7 +100,7 @@ is the exact file the agent follows. The manual steps are below.
103
100
  <summary><b>Claude Code (terminal)</b> — one command, no config file to find</summary>
104
101
 
105
102
  ```bash
106
- claude mcp add chrome-mcp -s user -- \
103
+ claude mcp add mcp-browser-extension -s user -- \
107
104
  npx -y mcp-browser-extension@latest \
108
105
  --allow-domain example.com --enable-mutations --persist-token
109
106
  ```
@@ -127,7 +124,7 @@ with `/mcp` inside a session — no restart needed.
127
124
  ```jsonc
128
125
  {
129
126
  "mcpServers": {
130
- "chrome-mcp": {
127
+ "mcp-browser-extension": {
131
128
  "command": "npx",
132
129
  "args": ["-y", "mcp-browser-extension@latest",
133
130
  "--allow-domain", "example.com", "--enable-mutations",
@@ -155,8 +152,8 @@ stricter default described next.
155
152
 
156
153
  Without `--persist-token` a fresh token is minted every boot (the secure
157
154
  default), which means re-pairing the extension on each restart. With it, the
158
- token is stored 0600 at `~/.chrome-mcp/token` and reused; the extension's
159
- keepalive auto-reconnects with no manual step. `CHROME_MCP_TOKEN` pins the token
155
+ token is stored 0600 at `~/.mcp-browser-extension/token` and reused; the extension's
156
+ keepalive auto-reconnects with no manual step. `MCP_BROWSER_EXTENSION_TOKEN` pins the token
160
157
  explicitly (and is never written to disk).
161
158
 
162
159
  **2. Install the extension** — **required**; the server can drive nothing without it.
@@ -177,8 +174,8 @@ or paste.
177
174
  <summary>Developers: load it unpacked instead</summary>
178
175
 
179
176
  The extension also ships inside the npm package, and every time the server boots
180
- it copies it to `~/chrome-mcp-extension` (`%USERPROFILE%\chrome-mcp-extension` on
181
- Windows; `CHROME_MCP_EXTENSION_DIR` moves it). `chrome://extensions` → enable
177
+ it copies it to `~/mcp-browser-extension` (`%USERPROFILE%\mcp-browser-extension` on
178
+ Windows; `MCP_BROWSER_EXTENSION_EXTENSION_DIR` moves it). `chrome://extensions` → enable
182
179
  **Developer mode** → **Load unpacked** → pick that folder. It pairs itself from a
183
180
  `pairing.json` the server writes there, and the server refreshes the files on each
184
181
  boot (never with an older build) so it reloads itself within 30 seconds.
@@ -211,7 +208,7 @@ stays in the toolbar. Hover it for the status in words.
211
208
  Manual fallback (the helper is turned off with `--no-native-host`, or Connect
212
209
  reports a problem): run `npx -y mcp-browser-extension@latest --print-pairing`,
213
210
  open the extension's **Settings**, and paste the `port` + `token` from
214
- `~/.chrome-mcp/handshake.json`.
211
+ `~/.mcp-browser-extension/handshake.json`.
215
212
 
216
213
  ### Extension missing after restarting Chrome
217
214
 
@@ -234,7 +231,7 @@ npx -y mcp-browser-extension@latest extension repair --apply
234
231
  ```
235
232
 
236
233
  The repair backs up the original preferences under
237
- `~/.chrome-mcp/extension-repair-backups/`, removes only the confirmed obsolete
234
+ `~/.mcp-browser-extension/extension-repair-backups/`, removes only the confirmed obsolete
238
235
  registration, and preserves the current extension and its saved settings. It
239
236
  refuses to write while a Chromium browser is running. Reopen Chrome afterwards.
240
237
  Use `--user-data-dir <directory>` for a custom browser data location, or
@@ -280,7 +277,7 @@ at startup or the `profile_use` tool at runtime.
280
277
  Naming is automatic. Chrome won't tell an extension which profile it runs in, so
281
278
  each install keeps a random id and the server names it: the first browser is
282
279
  `default`, the next `profile-2`, then `profile-3`, and so on. Names are stored in
283
- `~/.chrome-mcp/profiles.json`, so a browser keeps its name across restarts.
280
+ `~/.mcp-browser-extension/profiles.json`, so a browser keeps its name across restarts.
284
281
  `chrome_status` lists every paired browser (with its active tab as a hint), and
285
282
  `profile_rename` gives one a friendly name (`profile-2` → `work`). To pin a name
286
283
  yourself instead, type it into the extension's Options → Profile; that always wins.
@@ -299,7 +296,7 @@ start. Wrap it in `cmd /c`:
299
296
  ```jsonc
300
297
  {
301
298
  "mcpServers": {
302
- "chrome-mcp": {
299
+ "mcp-browser-extension": {
303
300
  "command": "cmd",
304
301
  "args": ["/c", "npx", "-y", "mcp-browser-extension@latest",
305
302
  "--allow-domain", "example.com", "--enable-mutations",
@@ -309,14 +306,14 @@ start. Wrap it in `cmd /c`:
309
306
  }
310
307
  ```
311
308
 
312
- Or from Claude Code: `claude mcp add chrome-mcp -- cmd /c npx -y mcp-browser-extension@latest --allow-domain example.com`
309
+ Or from Claude Code: `claude mcp add mcp-browser-extension -- cmd /c npx -y mcp-browser-extension@latest --allow-domain example.com`
313
310
 
314
311
  For normal use, install the extension from the Chrome Web Store as described
315
312
  above, then click **Connect**. Do not use **Load unpacked** as part of the normal
316
313
  Windows setup. The unpacked developer build has the same extension ID as the
317
314
  Store build, so loading it can replace the Store installation; Chrome may then
318
- disable the non-Store copy. If you are developing chrome-mcp, load
319
- `%USERPROFILE%\chrome-mcp-extension` in a separate Chrome profile.
315
+ disable the non-Store copy. If you are developing mcp-browser-extension, load
316
+ `%USERPROFILE%\mcp-browser-extension` in a separate Chrome profile.
320
317
 
321
318
  The tools cover tabs, navigation, interaction (`click`/`type`/`press`/`hover`/
322
319
  `scroll`/`select_option`), reads (`get_text`/`get_html`/`screenshot`/`eval`/`wait_for`),
@@ -349,7 +346,7 @@ It prints a connector URL like `https://<random>.trycloudflare.com/mcp/<key>`:
349
346
  - **Claude Code elsewhere / agents:** use `<url>/mcp` with `Authorization: Bearer <key>`;
350
347
  the exact `claude mcp add` line is printed too.
351
348
 
352
- The key (32 random bytes, kept in `~/.chrome-mcp/remote-key`) guards every
349
+ The key (32 random bytes, kept in `~/.mcp-browser-extension/remote-key`) guards every
353
350
  request; a wrong or missing key gets a bare 404. Anyone holding the URL can drive
354
351
  your browser within the allowed sites, so keep it private and keep the allowlist
355
352
  tight. `--rotate-remote-key` cuts every client off. The quick-tunnel URL changes on
@@ -557,7 +554,7 @@ for a run that was never going to print a PDF or upload a file.
557
554
  `--unsafe-enable-eval`.
558
555
  - An unknown name fails at startup and prints the catalog, so a typo can never
559
556
  quietly drop `click` from the surface.
560
- - `chrome-mcp --help` prints the full catalog of 40 names to pick from.
557
+ - `mcp-browser-extension --help` prints the full catalog of 42 names to pick from.
561
558
 
562
559
  ## Status
563
560
 
@@ -569,7 +566,7 @@ full-page and element capture), and focuses newly opened tabs by default. 111
569
566
  automated tests + a gated headed extension smoke.
570
567
 
571
568
  v0.2.0 — all six build phases complete and green. End-to-end working:
572
- `npx chrome-mcp` ⇄ bridge ⇄ extension ⇄ your real Chrome, with a Playwright CDP
569
+ `npx mcp-browser-extension` ⇄ bridge ⇄ extension ⇄ your real Chrome, with a Playwright CDP
573
570
  fallback. v0.2 adds the accessibility `snapshot` + element refs, auto-wait,
574
571
  cookies/storage/`select_option`, trusted input (`chrome.debugger`), a toolbar
575
572
  status badge, and a stable pairing token (`--persist-token`).
@@ -616,11 +613,11 @@ status badge, and a stable pairing token (`--persist-token`).
616
613
  `eval` off, downloads off, mutating tools off. Opt in explicitly:
617
614
 
618
615
  ```
619
- chrome-mcp --allow-domain example.com --enable-mutations
620
- chrome-mcp --policy ./policy.json # see policy.example.json
621
- chrome-mcp --unsafe-all-domains # loud footgun
622
- chrome-mcp --enable-observers # console/network/dialog capture (patches page globals)
623
- chrome-mcp --redact # scrub secret-shaped strings out of page reads
616
+ mcp-browser-extension --allow-domain example.com --enable-mutations
617
+ mcp-browser-extension --policy ./policy.json # see policy.example.json
618
+ mcp-browser-extension --unsafe-all-domains # loud footgun
619
+ mcp-browser-extension --enable-observers # console/network/dialog capture (patches page globals)
620
+ mcp-browser-extension --redact # scrub secret-shaped strings out of page reads
624
621
  ```
625
622
 
626
623
  **Allowing a site without a restart.** When a call is refused because its site
@@ -628,7 +625,7 @@ is not allowed, the extension's toolbar icon shows a `?`. Click it: the popup
628
625
  lists the blocked site with an **Allow** button, shows whether the site you are on
629
626
  is allowed (with its own Allow), and lists the allowed sites. The Options page
630
627
  (Settings in the popup) also has a box to allow any other site. An allowed site applies at once to every session sharing that Chrome, and
631
- is saved to `~/.chrome-mcp/allowed-sites.json` so it survives restarts. Sites
628
+ is saved to `~/.mcp-browser-extension/allowed-sites.json` so it survives restarts. Sites
632
629
  allowed there can be removed there; sites from `--allow-domain` stay until the
633
630
  flags change. The catch-all `*` can only come from `--unsafe-all-domains`. The
634
631
  agent cannot approve a site itself: MCP Browser Extension never reads or drives the
@@ -656,12 +653,12 @@ policy verdict (`allowed`/`denied`), how long it took, how many bytes came back,
656
653
  and how many secrets were scrubbed — so "what did the agent do in my browser" has
657
654
  an answer after the fact.
658
655
 
659
- The per-boot 256-bit token in `~/.chrome-mcp/handshake.json` (mode 0600) is the
656
+ The per-boot 256-bit token in `~/.mcp-browser-extension/handshake.json` (mode 0600) is the
660
657
  only trust boundary; it is never written to stdout/stderr. On POSIX the mode is
661
658
  re-verified after every write and the server **fails closed** if the file ends up
662
659
  group/other-accessible. Windows has no such bits — `chmod` there only toggles the
663
660
  read-only attribute — so the check is skipped and the token's confidentiality
664
- rests on the per-user ACL of `%USERPROFILE%\.chrome-mcp`.
661
+ rests on the per-user ACL of `%USERPROFILE%\.mcp-browser-extension`.
665
662
 
666
663
  ## Updates
667
664
 
@@ -671,9 +668,9 @@ npm when it starts: if a newer version is published, it starts that version in
671
668
  its place, with the same arguments, so an MCP config written months ago still
672
669
  runs the newest release. The check gives up after 1.5 s when you are offline,
673
670
  and a copy run from a git checkout never updates itself. The new server also
674
- refreshes the unpacked extension in `~/chrome-mcp-extension`, which reloads
671
+ refreshes the unpacked extension in `~/mcp-browser-extension`, which reloads
675
672
  itself; the Chrome Web Store copy updates through Chrome as usual. Turn it off
676
- with `--no-auto-update` or `CHROME_MCP_AUTO_UPDATE=0`.
673
+ with `--no-auto-update` or `MCP_BROWSER_EXTENSION_AUTO_UPDATE=0`.
677
674
 
678
675
  ## Telemetry
679
676
 
@@ -681,7 +678,7 @@ The MCP Browser Extension **server** (not the extension) sends anonymous usage s
681
678
  project can see how many installs are active, which versions and platforms are
682
679
  in use, and which tools fail most. A notice is printed the first time it runs.
683
680
 
684
- What is sent: a random install id (kept in `~/.chrome-mcp/telemetry.json`), the
681
+ What is sent: a random install id (kept in `~/.mcp-browser-extension/telemetry.json`), the
685
682
  server version, OS, CPU architecture and Node major version, whether the
686
683
  session owns the bridge port or shares it, how many browsers are paired, the
687
684
  paired extension's version and whether it is the store or an unpacked copy, and
@@ -709,7 +706,7 @@ The **browser extension sends nothing** — it only ever talks to `127.0.0.1`.
709
706
  Turn it off with any of:
710
707
 
711
708
  ```bash
712
- CHROME_MCP_TELEMETRY=0 # or false / off
709
+ MCP_BROWSER_EXTENSION_TELEMETRY=0 # or false / off
713
710
  DO_NOT_TRACK=1
714
711
  --no-telemetry # server flag
715
712
  ```
@@ -749,11 +746,11 @@ for local development; do not load this unpacked copy in the same Chrome profile
749
746
  as the Store extension. On Windows, Chrome may disable a non-Store build.
750
747
 
751
748
  `extension/` builds (esbuild) to `extension-dist/`, loaded via
752
- `chrome://extensions` → **Load unpacked** → select `~/chrome-mcp-extension`, the
749
+ `chrome://extensions` → **Load unpacked** → select `~/mcp-browser-extension`, the
753
750
  mirror the server refreshes from `extension-dist/` on every boot (loading
754
751
  `extension-dist/` directly also works). It pairs itself from the `pairing.json`
755
752
  the server writes into that folder; the **Options** page paste of `port` +
756
- `token` from `~/.chrome-mcp/handshake.json` (run
753
+ `token` from `~/.mcp-browser-extension/handshake.json` (run
757
754
  `npx -y mcp-browser-extension@latest --print-pairing` to get the path) is only
758
755
  the fallback.
759
756
 
package/SETUP.md CHANGED
@@ -4,7 +4,7 @@
4
4
  machine and prove it works.** MCP Browser Extension lets an MCP client drive the human's
5
5
  real Chrome browser: real logins, real cookies, no separate Chromium. It has two
6
6
  halves that must be paired: a stdio MCP server (npm package
7
- `@mehmoodqureshi/chrome-mcp`) and a Manifest V3 extension that ships inside the
7
+ `mcp-browser-extension`) and a Manifest V3 extension that ships inside the
8
8
  same package. Work autonomously; pause only for the two actions that must happen
9
9
  inside Chrome's own UI (loading the extension, pasting the pairing token).
10
10
 
@@ -40,10 +40,10 @@ extension to a plain folder directly under the home directory, and prints its
40
40
  path:
41
41
 
42
42
  ```
43
- npx -y @mehmoodqureshi/chrome-mcp@latest --extension-path
43
+ npx -y mcp-browser-extension@latest --extension-path
44
44
  ```
45
45
 
46
- It prints `~/chrome-mcp-extension` (on Windows `%USERPROFILE%\chrome-mcp-extension`).
46
+ It prints `~/mcp-browser-extension` (on Windows `%USERPROFILE%\mcp-browser-extension`).
47
47
  Verify with `ls` (or `dir`) that the folder holds `manifest.json` and
48
48
  `background.js`. Record the path; the human needs it in step 4. The install is
49
49
  small and downloads no browser: the server drives the Chrome the human already
@@ -62,14 +62,14 @@ unless they ask.
62
62
  **Claude Code** (registers for every project on this machine):
63
63
 
64
64
  ```
65
- claude mcp add chrome-mcp -s user -- \
66
- npx -y @mehmoodqureshi/chrome-mcp@latest \
65
+ claude mcp add mcp-browser-extension -s user -- \
66
+ npx -y mcp-browser-extension@latest \
67
67
  --allow-domain example.com --enable-mutations --persist-token
68
68
  ```
69
69
 
70
70
  Everything before `--` belongs to Claude Code. Everything after it is the
71
71
  server's own command line. Keep the `--` or `--allow-domain` gets read as a
72
- Claude Code option. Verify with `claude mcp list`: chrome-mcp should be listed.
72
+ Claude Code option. Verify with `claude mcp list`: mcp-browser-extension should be listed.
73
73
  It will show as connected once the server boots, even before the extension has
74
74
  paired.
75
75
 
@@ -80,9 +80,9 @@ Code uses a top-level `servers` key instead of `mcpServers`).
80
80
  ```json
81
81
  {
82
82
  "mcpServers": {
83
- "chrome-mcp": {
83
+ "mcp-browser-extension": {
84
84
  "command": "npx",
85
- "args": ["-y", "@mehmoodqureshi/chrome-mcp@latest",
85
+ "args": ["-y", "mcp-browser-extension@latest",
86
86
  "--allow-domain", "example.com",
87
87
  "--enable-mutations",
88
88
  "--persist-token"]
@@ -92,13 +92,13 @@ Code uses a top-level `servers` key instead of `mcpServers`).
92
92
  ```
93
93
 
94
94
  **Windows:** the command must be `cmd` with args `["/c", "npx", "-y",
95
- "@mehmoodqureshi/chrome-mcp@latest", ...]`, or for Claude Code:
96
- `claude mcp add chrome-mcp -s user -- cmd /c npx -y @mehmoodqureshi/chrome-mcp@latest --allow-domain example.com --enable-mutations --persist-token`.
95
+ "mcp-browser-extension@latest", ...]`, or for Claude Code:
96
+ `claude mcp add mcp-browser-extension -s user -- cmd /c npx -y mcp-browser-extension@latest --allow-domain example.com --enable-mutations --persist-token`.
97
97
 
98
98
  Tell the human to restart the client (or run `/mcp` in Claude Code) so the
99
- server loads. The first boot writes `~/.chrome-mcp/handshake.json` (mode 0600)
99
+ server loads. The first boot writes `~/.mcp-browser-extension/handshake.json` (mode 0600)
100
100
  holding the bridge port and the pairing token, and with `--persist-token` it
101
- also stores the token at `~/.chrome-mcp/token` for reuse.
101
+ also stores the token at `~/.mcp-browser-extension/token` for reuse.
102
102
 
103
103
  ## Step 4 — Load the extension (human action inside Chrome)
104
104
 
@@ -106,7 +106,7 @@ You cannot do this step yourself. Give the human these exact instructions:
106
106
 
107
107
  1. Open `chrome://extensions` in Chrome.
108
108
  2. Turn on **Developer mode** (top right).
109
- 3. Click **Load unpacked** and choose the `chrome-mcp-extension` folder in
109
+ 3. Click **Load unpacked** and choose the `mcp-browser-extension` folder in
110
110
  their home directory (the path from step 2).
111
111
  4. Confirm an extension named **MCP Browser Extension** now appears in the list.
112
112
 
@@ -149,7 +149,7 @@ retry the tool.
149
149
  ## Step 6 — Check the pairing
150
150
 
151
151
  Pairing needs no paste. Every time the server boots it writes `pairing.json`
152
- (mode 0600) into the same `chrome-mcp-extension` folder the human loaded in step 4.
152
+ (mode 0600) into the same `mcp-browser-extension` folder the human loaded in step 4.
153
153
  The extension reads that file from its own folder and pairs itself. So make
154
154
  sure a server has booted at least once since step 2, in either of these ways:
155
155
 
@@ -157,13 +157,13 @@ sure a server has booted at least once since step 2, in either of these ways:
157
157
  - start one yourself in pairing mode and leave it running in the background:
158
158
 
159
159
  ```
160
- npx -y @mehmoodqureshi/chrome-mcp@latest --print-pairing --persist-token
160
+ npx -y mcp-browser-extension@latest --print-pairing --persist-token
161
161
  ```
162
162
 
163
163
  Verify the file exists (do not print it):
164
164
 
165
165
  ```
166
- ls "$(npx -y @mehmoodqureshi/chrome-mcp@latest --extension-path)/pairing.json"
166
+ ls "$(npx -y mcp-browser-extension@latest --extension-path)/pairing.json"
167
167
  ```
168
168
 
169
169
  Then tell the human where to look. The status badge is on the extension's
@@ -190,11 +190,11 @@ extension folder or a read-only global install): read the port without
190
190
  printing the token,
191
191
 
192
192
  ```
193
- node -e "console.log(require(require('os').homedir()+'/.chrome-mcp/handshake.json').port)"
193
+ node -e "console.log(require(require('os').homedir()+'/.mcp-browser-extension/handshake.json').port)"
194
194
  ```
195
195
 
196
196
  then have the human open **Details** on MCP Browser Extension, then **Extension
197
- options**, enter that **Port**, open `~/.chrome-mcp/handshake.json` in a text
197
+ options**, enter that **Port**, open `~/.mcp-browser-extension/handshake.json` in a text
198
198
  editor and paste its `token` into the **Token** field, leave **Profile** as
199
199
  `default`, and click **Save**. The status line should read **connected** within
200
200
  a few seconds. Values saved by hand take precedence over the bundled file.
@@ -225,7 +225,7 @@ not stick. Re-check the port and token before anything else.
225
225
  Summarize for the human:
226
226
 
227
227
  - Node and package versions installed.
228
- - The absolute `chrome-mcp-extension` path they loaded.
228
+ - The absolute `mcp-browser-extension` path they loaded.
229
229
  - Which MCP client was configured, at which scope, with which domains and gates.
230
230
  - Whether the badge went green, and whether `tabs_list`, an allowed
231
231
  navigation, and a refused navigation each verified.
@@ -233,4 +233,4 @@ Summarize for the human:
233
233
 
234
234
  For any failure, name the exact symptom, what you tried, and the matching
235
235
  section of the README's troubleshooting notes at
236
- `https://github.com/Mehmoodqureshi/chrome-mcp#readme`.
236
+ `https://github.com/Mehmoodqureshi/mcp-browser-extension#readme`.
@@ -268,7 +268,7 @@ export type ServerFrame = CommandFrame | WelcomeFrame | UnauthFrame | PingFrame
268
268
  /** Frames the EXTENSION sends to the server. */
269
269
  export type ExtensionFrame = HelloFrame | ResultFrame | ErrorFrame | EventFrame | PongFrame | SiteGrantFrame;
270
270
  export type Frame = ServerFrame | ExtensionFrame;
271
- /** Shape of `$CHROME_MCP_DATA/handshake.json`. The token is a secret. */
271
+ /** Shape of `$MCP_BROWSER_EXTENSION_DATA/handshake.json`. The token is a secret. */
272
272
  export interface HandshakeFile {
273
273
  v: ProtocolVersion;
274
274
  port: number;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * shared/tab-border.ts — the pure half of the "chrome-mcp is working here"
2
+ * shared/tab-border.ts — the pure half of the "mcp-browser-extension is working here"
3
3
  * border: choosing its colour from the page's theme and writing the CSS.
4
4
  *
5
5
  * The extension paints the border with `chrome.scripting.insertCSS` on
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * shared/tab-border.ts — the pure half of the "chrome-mcp is working here"
3
+ * shared/tab-border.ts — the pure half of the "mcp-browser-extension is working here"
4
4
  * border: choosing its colour from the page's theme and writing the CSS.
5
5
  *
6
6
  * The extension paints the border with `chrome.scripting.insertCSS` on
@@ -6,7 +6,8 @@ exports.requireAccess = requireAccess;
6
6
  const node_crypto_1 = require("node:crypto");
7
7
  const node_fs_1 = require("node:fs");
8
8
  const node_path_1 = require("node:path");
9
- const SITE = (process.env.CHROME_MCP_ACCESS_API ?? 'https://mcp-browser-extension.com/api/access').replace(/\/$/, '');
9
+ const compat_1 = require("./compat");
10
+ const SITE = ((0, compat_1.runtimeEnv)('ACCESS_API') ?? 'https://mcp-browser-extension.com/api/access').replace(/\/$/, '');
10
11
  let accessPollMs = 2_000;
11
12
  let accessWaitMs = 45_000;
12
13
  const EMAIL_SCHEMA = {
@@ -1,7 +1,7 @@
1
1
  /**
2
- * src/auto-update.ts — keep every install on the latest chrome-mcp.
2
+ * src/auto-update.ts — keep every install on the latest mcp-browser-extension.
3
3
  *
4
- * Most people run chrome-mcp through `npx -y @mehmoodqureshi/chrome-mcp` in an
4
+ * Most people run mcp-browser-extension through `npx -y mcp-browser-extension` in an
5
5
  * MCP config. npx reuses whatever copy it cached first, so installs sat on old
6
6
  * versions for weeks (telemetry: three times as many sessions on 0.9.13 as on
7
7
  * the current 0.9.15) and never got the fixes. Nobody edits their MCP config to
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * So at startup, before binding the port, the server asks the npm registry for
11
11
  * the latest version. If it is newer than this copy, it hands off: it runs
12
- * `npx -y @mehmoodqureshi/chrome-mcp@<latest>` with the same arguments, passes
12
+ * `npx -y mcp-browser-extension@<latest>` with the same arguments, passes
13
13
  * stdin/stdout/stderr straight through (the MCP host talks to the new version
14
14
  * directly), and exits when that does. The new copy's server also mirrors its
15
15
  * extension build into the unpacked folder, so the extension follows.
@@ -17,12 +17,12 @@
17
17
  * It never gets in the way: a dev checkout (not under node_modules) is left
18
18
  * alone, the check gives up after a short timeout when offline, a failed spawn
19
19
  * falls back to running this copy, and the child is marked so it never hands
20
- * off again. Off with CHROME_MCP_AUTO_UPDATE=0 or --no-auto-update.
20
+ * off again. Off with MCP_BROWSER_EXTENSION_AUTO_UPDATE=0 or --no-auto-update.
21
21
  */
22
22
  import { type ChildProcess, type SpawnOptions } from 'node:child_process';
23
- export declare const PACKAGE_NAME = "@mehmoodqureshi/chrome-mcp";
23
+ export declare const PACKAGE_NAME = "mcp-browser-extension";
24
24
  /** Set on the handed-off child: it is already the latest, never hand off again. */
25
- export declare const HANDOFF_ENV = "CHROME_MCP_UPDATED_FROM";
25
+ export declare const HANDOFF_ENV = "MCP_BROWSER_EXTENSION_UPDATED_FROM";
26
26
  export interface HandOffOptions {
27
27
  current: string;
28
28
  /** This copy's package directory: only an installed copy (under node_modules) updates. */
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  /**
3
- * src/auto-update.ts — keep every install on the latest chrome-mcp.
3
+ * src/auto-update.ts — keep every install on the latest mcp-browser-extension.
4
4
  *
5
- * Most people run chrome-mcp through `npx -y @mehmoodqureshi/chrome-mcp` in an
5
+ * Most people run mcp-browser-extension through `npx -y mcp-browser-extension` in an
6
6
  * MCP config. npx reuses whatever copy it cached first, so installs sat on old
7
7
  * versions for weeks (telemetry: three times as many sessions on 0.9.13 as on
8
8
  * the current 0.9.15) and never got the fixes. Nobody edits their MCP config to
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * So at startup, before binding the port, the server asks the npm registry for
12
12
  * the latest version. If it is newer than this copy, it hands off: it runs
13
- * `npx -y @mehmoodqureshi/chrome-mcp@<latest>` with the same arguments, passes
13
+ * `npx -y mcp-browser-extension@<latest>` with the same arguments, passes
14
14
  * stdin/stdout/stderr straight through (the MCP host talks to the new version
15
15
  * directly), and exits when that does. The new copy's server also mirrors its
16
16
  * extension build into the unpacked folder, so the extension follows.
@@ -18,7 +18,7 @@
18
18
  * It never gets in the way: a dev checkout (not under node_modules) is left
19
19
  * alone, the check gives up after a short timeout when offline, a failed spawn
20
20
  * falls back to running this copy, and the child is marked so it never hands
21
- * off again. Off with CHROME_MCP_AUTO_UPDATE=0 or --no-auto-update.
21
+ * off again. Off with MCP_BROWSER_EXTENSION_AUTO_UPDATE=0 or --no-auto-update.
22
22
  */
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.HANDOFF_ENV = exports.PACKAGE_NAME = void 0;
@@ -28,17 +28,18 @@ exports.isInstalledCopy = isInstalledCopy;
28
28
  exports.maybeHandOff = maybeHandOff;
29
29
  const node_child_process_1 = require("node:child_process");
30
30
  const node_path_1 = require("node:path");
31
- exports.PACKAGE_NAME = '@mehmoodqureshi/chrome-mcp';
31
+ const compat_1 = require("./compat");
32
+ exports.PACKAGE_NAME = 'mcp-browser-extension';
32
33
  const REGISTRY_URL = `https://registry.npmjs.org/${exports.PACKAGE_NAME}/latest`;
33
34
  /** The registry answers in well under this; offline must not delay startup more. */
34
35
  const CHECK_TIMEOUT_MS = 1_500;
35
36
  /** Set on the handed-off child: it is already the latest, never hand off again. */
36
- exports.HANDOFF_ENV = 'CHROME_MCP_UPDATED_FROM';
37
+ exports.HANDOFF_ENV = 'MCP_BROWSER_EXTENSION_UPDATED_FROM';
37
38
  /** Whether auto-update is off, by env, flag, or because this IS the handed-off copy. */
38
39
  function autoUpdateDisabled(env, disabledByFlag = false) {
39
- if (disabledByFlag || env[exports.HANDOFF_ENV])
40
+ if (disabledByFlag || (0, compat_1.runtimeEnv)('UPDATED_FROM', env))
40
41
  return true;
41
- const v = (env.CHROME_MCP_AUTO_UPDATE ?? '').trim().toLowerCase();
42
+ const v = ((0, compat_1.runtimeEnv)('AUTO_UPDATE', env) ?? '').trim().toLowerCase();
42
43
  return ['0', 'false', 'off', 'no'].includes(v);
43
44
  }
44
45
  /** True when `latest` is a plain release strictly newer than `current` (x.y.z). */
@@ -3,7 +3,7 @@
3
3
  * drafts was deleted on purpose).
4
4
  *
5
5
  * - Fresh 256-bit token EVERY boot by default, never persisted across restarts.
6
- * Persistence is OPT-IN (`--persist-token` / `CHROME_MCP_TOKEN`) for hosts
6
+ * Persistence is OPT-IN (`--persist-token` / `MCP_BROWSER_EXTENSION_TOKEN`) for hosts
7
7
  * that want a stable token so the extension never has to re-pair.
8
8
  * - Written atomically (tmp + rename) to `handshake.json` at mode 0600; the
9
9
  * mode is re-verified after write and we FAIL CLOSED if it can't be set.
@@ -27,7 +27,7 @@ export declare function readPersistedToken(dir: string): string | null;
27
27
  export declare function writePersistedToken(dir: string, token: string): string;
28
28
  /**
29
29
  * Resolve the token for this boot:
30
- * 1. `CHROME_MCP_TOKEN` env — an explicit pin; used verbatim, never written to disk.
30
+ * 1. `MCP_BROWSER_EXTENSION_TOKEN` env — an explicit pin; used verbatim, never written to disk.
31
31
  * 2. `persist` on — reuse the on-disk token (creating + saving one on first run),
32
32
  * so the extension stays paired across restarts.
33
33
  * 3. otherwise — a fresh per-boot token (the secure default; never persisted).
@@ -63,7 +63,7 @@ export declare function portIsListening(port: number, timeoutMs?: number): Promi
63
63
  /**
64
64
  * Should a hub on `port` leave `<extDir>/pairing.json` alone? Yes when the file
65
65
  * already points the extension at a DIFFERENT port that is still live: another
66
- * chrome-mcp (e.g. one started with its own CHROME_MCP_DATA / --ws-port) owns
66
+ * mcp-browser-extension (e.g. one started with its own MCP_BROWSER_EXTENSION_DATA / --ws-port) owns
67
67
  * that pairing, and overwriting it would silently steal the user's extension.
68
68
  * A file naming our own port, a dead port, or no file at all is fair game.
69
69
  */
@@ -4,7 +4,7 @@
4
4
  * drafts was deleted on purpose).
5
5
  *
6
6
  * - Fresh 256-bit token EVERY boot by default, never persisted across restarts.
7
- * Persistence is OPT-IN (`--persist-token` / `CHROME_MCP_TOKEN`) for hosts
7
+ * Persistence is OPT-IN (`--persist-token` / `MCP_BROWSER_EXTENSION_TOKEN`) for hosts
8
8
  * that want a stable token so the extension never has to re-pair.
9
9
  * - Written atomically (tmp + rename) to `handshake.json` at mode 0600; the
10
10
  * mode is re-verified after write and we FAIL CLOSED if it can't be set.
@@ -35,6 +35,7 @@ const node_crypto_1 = require("node:crypto");
35
35
  const node_net_1 = require("node:net");
36
36
  const protocol_1 = require("../../shared/protocol");
37
37
  const datadir_1 = require("./datadir");
38
+ const compat_1 = require("../compat");
38
39
  /** A fresh 256-bit token, base64url. Generated once per server boot. */
39
40
  function generateToken() {
40
41
  return (0, node_crypto_1.randomBytes)(32).toString('base64url');
@@ -91,13 +92,13 @@ function writePersistedToken(dir, token) {
91
92
  }
92
93
  /**
93
94
  * Resolve the token for this boot:
94
- * 1. `CHROME_MCP_TOKEN` env — an explicit pin; used verbatim, never written to disk.
95
+ * 1. `MCP_BROWSER_EXTENSION_TOKEN` env — an explicit pin; used verbatim, never written to disk.
95
96
  * 2. `persist` on — reuse the on-disk token (creating + saving one on first run),
96
97
  * so the extension stays paired across restarts.
97
98
  * 3. otherwise — a fresh per-boot token (the secure default; never persisted).
98
99
  */
99
100
  function resolveToken(dir, opts) {
100
- const fromEnv = process.env.CHROME_MCP_TOKEN?.trim();
101
+ const fromEnv = (0, compat_1.runtimeEnv)('TOKEN')?.trim();
101
102
  if (fromEnv)
102
103
  return fromEnv;
103
104
  if (opts.persist) {
@@ -176,7 +177,7 @@ function portIsListening(port, timeoutMs = 500) {
176
177
  /**
177
178
  * Should a hub on `port` leave `<extDir>/pairing.json` alone? Yes when the file
178
179
  * already points the extension at a DIFFERENT port that is still live: another
179
- * chrome-mcp (e.g. one started with its own CHROME_MCP_DATA / --ws-port) owns
180
+ * mcp-browser-extension (e.g. one started with its own MCP_BROWSER_EXTENSION_DATA / --ws-port) owns
180
181
  * that pairing, and overwriting it would silently steal the user's extension.
181
182
  * A file naming our own port, a dead port, or no file at all is fair game.
182
183
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * src/bridge/datadir.ts — the Electron-free data dir (the LinkedIn repo resolved
3
- * this via `app.getPath`; we use `$CHROME_MCP_DATA` || `~/.chrome-mcp`). Holds
3
+ * this via `app.getPath`; we use `$MCP_BROWSER_EXTENSION_DATA` || `~/.mcp-browser-extension`). Holds
4
4
  * the 0600 handshake and, later, the CDP-fallback profile.
5
5
  */
6
6
  /** Create (if needed) and return the data dir, 0700 so only the user can read it. */
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * src/bridge/datadir.ts — the Electron-free data dir (the LinkedIn repo resolved
4
- * this via `app.getPath`; we use `$CHROME_MCP_DATA` || `~/.chrome-mcp`). Holds
4
+ * this via `app.getPath`; we use `$MCP_BROWSER_EXTENSION_DATA` || `~/.mcp-browser-extension`). Holds
5
5
  * the 0600 handshake and, later, the CDP-fallback profile.
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,9 +1,9 @@
1
1
  /**
2
- * src/bridge/evict.ts — take a pinned port back from a stale chrome-mcp.
2
+ * src/bridge/evict.ts — take a pinned port back from a stale mcp-browser-extension.
3
3
  *
4
- * A second session normally JOINS the chrome-mcp holding the port as a peer
4
+ * A second session normally JOINS the mcp-browser-extension holding the port as a peer
5
5
  * (see ./peer) and nobody is stopped. This is the fallback for when joining
6
- * fails: an older chrome-mcp that can't share the port, or a hung one. It will
6
+ * fails: an older mcp-browser-extension that can't share the port, or a hung one. It will
7
7
  * never release the port on its own, so rather than fail with EADDRINUSE and
8
8
  * make the user kill it by hand, we do that for them.
9
9
  *
@@ -12,13 +12,13 @@
12
12
  * - the handshake names that port (so it describes *this* listener), and
13
13
  * - the pid is not us, and
14
14
  * - the pid is alive, and
15
- * - its command line mentions chrome-mcp.
15
+ * - its command line mentions mcp-browser-extension.
16
16
  * If any check fails we leave the process alone and let the caller surface the
17
17
  * plain-English port-busy error instead. Refusing to evict is always safe; a
18
18
  * wrong kill is not.
19
19
  */
20
- /** Does this command line belong to a chrome-mcp server? */
21
- export declare function looksLikeChromeMcp(cmdline: string): boolean;
20
+ /** Does this command line belong to a mcp-browser-extension server? */
21
+ export declare function looksLikeMcpBrowserExtension(cmdline: string): boolean;
22
22
  export interface EvictDeps {
23
23
  /** Injectable for tests; defaults to the real probes. */
24
24
  isAlive?: (pid: number) => boolean;
@@ -26,7 +26,7 @@ export interface EvictDeps {
26
26
  kill?: (pid: number, signal: NodeJS.Signals) => void;
27
27
  }
28
28
  /**
29
- * Try to free `port` by terminating the chrome-mcp that owns it.
29
+ * Try to free `port` by terminating the mcp-browser-extension that owns it.
30
30
  * Returns true only if an owner was found, killed, and confirmed gone.
31
31
  */
32
32
  export declare function evictPortOwner(dataDir: string, port: number, log: (message: string) => void, deps?: EvictDeps): Promise<boolean>;