brave-real-browser-mcp-server 2.12.12 → 2.14.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.
|
@@ -167,6 +167,68 @@ export async function handleType(args) {
|
|
|
167
167
|
}, 'Failed to type text');
|
|
168
168
|
});
|
|
169
169
|
}
|
|
170
|
+
// Press key handler
|
|
171
|
+
export async function handlePressKey(args) {
|
|
172
|
+
return await withWorkflowValidation('press_key', args, async () => {
|
|
173
|
+
return await withErrorHandling(async () => {
|
|
174
|
+
const pageInstance = getPageInstance();
|
|
175
|
+
if (!pageInstance) {
|
|
176
|
+
throw new Error('Browser not initialized. Call browser_init first.');
|
|
177
|
+
}
|
|
178
|
+
const { key, selector, modifiers = [] } = args;
|
|
179
|
+
try {
|
|
180
|
+
// If selector is provided, focus on element first
|
|
181
|
+
if (selector) {
|
|
182
|
+
const elementResult = await selfHealingLocators.findElementWithFallbacks(pageInstance, selector);
|
|
183
|
+
if (elementResult) {
|
|
184
|
+
await elementResult.element.focus();
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
console.warn(`Element not found: ${selector}, pressing key on current focus`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Press key with modifiers if specified
|
|
191
|
+
if (modifiers.length > 0) {
|
|
192
|
+
// Hold down modifiers
|
|
193
|
+
for (const modifier of modifiers) {
|
|
194
|
+
await pageInstance.keyboard.down(modifier);
|
|
195
|
+
}
|
|
196
|
+
// Press the main key
|
|
197
|
+
await pageInstance.keyboard.press(key);
|
|
198
|
+
// Release modifiers
|
|
199
|
+
for (const modifier of modifiers.reverse()) {
|
|
200
|
+
await pageInstance.keyboard.up(modifier);
|
|
201
|
+
}
|
|
202
|
+
const modifierStr = modifiers.join('+');
|
|
203
|
+
return {
|
|
204
|
+
content: [
|
|
205
|
+
{
|
|
206
|
+
type: 'text',
|
|
207
|
+
text: `Pressed key combination: ${modifierStr}+${key}${selector ? ` on element: ${selector}` : ''}\n\n✅ Keyboard interaction completed successfully`,
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// Simple key press without modifiers
|
|
214
|
+
await pageInstance.keyboard.press(key);
|
|
215
|
+
return {
|
|
216
|
+
content: [
|
|
217
|
+
{
|
|
218
|
+
type: 'text',
|
|
219
|
+
text: `Pressed key: ${key}${selector ? ` on element: ${selector}` : ''}\n\n✅ Keyboard interaction completed successfully`,
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
catch (pressError) {
|
|
226
|
+
throw new Error(`Failed to press key: ${key}. ` +
|
|
227
|
+
`Error: ${pressError instanceof Error ? pressError.message : String(pressError)}`);
|
|
228
|
+
}
|
|
229
|
+
}, 'Failed to press key');
|
|
230
|
+
});
|
|
231
|
+
}
|
|
170
232
|
// Solve captcha handler
|
|
171
233
|
export async function handleSolveCaptcha(args) {
|
|
172
234
|
return await withErrorHandling(async () => {
|
package/dist/mcp-server.js
CHANGED
|
@@ -5,7 +5,7 @@ import { validateMCPResponse } from './mcp-response-validator.js';
|
|
|
5
5
|
// Import handlers
|
|
6
6
|
import { handleBrowserInit, handleBrowserClose } from './handlers/browser-handlers.js';
|
|
7
7
|
import { handleNavigate, handleWait } from './handlers/navigation-handlers.js';
|
|
8
|
-
import { handleClick, handleType, handleSolveCaptcha, handleRandomScroll } from './handlers/interaction-handlers.js';
|
|
8
|
+
import { handleClick, handleType, handlePressKey, handleSolveCaptcha, handleRandomScroll } from './handlers/interaction-handlers.js';
|
|
9
9
|
import { handleGetContent, handleFindSelector } from './handlers/content-handlers.js';
|
|
10
10
|
import { handleSaveContentAsMarkdown } from './handlers/file-handlers.js';
|
|
11
11
|
import { handleScrapeTable, handleExtractList, handleExtractJSON, handleScrapeMetaTags, handleExtractSchema } from './handlers/data-extraction-handlers.js';
|
|
@@ -54,6 +54,9 @@ export async function createMcpServer() {
|
|
|
54
54
|
case TOOL_NAMES.TYPE:
|
|
55
55
|
result = await handleType(args);
|
|
56
56
|
break;
|
|
57
|
+
case TOOL_NAMES.PRESS_KEY:
|
|
58
|
+
result = await handlePressKey(args);
|
|
59
|
+
break;
|
|
57
60
|
case TOOL_NAMES.WAIT:
|
|
58
61
|
result = await handleWait(args);
|
|
59
62
|
break;
|
package/dist/tool-definitions.js
CHANGED
|
@@ -172,6 +172,33 @@ export const TOOLS = [
|
|
|
172
172
|
required: ['selector', 'text'],
|
|
173
173
|
},
|
|
174
174
|
},
|
|
175
|
+
{
|
|
176
|
+
name: 'press_key',
|
|
177
|
+
description: 'Press keyboard keys (Enter, Tab, Escape, Arrow keys, etc.) - Useful for form submission, navigation, and keyboard shortcuts',
|
|
178
|
+
inputSchema: {
|
|
179
|
+
type: 'object',
|
|
180
|
+
properties: {
|
|
181
|
+
key: {
|
|
182
|
+
type: 'string',
|
|
183
|
+
description: 'Key to press. Common keys: Enter, Tab, Escape, Backspace, Delete, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Space, PageUp, PageDown, Home, End, F1-F12',
|
|
184
|
+
enum: ['Enter', 'Tab', 'Escape', 'Backspace', 'Delete', 'Space', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'PageUp', 'PageDown', 'Home', 'End', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12'],
|
|
185
|
+
},
|
|
186
|
+
selector: {
|
|
187
|
+
type: 'string',
|
|
188
|
+
description: 'Optional: CSS selector of element to focus before pressing key',
|
|
189
|
+
},
|
|
190
|
+
modifiers: {
|
|
191
|
+
type: 'array',
|
|
192
|
+
description: 'Optional: Modifier keys to hold (Ctrl, Shift, Alt, Meta)',
|
|
193
|
+
items: {
|
|
194
|
+
type: 'string',
|
|
195
|
+
enum: ['Control', 'Shift', 'Alt', 'Meta'],
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
required: ['key'],
|
|
200
|
+
},
|
|
201
|
+
},
|
|
175
202
|
{
|
|
176
203
|
name: 'wait',
|
|
177
204
|
description: 'Wait for various conditions',
|
|
@@ -1480,6 +1507,7 @@ export const TOOL_NAMES = {
|
|
|
1480
1507
|
GET_CONTENT: 'get_content',
|
|
1481
1508
|
CLICK: 'click',
|
|
1482
1509
|
TYPE: 'type',
|
|
1510
|
+
PRESS_KEY: 'press_key',
|
|
1483
1511
|
WAIT: 'wait',
|
|
1484
1512
|
BROWSER_CLOSE: 'browser_close',
|
|
1485
1513
|
SOLVE_CAPTCHA: 'solve_captcha',
|
|
@@ -1554,6 +1582,6 @@ export const TOOL_NAMES = {
|
|
|
1554
1582
|
export const TOOL_CATEGORIES = {
|
|
1555
1583
|
BROWSER_MANAGEMENT: [TOOL_NAMES.BROWSER_INIT, TOOL_NAMES.BROWSER_CLOSE],
|
|
1556
1584
|
NAVIGATION: [TOOL_NAMES.NAVIGATE, TOOL_NAMES.WAIT],
|
|
1557
|
-
INTERACTION: [TOOL_NAMES.CLICK, TOOL_NAMES.TYPE, TOOL_NAMES.SOLVE_CAPTCHA, TOOL_NAMES.RANDOM_SCROLL],
|
|
1585
|
+
INTERACTION: [TOOL_NAMES.CLICK, TOOL_NAMES.TYPE, TOOL_NAMES.PRESS_KEY, TOOL_NAMES.SOLVE_CAPTCHA, TOOL_NAMES.RANDOM_SCROLL],
|
|
1558
1586
|
CONTENT: [TOOL_NAMES.GET_CONTENT, TOOL_NAMES.FIND_SELECTOR, TOOL_NAMES.SAVE_CONTENT_AS_MARKDOWN],
|
|
1559
1587
|
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-browser-mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.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",
|
|
7
7
|
"scripts": {
|
|
8
|
+
"preinstall": "npm view brave-real-puppeteer-core version > .latest-version 2>&1 || echo 'Version check skipped'",
|
|
8
9
|
"postinstall": "node scripts/patch-puppeteer-screen-recorder.cjs && node scripts/update-to-latest.cjs || echo 'Auto-update skipped'",
|
|
9
10
|
"clean": "rimraf dist",
|
|
10
11
|
"clean:cache": "npm cache clean --force",
|
|
@@ -133,12 +134,33 @@
|
|
|
133
134
|
"linux",
|
|
134
135
|
"win32"
|
|
135
136
|
],
|
|
137
|
+
"resolutions": {
|
|
138
|
+
"puppeteer": "npm:brave-real-puppeteer-core@latest",
|
|
139
|
+
"puppeteer-core": "npm:brave-real-puppeteer-core@latest",
|
|
140
|
+
"**/puppeteer": "npm:brave-real-puppeteer-core@latest",
|
|
141
|
+
"**/puppeteer-core": "npm:brave-real-puppeteer-core@latest"
|
|
142
|
+
},
|
|
136
143
|
"overrides": {
|
|
137
144
|
"puppeteer": "npm:brave-real-puppeteer-core@latest",
|
|
138
145
|
"puppeteer-core": "npm:brave-real-puppeteer-core@latest",
|
|
139
146
|
"puppeteer-screen-recorder": {
|
|
140
147
|
"puppeteer": "npm:brave-real-puppeteer-core@latest",
|
|
141
|
-
"
|
|
148
|
+
"puppeteer-core": "npm:brave-real-puppeteer-core@latest",
|
|
149
|
+
"fluent-ffmpeg": "latest",
|
|
150
|
+
"glob": "latest",
|
|
151
|
+
"rimraf": "latest"
|
|
152
|
+
},
|
|
153
|
+
"brave-real-browser": {
|
|
154
|
+
"puppeteer": "npm:brave-real-puppeteer-core@latest",
|
|
155
|
+
"puppeteer-core": "npm:brave-real-puppeteer-core@latest"
|
|
156
|
+
},
|
|
157
|
+
"tesseract.js": {
|
|
158
|
+
"puppeteer": "npm:brave-real-puppeteer-core@latest",
|
|
159
|
+
"puppeteer-core": "npm:brave-real-puppeteer-core@latest"
|
|
160
|
+
},
|
|
161
|
+
"*": {
|
|
162
|
+
"puppeteer": "npm:brave-real-puppeteer-core@latest",
|
|
163
|
+
"puppeteer-core": "npm:brave-real-puppeteer-core@latest"
|
|
142
164
|
},
|
|
143
165
|
"fluent-ffmpeg": "latest",
|
|
144
166
|
"glob": "latest",
|
|
@@ -35,17 +35,18 @@ try {
|
|
|
35
35
|
// Check if patch is needed
|
|
36
36
|
if (packageJson.peerDependencies && packageJson.peerDependencies.puppeteer) {
|
|
37
37
|
const currentValue = packageJson.peerDependencies.puppeteer;
|
|
38
|
+
const targetValue = 'npm:brave-real-puppeteer-core@latest';
|
|
38
39
|
|
|
39
|
-
//
|
|
40
|
-
if (currentValue
|
|
41
|
-
// Update to brave-real-puppeteer-core
|
|
42
|
-
packageJson.peerDependencies.puppeteer =
|
|
40
|
+
// Always update to ensure it's using @latest tag (not @>=24.0.0)
|
|
41
|
+
if (currentValue !== targetValue) {
|
|
42
|
+
// Update to brave-real-puppeteer-core with latest tag
|
|
43
|
+
packageJson.peerDependencies.puppeteer = targetValue;
|
|
43
44
|
|
|
44
45
|
// Write back to file
|
|
45
46
|
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2), 'utf8');
|
|
46
47
|
|
|
47
48
|
console.log(' ✓ puppeteer-screen-recorder patched successfully');
|
|
48
|
-
console.log(' ✓ peerDependencies.puppeteer: npm:brave-real-puppeteer-core
|
|
49
|
+
console.log(' ✓ peerDependencies.puppeteer: npm:brave-real-puppeteer-core@latest');
|
|
49
50
|
} else {
|
|
50
51
|
console.log(' ✓ puppeteer-screen-recorder already patched');
|
|
51
52
|
}
|
|
@@ -54,7 +54,11 @@ try {
|
|
|
54
54
|
for (const pkg of packagesToUpdate) {
|
|
55
55
|
try {
|
|
56
56
|
console.log(` Updating ${pkg}...`);
|
|
57
|
-
|
|
57
|
+
|
|
58
|
+
// Force update for brave-real-puppeteer-core
|
|
59
|
+
const forceFlag = pkg === 'brave-real-puppeteer-core' ? '--force' : '';
|
|
60
|
+
|
|
61
|
+
execSync(`npm install ${pkg}@latest --save --no-audit --no-fund ${forceFlag}`, {
|
|
58
62
|
stdio: 'pipe',
|
|
59
63
|
cwd: process.cwd()
|
|
60
64
|
});
|
|
@@ -76,7 +80,13 @@ try {
|
|
|
76
80
|
});
|
|
77
81
|
const parsed = JSON.parse(version);
|
|
78
82
|
const installedVersion = parsed.dependencies?.[pkg]?.version || 'not found';
|
|
79
|
-
|
|
83
|
+
|
|
84
|
+
// Show 'latest' for brave-real-puppeteer-core
|
|
85
|
+
if (pkg === 'brave-real-puppeteer-core') {
|
|
86
|
+
console.log(` ${pkg}: ${installedVersion} (latest)`);
|
|
87
|
+
} else {
|
|
88
|
+
console.log(` ${pkg}: ${installedVersion}`);
|
|
89
|
+
}
|
|
80
90
|
} catch (error) {
|
|
81
91
|
// Ignore errors
|
|
82
92
|
}
|