@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
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
const { spawn } = require('child_process');
|
|
9
9
|
const readline = require('readline');
|
|
10
10
|
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
11
12
|
|
|
12
13
|
let requestId = 0;
|
|
13
14
|
let proc;
|
|
@@ -28,9 +29,10 @@ function sendRequest(method, params = {}) {
|
|
|
28
29
|
|
|
29
30
|
async function runTests() {
|
|
30
31
|
console.log('🌐 Browser Automation Test Suite\n');
|
|
31
|
-
console.log('='
|
|
32
|
+
console.log('='.repeat(60));
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
const serverPath = path.join(__dirname, '..', 'src', 'index.js');
|
|
35
|
+
proc = spawn('node', [serverPath], {
|
|
34
36
|
stdio: ['pipe', 'pipe', 'pipe']
|
|
35
37
|
});
|
|
36
38
|
|
|
@@ -47,6 +49,9 @@ async function runTests() {
|
|
|
47
49
|
'Navigate to Example.com',
|
|
48
50
|
'Evaluate JavaScript',
|
|
49
51
|
'Take Screenshot',
|
|
52
|
+
'Open New Page',
|
|
53
|
+
'List Pages',
|
|
54
|
+
'Wait',
|
|
50
55
|
'Cleanup'
|
|
51
56
|
];
|
|
52
57
|
|
|
@@ -123,9 +128,41 @@ async function runTests() {
|
|
|
123
128
|
break;
|
|
124
129
|
|
|
125
130
|
case 6: // Screenshot
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
131
|
+
console.log(` ✅ ${currentTest}`);
|
|
132
|
+
testStep++;
|
|
133
|
+
|
|
134
|
+
// Open new page
|
|
135
|
+
setTimeout(() => sendRequest('tools/call', {
|
|
136
|
+
name: 'browser_new_page',
|
|
137
|
+
arguments: { url: 'https://google.com' }
|
|
138
|
+
}), 100);
|
|
139
|
+
break;
|
|
140
|
+
|
|
141
|
+
case 7: // New Page
|
|
142
|
+
console.log(` ✅ ${currentTest}`);
|
|
143
|
+
testStep++;
|
|
144
|
+
|
|
145
|
+
// List pages
|
|
146
|
+
setTimeout(() => sendRequest('tools/call', {
|
|
147
|
+
name: 'browser_list_pages',
|
|
148
|
+
arguments: {}
|
|
149
|
+
}), 100);
|
|
150
|
+
|
|
151
|
+
break;
|
|
152
|
+
|
|
153
|
+
case 8: // List Pages
|
|
154
|
+
console.log(` ✅ ${currentTest}`);
|
|
155
|
+
testStep++;
|
|
156
|
+
|
|
157
|
+
// Wait
|
|
158
|
+
setTimeout(() => sendRequest('tools/call', {
|
|
159
|
+
name: 'browser_wait',
|
|
160
|
+
arguments: { ms: 500 }
|
|
161
|
+
}), 100);
|
|
162
|
+
break;
|
|
163
|
+
|
|
164
|
+
case 9: // Wait
|
|
165
|
+
console.log(` ✅ ${currentTest}`);
|
|
129
166
|
testStep++;
|
|
130
167
|
|
|
131
168
|
// All tests complete
|
|
@@ -138,6 +175,8 @@ async function runTests() {
|
|
|
138
175
|
console.log(' • Page navigation (example.com)');
|
|
139
176
|
console.log(' • JavaScript evaluation');
|
|
140
177
|
console.log(' • Screenshot capture');
|
|
178
|
+
console.log(' • Multi-page management');
|
|
179
|
+
console.log(' • Wait utility');
|
|
141
180
|
console.log('\n✨ The MCP server is fully functional!\n');
|
|
142
181
|
|
|
143
182
|
proc.kill();
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const { spawn } = require('child_process');
|
|
8
8
|
const readline = require('readline');
|
|
9
|
+
const path = require('path');
|
|
9
10
|
|
|
10
11
|
let requestId = 0;
|
|
11
12
|
|
|
@@ -36,9 +37,10 @@ function sendNotification(proc, method, params = {}) {
|
|
|
36
37
|
|
|
37
38
|
async function runTests() {
|
|
38
39
|
console.log('🧪 Starting MCP Server Tests\n');
|
|
39
|
-
console.log('='
|
|
40
|
+
console.log('='.repeat(50));
|
|
40
41
|
|
|
41
|
-
const
|
|
42
|
+
const serverPath = path.join(__dirname, '..', 'src', 'index.js');
|
|
43
|
+
const proc = spawn('node', [serverPath], {
|
|
42
44
|
stdio: ['pipe', 'pipe', 'pipe']
|
|
43
45
|
});
|
|
44
46
|
|
|
@@ -100,7 +102,9 @@ async function runTests() {
|
|
|
100
102
|
console.log(`\n✅ All tests passed! (${testsCompleted}/${totalTests})`);
|
|
101
103
|
console.log('\n📊 Test Summary:');
|
|
102
104
|
console.log(' ✅ MCP Protocol initialization');
|
|
103
|
-
console.log(' ✅ Tools listing (
|
|
105
|
+
console.log(' ✅ Tools listing (37 tools)');
|
|
106
|
+
|
|
107
|
+
|
|
104
108
|
console.log(' ✅ Browser automation (health check)');
|
|
105
109
|
console.log('\n🎉 MCP Server is fully functional!\n');
|
|
106
110
|
proc.kill();
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Media Awareness Test Suite
|
|
5
|
+
* Tests browser_get_media_summary, browser_control_media, browser_get_audio_analysis
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const readline = require('readline');
|
|
11
|
+
|
|
12
|
+
const serverPath = path.join(__dirname, '..', 'src', 'index.js');
|
|
13
|
+
const proc = spawn('node', [serverPath], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
14
|
+
|
|
15
|
+
proc.stderr.on('data', (data) => {
|
|
16
|
+
console.error(data.toString().trim());
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
proc.on('error', (err) => {
|
|
20
|
+
console.error('Server error:', err);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const rl = readline.createInterface({ input: proc.stdout, terminal: false });
|
|
25
|
+
|
|
26
|
+
let messageId = 1;
|
|
27
|
+
let testStep = 0;
|
|
28
|
+
|
|
29
|
+
function sendRequest(method, params) {
|
|
30
|
+
const request = { jsonrpc: '2.0', id: messageId++, method, params };
|
|
31
|
+
proc.stdin.write(JSON.stringify(request) + '\n');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log('🌐 Media Awareness Test Suite\n');
|
|
35
|
+
|
|
36
|
+
rl.on('line', (line) => {
|
|
37
|
+
try {
|
|
38
|
+
const response = JSON.parse(line);
|
|
39
|
+
if (response.method === 'notifications/resources/list_changed') return;
|
|
40
|
+
if (response.error) {
|
|
41
|
+
console.error('❌ Error:', response.error.message);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
if (response.result && response.id) {
|
|
45
|
+
handleResponse(response);
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
// Ignore non-JSON lines
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
function handleResponse(response) {
|
|
53
|
+
const currentTest = steps[testStep];
|
|
54
|
+
if (!currentTest) return;
|
|
55
|
+
|
|
56
|
+
console.log(`➡️ ${currentTest.name}`);
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
currentTest.verify(response);
|
|
60
|
+
console.log(` ✅ Passed\n`);
|
|
61
|
+
} catch (err) {
|
|
62
|
+
console.error(` ❌ Failed: ${err.message}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
testStep++;
|
|
67
|
+
if (testStep < steps.length) {
|
|
68
|
+
setTimeout(() => {
|
|
69
|
+
sendRequest(steps[testStep].method, steps[testStep].params());
|
|
70
|
+
}, 500);
|
|
71
|
+
} else {
|
|
72
|
+
console.log('🎉 All media tests passed!');
|
|
73
|
+
proc.kill();
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const steps = [
|
|
79
|
+
{
|
|
80
|
+
name: 'Initialize',
|
|
81
|
+
method: 'initialize',
|
|
82
|
+
params: () => ({
|
|
83
|
+
protocolVersion: '2024-11-05',
|
|
84
|
+
capabilities: {},
|
|
85
|
+
clientInfo: { name: 'test-suite', version: '1.0.0' }
|
|
86
|
+
}),
|
|
87
|
+
verify: () => { }
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'Navigate to Local Media Test',
|
|
91
|
+
method: 'tools/call',
|
|
92
|
+
params: () => ({
|
|
93
|
+
name: 'browser_navigate',
|
|
94
|
+
arguments: { url: 'file://' + path.join(__dirname, 'fixtures', 'test-media.html') }
|
|
95
|
+
}),
|
|
96
|
+
verify: () => { }
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'Wait for Audio Element',
|
|
100
|
+
method: 'tools/call',
|
|
101
|
+
params: () => ({
|
|
102
|
+
name: 'browser_wait_for_selector',
|
|
103
|
+
arguments: { selector: 'audio', timeout: 10000 }
|
|
104
|
+
}),
|
|
105
|
+
verify: () => { }
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'Get Media Summary',
|
|
109
|
+
method: 'tools/call',
|
|
110
|
+
params: () => ({
|
|
111
|
+
name: 'browser_get_media_summary',
|
|
112
|
+
arguments: {}
|
|
113
|
+
}),
|
|
114
|
+
verify: (res) => {
|
|
115
|
+
const summary = JSON.parse(res.result.content[0].text);
|
|
116
|
+
console.log(` Found ${summary.length} media element(s)`);
|
|
117
|
+
if (!Array.isArray(summary)) throw new Error('Result is not an array');
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'Play Media',
|
|
122
|
+
method: 'tools/call',
|
|
123
|
+
params: () => ({
|
|
124
|
+
name: 'browser_control_media',
|
|
125
|
+
arguments: { selector: 'audio', action: 'play' }
|
|
126
|
+
}),
|
|
127
|
+
verify: (res) => {
|
|
128
|
+
const result = JSON.parse(res.result.content[0].text);
|
|
129
|
+
if (result.status !== 'playing') throw new Error('Failed to play');
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'Wait for Playback',
|
|
134
|
+
method: 'tools/call',
|
|
135
|
+
params: () => ({
|
|
136
|
+
name: 'browser_wait',
|
|
137
|
+
arguments: { ms: 1000 }
|
|
138
|
+
}),
|
|
139
|
+
verify: () => { }
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'Analyze Audio',
|
|
143
|
+
method: 'tools/call',
|
|
144
|
+
params: () => ({
|
|
145
|
+
name: 'browser_get_audio_analysis',
|
|
146
|
+
arguments: { durationMs: 500 }
|
|
147
|
+
}),
|
|
148
|
+
verify: (res) => {
|
|
149
|
+
const analysis = JSON.parse(res.result.content[0].text);
|
|
150
|
+
if (typeof analysis.averageVolume !== 'number') throw new Error('Invalid analysis');
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: 'Pause Media',
|
|
155
|
+
method: 'tools/call',
|
|
156
|
+
params: () => ({
|
|
157
|
+
name: 'browser_control_media',
|
|
158
|
+
arguments: { selector: 'audio', action: 'pause' }
|
|
159
|
+
}),
|
|
160
|
+
verify: (res) => {
|
|
161
|
+
const result = JSON.parse(res.result.content[0].text);
|
|
162
|
+
if (result.status !== 'paused') throw new Error('Failed to pause');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
];
|
|
166
|
+
|
|
167
|
+
// Start tests
|
|
168
|
+
setTimeout(() => sendRequest(steps[0].method, steps[0].params()), 500);
|
package/CHANGELOG-v1.0.2.md
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
# Changelog - Version 1.0.2
|
|
2
|
-
|
|
3
|
-
## Release Date
|
|
4
|
-
2025-12-26
|
|
5
|
-
|
|
6
|
-
## Summary
|
|
7
|
-
Enhanced browser detection and standalone mode support. The MCP server now intelligently searches for and uses system Chrome/Chromium installations, eliminating the need for redundant browser downloads.
|
|
8
|
-
|
|
9
|
-
## New Features
|
|
10
|
-
|
|
11
|
-
### 1. Smart Chrome/Chromium Detection
|
|
12
|
-
- **New function**: `findChromeExecutable()` searches for Chrome/Chromium in common system locations
|
|
13
|
-
- **Search locations**:
|
|
14
|
-
- Linux: `/usr/bin/google-chrome`, `/usr/bin/chromium`, `/usr/bin/chromium-browser`, `/snap/bin/chromium`
|
|
15
|
-
- macOS: `/Applications/Google Chrome.app`, `/Applications/Chromium.app`
|
|
16
|
-
- Windows: `C:\Program Files\Google\Chrome\Application\chrome.exe`
|
|
17
|
-
- Also uses `which` command as fallback on Unix systems
|
|
18
|
-
|
|
19
|
-
### 2. Three-Tier Browser Strategy
|
|
20
|
-
The server now tries browsers in this order:
|
|
21
|
-
1. **Antigravity Mode**: Connect to existing Chrome on port 9222 (if available)
|
|
22
|
-
2. **System Browser**: Use system-installed Chrome/Chromium (if found)
|
|
23
|
-
3. **Playwright Chromium**: Fall back to Playwright's Chromium (if installed)
|
|
24
|
-
|
|
25
|
-
### 3. Improved Error Messages
|
|
26
|
-
When no browser is found, users get clear, actionable instructions:
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
❌ No Chrome/Chromium browser found!
|
|
30
|
-
|
|
31
|
-
This MCP server needs a Chrome or Chromium browser to work.
|
|
32
|
-
|
|
33
|
-
Option 1 - Install Chrome/Chromium on your system:
|
|
34
|
-
• Ubuntu/Debian: sudo apt install google-chrome-stable
|
|
35
|
-
• Ubuntu/Debian: sudo apt install chromium-browser
|
|
36
|
-
• Fedora: sudo dnf install google-chrome-stable
|
|
37
|
-
• macOS: brew install --cask google-chrome
|
|
38
|
-
• Or download from: https://www.google.com/chrome/
|
|
39
|
-
|
|
40
|
-
Option 2 - Install Playwright's Chromium:
|
|
41
|
-
npm install playwright
|
|
42
|
-
npx playwright install chromium
|
|
43
|
-
|
|
44
|
-
Option 3 - Use with Antigravity:
|
|
45
|
-
Open Antigravity and click the Chrome logo (top right) to start the browser.
|
|
46
|
-
This MCP server will automatically connect to it.
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Bug Fixes
|
|
50
|
-
|
|
51
|
-
### 1. Browser Reconnection
|
|
52
|
-
- Fixed browser disconnection detection
|
|
53
|
-
- Improved reconnection logic after browser crashes or closures
|
|
54
|
-
|
|
55
|
-
## Changes
|
|
56
|
-
|
|
57
|
-
### package.json
|
|
58
|
-
- Moved Playwright from `peerDependencies` to `dependencies` (^1.57.0)
|
|
59
|
-
- Removed `postinstall` script (no longer auto-installs Chromium)
|
|
60
|
-
- Users can now choose: system Chrome, Chromium, or Playwright Chromium
|
|
61
|
-
|
|
62
|
-
### browser-mcp-server-playwright.js
|
|
63
|
-
- Added `findChromeExecutable()` function (+43 lines)
|
|
64
|
-
- Enhanced browser launch logic with Chrome detection
|
|
65
|
-
- Improved error handling with context-aware messages
|
|
66
|
-
- Better debug logging for troubleshooting
|
|
67
|
-
|
|
68
|
-
## Benefits
|
|
69
|
-
|
|
70
|
-
✅ **No Redundant Downloads**: Uses existing Chrome/Chromium installations
|
|
71
|
-
✅ **Disk Space Savings**: Avoids downloading ~275MB Playwright Chromium if system browser exists
|
|
72
|
-
✅ **Faster Installation**: No browser download during npm install
|
|
73
|
-
✅ **Better UX**: Clear error messages guide users to solutions
|
|
74
|
-
✅ **Flexible**: Works with Antigravity, system browsers, OR Playwright Chromium
|
|
75
|
-
✅ **Cross-Platform**: Supports Linux, macOS, and Windows
|
|
76
|
-
|
|
77
|
-
## Compatibility
|
|
78
|
-
|
|
79
|
-
- **Node.js**: >=16.0.0
|
|
80
|
-
- **Playwright**: ^1.57.0
|
|
81
|
-
- **Browsers**: Chrome, Chromium, or Playwright Chromium
|
|
82
|
-
|
|
83
|
-
## Testing
|
|
84
|
-
|
|
85
|
-
All 16 browser automation tools tested and verified:
|
|
86
|
-
- ✅ browser_navigate
|
|
87
|
-
- ✅ browser_click
|
|
88
|
-
- ✅ browser_screenshot
|
|
89
|
-
- ✅ browser_get_text
|
|
90
|
-
- ✅ browser_type
|
|
91
|
-
- ✅ browser_evaluate
|
|
92
|
-
- ✅ browser_wait_for_selector
|
|
93
|
-
- ✅ browser_scroll
|
|
94
|
-
- ✅ browser_resize_window
|
|
95
|
-
- ✅ browser_get_dom
|
|
96
|
-
- ✅ browser_start_video_recording
|
|
97
|
-
- ✅ browser_stop_video_recording
|
|
98
|
-
- ✅ browser_health_check
|
|
99
|
-
- ✅ browser_console_start
|
|
100
|
-
- ✅ browser_console_get
|
|
101
|
-
- ✅ browser_console_clear
|
|
102
|
-
|
|
103
|
-
## Migration Guide
|
|
104
|
-
|
|
105
|
-
### From v1.0.1 to v1.0.2
|
|
106
|
-
|
|
107
|
-
**No action required!** The update is fully backward compatible.
|
|
108
|
-
|
|
109
|
-
**If you had Playwright Chromium installed:**
|
|
110
|
-
- It will still work as a fallback
|
|
111
|
-
- But the server will prefer your system Chrome/Chromium if available
|
|
112
|
-
|
|
113
|
-
**If you didn't have any browser:**
|
|
114
|
-
- The new error messages will guide you through installation options
|
|
115
|
-
- Choose the option that works best for your system
|
|
116
|
-
|
|
117
|
-
## Debug Logs
|
|
118
|
-
|
|
119
|
-
Server logs are written to: `/tmp/mcp-browser-server.log`
|
|
120
|
-
|
|
121
|
-
Example log output:
|
|
122
|
-
```
|
|
123
|
-
Found Chrome at: /usr/bin/google-chrome
|
|
124
|
-
Using system Chrome/Chromium: /usr/bin/google-chrome
|
|
125
|
-
✅ Successfully launched new Chrome instance (Standalone mode)
|
|
126
|
-
```
|