mcpbrowser 0.3.28 → 0.3.29
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/package.json +1 -1
- package/src/browsers/ChromiumBrowser.js +59 -2
- package/src/browsers/brave.js +11 -1
- package/src/browsers/chrome.js +11 -1
- package/src/browsers/edge.js +11 -1
- package/src/utils.js +59 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcpbrowser",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.29",
|
|
4
4
|
"mcpName": "io.github.cherchyk/mcpbrowser",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "MCP browser server - fetch web pages using real Chrome/Edge/Brave browser. Handles authentication, SSO, CAPTCHAs, and anti-bot protection. Browser automation for AI assistants.",
|
|
@@ -9,8 +9,9 @@ import puppeteer from 'puppeteer-core';
|
|
|
9
9
|
import { existsSync } from "fs";
|
|
10
10
|
import os from "os";
|
|
11
11
|
import path from "path";
|
|
12
|
-
import { spawn } from "child_process";
|
|
12
|
+
import { spawn, execSync } from "child_process";
|
|
13
13
|
import logger from '../core/logger.js';
|
|
14
|
+
import { isWSL, wslToWindowsPath, windowsPathToWSL } from '../utils.js';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Base class for all Chromium-based browsers
|
|
@@ -49,6 +50,18 @@ export class ChromiumBrowser extends BaseBrowser {
|
|
|
49
50
|
const platform = os.platform();
|
|
50
51
|
const home = os.homedir();
|
|
51
52
|
|
|
53
|
+
// In WSL the browser is a Windows process, so the user-data-dir
|
|
54
|
+
// must reside on a Windows-accessible filesystem (e.g. /mnt/c/…).
|
|
55
|
+
if (isWSL()) {
|
|
56
|
+
const windowsLocalAppData = this._getWindowsLocalAppData();
|
|
57
|
+
if (windowsLocalAppData) {
|
|
58
|
+
// windowsLocalAppData is already a WSL path like /mnt/c/Users/.../AppData/Local
|
|
59
|
+
return path.join(windowsLocalAppData, `MCPBrowser/${this.config.userDataDirName}`);
|
|
60
|
+
}
|
|
61
|
+
// Fallback: predictable location on C: drive
|
|
62
|
+
return `/mnt/c/MCPBrowserData/${this.config.userDataDirName}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
52
65
|
if (platform === "win32") {
|
|
53
66
|
return path.join(home, `AppData/Local/MCPBrowser/${this.config.userDataDirName}`);
|
|
54
67
|
} else if (platform === "darwin") {
|
|
@@ -74,6 +87,37 @@ export class ChromiumBrowser extends BaseBrowser {
|
|
|
74
87
|
}
|
|
75
88
|
}
|
|
76
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Resolve the Windows %LOCALAPPDATA% directory as a WSL path.
|
|
92
|
+
* Cached per-process. Returns null on failure.
|
|
93
|
+
* @returns {string|null} WSL-style path (e.g. /mnt/c/Users/.../AppData/Local)
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
_getWindowsLocalAppData() {
|
|
97
|
+
// Use a class-level cache so we only shell out once
|
|
98
|
+
if (ChromiumBrowser._wslLocalAppData !== undefined) {
|
|
99
|
+
return ChromiumBrowser._wslLocalAppData;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
const raw = execSync('cmd.exe /c echo %LOCALAPPDATA%', {
|
|
104
|
+
encoding: 'utf8',
|
|
105
|
+
timeout: 5000,
|
|
106
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
107
|
+
}).trim();
|
|
108
|
+
|
|
109
|
+
if (raw && !raw.includes('%LOCALAPPDATA%')) {
|
|
110
|
+
ChromiumBrowser._wslLocalAppData = windowsPathToWSL(raw);
|
|
111
|
+
return ChromiumBrowser._wslLocalAppData;
|
|
112
|
+
}
|
|
113
|
+
} catch {
|
|
114
|
+
// cmd.exe not available or timed out
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
ChromiumBrowser._wslLocalAppData = null;
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
77
121
|
/**
|
|
78
122
|
* Find the browser executable path
|
|
79
123
|
* @returns {string|undefined}
|
|
@@ -109,14 +153,24 @@ export class ChromiumBrowser extends BaseBrowser {
|
|
|
109
153
|
}
|
|
110
154
|
|
|
111
155
|
const userDataDir = this.getDefaultUserDataDir();
|
|
156
|
+
|
|
157
|
+
// When running inside WSL the browser executable is a Windows process.
|
|
158
|
+
// It does not understand WSL paths (/mnt/c/…), so convert to a native
|
|
159
|
+
// Windows path for the --user-data-dir argument.
|
|
160
|
+
const userDataDirArg = isWSL() ? wslToWindowsPath(userDataDir) : userDataDir;
|
|
161
|
+
|
|
112
162
|
const args = [
|
|
113
163
|
`--remote-debugging-port=${this.config.port}`,
|
|
114
|
-
`--user-data-dir=${
|
|
164
|
+
`--user-data-dir=${userDataDirArg}`,
|
|
115
165
|
'--no-first-run',
|
|
116
166
|
'--no-default-browser-check'
|
|
117
167
|
];
|
|
118
168
|
|
|
119
169
|
logger.info(`Launching ${this.config.name} with remote debugging on port ${this.config.port}...`);
|
|
170
|
+
if (isWSL()) {
|
|
171
|
+
logger.info(`WSL detected – launching Windows browser at ${execPath}`);
|
|
172
|
+
logger.info(` user-data-dir (Windows): ${userDataDirArg}`);
|
|
173
|
+
}
|
|
120
174
|
|
|
121
175
|
const child = spawn(execPath, args, {
|
|
122
176
|
detached: true,
|
|
@@ -181,3 +235,6 @@ export class ChromiumBrowser extends BaseBrowser {
|
|
|
181
235
|
this.browser = null;
|
|
182
236
|
}
|
|
183
237
|
}
|
|
238
|
+
|
|
239
|
+
// Static cache for WSL %LOCALAPPDATA% lookup (undefined = not yet resolved)
|
|
240
|
+
ChromiumBrowser._wslLocalAppData = undefined;
|
package/src/browsers/brave.js
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
import { ChromiumBrowser } from './ChromiumBrowser.js';
|
|
7
7
|
import os from "os";
|
|
8
|
+
import { isWSL } from '../utils.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Get platform-specific default paths where Brave browser is typically installed.
|
|
12
|
+
* When running under WSL, Windows-side paths (via /mnt/c/) are also included.
|
|
11
13
|
* @returns {string[]} Array of possible Brave executable paths for the current platform
|
|
12
14
|
*/
|
|
13
15
|
function getDefaultBravePaths() {
|
|
@@ -24,13 +26,21 @@ function getDefaultBravePaths() {
|
|
|
24
26
|
"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
|
|
25
27
|
];
|
|
26
28
|
} else {
|
|
27
|
-
|
|
29
|
+
const paths = [
|
|
28
30
|
"/usr/bin/brave",
|
|
29
31
|
"/usr/bin/brave-browser",
|
|
30
32
|
"/usr/bin/brave-browser-stable",
|
|
31
33
|
"/opt/brave.com/brave/brave-browser",
|
|
32
34
|
"/snap/bin/brave",
|
|
33
35
|
];
|
|
36
|
+
// In WSL, also look for Windows-side Brave via /mnt/c/
|
|
37
|
+
if (isWSL()) {
|
|
38
|
+
paths.push(
|
|
39
|
+
"/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
40
|
+
"/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return paths;
|
|
34
44
|
}
|
|
35
45
|
}
|
|
36
46
|
|
package/src/browsers/chrome.js
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
import { ChromiumBrowser } from './ChromiumBrowser.js';
|
|
7
7
|
import os from "os";
|
|
8
|
+
import { isWSL } from '../utils.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Get platform-specific default paths where Chrome is typically installed.
|
|
12
|
+
* When running under WSL, Windows-side paths (via /mnt/c/) are also included.
|
|
11
13
|
* @returns {string[]} Array of possible Chrome executable paths for the current platform
|
|
12
14
|
*/
|
|
13
15
|
function getDefaultChromePaths() {
|
|
@@ -24,11 +26,19 @@ function getDefaultChromePaths() {
|
|
|
24
26
|
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
|
25
27
|
];
|
|
26
28
|
} else {
|
|
27
|
-
|
|
29
|
+
const paths = [
|
|
28
30
|
"/usr/bin/google-chrome",
|
|
29
31
|
"/usr/bin/chromium-browser",
|
|
30
32
|
"/usr/bin/chromium",
|
|
31
33
|
];
|
|
34
|
+
// In WSL, also look for Windows-side Chrome via /mnt/c/
|
|
35
|
+
if (isWSL()) {
|
|
36
|
+
paths.push(
|
|
37
|
+
"/mnt/c/Program Files/Google/Chrome/Application/chrome.exe",
|
|
38
|
+
"/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return paths;
|
|
32
42
|
}
|
|
33
43
|
}
|
|
34
44
|
|
package/src/browsers/edge.js
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
import { ChromiumBrowser } from './ChromiumBrowser.js';
|
|
7
7
|
import os from "os";
|
|
8
|
+
import { isWSL } from '../utils.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Get platform-specific default paths where Edge browser is typically installed.
|
|
12
|
+
* When running under WSL, Windows-side paths (via /mnt/c/) are also included.
|
|
11
13
|
* @returns {string[]} Array of possible Edge executable paths for the current platform
|
|
12
14
|
*/
|
|
13
15
|
function getDefaultEdgePaths() {
|
|
@@ -23,13 +25,21 @@ function getDefaultEdgePaths() {
|
|
|
23
25
|
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
|
|
24
26
|
];
|
|
25
27
|
} else {
|
|
26
|
-
|
|
28
|
+
const paths = [
|
|
27
29
|
"/usr/bin/microsoft-edge",
|
|
28
30
|
"/usr/bin/microsoft-edge-stable",
|
|
29
31
|
"/usr/bin/microsoft-edge-beta",
|
|
30
32
|
"/usr/bin/microsoft-edge-dev",
|
|
31
33
|
"/opt/microsoft/msedge/msedge",
|
|
32
34
|
];
|
|
35
|
+
// In WSL, also look for Windows-side Edge via /mnt/c/
|
|
36
|
+
if (isWSL()) {
|
|
37
|
+
paths.push(
|
|
38
|
+
"/mnt/c/Program Files/Microsoft/Edge/Application/msedge.exe",
|
|
39
|
+
"/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe",
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return paths;
|
|
33
43
|
}
|
|
34
44
|
}
|
|
35
45
|
|
package/src/utils.js
CHANGED
|
@@ -2,6 +2,65 @@
|
|
|
2
2
|
* Utility functions for MCPBrowser
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { readFileSync } from 'fs';
|
|
6
|
+
import os from 'os';
|
|
7
|
+
|
|
8
|
+
// --- WSL Detection & Path Helpers ---
|
|
9
|
+
|
|
10
|
+
let _isWSL = null;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Detect if running inside Windows Subsystem for Linux (WSL).
|
|
14
|
+
* Result is cached after first call.
|
|
15
|
+
* @returns {boolean}
|
|
16
|
+
*/
|
|
17
|
+
export function isWSL() {
|
|
18
|
+
if (_isWSL === null) {
|
|
19
|
+
if (os.platform() !== 'linux') {
|
|
20
|
+
_isWSL = false;
|
|
21
|
+
} else {
|
|
22
|
+
try {
|
|
23
|
+
const version = readFileSync('/proc/version', 'utf8');
|
|
24
|
+
_isWSL = /microsoft|wsl/i.test(version);
|
|
25
|
+
} catch {
|
|
26
|
+
_isWSL = false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return _isWSL;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Convert a WSL mount path to a Windows path.
|
|
35
|
+
* e.g. /mnt/c/Program Files/Google → C:\Program Files\Google
|
|
36
|
+
* Non-WSL paths are returned unchanged.
|
|
37
|
+
* @param {string} wslPath
|
|
38
|
+
* @returns {string}
|
|
39
|
+
*/
|
|
40
|
+
export function wslToWindowsPath(wslPath) {
|
|
41
|
+
const match = wslPath.match(/^\/mnt\/([a-zA-Z])\/(.*)/);
|
|
42
|
+
if (match) {
|
|
43
|
+
const drive = match[1].toUpperCase();
|
|
44
|
+
const rest = match[2].replace(/\//g, '\\');
|
|
45
|
+
return `${drive}:\\${rest}`;
|
|
46
|
+
}
|
|
47
|
+
return wslPath;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Convert a Windows path to a WSL mount path.
|
|
52
|
+
* e.g. C:\Users\foo → /mnt/c/Users/foo
|
|
53
|
+
* @param {string} windowsPath
|
|
54
|
+
* @returns {string}
|
|
55
|
+
*/
|
|
56
|
+
export function windowsPathToWSL(windowsPath) {
|
|
57
|
+
return windowsPath
|
|
58
|
+
.replace(/\\/g, '/')
|
|
59
|
+
.replace(/^([A-Za-z]):/, (_, d) => `/mnt/${d.toLowerCase()}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// --- General Utilities ---
|
|
63
|
+
|
|
5
64
|
/**
|
|
6
65
|
* Truncate a string to a maximum length, adding "... [truncated]" if truncated.
|
|
7
66
|
* @param {string} str - The string to truncate
|