brave-real-browser-mcp-server 2.14.14 → 2.15.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/package.json +1 -1
- package/scripts/setup-brave.cjs +171 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-browser-mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
4
|
"description": "Universal AI IDE MCP Server - Auto-detects and supports all AI IDEs (Claude Desktop, Cursor, Windsurf, Cline, Zed, VSCode, Qoder AI, etc.) with Brave browser automation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const { execSync, exec } = require('child_process');
|
|
5
|
+
const https = require('https');
|
|
6
|
+
|
|
7
|
+
// Colors for console output
|
|
8
|
+
const colors = {
|
|
9
|
+
reset: "\x1b[0m",
|
|
10
|
+
bright: "\x1b[1m",
|
|
11
|
+
green: "\x1b[32m",
|
|
12
|
+
yellow: "\x1b[33m",
|
|
13
|
+
red: "\x1b[31m",
|
|
14
|
+
cyan: "\x1b[36m"
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function log(message, type = 'info') {
|
|
18
|
+
const timestamp = new Date().toISOString();
|
|
19
|
+
let color = colors.reset;
|
|
20
|
+
if (type === 'success') color = colors.green;
|
|
21
|
+
if (type === 'warn') color = colors.yellow;
|
|
22
|
+
if (type === 'error') color = colors.red;
|
|
23
|
+
if (type === 'info') color = colors.cyan;
|
|
24
|
+
console.log(`${color}[${type.toUpperCase()}] ${message}${colors.reset}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const platform = os.platform();
|
|
28
|
+
|
|
29
|
+
// Define standard paths including the user's specific request
|
|
30
|
+
const bravePaths = {
|
|
31
|
+
win32: [
|
|
32
|
+
'C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe', // User's requested primary path
|
|
33
|
+
'C:\\Program Files (x86)\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
|
|
34
|
+
path.join(os.homedir(), 'AppData', 'Local', 'BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe')
|
|
35
|
+
],
|
|
36
|
+
darwin: [
|
|
37
|
+
'/Applications/Brave Browser.app/Contents/MacOS/Brave Browser'
|
|
38
|
+
],
|
|
39
|
+
linux: [
|
|
40
|
+
'/usr/bin/brave-browser',
|
|
41
|
+
'/usr/bin/brave',
|
|
42
|
+
'/snap/bin/brave'
|
|
43
|
+
]
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
async function checkBraveInstallation() {
|
|
47
|
+
log("Checking for Brave Browser installation...", 'info');
|
|
48
|
+
|
|
49
|
+
let foundPath = null;
|
|
50
|
+
const pathsToCheck = bravePaths[platform] || [];
|
|
51
|
+
|
|
52
|
+
for (const p of pathsToCheck) {
|
|
53
|
+
if (fs.existsSync(p)) {
|
|
54
|
+
foundPath = p;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (foundPath) {
|
|
60
|
+
log(`Brave Browser found at: ${foundPath}`, 'success');
|
|
61
|
+
updateEnvFile(foundPath);
|
|
62
|
+
return true;
|
|
63
|
+
} else {
|
|
64
|
+
log("Brave Browser not found in standard locations.", 'warn');
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function updateEnvFile(bravePath) {
|
|
70
|
+
const envPath = path.join(__dirname, '..', '.env');
|
|
71
|
+
try {
|
|
72
|
+
let envContent = '';
|
|
73
|
+
if (fs.existsSync(envPath)) {
|
|
74
|
+
envContent = fs.readFileSync(envPath, 'utf8');
|
|
75
|
+
} else {
|
|
76
|
+
// Create from example if possible, or just start empty
|
|
77
|
+
const examplePath = path.join(__dirname, '..', '.env.example');
|
|
78
|
+
if(fs.existsSync(examplePath)) {
|
|
79
|
+
envContent = fs.readFileSync(examplePath, 'utf8');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Check if BRAVE_PATH is already set
|
|
84
|
+
if (envContent.includes('BRAVE_PATH=')) {
|
|
85
|
+
// Replace existing
|
|
86
|
+
const newContent = envContent.replace(/^BRAVE_PATH=.*$/m, `BRAVE_PATH=${bravePath}`);
|
|
87
|
+
if (newContent !== envContent) {
|
|
88
|
+
fs.writeFileSync(envPath, newContent);
|
|
89
|
+
log("Updated .env with detected Brave path.", 'success');
|
|
90
|
+
} else {
|
|
91
|
+
log(".env already has a BRAVE_PATH set (or format differs).", 'info');
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
// Append
|
|
95
|
+
fs.appendFileSync(envPath, `\nBRAVE_PATH=${bravePath}\n`);
|
|
96
|
+
log("Appended BRAVE_PATH to .env.", 'success');
|
|
97
|
+
}
|
|
98
|
+
} catch (err) {
|
|
99
|
+
log(`Failed to update .env: ${err.message}`, 'error');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function installBrave() {
|
|
104
|
+
log("Attempting to install Brave Browser...", 'info');
|
|
105
|
+
|
|
106
|
+
if (platform === 'win32') {
|
|
107
|
+
const installerUrl = 'https://laptop-updates.brave.com/latest/winx64'; // Standard stub installer
|
|
108
|
+
const installerPath = path.join(os.tmpdir(), 'BraveBrowserSetup.exe');
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
await downloadFile(installerUrl, installerPath);
|
|
112
|
+
log(`Installer downloaded to ${installerPath}`, 'success');
|
|
113
|
+
log("Running installer... Please follow the prompts if any appear.", 'info');
|
|
114
|
+
|
|
115
|
+
// Run installer
|
|
116
|
+
// /silent /install are common flags for Chromium based browsers.
|
|
117
|
+
// But we use start to let it run interactively if needed, or silent if possible.
|
|
118
|
+
// The standard stub installer usually just runs.
|
|
119
|
+
exec(`"${installerPath}"`, (error, stdout, stderr) => {
|
|
120
|
+
if (error) {
|
|
121
|
+
log(`Installer execution failed: ${error.message}`, 'error');
|
|
122
|
+
} else {
|
|
123
|
+
log("Installer started. Please complete the installation.", 'success');
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
} catch (err) {
|
|
128
|
+
log(`Failed to download/run installer: ${err.message}`, 'error');
|
|
129
|
+
log("Please install Brave manually from https://brave.com/download/", 'warn');
|
|
130
|
+
}
|
|
131
|
+
} else if (platform === 'darwin') {
|
|
132
|
+
log("Automatic installation on macOS is complex. Opening download page...", 'info');
|
|
133
|
+
exec('open https://brave.com/download/');
|
|
134
|
+
} else if (platform === 'linux') {
|
|
135
|
+
log("Please install Brave using your package manager (apt, dnf, snap, etc.).", 'info');
|
|
136
|
+
console.log("Visit: https://brave.com/linux/");
|
|
137
|
+
} else {
|
|
138
|
+
log(`Unsupported platform for auto-install: ${platform}`, 'error');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function downloadFile(url, dest) {
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
const file = fs.createWriteStream(dest);
|
|
145
|
+
https.get(url, (response) => {
|
|
146
|
+
if (response.statusCode !== 200) {
|
|
147
|
+
reject(new Error(`Failed to download: Status Code ${response.statusCode}`));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
response.pipe(file);
|
|
151
|
+
file.on('finish', () => {
|
|
152
|
+
file.close(resolve);
|
|
153
|
+
});
|
|
154
|
+
}).on('error', (err) => {
|
|
155
|
+
fs.unlink(dest, () => {}); // Delete the file async. (But we don't check result)
|
|
156
|
+
reject(err);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function main() {
|
|
162
|
+
const isInstalled = await checkBraveInstallation();
|
|
163
|
+
if (!isInstalled) {
|
|
164
|
+
await installBrave();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
main().catch(err => {
|
|
169
|
+
console.error("Setup script failed:", err);
|
|
170
|
+
process.exit(0);
|
|
171
|
+
});
|