brave-real-browser-mcp-server 2.21.8 → 2.23.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/README.md +148 -89
- package/dist/core-infrastructure.js +8 -1
- package/dist/handlers/browser-handlers.js +25 -2
- package/dist/handlers/content-handlers.js +22 -2
- package/dist/handlers/interaction-handlers.js +61 -8
- package/dist/handlers/navigation-handlers.js +72 -13
- package/dist/handlers/session-sync-handler.js +196 -0
- package/dist/handlers/tool-executor.js +249 -0
- package/dist/index.js +178 -7
- package/dist/lsp/browser-automation-lsp.js +626 -0
- package/dist/lsp/typescript-analyzer.js +523 -0
- package/dist/shared/context-enricher.js +228 -0
- package/dist/shared/event-bus.js +128 -0
- package/dist/shared/sse-lsp-streamer.js +212 -0
- package/dist/tool-definitions.js +10 -2
- package/dist/transport/index.js +16 -0
- package/dist/transport/progress-notifier.js +237 -0
- package/dist/transport/session-manager.js +333 -0
- package/dist/transport/transport-factory.js +405 -0
- package/dist/unified-server.js +560 -0
- package/package.json +18 -7
package/README.md
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
# Brave Real Browser MCP Server
|
|
2
2
|
|
|
3
|
-
> **AI assistants
|
|
3
|
+
> **AI assistants के लिए powerful, anti-detection browser automation - Unified MCP+LSP+SSE ecosystem**
|
|
4
4
|
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
[](https://www.npmjs.com/package/brave-real-browser-mcp-server)
|
|
7
7
|
|
|
8
8
|
## 🚀 Quick Start
|
|
9
9
|
|
|
10
|
-
###
|
|
11
|
-
|
|
12
|
-
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
13
|
-
**Mac:** `~/Library/Application Support/Claude/`
|
|
14
|
-
**Linux:** `~/.config/Claude/`
|
|
10
|
+
### Option 1: NPX (Recommended for AI IDEs)
|
|
15
11
|
|
|
16
12
|
```json
|
|
17
13
|
{
|
|
@@ -24,127 +20,182 @@
|
|
|
24
20
|
}
|
|
25
21
|
```
|
|
26
22
|
|
|
27
|
-
|
|
23
|
+
**Config locations:**
|
|
24
|
+
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
25
|
+
- **Mac:** `~/Library/Application Support/Claude/`
|
|
26
|
+
- **Linux:** `~/.config/Claude/`
|
|
27
|
+
|
|
28
|
+
### Option 2: Unified Server (Full Features)
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
```bash
|
|
31
|
+
npm run dev
|
|
32
|
+
```
|
|
31
33
|
|
|
32
34
|
---
|
|
33
35
|
|
|
34
36
|
## ✨ Features
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
| Feature | Description |
|
|
39
|
+
|---------|-------------|
|
|
40
|
+
| **33 MCP Tools** | Complete browser automation toolkit |
|
|
41
|
+
| **Unified Server** | MCP + SSE + LSP in one command |
|
|
42
|
+
| **Stealth Mode** | 50+ anti-detection features |
|
|
43
|
+
| **Captcha Solving** | reCAPTCHA, hCaptcha, Turnstile |
|
|
44
|
+
| **Brave Browser** | Auto-detection, uBlock Origin built-in |
|
|
45
|
+
| **TypeScript Analyzer** | Full Compiler API integration |
|
|
46
|
+
| **Real-time Streaming** | SSE for live progress updates |
|
|
47
|
+
| **Auto-Sync** | SharedEventBus connects all protocols |
|
|
42
48
|
|
|
43
49
|
---
|
|
44
50
|
|
|
45
|
-
##
|
|
51
|
+
## 🌐 Unified MCP+LSP+SSE Ecosystem
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
| Tool | Description |
|
|
49
|
-
|------|-------------|
|
|
50
|
-
| `browser_init` | Initialize stealth browser with anti-detection |
|
|
51
|
-
| `navigate` | Navigate to any URL |
|
|
52
|
-
| `get_content` | Extract page content (HTML/text) |
|
|
53
|
-
| `browser_close` | Close browser instance |
|
|
53
|
+
**एक command से सब active:**
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
| `click` | Click on elements |
|
|
59
|
-
| `type` | Type text into inputs |
|
|
60
|
-
| `wait` | Wait for conditions |
|
|
61
|
-
| `press_key` | Simulate keyboard |
|
|
55
|
+
```bash
|
|
56
|
+
npm run dev
|
|
57
|
+
```
|
|
62
58
|
|
|
63
|
-
###
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
### Output:
|
|
60
|
+
```
|
|
61
|
+
🦁 Brave Real Browser - Unified Server v2.22.0
|
|
62
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
63
|
+
📡 HTTP Server: http://localhost:3000
|
|
64
|
+
|
|
65
|
+
🛠️ Available MCP Tools:
|
|
66
|
+
🚀 browser_init 🔴 browser_close 🌐 navigate
|
|
67
|
+
📄 get_content 🔍 find_element 🖱️ click
|
|
68
|
+
⌨️ type 🤖 solve_captcha 🎬 media_extractor
|
|
69
|
+
... and 24 more tools
|
|
70
|
+
|
|
71
|
+
🔗 SharedEventBus: Auto-syncing MCP ↔ LSP ↔ SSE
|
|
72
|
+
📋 Total: 33 MCP tools | TypeScript Analyzer Active
|
|
73
|
+
✅ Ready! All protocols unified and auto-synced.
|
|
74
|
+
```
|
|
70
75
|
|
|
71
|
-
###
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
76
|
+
### All Endpoints:
|
|
77
|
+
|
|
78
|
+
| Category | Endpoint | Purpose |
|
|
79
|
+
|----------|----------|---------|
|
|
80
|
+
| **MCP** | `POST /mcp` | MCP over HTTP |
|
|
81
|
+
| **MCP** | `GET /mcp/sse` | SSE real-time streaming |
|
|
82
|
+
| **MCP** | `POST /mcp/message` | SSE message handler |
|
|
83
|
+
| **LSP** | `POST /lsp/completion` | Autocomplete |
|
|
84
|
+
| **LSP** | `POST /lsp/hover` | Hover documentation |
|
|
85
|
+
| **LSP** | `POST /lsp/analyze` | TypeScript analysis |
|
|
86
|
+
| **LSP** | `POST /lsp/definition` | Go to definition |
|
|
87
|
+
| **LSP** | `POST /lsp/references` | Find references |
|
|
88
|
+
| **Other** | `GET /health` | Health check |
|
|
89
|
+
| **Other** | `GET /events` | Event bus stats |
|
|
79
90
|
|
|
80
|
-
|
|
81
|
-
| Tool | Description |
|
|
82
|
-
|------|-------------|
|
|
83
|
-
| `breadcrumb_navigator` | Navigate via breadcrumbs |
|
|
84
|
-
| `redirect_tracer` | Trace URL redirects |
|
|
85
|
-
| `m3u8_parser` | Parse HLS/m3u8 streams |
|
|
91
|
+
---
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
## 🛠️ All 33 MCP Tools
|
|
94
|
+
|
|
95
|
+
### Browser Management
|
|
88
96
|
| Tool | Description |
|
|
89
97
|
|------|-------------|
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `ajax_content_waiter` | Wait for AJAX content |
|
|
93
|
-
| `deep_analysis` | Comprehensive page analysis |
|
|
98
|
+
| `browser_init` | Initialize Brave browser with stealth |
|
|
99
|
+
| `browser_close` | Close browser instance |
|
|
94
100
|
|
|
95
|
-
###
|
|
101
|
+
### Navigation
|
|
96
102
|
| Tool | Description |
|
|
97
103
|
|------|-------------|
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `element_screenshot` | Screenshot elements |
|
|
104
|
+
| `navigate` | Navigate to URL |
|
|
105
|
+
| `wait` | Wait for conditions |
|
|
101
106
|
|
|
102
|
-
###
|
|
107
|
+
### Content
|
|
103
108
|
| Tool | Description |
|
|
104
109
|
|------|-------------|
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
110
|
+
| `get_content` | Get page HTML/text |
|
|
111
|
+
| `find_element` | Find by selector/text/AI |
|
|
112
|
+
| `save_content_as_markdown` | Save as markdown file |
|
|
108
113
|
|
|
109
|
-
###
|
|
114
|
+
### Interaction
|
|
110
115
|
| Tool | Description |
|
|
111
116
|
|------|-------------|
|
|
112
|
-
| `
|
|
117
|
+
| `click` | Click on element |
|
|
118
|
+
| `type` | Type text into input |
|
|
119
|
+
| `press_key` | Keyboard press |
|
|
113
120
|
| `random_scroll` | Natural scrolling |
|
|
114
121
|
| `solve_captcha` | Solve CAPTCHAs |
|
|
115
122
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
123
|
+
### Media Extraction
|
|
124
|
+
| Tool | Description |
|
|
125
|
+
|------|-------------|
|
|
126
|
+
| `media_extractor` | Extract video/audio |
|
|
127
|
+
| `m3u8_parser` | Parse HLS streams |
|
|
128
|
+
| `stream_extractor` | Direct download URLs |
|
|
119
129
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
### Advanced
|
|
131
|
+
| Tool | Description |
|
|
132
|
+
|------|-------------|
|
|
133
|
+
| `search_content` | Search patterns |
|
|
134
|
+
| `extract_json` | Extract embedded JSON |
|
|
135
|
+
| `scrape_meta_tags` | Meta/OG tags |
|
|
136
|
+
| `deep_analysis` | Full page analysis |
|
|
137
|
+
| `network_recorder` | Record traffic |
|
|
138
|
+
| `api_finder` | Discover APIs |
|
|
139
|
+
| `ajax_content_waiter` | Wait for AJAX |
|
|
140
|
+
| `link_harvester` | Harvest links |
|
|
141
|
+
| `batch_element_scraper` | Batch scrape |
|
|
142
|
+
| `extract_schema` | Schema.org data |
|
|
143
|
+
| `element_screenshot` | Screenshot element |
|
|
144
|
+
| `breadcrumb_navigator` | Navigate breadcrumbs |
|
|
145
|
+
| `redirect_tracer` | Trace redirects |
|
|
146
|
+
| `progress_tracker` | Track progress |
|
|
147
|
+
| `cookie_manager` | Manage cookies |
|
|
148
|
+
| `file_downloader` | Download files |
|
|
149
|
+
| `iframe_handler` | Handle iframes |
|
|
150
|
+
| `popup_handler` | Handle popups |
|
|
127
151
|
|
|
128
152
|
---
|
|
129
153
|
|
|
130
|
-
##
|
|
154
|
+
## 📋 Commands
|
|
131
155
|
|
|
132
156
|
```bash
|
|
133
|
-
# Clone
|
|
134
|
-
git clone https://github.com/codeiva4u/Brave-Real-Browser-Mcp-Server.git
|
|
135
|
-
cd Brave-Real-Browser-Mcp-Server
|
|
136
|
-
|
|
137
157
|
# Install
|
|
138
158
|
npm install
|
|
139
159
|
|
|
140
160
|
# Build
|
|
141
161
|
npm run build
|
|
142
162
|
|
|
143
|
-
#
|
|
163
|
+
# Development (Unified - Recommended!)
|
|
164
|
+
npm run dev # MCP + SSE + LSP on port 3000
|
|
165
|
+
|
|
166
|
+
# Alternate modes
|
|
167
|
+
npm run dev:stdio # STDIO only (for AI IDEs)
|
|
168
|
+
npm run dev:sse # SSE standalone
|
|
169
|
+
npm run dev:http # HTTP Stream standalone
|
|
170
|
+
|
|
171
|
+
# Production
|
|
172
|
+
npm start # Unified server
|
|
173
|
+
npm run start:stdio # STDIO mode
|
|
174
|
+
|
|
175
|
+
# Tests
|
|
144
176
|
npm test
|
|
177
|
+
npm run test:e2e
|
|
178
|
+
```
|
|
145
179
|
|
|
146
|
-
|
|
147
|
-
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## ⚙️ Environment Variables
|
|
183
|
+
|
|
184
|
+
| Variable | Default | Description |
|
|
185
|
+
|----------|---------|-------------|
|
|
186
|
+
| `MCP_PORT` | `3000` | Server port |
|
|
187
|
+
| `MCP_HOST` | `localhost` | Server host |
|
|
188
|
+
| `DEBUG` | `false` | Debug logging |
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## 🔧 Browser Options
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"headless": false,
|
|
197
|
+
"proxy": "http://proxy:8080"
|
|
198
|
+
}
|
|
148
199
|
```
|
|
149
200
|
|
|
150
201
|
---
|
|
@@ -152,15 +203,23 @@ npm run dev
|
|
|
152
203
|
## 📋 Prerequisites
|
|
153
204
|
|
|
154
205
|
- **Node.js** >= 18.0.0
|
|
155
|
-
- **Brave Browser** (
|
|
156
|
-
|
|
157
|
-
> **Note:** Brave Browser is automatically detected. No manual configuration needed!
|
|
206
|
+
- **Brave Browser** (auto-detected)
|
|
158
207
|
|
|
159
208
|
---
|
|
160
209
|
|
|
161
|
-
##
|
|
210
|
+
## 🐛 Troubleshooting
|
|
211
|
+
|
|
212
|
+
### Port in use
|
|
213
|
+
```bash
|
|
214
|
+
MCP_PORT=3001 npm run dev
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Debug mode
|
|
218
|
+
```bash
|
|
219
|
+
DEBUG=true npm run dev
|
|
220
|
+
```
|
|
162
221
|
|
|
163
|
-
|
|
222
|
+
---
|
|
164
223
|
|
|
165
224
|
## 📄 License
|
|
166
225
|
|
|
@@ -148,12 +148,19 @@ export function handleToolResponse(result, successMessage) {
|
|
|
148
148
|
// MCP server configuration constants
|
|
149
149
|
export const MCP_SERVER_CONFIG = {
|
|
150
150
|
name: 'brave-real-browser-mcp-server',
|
|
151
|
-
version: '
|
|
151
|
+
version: '2.22.0',
|
|
152
152
|
capabilities: {
|
|
153
153
|
tools: {},
|
|
154
154
|
resources: {},
|
|
155
155
|
prompts: {},
|
|
156
156
|
},
|
|
157
|
+
extendedCapabilities: {
|
|
158
|
+
streaming: true,
|
|
159
|
+
sessionManagement: true,
|
|
160
|
+
autoSync: true,
|
|
161
|
+
progressNotifications: true,
|
|
162
|
+
transports: ['stdio', 'sse', 'http-stream'],
|
|
163
|
+
},
|
|
157
164
|
};
|
|
158
165
|
// Process cleanup utilities
|
|
159
166
|
export function setupProcessCleanup(cleanupCallback) {
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import { initializeBrowser, closeBrowser, getBrowserInstance, getPageInstance, getContentPriorityConfig, updateContentPriorityConfig } from '../browser-manager.js';
|
|
2
2
|
import { withErrorHandling } from '../system-utils.js';
|
|
3
3
|
import { validateWorkflow, recordExecution, workflowValidator } from '../workflow-validation.js';
|
|
4
|
-
|
|
4
|
+
import { getProgressNotifier } from '../transport/progress-notifier.js';
|
|
5
|
+
// Browser initialization handler with real-time progress
|
|
5
6
|
export async function handleBrowserInit(args) {
|
|
7
|
+
const progressNotifier = getProgressNotifier();
|
|
8
|
+
const progressToken = `browser-init-${Date.now()}`;
|
|
9
|
+
const tracker = progressNotifier.createTracker(progressToken);
|
|
6
10
|
return await withWorkflowValidation('browser_init', args, async () => {
|
|
7
11
|
return await withErrorHandling(async () => {
|
|
12
|
+
tracker.start(100, '🚀 Starting browser initialization...');
|
|
8
13
|
// Update content priority configuration if provided
|
|
9
14
|
if (args.contentPriority) {
|
|
15
|
+
tracker.setProgress(10, '⚙️ Applying content priority settings...');
|
|
10
16
|
updateContentPriorityConfig(args.contentPriority);
|
|
11
17
|
}
|
|
12
18
|
// Parse connectOption if it's a string
|
|
13
19
|
if (typeof args.connectOption === 'string') {
|
|
20
|
+
tracker.setProgress(15, '📝 Parsing connection options...');
|
|
14
21
|
try {
|
|
15
22
|
args.connectOption = JSON.parse(args.connectOption);
|
|
16
23
|
}
|
|
@@ -19,7 +26,13 @@ export async function handleBrowserInit(args) {
|
|
|
19
26
|
args.connectOption = {};
|
|
20
27
|
}
|
|
21
28
|
}
|
|
29
|
+
tracker.setProgress(20, '🔍 Detecting Brave Browser...');
|
|
30
|
+
tracker.setProgress(30, '🛡️ Applying anti-detection features...');
|
|
31
|
+
tracker.setProgress(40, '🔌 Loading stealth plugins...');
|
|
32
|
+
tracker.setProgress(50, '🚀 Launching browser...');
|
|
22
33
|
await initializeBrowser(args);
|
|
34
|
+
tracker.setProgress(80, '📄 Creating new page...');
|
|
35
|
+
tracker.setProgress(90, '✅ Browser ready!');
|
|
23
36
|
const config = getContentPriorityConfig();
|
|
24
37
|
const configMessage = config.prioritizeContent
|
|
25
38
|
? '\n\n💡 Content Priority Mode: get_content is prioritized for better reliability. Use get_content for page analysis instead of screenshots.'
|
|
@@ -29,6 +42,7 @@ export async function handleBrowserInit(args) {
|
|
|
29
42
|
' • Then: Use get_content to analyze page content\n' +
|
|
30
43
|
' • Finally: Use find_selector and interaction tools\n\n' +
|
|
31
44
|
'✅ Workflow validation is now active - prevents blind selector guessing';
|
|
45
|
+
tracker.complete('🎉 Browser initialized successfully');
|
|
32
46
|
return {
|
|
33
47
|
content: [
|
|
34
48
|
{
|
|
@@ -40,13 +54,22 @@ export async function handleBrowserInit(args) {
|
|
|
40
54
|
}, 'Failed to initialize browser');
|
|
41
55
|
});
|
|
42
56
|
}
|
|
43
|
-
// Browser close handler
|
|
57
|
+
// Browser close handler with real-time progress
|
|
44
58
|
export async function handleBrowserClose() {
|
|
59
|
+
const progressNotifier = getProgressNotifier();
|
|
60
|
+
const progressToken = `browser-close-${Date.now()}`;
|
|
61
|
+
const tracker = progressNotifier.createTracker(progressToken);
|
|
45
62
|
return await withWorkflowValidation('browser_close', {}, async () => {
|
|
46
63
|
return await withErrorHandling(async () => {
|
|
64
|
+
tracker.start(100, '🔄 Closing browser...');
|
|
65
|
+
tracker.setProgress(20, '💾 Saving session state...');
|
|
66
|
+
tracker.setProgress(40, '🧹 Cleaning up processes...');
|
|
47
67
|
await closeBrowser();
|
|
68
|
+
tracker.setProgress(70, '🔄 Resetting workflow state...');
|
|
48
69
|
// Reset workflow state when browser is closed
|
|
49
70
|
workflowValidator.reset();
|
|
71
|
+
tracker.setProgress(90, '✅ Browser closed!');
|
|
72
|
+
tracker.complete('🎉 Browser closed successfully');
|
|
50
73
|
return {
|
|
51
74
|
content: [
|
|
52
75
|
{
|
|
@@ -1,30 +1,41 @@
|
|
|
1
1
|
import { getPageInstance } from '../browser-manager.js';
|
|
2
2
|
import { withErrorHandling } from '../system-utils.js';
|
|
3
3
|
import { validateWorkflow, recordExecution, workflowValidator } from '../workflow-validation.js';
|
|
4
|
-
|
|
4
|
+
import { getProgressNotifier } from '../transport/progress-notifier.js';
|
|
5
|
+
// Get content handler with real-time progress
|
|
5
6
|
export async function handleGetContent(args) {
|
|
7
|
+
const progressNotifier = getProgressNotifier();
|
|
8
|
+
const progressToken = `get-content-${Date.now()}`;
|
|
9
|
+
const tracker = progressNotifier.createTracker(progressToken);
|
|
6
10
|
return await withWorkflowValidation('get_content', args, async () => {
|
|
7
11
|
return await withErrorHandling(async () => {
|
|
12
|
+
tracker.start(100, '📄 Starting content extraction...');
|
|
8
13
|
const pageInstance = getPageInstance();
|
|
9
14
|
if (!pageInstance) {
|
|
15
|
+
tracker.fail('Browser not initialized');
|
|
10
16
|
throw new Error('Browser not initialized. Call browser_init first.');
|
|
11
17
|
}
|
|
12
18
|
const { type = 'html', selector } = args;
|
|
13
19
|
let content;
|
|
14
20
|
if (selector) {
|
|
21
|
+
tracker.setProgress(20, `🔍 Finding element: ${selector}`);
|
|
15
22
|
// Get content from specific element
|
|
16
23
|
const element = await pageInstance.$(selector);
|
|
17
24
|
if (!element) {
|
|
25
|
+
tracker.fail('Element not found');
|
|
18
26
|
throw new Error(`Element not found: ${selector}. Use find_selector to locate elements first.`);
|
|
19
27
|
}
|
|
28
|
+
tracker.setProgress(40, '📝 Extracting element content...');
|
|
20
29
|
if (type === 'text') {
|
|
21
30
|
content = await pageInstance.$eval(selector, (el) => el.innerText || el.textContent || '');
|
|
22
31
|
}
|
|
23
32
|
else {
|
|
24
33
|
content = await pageInstance.$eval(selector, (el) => el.outerHTML || '');
|
|
25
34
|
}
|
|
35
|
+
tracker.setProgress(70, `✅ Extracted ${content.length} characters from element`);
|
|
26
36
|
}
|
|
27
37
|
else {
|
|
38
|
+
tracker.setProgress(20, '📄 Extracting full page content...');
|
|
28
39
|
// Get full page content
|
|
29
40
|
if (type === 'text') {
|
|
30
41
|
content = await pageInstance.evaluate(() => document.body?.innerText || document.documentElement?.innerText || document.body?.textContent || '');
|
|
@@ -32,12 +43,15 @@ export async function handleGetContent(args) {
|
|
|
32
43
|
else {
|
|
33
44
|
content = await pageInstance.content();
|
|
34
45
|
}
|
|
46
|
+
tracker.setProgress(70, `✅ Extracted ${content.length} characters from page`);
|
|
35
47
|
}
|
|
48
|
+
tracker.setProgress(90, '📋 Preparing response...');
|
|
36
49
|
// Return content directly - LLM handles its own token limits
|
|
37
50
|
const workflowMessage = '\n\n🔄 Workflow Status: Content analyzed\n' +
|
|
38
51
|
' • Next step: Use find_selector to locate specific elements\n' +
|
|
39
52
|
' • Then: Use interaction tools (click, type) for automation\n\n' +
|
|
40
53
|
'✅ Content available for element discovery and interactions';
|
|
54
|
+
tracker.complete(`🎉 Content extracted successfully (${content.length} chars)`);
|
|
41
55
|
return {
|
|
42
56
|
content: [
|
|
43
57
|
{
|
|
@@ -49,17 +63,23 @@ export async function handleGetContent(args) {
|
|
|
49
63
|
}, 'Failed to get page content');
|
|
50
64
|
});
|
|
51
65
|
}
|
|
52
|
-
// Find selector handler
|
|
66
|
+
// Find selector handler with real-time progress
|
|
53
67
|
export async function handleFindSelector(args) {
|
|
68
|
+
const progressNotifier = getProgressNotifier();
|
|
69
|
+
const progressToken = `find-selector-${Date.now()}`;
|
|
70
|
+
const tracker = progressNotifier.createTracker(progressToken);
|
|
54
71
|
return await withWorkflowValidation('find_selector', args, async () => {
|
|
55
72
|
return await withErrorHandling(async () => {
|
|
73
|
+
tracker.start(100, '🔍 Starting element search...');
|
|
56
74
|
const pageInstance = getPageInstance();
|
|
57
75
|
if (!pageInstance) {
|
|
76
|
+
tracker.fail('Browser not initialized');
|
|
58
77
|
throw new Error('Browser not initialized. Call browser_init first.');
|
|
59
78
|
}
|
|
60
79
|
const { text, selector, xpath, attributes, description, exact = false, context, shadowDOM = false, searchFrames = false } = args || {};
|
|
61
80
|
// Ensure elementType has a fallback value
|
|
62
81
|
const elementType = args?.elementType || '*';
|
|
82
|
+
tracker.setProgress(10, '🔧 Preparing search strategies...');
|
|
63
83
|
// Helper: Search in Shadow DOM
|
|
64
84
|
const searchInShadowDOM = async (sel) => {
|
|
65
85
|
return await pageInstance.evaluate((selector) => {
|