@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.
- package/CHANGELOG-v1.3.0.md +42 -0
- package/README.md +190 -45
- package/package.json +10 -10
- package/plugins/.gitkeep +0 -0
- package/src/.gitkeep +0 -0
- package/src/browser.js +150 -0
- package/src/index.js +126 -0
- package/src/tools/.gitkeep +0 -0
- package/src/tools/console.js +139 -0
- package/src/tools/docs.js +813 -0
- package/src/tools/index.js +56 -0
- package/src/tools/info.js +139 -0
- package/src/tools/interaction.js +126 -0
- package/src/tools/keyboard.js +27 -0
- package/src/tools/media.js +264 -0
- package/src/tools/mouse.js +104 -0
- package/src/tools/navigation.js +72 -0
- package/src/tools/pages.js +149 -0
- package/src/tools/system.js +192 -0
- package/src/utils.js +120 -0
- package/tests/.gitkeep +0 -0
- package/tests/fixtures/.gitkeep +0 -0
- package/tests/fixtures/test-media.html +35 -0
- package/{test-browser-automation.js → tests/test-browser-automation.js} +44 -5
- package/{test-mcp.js → tests/test-mcp.js} +7 -3
- package/tests/test-media-tools.js +168 -0
- package/CHANGELOG-v1.0.2.md +0 -126
- package/browser-mcp-server-playwright.js +0 -792
|
@@ -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
|
-
**
|
|
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
|
-
- ✅ **
|
|
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
|
|
77
|
-
https://raw.githubusercontent.com/ricardodeazambuja/browser-mcp-server/main/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
253
|
+
gemini mcp add --trust browser node /path/to/src/index.js
|
|
253
254
|
```
|
|
254
255
|
|
|
255
|
-
## Available Tools (
|
|
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
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
###
|
|
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://
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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
|
|
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/
|
|
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
|
-
├──
|
|
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
|
|
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 (
|
|
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
|
+
"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": "
|
|
5
|
+
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"browser-mcp-server": "./
|
|
7
|
+
"browser-mcp-server": "./src/index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"start": "node
|
|
10
|
+
"start": "node src/index.js",
|
|
11
11
|
"install-browsers": "npx playwright install chromium",
|
|
12
|
-
"test": "
|
|
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
|
-
"
|
|
43
|
+
"src/",
|
|
44
44
|
"README.md",
|
|
45
45
|
"LICENSE",
|
|
46
|
-
"CHANGELOG-v1.0.
|
|
47
|
-
"
|
|
48
|
-
"
|
|
46
|
+
"CHANGELOG-v1.3.0.md",
|
|
47
|
+
"tests/",
|
|
48
|
+
"plugins/"
|
|
49
49
|
]
|
|
50
|
-
}
|
|
50
|
+
}
|
package/plugins/.gitkeep
ADDED
|
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
|
+
};
|