@ricardodeazambuja/browser-mcp-server 1.0.3 → 1.3.0

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,42 @@
1
+ # Changelog - v1.3.0 (2025-12-27)
2
+
3
+ This is a major architectural release that modularizes the entire codebase for better maintainability, testing, and extensibility.
4
+
5
+ ## ⭐ New Features
6
+
7
+ - **Modular Architecture**: The codebase is now organization into focused modules in `src/`:
8
+ - `src/index.js`: Main entry point and MCP protocol handler
9
+ - `src/browser.js`: Centralized browser connection and state management
10
+ - `src/tools/`: Dedicated modules for each tool category (navigation, interaction, media, etc.)
11
+ - `src/utils.js`: Shared utilities
12
+ - **Plugin System**: New `plugins/` directory allows adding specialized tool modules that are auto-discovered by `src/tools/index.js`.
13
+ - **Improved Test Suite**: Tests are now organized in the `tests/` directory with `fixtures/`.
14
+ - **Reduced Bundle Size**: The main entry point is now cleaner and easier to maintain.
15
+
16
+ ## 🛠 Refactoring
17
+
18
+ - **Source Code**: Moved all source code from the root directory to `src/`.
19
+ - **Entry Point**: Replaced the monolithic `browser-mcp-server-playwright.js` with `src/index.js`.
20
+ - **Tool Logic**: Extracted tool implementations from the main server file into:
21
+ - `src/tools/navigation.js`
22
+ - `src/tools/interaction.js`
23
+ - `src/tools/media.js`
24
+ - `src/tools/system.js`
25
+ - `src/tools/console.js`
26
+ - `src/tools/info.js`
27
+ - `src/tools/mouse.js`
28
+ - `src/tools/keyboard.js`
29
+ - `src/tools/pages.js`
30
+ - **Utilities**: Extracted `debugLog`, `loadPlaywright`, and `findChromeExecutable` to `src/utils.js`.
31
+
32
+ ## 🧹 Cleanup
33
+
34
+ - Removed the legacy `browser-mcp-server-playwright.js` wrapper file.
35
+ - Removed old `.tgz` build artifacts.
36
+ - Updated `package.json` to point `main` and `bin` to `src/index.js`.
37
+
38
+ ## 🧪 Testing
39
+
40
+ - Verified all 36 tools function correctly after modularization.
41
+ - Verified MCP protocol communication.
42
+ - Verified browser connection strategies (Antigravity, System Chrome, Playwright).
package/README.md CHANGED
@@ -2,14 +2,15 @@
2
2
 
3
3
  A universal browser automation MCP server using Playwright. Control Chrome programmatically through the Model Context Protocol.
4
4
 
5
- **16 powerful browser automation tools** including navigation, clicking, typing, screenshots, console capture, and session recording.
5
+ **37 powerful browser automation tools** including multi-tab management, media monitoring/control, low-level interaction, session recording, and on-demand documentation.
6
6
 
7
7
  ## Features
8
8
 
9
9
  - ✅ **Smart Chrome Detection**: Automatically finds and uses system Chrome/Chromium
10
10
  - ✅ **Three-Tier Strategy**: Antigravity Chrome → System Chrome → Playwright Chromium
11
11
  - ✅ **Universal**: Works with Antigravity, Claude Desktop, and any MCP client
12
- - ✅ **16 Tools**: Navigate, click, type, screenshot, console logs, and more
12
+ - ✅ **37 Tools**: Media control, multi-tab, pixel-based interaction, and more
13
+ - ✅ **On-Demand Docs**: Built-in documentation tool with return schemas and examples
13
14
  - ✅ **Auto-Install**: Playwright installed automatically via npm (no manual setup)
