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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brave-real-browser-mcp-server",
3
- "version": "2.34.1",
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-mcp": "./dist/index.js"
25
+ "brave": "./src/index.js",
26
+ "brave-mcp": "./dist/index.js",
27
+ "brave-lsp": "./src/lsp/index.js"
26
28
  },
27
29
  "scripts": {
28
- "dev": "node src/mcp/index.js",
29
- "mcp": "node src/mcp/index.js",
30
- "mcp:verbose": "node src/mcp/index.js --verbose",
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.49.1",
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.10.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.49.1",
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.16.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.10.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.49.1",
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.16.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 };