brave-real-browser-mcp-server 2.34.1 → 2.36.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 +13 -6
- package/packages/brave-real-blocker/package.json +2 -2
- package/packages/brave-real-launcher/package.json +2 -2
- package/packages/brave-real-puppeteer-core/package.json +2 -2
- package/src/index.js +144 -0
- package/src/lsp/capabilities/autocomplete.js +102 -0
- package/src/lsp/capabilities/diagnostics.js +553 -0
- package/src/lsp/capabilities/hover.js +65 -0
- package/src/lsp/capabilities/refactoring.js +297 -0
- package/src/lsp/capabilities/simulation.js +31 -0
- package/src/lsp/capabilities/snippets.js +13 -0
- package/src/lsp/index.js +24 -0
- package/src/lsp/languages/en.js +66 -0
- package/src/lsp/languages/hi.js +50 -0
- package/src/lsp/server.js +78 -0
- package/src/lsp/utils/i18n.js +29 -0
- package/src/mcp/tools.js +13 -758
- package/src/shared/tools.js +878 -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.36.0",
|
|
4
4
|
"description": "MCP Server for Brave Real Browser - Puppeteer with Brave Browser, Stealth Mode, Ad Blocker, and Turnstile Auto-Solver for undetectable web automation.",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/esm/index.mjs",
|
|
@@ -22,12 +22,17 @@
|
|
|
22
22
|
"node": ">=18.0.0"
|
|
23
23
|
},
|
|
24
24
|
"bin": {
|
|
25
|
-
"brave
|
|
25
|
+
"brave": "./src/index.js",
|
|
26
|
+
"brave-mcp": "./dist/index.js",
|
|
27
|
+
"brave-lsp": "./src/lsp/index.js"
|
|
26
28
|
},
|
|
27
29
|
"scripts": {
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"mcp
|
|
30
|
+
"start": "node src/index.js",
|
|
31
|
+
"dev": "node src/index.js mcp",
|
|
32
|
+
"mcp": "node src/index.js mcp",
|
|
33
|
+
"mcp:verbose": "node src/index.js mcp --verbose",
|
|
34
|
+
"lsp": "node src/index.js lsp",
|
|
35
|
+
"list": "node src/index.js --list",
|
|
31
36
|
"build": "echo 'Root package uses pre-built lib/ - no build needed'",
|
|
32
37
|
"build:self": "echo 'Root package uses pre-built lib/ - no build needed'",
|
|
33
38
|
"test": "npm run cjs_test && npm run esm_test",
|
|
@@ -65,11 +70,13 @@
|
|
|
65
70
|
"license": "ISC",
|
|
66
71
|
"dependencies": {
|
|
67
72
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
68
|
-
"brave-real-puppeteer-core": "^24.
|
|
73
|
+
"brave-real-puppeteer-core": "^24.51.0",
|
|
69
74
|
"ghost-cursor": "^1.4.2",
|
|
70
75
|
"puppeteer-extra": "^3.3.6",
|
|
71
76
|
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
|
72
77
|
"tree-kill": "^1.2.2",
|
|
78
|
+
"vscode-languageserver": "^9.0.1",
|
|
79
|
+
"vscode-languageserver-textdocument": "^1.0.12",
|
|
73
80
|
"xvfb": "^0.4.0"
|
|
74
81
|
},
|
|
75
82
|
"devDependencies": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-blocker",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Advanced uBlock Origin management and stealth features for Brave Real Browser",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"@types/adm-zip": "^0.5.5",
|
|
64
64
|
"@types/fs-extra": "^11.0.4",
|
|
65
65
|
"@types/node": "^20.0.0",
|
|
66
|
-
"brave-real-puppeteer-core": "^24.
|
|
66
|
+
"brave-real-puppeteer-core": "^24.51.0",
|
|
67
67
|
"mocha": "^10.4.0",
|
|
68
68
|
"puppeteer-core": "^24.35.0",
|
|
69
69
|
"sinon": "^17.0.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-launcher",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "Launch Brave Browser with ease from node. Based on chrome-launcher with Brave-specific support.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"typescript": "^5.0.0"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"brave-real-blocker": "^1.
|
|
57
|
+
"brave-real-blocker": "^1.12.0",
|
|
58
58
|
"escape-string-regexp": "^4.0.0",
|
|
59
59
|
"is-wsl": "^2.2.0",
|
|
60
60
|
"which": "^4.0.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-puppeteer-core",
|
|
3
|
-
"version": "24.
|
|
3
|
+
"version": "24.51.0",
|
|
4
4
|
"description": "🦁 Brave Real-World Optimized Puppeteer & Playwright Core with 1-5ms ultra-fast timing, 50+ professional stealth features, intelligent browser auto-detection, and 100% bot detection bypass. Features cross-platform Brave browser integration, comprehensive anti-detection, and breakthrough performance improvements.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"automation",
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
"test-version": "node ./scripts/test-version-management.js"
|
|
133
133
|
},
|
|
134
134
|
"dependencies": {
|
|
135
|
-
"brave-real-launcher": "^1.
|
|
135
|
+
"brave-real-launcher": "^1.18.0",
|
|
136
136
|
"get-east-asian-width": "^1.4.0",
|
|
137
137
|
"yargs": "^18.0.0"
|
|
138
138
|
},
|
package/src/index.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Brave Real Browser - Unified Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* node src/index.js mcp - Start MCP Server (default)
|
|
7
|
+
* node src/index.js lsp - Start LSP Server
|
|
8
|
+
* node src/index.js --help - Show help
|
|
9
|
+
*
|
|
10
|
+
* npm scripts:
|
|
11
|
+
* npm run dev - Start MCP server
|
|
12
|
+
* npm run mcp - Start MCP server
|
|
13
|
+
* npm run lsp - Start LSP server
|
|
14
|
+
*
|
|
15
|
+
* For AI Assistants (MCP):
|
|
16
|
+
* Claude Desktop, Cursor, Copilot, etc.
|
|
17
|
+
*
|
|
18
|
+
* For IDEs (LSP):
|
|
19
|
+
* VS Code, Neovim, Sublime Text, etc.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const { TOOLS, TOOL_DISPLAY, CATEGORIES } = require('./shared/tools.js');
|
|
23
|
+
|
|
24
|
+
// ANSI colors for terminal
|
|
25
|
+
const colors = {
|
|
26
|
+
reset: '\x1b[0m',
|
|
27
|
+
bright: '\x1b[1m',
|
|
28
|
+
dim: '\x1b[2m',
|
|
29
|
+
green: '\x1b[32m',
|
|
30
|
+
yellow: '\x1b[33m',
|
|
31
|
+
blue: '\x1b[34m',
|
|
32
|
+
magenta: '\x1b[35m',
|
|
33
|
+
cyan: '\x1b[36m',
|
|
34
|
+
red: '\x1b[31m',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Display help message
|
|
39
|
+
*/
|
|
40
|
+
function showHelp() {
|
|
41
|
+
console.log(`
|
|
42
|
+
${colors.bright}${colors.cyan}🦁 Brave Real Browser - Unified Server${colors.reset}
|
|
43
|
+
|
|
44
|
+
${colors.bright}USAGE:${colors.reset}
|
|
45
|
+
node src/index.js [mode] [options]
|
|
46
|
+
|
|
47
|
+
${colors.bright}MODES:${colors.reset}
|
|
48
|
+
${colors.green}mcp${colors.reset} Start MCP Server for AI agents (default)
|
|
49
|
+
${colors.green}lsp${colors.reset} Start LSP Server for IDE intelligence
|
|
50
|
+
|
|
51
|
+
${colors.bright}OPTIONS:${colors.reset}
|
|
52
|
+
${colors.yellow}--help, -h${colors.reset} Show this help message
|
|
53
|
+
${colors.yellow}--verbose, -v${colors.reset} Show detailed tool information
|
|
54
|
+
${colors.yellow}--list${colors.reset} List all available tools
|
|
55
|
+
|
|
56
|
+
${colors.bright}EXAMPLES:${colors.reset}
|
|
57
|
+
node src/index.js mcp # Start MCP server
|
|
58
|
+
node src/index.js lsp # Start LSP server
|
|
59
|
+
node src/index.js --list # List all tools
|
|
60
|
+
|
|
61
|
+
${colors.bright}NPM SCRIPTS:${colors.reset}
|
|
62
|
+
npm run dev # Start MCP server
|
|
63
|
+
npm run mcp # Start MCP server
|
|
64
|
+
npm run lsp # Start LSP server
|
|
65
|
+
|
|
66
|
+
${colors.bright}TOOL CATEGORIES (${TOOLS.length} tools):${colors.reset}
|
|
67
|
+
${Object.entries(CATEGORIES).map(([key, cat]) => {
|
|
68
|
+
const count = TOOLS.filter(t => t.category === key).length;
|
|
69
|
+
return ` ${cat.emoji} ${colors.yellow}${cat.name.padEnd(15)}${colors.reset} ${colors.dim}(${count} tools)${colors.reset}`;
|
|
70
|
+
}).join('\n')}
|
|
71
|
+
|
|
72
|
+
${colors.dim}MCP: For AI assistants (Claude, Cursor, Copilot)
|
|
73
|
+
LSP: For IDE code intelligence (VS Code, Neovim)${colors.reset}
|
|
74
|
+
`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* List all available tools
|
|
79
|
+
*/
|
|
80
|
+
function listTools() {
|
|
81
|
+
console.log(`\n${colors.bright}${colors.cyan}🦁 Available Tools (${TOOLS.length}):${colors.reset}\n`);
|
|
82
|
+
|
|
83
|
+
for (const [key, cat] of Object.entries(CATEGORIES)) {
|
|
84
|
+
const tools = TOOLS.filter(t => t.category === key);
|
|
85
|
+
if (tools.length === 0) continue;
|
|
86
|
+
|
|
87
|
+
console.log(`${colors.bright}${cat.emoji} ${cat.name}${colors.reset} ${colors.dim}(${tools.length})${colors.reset}`);
|
|
88
|
+
console.log(`${colors.dim}${'─'.repeat(50)}${colors.reset}`);
|
|
89
|
+
|
|
90
|
+
for (const tool of tools) {
|
|
91
|
+
const required = tool.inputSchema?.required || [];
|
|
92
|
+
console.log(` ${tool.emoji} ${colors.yellow}${tool.name.padEnd(25)}${colors.reset} ${colors.dim}${tool.description.substring(0, 40)}${colors.reset}`);
|
|
93
|
+
}
|
|
94
|
+
console.log('');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Main entry point
|
|
100
|
+
*/
|
|
101
|
+
async function main() {
|
|
102
|
+
const args = process.argv.slice(2);
|
|
103
|
+
|
|
104
|
+
// Parse arguments
|
|
105
|
+
const hasHelp = args.includes('--help') || args.includes('-h');
|
|
106
|
+
const hasList = args.includes('--list');
|
|
107
|
+
const mode = args.find(a => ['mcp', 'lsp'].includes(a.toLowerCase())) || 'mcp';
|
|
108
|
+
|
|
109
|
+
if (hasHelp) {
|
|
110
|
+
showHelp();
|
|
111
|
+
process.exit(0);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (hasList) {
|
|
115
|
+
listTools();
|
|
116
|
+
process.exit(0);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Start appropriate server
|
|
120
|
+
if (mode.toLowerCase() === 'lsp') {
|
|
121
|
+
// Start LSP Server
|
|
122
|
+
require('./lsp/index.js');
|
|
123
|
+
} else {
|
|
124
|
+
// Start MCP Server (default)
|
|
125
|
+
require('./mcp/index.js');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Export for programmatic use
|
|
130
|
+
module.exports = {
|
|
131
|
+
TOOLS,
|
|
132
|
+
TOOL_DISPLAY,
|
|
133
|
+
CATEGORIES,
|
|
134
|
+
startMCP: () => require('./mcp/index.js'),
|
|
135
|
+
startLSP: () => require('./lsp/index.js'),
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// Run if called directly
|
|
139
|
+
if (require.main === module) {
|
|
140
|
+
main().catch(error => {
|
|
141
|
+
console.error(`${colors.red}❌ Fatal error:${colors.reset}`, error.message);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autocomplete Capability
|
|
3
|
+
*/
|
|
4
|
+
const { CompletionItemKind, InsertTextFormat } = require('vscode-languageserver/node');
|
|
5
|
+
|
|
6
|
+
function getCompletions(document, position, tools, lang, settings) {
|
|
7
|
+
const text = document.getText();
|
|
8
|
+
const offset = document.offsetAt(position);
|
|
9
|
+
const lineText = text.split('\n')[position.line] || '';
|
|
10
|
+
const prefix = getPrefix(lineText, position.character);
|
|
11
|
+
const completions = [];
|
|
12
|
+
const context = detectContext(text, offset);
|
|
13
|
+
|
|
14
|
+
if (context.type === 'tool_name' || context.type === 'start') {
|
|
15
|
+
for (const tool of tools) {
|
|
16
|
+
const toolLang = lang.tools[tool.name] || {};
|
|
17
|
+
if (tool.name.toLowerCase().startsWith(prefix) || prefix === '') {
|
|
18
|
+
completions.push({
|
|
19
|
+
label: tool.name,
|
|
20
|
+
kind: CompletionItemKind.Function,
|
|
21
|
+
detail: `${tool.emoji} ${toolLang.detail || tool.description}`,
|
|
22
|
+
documentation: toolLang.documentation || tool.description,
|
|
23
|
+
insertText: generateToolSnippet(tool),
|
|
24
|
+
insertTextFormat: InsertTextFormat.Snippet,
|
|
25
|
+
data: { toolName: tool.name },
|
|
26
|
+
sortText: `0_${tool.name}`,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (context.type === 'parameter_name') {
|
|
33
|
+
const tool = tools.find(t => t.name === context.toolName);
|
|
34
|
+
if (tool?.inputSchema?.properties) {
|
|
35
|
+
const toolLang = lang.tools[tool.name] || {};
|
|
36
|
+
for (const [name, schema] of Object.entries(tool.inputSchema.properties)) {
|
|
37
|
+
if (name.toLowerCase().startsWith(prefix) || prefix === '') {
|
|
38
|
+
completions.push({
|
|
39
|
+
label: name,
|
|
40
|
+
kind: CompletionItemKind.Property,
|
|
41
|
+
detail: schema.type,
|
|
42
|
+
documentation: toolLang.parameters?.[name] || schema.description,
|
|
43
|
+
insertText: `${name}: `,
|
|
44
|
+
sortText: tool.inputSchema.required?.includes(name) ? `0_${name}` : `1_${name}`,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (context.type === 'parameter_value') {
|
|
52
|
+
const tool = tools.find(t => t.name === context.toolName);
|
|
53
|
+
const schema = tool?.inputSchema?.properties?.[context.paramName];
|
|
54
|
+
if (schema?.enum) {
|
|
55
|
+
for (const value of schema.enum) {
|
|
56
|
+
completions.push({ label: value, kind: CompletionItemKind.EnumMember, insertText: `'${value}'` });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (schema?.type === 'boolean') {
|
|
60
|
+
completions.push({ label: 'true', kind: CompletionItemKind.Keyword }, { label: 'false', kind: CompletionItemKind.Keyword });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return completions;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function generateToolSnippet(tool) {
|
|
68
|
+
const required = tool.inputSchema.required || [];
|
|
69
|
+
const props = tool.inputSchema.properties || {};
|
|
70
|
+
if (required.length === 0) return `${tool.name}()`;
|
|
71
|
+
let i = 1;
|
|
72
|
+
const params = required.map(p => {
|
|
73
|
+
const prop = props[p];
|
|
74
|
+
if (prop?.type === 'string') return `${p}: '\${${i++}}'`;
|
|
75
|
+
if (prop?.type === 'boolean') return `${p}: \${${i++}:false}`;
|
|
76
|
+
if (prop?.type === 'number') return `${p}: \${${i++}:0}`;
|
|
77
|
+
return `${p}: \${${i++}}`;
|
|
78
|
+
});
|
|
79
|
+
return `${tool.name}({ ${params.join(', ')} })`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getPrefix(line, char) {
|
|
83
|
+
let start = char;
|
|
84
|
+
while (start > 0 && /\w/.test(line[start - 1])) start--;
|
|
85
|
+
return line.substring(start, char).toLowerCase();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function detectContext(text, offset) {
|
|
89
|
+
const before = text.substring(0, offset);
|
|
90
|
+
if (/(\w+)\s*\(\s*\{[^}]*(\w+)\s*:\s*['"]?$/.test(before)) {
|
|
91
|
+
const match = before.match(/(\w+)\s*\(\s*\{[^}]*(\w+)\s*:\s*['"]?$/);
|
|
92
|
+
return { type: 'parameter_value', toolName: match[1], paramName: match[2] };
|
|
93
|
+
}
|
|
94
|
+
if (/(\w+)\s*\(\s*\{[^}]*$/.test(before)) {
|
|
95
|
+
const match = before.match(/(\w+)\s*\(\s*\{[^}]*$/);
|
|
96
|
+
return { type: 'parameter_name', toolName: match[1] };
|
|
97
|
+
}
|
|
98
|
+
if (/(?:await\s+|^\s*)$/.test(before)) return { type: 'tool_name' };
|
|
99
|
+
return { type: 'start' };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = { getCompletions };
|