14
15
  - ✅ **Safe**: Isolated browser profile (won't touch your personal Chrome)
15
16
  - ✅ **Console Capture**: Debug JavaScript errors in real-time
@@ -73,8 +74,8 @@ npx playwright install chromium
73
74
 
74
75
  ```bash
75
76
  # Download the main file directly (no git required)
76
- curl -o browser-mcp-server-playwright.js \
77
- https://raw.githubusercontent.com/ricardodeazambuja/browser-mcp-server/main/browser-mcp-server-playwright.js
77
+ curl -o src/index.js \
78
+ https://raw.githubusercontent.com/ricardodeazambuja/browser-mcp-server/main/src/index.js
78
79
 
79
80
  # Install Playwright
80
81
  npm install playwright
@@ -93,7 +94,7 @@ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_
93
94
  "mcpServers": {
94
95
  "browser-tools": {
95
96
  "command": "node",
96
- "args": ["/absolute/path/to/browser-mcp-server-playwright.js"]
97
+ "args": ["/absolute/path/to/src/index.js"]
97
98
  }
98
99
  }
99
100
  }
@@ -123,7 +124,7 @@ Add to `~/.gemini/antigravity/mcp_config.json`:
123
124
  "mcpServers": {
124
125
  "browser-tools": {
125
126
  "command": "node",
126
- "args": ["/home/username/.gemini/antigravity/browser-mcp-server-playwright.js"]
127
+ "args": ["/home/username/.gemini/antigravity/src/index.js"]
127
128
  }
128
129
  }
129
130
  }
@@ -151,12 +152,12 @@ Add the browser-mcp-server using the Claude CLI:
151
152
  ```bash
152
153
  # Install the MCP server with default isolated profile
153
154
  claude mcp add --transport stdio browser \
154
- -- node /absolute/path/to/browser-mcp-server-playwright.js
155
+ -- node /absolute/path/to/src/index.js
155
156
 
156
157
  # Or with custom browser profile for more control
157
158
  claude mcp add --transport stdio browser \
158
159
  --env MCP_BROWSER_PROFILE=/path/to/custom/profile \
159
- -- node /absolute/path/to/browser-mcp-server-playwright.js
160
+ -- node /absolute/path/to/src/index.js
160
161
  ```
161
162
 
162
163
  **Using NPM:**
@@ -202,11 +203,11 @@ Add the browser-mcp-server using the Gemini CLI commands:
202
203
  **Using local installation:**
203
204
  ```bash
204
205
  # Install the MCP server with default isolated profile
205
- gemini mcp add browser node /absolute/path/to/browser-mcp-server-playwright.js
206
+ gemini mcp add browser node /absolute/path/to/src/index.js
206
207
 
207
208
  # Or with custom browser profile
208
209
  gemini mcp add -e MCP_BROWSER_PROFILE=/path/to/custom/profile browser \
209
- node /absolute/path/to/browser-mcp-server-playwright.js
210
+ node /absolute/path/to/src/index.js
210
211
  ```
211
212
 
212
213
  **Using NPM:**
@@ -243,40 +244,124 @@ gemini mcp remove browser
243
244
 
244
245
  ```bash
245
246
  # Add with specific scope (user vs project)
246
- gemini mcp add -s user browser node /path/to/browser-mcp-server-playwright.js
247
+ gemini mcp add -s user browser node /path/to/src/index.js
247
248
 
248
249
  # Add with timeout configuration
249
- gemini mcp add --timeout 30000 browser node /path/to/browser-mcp-server-playwright.js
250
+ gemini mcp add --timeout 30000 browser node /path/to/src/index.js
250
251
 
251
252
  # Skip tool confirmation prompts (use with caution)
252
- gemini mcp add --trust browser node /path/to/browser-mcp-server-playwright.js
253
+ gemini mcp add --trust browser node /path/to/src/index.js
253
254
  ```
254
255
 
255
- ## Available Tools (16)
256
+ ## Available Tools (37)
257
+
258
+ ### Documentation
259
+ 1. **browser_docs(toolName?)** - Get detailed docs, return schemas, examples, and caveats for any tool
260
+
261
+ ### Multi-Page Management
262
+ 2. **browser_list_pages()** - List all open tabs/pages
263
+ 3. **browser_new_page(url?)** - Open a new tab
264
+ 4. **browser_switch_page(index)** - Switch active tab
265
+ 5. **browser_close_page(index?)** - Close a tab
266
+
267
+ ### Media Awareness & Control
268
+ 6. **browser_get_media_summary()** - List all audio/video elements with state
269
+ 7. **browser_get_audio_analysis(durationMs?, selector?)** - Analyze audio output (volume, spectrum)
270
+ 8. **browser_control_media(selector, action, value?)** - Play, pause, mute, seek
256
271
 
257
272
  ### Navigation & Interaction
258
- 1. **browser_navigate(url)** - Navigate to a URL
259
- 2. **browser_click(selector)** - Click an element
260
- 3. **browser_type(selector, text)** - Type text into an input
261
- 4. **browser_scroll(x?, y?)** - Scroll the page
273
+ 9. **browser_navigate(url)** - Navigate to a URL
274
+ 10. **browser_click(selector)** - Click an element (selector-based)
275
+ 11. **browser_type(selector, text)** - Type text into an input
276
+ 12. **browser_scroll(x?, y?)** - Scroll the page (generic)
277
+ 13. **browser_reload()** - Reload current page
278
+ 14. **browser_go_back()** - Navigate back
279
+ 15. **browser_go_forward()** - Navigate forward
280
+ 16. **browser_wait(ms)** - Pause execution
281
+
282
+ ### Low-Level Interaction
283
+ 17. **browser_mouse_move(x, y)** - Move mouse to pixel coordinates
284
+ 18. **browser_mouse_click(x?, y?, button?, count?)** - Click at pixel coordinates
285
+ 19. **browser_mouse_drag(fromX, fromY, toX, toY)** - Drag and drop
286
+ 20. **browser_mouse_wheel(deltaX, deltaY)** - Scroll mouse wheel
287
+ 21. **browser_press_key(key)** - Send keyboard event (e.g. "Enter")
262
288
 
263
289
  ### Information Gathering
264
- 5. **browser_screenshot(fullPage?)** - Capture screenshot
265
- 6. **browser_get_text(selector)** - Get text from element
266
- 7. **browser_get_dom(selector?)** - Get DOM structure
267
- 8. **browser_evaluate(code)** - Execute JavaScript
268
-
269
- ### Console Debugging ⭐ NEW
270
- 9. **browser_console_start(level?)** - Start capturing console logs
271
- 10. **browser_console_get(filter?)** - Get captured logs
272
- 11. **browser_console_clear()** - Clear logs and stop
273
-
274
- ### Advanced
275
- 12. **browser_wait_for_selector(selector, timeout?)** - Wait for element
276
- 13. **browser_resize_window(width, height)** - Resize browser window
277
- 14. **browser_start_video_recording(path?)** - Start recording session (Playwright traces)
278
- 15. **browser_stop_video_recording()** - Stop and save recording
279
- 16. **browser_health_check()** - Verify browser connection
290
+ 22. **browser_screenshot(fullPage?)** - Capture screenshot
291
+ 23. **browser_get_text(selector)** - Get text from element
292
+ 24. **browser_get_dom(selector?)** - Get DOM structure
293
+ 25. **browser_read_page()** - Get page metadata (title, URL)
294
+ 26. **browser_evaluate(code)** - Execute JavaScript
295
+
296
+ ### Console Debugging
297
+ 27. **browser_console_start(level?)** - Start capturing logs
298
+ 28. **browser_console_get(filter?)** - Get captured logs
299
+ 29. **browser_console_clear()** - Clear logs and stop
300
+
301
+ ### Advanced Interaction
302
+ 30. **browser_hover(selector)** - Hover over element
303
+ 31. **browser_focus(selector)** - Focus element
304
+ 32. **browser_select(selector, values)** - Select dropdown options
305
+ 33. **browser_wait_for_selector(selector, timeout?)** - Wait for element
306
+ 34. **browser_resize_window(width, height)** - Resize window
307
+ 35. **browser_start_video_recording(path?)** - Start session recording
308
+ 36. **browser_stop_video_recording()** - Stop and save recording
309
+ 37. **browser_health_check()** - Verify browser connection
310
+
311
+ ## On-Demand Documentation
312
+
313
+ The `browser_docs` tool provides comprehensive documentation for all browser tools **without increasing token overhead** in normal operations.
314
+
315
+ ### Why This Matters
316
+
317
+ - **Token Efficient**: Tool descriptions stay concise (saving tokens on every request)
318
+ - **Comprehensive**: Detailed docs available when needed (return schemas, examples, caveats)
319
+ - **Self-Documenting**: AI agents can discover tool capabilities on-demand
320
+
321
+ ### What You Get
322
+
323
+ When calling `browser_docs(toolName)`, you receive:
324
+ - **Parameter Details**: Types, optionality, defaults, enums
325
+ - **Return Value Schemas**: Exact structure of what the tool returns
326
+ - **Selector Syntax**: How to write Playwright selectors (CSS, text, data attributes)
327
+ - **Important Caveats**: Warnings about CORS, clearing behavior, state management
328
+ - **Practical Examples**: Real-world usage patterns
329
+
330
+ ### Usage
331
+
332
+ ```javascript
333
+ // Get docs for a specific tool
334
+ browser_docs({ toolName: 'browser_get_audio_analysis' })
335
+
336
+ // List all available tools
337
+ browser_docs({})
338
+
339
+ // Invalid tool name suggests similar tools
340
+ browser_docs({ toolName: 'navigate' })
341
+ // → Did you mean: browser_navigate, browser_go_back, ...
342
+ ```
343
+
344
+ ### Example Output
345
+
346
+ ```
347
+ 📖 browser_type(selector, text)
348
+
349
+ Type text into an input field.
350
+
351
+ Parameters:
352
+ • selector (string, required) - Playwright selector for the input
353
+ • text (string, required) - Text to type
354
+
355
+ Returns:
356
+ { content: [{ type: 'text', text: 'Typed into <selector>' }] }
357
+
358
+ ⚠️ Important:
359
+ • Uses page.fill() which CLEARS the field first, then types
360
+ • Does NOT append to existing text
361
+
362
+ Example:
363
+ browser_type({ selector: '#username', text: 'john@example.com' })
364
+ ```
280
365
 
281
366
  ## Examples
282
367
 
@@ -297,14 +382,48 @@ browser_console_get(filter: "error")
297
382
  // Shows: ❌ [ERROR] Uncaught TypeError: ...
298
383
  ```
299
384
 
300
- ### Automate Form Submission
385
+ ### Media Monitoring & Control
386
+ ```javascript
387
+ // Agent uses:
388
+ browser_navigate("https://youtube.com/watch?v=...")
389
+ browser_get_media_summary() // See active video state
390
+ browser_control_media(selector: "video", action: "play")
391
+ browser_get_audio_analysis(durationMs: 2000) // "Hear" the volume
392
+ ```
393
+
394
+ ### Multi-Tab Automation
301
395
  ```javascript
302
396
  // Agent uses:
303
- browser_navigate("https://example.com/login")
304
- browser_type("#username", "user@example.com")
305
- browser_type("#password", "secret")
306
- browser_click("#login-button")
307
- browser_wait_for_selector(".dashboard")
397
+ browser_navigate("https://wikipedia.org")
398
+ browser_new_page("https://google.com")
399
+ browser_list_pages() // Shows 2 pages
400
+ browser_switch_page(0) // Back to Wikipedia
401
+ ```
402
+
403
+ ### Pixel-Based Interaction
404
+ ```javascript
405
+ // Agent uses:
406
+ browser_mouse_move(500, 300)
407
+ browser_mouse_click(button: "right")
408
+ browser_press_key("Enter")
409
+ ```
410
+
411
+ ### Get Tool Documentation
412
+ ```javascript
413
+ // Agent uses:
414
+ browser_docs(toolName: "browser_get_audio_analysis")
415
+ // Returns:
416
+ // 📖 browser_get_audio_analysis(durationMs?, selector?)
417
+ //
418
+ // Parameters:
419
+ // • durationMs (number, optional) - Duration to analyze in ms (default: 2000)
420
+ // • selector (string, optional) - Selector for specific media element
421
+ //
422
+ // Returns: { isSilent: boolean, averageVolume: number, ... }
423
+ // ⚠️ Important: Requires CORS headers for cross-origin media
424
+
425
+ // List all tools:
426
+ browser_docs() // Shows all 37 tools
308
427
  ```
309
428
 
310
429
  ## How It Works
@@ -381,7 +500,7 @@ This MCP server provides powerful browser automation capabilities. Please review
381
500
  export MCP_BROWSER_PROFILE="$HOME/.mcp-browser-profile"
382
501
 
383
502
  # Then run the server
384
- node browser-mcp-server-playwright.js
503
+ node src/index.js
385
504
  ```
386
505
 
387
506
  ### MCP Config with Environment Variables
@@ -391,7 +510,7 @@ node browser-mcp-server-playwright.js
391
510
  "mcpServers": {
392
511
  "browser-tools": {
393
512
  "command": "node",
394
- "args": ["/path/to/browser-mcp-server-playwright.js"],
513
+ "args": ["/path/to/src/index.js"],
395
514
  "env": {
396
515
  "MCP_BROWSER_PROFILE": "/tmp/my-custom-profile"
397
516
  }
@@ -452,7 +571,14 @@ Use the `browser_health_check` tool to verify:
452
571
 
453
572
  ```
454
573
  browser-mcp-server/
455
- ├── browser-mcp-server-playwright.js # Main server
574
+ ├── src/index.js # Main server entry point
575
+ ├── src/ # Source code
576
+ │ ├── index.js # Main server class
577
+ │ ├── browser.js # Browser management
578
+ │ ├── tools/ # Tool modules
579
+ │ └── utils.js # Utilities
580
+ ├── tests/ # Test suite
581
+ ├── plugins/ # Plugin directory
456
582
  ├── package.json # npm package config
457
583
  ├── README.md # This file
458
584
  └── LICENSE # MIT license
@@ -465,7 +591,7 @@ browser-mcp-server/
465
591
  npm test
466
592
 
467
593
  # Manual test
468
- echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' | node browser-mcp-server-playwright.js
594
+ echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' | node src/index.js
469
595
  ```
470
596
 
471
597
  ### Debug Logging
@@ -520,7 +646,7 @@ Check `/tmp/mcp-browser-server.log` for detailed logs:
520
646
  ## Comparison with Other Tools
521
647
 
522
648
  ### vs. Puppeteer MCP Servers
523
- - ✅ More tools (16 vs typical 8-10)
649
+ - ✅ More tools (37 vs typical 8-10)
524
650
  - ✅ Console capture built-in
525
651
  - ✅ Better error messages
526
652
  - ✅ Hybrid mode (connect OR launch)
@@ -563,6 +689,25 @@ MIT License - see LICENSE file
563
689
 
564
690
  ## Changelog
565
691
 
692
+ ### v1.3.0 (2025-12-27) ⭐ NEW
693
+ - ✅ **On-Demand Documentation**: New `browser_docs` tool provides detailed specs, return schemas, examples, and caveats for all 37 tools
694
+ - ✅ **Modular Architecture**: Complete refactor into `src/` modules for better maintainability
695
+ - ✅ **Plugin System**: New `plugins/` directory for extending functionality
696
+ - ✅ **Improved Testing**: Dedicated `tests/` directory with fixtures
697
+ - ✅ **Core Stability**: Separated browser logic, tools, and protocol handling
698
+ - ✅ **Token Efficient**: Documentation loaded on-demand, keeping tool descriptions concise
699
+
700
+ ### v1.2.0 (2025-12-27)
701
+ - ✅ **Media Awareness**: Added audio/video inspection, spectral analysis, and control tools (36 tools total)
702
+ - ✅ **Tool**: `browser_get_media_summary`, `browser_get_audio_analysis`, `browser_control_media`
703
+
704
+ ### v1.1.0 (2025-12-27)
705
+ - ✅ **Tool Parity**: Achieved parity with `browser-subagent` (33 tools total)
706
+ - ✅ **Multi-Page**: Added support for multiple browser tabs/pages
707
+ - ✅ **Low-Level Control**: Added keyboard/mouse event tools (pixel-based)
708
+ - ✅ **Utilities**: Added `reload`, `go_back`, `go_forward`, `wait`, `hover`, `focus`, `select`
709
+ - ✅ **Testing**: Updated test suites to include new tools
710
+
566
711
  ### v1.0.3 (2025-12-26)
567
712
  - ✅ **Documentation**: Updated README with v1.0.2 features and clearer installation instructions
568
713
  - ✅ **Code Comments**: Updated header to reflect universal compatibility and all features
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@ricardodeazambuja/browser-mcp-server",
3
- "version": "1.0.3",
3
+ "version": "1.3.0",
4
4
  "description": "Universal browser automation MCP server using Playwright. Works with Antigravity, Claude Desktop, and any MCP client.",
5
- "main": "browser-mcp-server-playwright.js",
5
+ "main": "src/index.js",
6
6
  "bin": {
7
- "browser-mcp-server": "./browser-mcp-server-playwright.js"
7
+ "browser-mcp-server": "./src/index.js"
8
8
  },
9
9
  "scripts": {
10
- "start": "node browser-mcp-server-playwright.js",
10
+ "start": "node src/index.js",
11
11
  "install-browsers": "npx playwright install chromium",
12
- "test": "echo 'Testing MCP server...' && echo '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0.0\"}}}' | node browser-mcp-server-playwright.js"
12
+ "test": "node tests/test-mcp.js"
13
13
  },
14
14
  "keywords": [
15
15
  "mcp",
@@ -40,11 +40,11 @@
40
40
  "playwright": "^1.57.0"
41
41
  },
42
42
  "files": [
43
- "browser-mcp-server-playwright.js",
43
+ "src/",
44
44
  "README.md",
45
45
  "LICENSE",
46
- "CHANGELOG-v1.0.2.md",
47
- "test-mcp.js",
48
- "test-browser-automation.js"
46
+ "CHANGELOG-v1.3.0.md",
47
+ "tests/",
48
+ "plugins/"
49
49
  ]
50
- }
50
+ }
File without changes
package/src/.gitkeep ADDED
File without changes
package/src/browser.js ADDED
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Browser connection and state management
3
+ */
4
+
5
+ const os = require('os');
6
+ const { debugLog, loadPlaywright, findChromeExecutable } = require('./utils');
7
+
8
+ // Browser state
9
+ let browser = null;
10
+ let context = null;
11
+ let page = null;
12
+ let activePageIndex = 0;
13
+
14
+ /**
15
+ * Connect to existing Chrome or launch new instance (hybrid mode)
16
+ * @returns {Object} { browser, context, page }
17
+ */
18
+ async function connectToBrowser() {
19
+ // Check if browser is disconnected or closed
20
+ if (browser && (!browser.isConnected || !browser.isConnected())) {
21
+ debugLog('Browser connection lost, resetting...');
22
+ browser = null;
23
+ context = null;
24
+ page = null;
25
+ }
26
+
27
+ if (!browser) {
28
+ try {
29
+ const pw = loadPlaywright();
30
+
31
+ // STRATEGY 1: Try to connect to existing Chrome (Antigravity mode)
32
+ try {
33
+ debugLog('Attempting to connect to Chrome on port 9222...');
34
+ browser = await pw.chromium.connectOverCDP('http://localhost:9222');
35
+ debugLog('✅ Connected to existing Chrome (Antigravity mode)');
36
+
37
+ const contexts = browser.contexts();
38
+ context = contexts.length > 0 ? contexts[0] : await browser.newContext();
39
+ } catch (connectError) {
40
+ debugLog(`Could not connect to existing Chrome: ${connectError.message}`);
41
+ }
42
+
43
+ // STRATEGY 2: Launch our own Chrome (Standalone mode)
44
+ if (!browser) {
45
+ debugLog('No existing Chrome found. Launching new instance...');
46
+
47
+ const profileDir = process.env.MCP_BROWSER_PROFILE ||
48
+ `${os.tmpdir()}/chrome-mcp-profile`;
49
+
50
+ debugLog(`Browser profile: ${profileDir}`);
51
+
52
+ const chromeExecutable = findChromeExecutable();
53
+ const launchOptions = {
54
+ headless: false,
55
+ args: [
56
+ '--remote-debugging-port=9222',
57
+ '--no-first-run',
58
+ '--no-default-browser-check',
59
+ '--disable-fre',
60
+ '--disable-features=TranslateUI,OptGuideOnDeviceModel',
61
+ '--disable-sync',
62
+ '--disable-component-update',
63
+ '--disable-background-networking',
64
+ '--disable-breakpad',
65
+ '--disable-background-timer-throttling',
66
+ '--disable-backgrounding-occluded-windows',
67
+ '--disable-renderer-backgrounding'
68
+ ]
69
+ };
70
+
71
+ if (chromeExecutable) {
72
+ debugLog(`Using system Chrome/Chromium: ${chromeExecutable}`);
73
+ launchOptions.executablePath = chromeExecutable;
74
+ } else {
75
+ debugLog('No system Chrome/Chromium found. Attempting to use Playwright Chromium...');
76
+ }
77
+
78
+ try {
79
+ context = await pw.chromium.launchPersistentContext(profileDir, launchOptions);
80
+ browser = context;
81
+ } catch (launchError) {
82
+ if (!chromeExecutable && launchError.message.includes("Executable doesn't exist")) {
83
+ debugLog('Playwright Chromium not installed and no system Chrome found');
84
+ throw new Error(
85
+ '❌ No Chrome/Chromium browser found!\n\n' +
86
+ 'This MCP server needs a Chrome or Chromium browser to work.\n\n' +
87
+ 'Option 1 - Install Chrome/Chromium on your system\n' +
88
+ 'Option 2 - Install Playwright\'s Chromium: npx playwright install chromium\n' +
89
+ 'Option 3 - Use with Antigravity: Open browser via Chrome logo\n'
90
+ );
91
+ }
92
+ throw launchError;
93
+ }
94
+ debugLog('✅ Successfully launched new Chrome instance (Standalone mode)');
95
+ }
96
+
97
+ } catch (error) {
98
+ debugLog(`Failed to connect/launch Chrome: ${error.message}`);
99
+ throw error;
100
+ }
101
+ }
102
+
103
+ // Ensure we have a context and page
104
+ if (!context) {
105
+ const contexts = browser.contexts();
106
+ context = contexts.length > 0 ? contexts[0] : await browser.newContext();
107
+ }
108
+
109
+ const pages = context.pages();
110
+ if (pages.length === 0) {
111
+ page = await context.newPage();
112
+ activePageIndex = 0;
113
+ } else {
114
+ if (activePageIndex >= pages.length) activePageIndex = pages.length - 1;
115
+ page = pages[activePageIndex];
116
+ }
117
+
118
+ return { browser, context, page };
119
+ }
120
+
121
+ /**
122
+ * Get browser state
123
+ */
124
+ function getBrowserState() {
125
+ return { browser, context, page, activePageIndex };
126
+ }
127
+
128
+ /**
129
+ * Set active page index
130
+ */
131
+ function setActivePageIndex(index) {
132
+ activePageIndex = index;
133
+ }
134
+
135
+ /**
136
+ * Reset browser state
137
+ */
138
+ function resetBrowserState() {
139
+ browser = null;
140
+ context = null;
141
+ page = null;
142
+ activePageIndex = 0;
143
+ }
144
+
145
+ module.exports = {
146
+ connectToBrowser,
147
+ getBrowserState,
148
+ setActivePageIndex,
149
+ resetBrowserState
150
+ };