@ricardodeazambuja/browser-mcp-server 1.0.3 → 1.4.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.
Files changed (43) hide show
  1. package/CHANGELOG-v1.3.0.md +42 -0
  2. package/CHANGELOG-v1.4.0.md +8 -0
  3. package/README.md +271 -45
  4. package/package.json +11 -10
  5. package/plugins/.gitkeep +0 -0
  6. package/src/.gitkeep +0 -0
  7. package/src/browser.js +152 -0
  8. package/src/cdp.js +58 -0
  9. package/src/index.js +126 -0
  10. package/src/tools/.gitkeep +0 -0
  11. package/src/tools/console.js +139 -0
  12. package/src/tools/docs.js +1611 -0
  13. package/src/tools/index.js +60 -0
  14. package/src/tools/info.js +139 -0
  15. package/src/tools/interaction.js +126 -0
  16. package/src/tools/keyboard.js +27 -0
  17. package/src/tools/media.js +264 -0
  18. package/src/tools/mouse.js +104 -0
  19. package/src/tools/navigation.js +72 -0
  20. package/src/tools/network.js +552 -0
  21. package/src/tools/pages.js +149 -0
  22. package/src/tools/performance.js +517 -0
  23. package/src/tools/security.js +470 -0
  24. package/src/tools/storage.js +467 -0
  25. package/src/tools/system.js +196 -0
  26. package/src/utils.js +131 -0
  27. package/tests/.gitkeep +0 -0
  28. package/tests/fixtures/.gitkeep +0 -0
  29. package/tests/fixtures/test-media.html +35 -0
  30. package/tests/fixtures/test-network.html +48 -0
  31. package/tests/fixtures/test-performance.html +61 -0
  32. package/tests/fixtures/test-security.html +33 -0
  33. package/tests/fixtures/test-storage.html +76 -0
  34. package/tests/run-all.js +50 -0
  35. package/{test-browser-automation.js → tests/test-browser-automation.js} +44 -5
  36. package/{test-mcp.js → tests/test-mcp.js} +9 -4
  37. package/tests/test-media-tools.js +168 -0
  38. package/tests/test-network.js +212 -0
  39. package/tests/test-performance.js +254 -0
  40. package/tests/test-security.js +203 -0
  41. package/tests/test-storage.js +192 -0
  42. package/CHANGELOG-v1.0.2.md +0 -126
  43. package/browser-mcp-server-playwright.js +0 -792
@@ -0,0 +1,1611 @@
1
+ const definitions = [
2
+ {
3
+ name: 'browser_docs',
4
+ description: 'Get detailed documentation, return values, examples, and caveats for any browser tool',
5
+ inputSchema: {
6
+ type: 'object',
7
+ properties: {
8
+ toolName: {
9
+ type: 'string',
10
+ description: 'Name of the tool to get docs for (e.g., browser_navigate, browser_get_audio_analysis)'
11
+ }
12
+ },
13
+ required: ['toolName'],
14
+ additionalProperties: false,
15
+ $schema: 'http://json-schema.org/draft-07/schema#'
16
+ }
17
+ }
18
+ ];
19
+
20
+ const toolDocs = {
21
+ // Navigation
22
+ browser_navigate: `
23
+ 📖 browser_navigate(url)
24
+
25
+ Navigate to a URL in the browser.
26
+
27
+ Parameters:
28
+ • url (string, required) - The URL to navigate to
29
+
30
+ Returns:
31
+ { content: [{ type: 'text', text: 'Navigated to <url>' }] }
32
+
33
+ Behavior:
34
+ • Waits for 'domcontentloaded' event (not full page load)
35
+ • For SPAs or slow-loading pages, consider using browser_wait_for_selector after
36
+
37
+ Example:
38
+ browser_navigate({ url: 'https://example.com' })
39
+ `,
40
+
41
+ browser_reload: `
42
+ 📖 browser_reload()
43
+
44
+ Reload the current page.
45
+
46
+ Parameters:
47
+ None
48
+
49
+ Returns:
50
+ { content: [{ type: 'text', text: 'Reloaded page' }] }
51
+
52
+ Behavior:
53
+ • Waits for 'domcontentloaded' event
54
+
55
+ Example:
56
+ browser_reload({})
57
+ `,
58
+
59
+ browser_go_back: `
60
+ 📖 browser_go_back()
61
+
62
+ Navigate back in browser history.
63
+
64
+ Parameters:
65
+ None
66
+
67
+ Returns:
68
+ { content: [{ type: 'text', text: 'Navigated back' }] }
69
+
70
+ Example:
71
+ browser_go_back({})
72
+ `,
73
+
74
+ browser_go_forward: `
75
+ 📖 browser_go_forward()
76
+
77
+ Navigate forward in browser history.
78
+
79
+ Parameters:
80
+ None
81
+
82
+ Returns:
83
+ { content: [{ type: 'text', text: 'Navigated forward' }] }
84
+
85
+ Example:
86
+ browser_go_forward({})
87
+ `,
88
+
89
+ // Interaction
90
+ browser_click: `
91
+ 📖 browser_click(selector)
92
+
93
+ Click an element using a Playwright selector.
94
+
95
+ Parameters:
96
+ • selector (string, required) - Playwright selector for the element
97
+
98
+ Selector Syntax:
99
+ • CSS: '#id', '.class', 'button.primary'
100
+ • Text: 'text=Click me', 'text="exact match"'
101
+ • Data attributes: '[data-testid="submit"]'
102
+ • Chaining: 'div.container >> button'
103
+
104
+ Returns:
105
+ { content: [{ type: 'text', text: 'Clicked <selector>' }] }
106
+
107
+ Example:
108
+ browser_click({ selector: 'button.submit' })
109
+ browser_click({ selector: 'text=Login' })
110
+ `,
111
+
112
+ browser_type: `
113
+ 📖 browser_type(selector, text)
114
+
115
+ Type text into an input field.
116
+
117
+ Parameters:
118
+ • selector (string, required) - Playwright selector for the input
119
+ • text (string, required) - Text to type
120
+
121
+ Returns:
122
+ { content: [{ type: 'text', text: 'Typed into <selector>' }] }
123
+
124
+ ⚠️ Important:
125
+ • Uses page.fill() which CLEARS the field first, then types
126
+ • Does NOT append to existing text
127
+ • For appending, use browser_evaluate to set element.value
128
+
129
+ Example:
130
+ browser_type({ selector: '#username', text: 'john@example.com' })
131
+ `,
132
+
133
+ browser_hover: `
134
+ 📖 browser_hover(selector)
135
+
136
+ Hover over an element.
137
+
138
+ Parameters:
139
+ • selector (string, required) - Playwright selector for the element
140
+
141
+ Returns:
142
+ { content: [{ type: 'text', text: 'Hovered over <selector>' }] }
143
+
144
+ Example:
145
+ browser_hover({ selector: '.menu-item' })
146
+ `,
147
+
148
+ browser_focus: `
149
+ 📖 browser_focus(selector)
150
+
151
+ Focus an element.
152
+
153
+ Parameters:
154
+ • selector (string, required) - Playwright selector for the element
155
+
156
+ Returns:
157
+ { content: [{ type: 'text', text: 'Focused <selector>' }] }
158
+
159
+ Example:
160
+ browser_focus({ selector: 'input[name="email"]' })
161
+ `,
162
+
163
+ browser_select: `
164
+ 📖 browser_select(selector, values)
165
+
166
+ Select options in a dropdown.
167
+
168
+ Parameters:
169
+ • selector (string, required) - Playwright selector for the select element
170
+ • values (array of strings, required) - Values to select
171
+
172
+ Returns:
173
+ { content: [{ type: 'text', text: 'Selected values in <selector>' }] }
174
+
175
+ Example:
176
+ browser_select({ selector: '#country', values: ['US'] })
177
+ browser_select({ selector: '#colors', values: ['red', 'blue'] })
178
+ `,
179
+
180
+ browser_scroll: `
181
+ 📖 browser_scroll(x?, y?)
182
+
183
+ Scroll the page to specific coordinates.
184
+
185
+ Parameters:
186
+ • x (number, optional) - Horizontal scroll position (default: 0)
187
+ • y (number, optional) - Vertical scroll position (default: 0)
188
+
189
+ Returns:
190
+ { content: [{ type: 'text', text: 'Scrolled to (x, y)' }] }
191
+
192
+ Example:
193
+ browser_scroll({ y: 1000 }) // Scroll down 1000px
194
+ browser_scroll({ x: 500, y: 800 })
195
+ `,
196
+
197
+ // Mouse & Keyboard
198
+ browser_mouse_move: `
199
+ 📖 browser_mouse_move(x, y)
200
+
201
+ Move mouse to pixel coordinates.
202
+
203
+ Parameters:
204
+ • x (number, required) - X coordinate in pixels
205
+ • y (number, required) - Y coordinate in pixels
206
+
207
+ Returns:
208
+ { content: [{ type: 'text', text: 'Moved mouse to (x, y)' }] }
209
+
210
+ Example:
211
+ browser_mouse_move({ x: 500, y: 300 })
212
+ `,
213
+
214
+ browser_mouse_click: `
215
+ 📖 browser_mouse_click(x?, y?, button?, clickCount?)
216
+
217
+ Click at pixel coordinates or current position.
218
+
219
+ Parameters:
220
+ • x (number, optional) - X coordinate
221
+ • y (number, optional) - Y coordinate
222
+ • button (string, optional) - 'left', 'right', or 'middle' (default: 'left')
223
+ • clickCount (number, optional) - 1 for single, 2 for double (default: 1)
224
+
225
+ Returns:
226
+ { content: [{ type: 'text', text: 'Clicked at (x, y)' }] }
227
+
228
+ Example:
229
+ browser_mouse_click({ x: 100, y: 200 })
230
+ browser_mouse_click({ button: 'right' }) // Right-click at current position
231
+ browser_mouse_click({ x: 100, y: 200, clickCount: 2 }) // Double-click
232
+ `,
233
+
234
+ browser_mouse_drag: `
235
+ 📖 browser_mouse_drag(fromX, fromY, toX, toY)
236
+
237
+ Drag from one position to another.
238
+
239
+ Parameters:
240
+ • fromX (number, required) - Starting X coordinate
241
+ • fromY (number, required) - Starting Y coordinate
242
+ • toX (number, required) - Ending X coordinate
243
+ • toY (number, required) - Ending Y coordinate
244
+
245
+ Returns:
246
+ { content: [{ type: 'text', text: 'Dragged from (fromX, fromY) to (toX, toY)' }] }
247
+
248
+ Example:
249
+ browser_mouse_drag({ fromX: 100, fromY: 100, toX: 300, toY: 300 })
250
+ `,
251
+
252
+ browser_mouse_wheel: `
253
+ 📖 browser_mouse_wheel(deltaX, deltaY)
254
+
255
+ Scroll the mouse wheel.
256
+
257
+ Parameters:
258
+ • deltaX (number, required) - Horizontal scroll amount
259
+ • deltaY (number, required) - Vertical scroll amount
260
+
261
+ Returns:
262
+ { content: [{ type: 'text', text: 'Mouse wheel scrolled' }] }
263
+
264
+ Example:
265
+ browser_mouse_wheel({ deltaX: 0, deltaY: 100 }) // Scroll down
266
+ `,
267
+
268
+ browser_press_key: `
269
+ 📖 browser_press_key(key)
270
+
271
+ Send a keyboard event.
272
+
273
+ Parameters:
274
+ • key (string, required) - Key to press (e.g., 'Enter', 'Escape', 'Control+A')
275
+
276
+ Returns:
277
+ { content: [{ type: 'text', text: 'Pressed key: <key>' }] }
278
+
279
+ Common Keys:
280
+ • 'Enter', 'Escape', 'Tab', 'Backspace', 'Delete'
281
+ • 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'
282
+ • 'Control+A', 'Control+C', 'Control+V'
283
+ • 'Shift+Tab', 'Alt+F4'
284
+
285
+ Example:
286
+ browser_press_key({ key: 'Enter' })
287
+ browser_press_key({ key: 'Control+A' })
288
+ `,
289
+
290
+ // Pages
291
+ browser_list_pages: `
292
+ 📖 browser_list_pages()
293
+
294
+ List all open browser tabs/pages.
295
+
296
+ Parameters:
297
+ None
298
+
299
+ Returns:
300
+ { content: [{ type: 'text', text: JSON with array of pages }] }
301
+
302
+ Return Structure:
303
+ [
304
+ { index: 0, url: 'https://...', title: '...' },
305
+ { index: 1, url: 'https://...', title: '...' }
306
+ ]
307
+
308
+ Example:
309
+ browser_list_pages({})
310
+ `,
311
+
312
+ browser_new_page: `
313
+ 📖 browser_new_page(url?)
314
+
315
+ Open a new browser tab.
316
+
317
+ Parameters:
318
+ • url (string, optional) - URL to navigate to in the new tab
319
+
320
+ Returns:
321
+ { content: [{ type: 'text', text: 'Opened new page...' }] }
322
+
323
+ Example:
324
+ browser_new_page({}) // Blank tab
325
+ browser_new_page({ url: 'https://example.com' })
326
+ `,
327
+
328
+ browser_switch_page: `
329
+ 📖 browser_switch_page(index)
330
+
331
+ Switch to a different browser tab.
332
+
333
+ Parameters:
334
+ • index (number, required) - The index of the page to switch to (from browser_list_pages)
335
+
336
+ Returns:
337
+ { content: [{ type: 'text', text: 'Switched to page <index>' }] }
338
+
339
+ Example:
340
+ browser_switch_page({ index: 0 })
341
+ `,
342
+
343
+ browser_close_page: `
344
+ 📖 browser_close_page(index?)
345
+
346
+ Close a browser tab.
347
+
348
+ Parameters:
349
+ • index (number, optional) - Index of page to close (closes current page if not specified)
350
+
351
+ Returns:
352
+ { content: [{ type: 'text', text: 'Closed page...' }] }
353
+
354
+ Example:
355
+ browser_close_page({}) // Close current page
356
+ browser_close_page({ index: 1 }) // Close specific page
357
+ `,
358
+
359
+ // Info
360
+ browser_screenshot: `
361
+ 📖 browser_screenshot(fullPage?)
362
+
363
+ Take a screenshot of the current page.
364
+
365
+ Parameters:
366
+ • fullPage (boolean, optional) - Capture full page (default: false)
367
+
368
+ Returns:
369
+ { content: [{ type: 'image', data: '<base64>', mimeType: 'image/png' }] }
370
+
371
+ ⚠️ Important:
372
+ • Returns base64-encoded PNG image data
373
+ • fullPage=true captures entire scrollable page
374
+ • fullPage=false captures visible viewport only
375
+
376
+ Example:
377
+ browser_screenshot({}) // Viewport only
378
+ browser_screenshot({ fullPage: true }) // Entire page
379
+ `,
380
+
381
+ browser_get_text: `
382
+ 📖 browser_get_text(selector)
383
+
384
+ Get text content from an element.
385
+
386
+ Parameters:
387
+ • selector (string, required) - Playwright selector for the element
388
+
389
+ Returns:
390
+ { content: [{ type: 'text', text: '<text content of element>' }] }
391
+
392
+ Example:
393
+ browser_get_text({ selector: '.main-heading' })
394
+ `,
395
+
396
+ browser_evaluate: `
397
+ 📖 browser_evaluate(code)
398
+
399
+ Execute JavaScript in the browser context.
400
+
401
+ Parameters:
402
+ • code (string, required) - JavaScript code to execute
403
+
404
+ Returns:
405
+ { content: [{ type: 'text', text: JSON.stringify(result) }] }
406
+
407
+ ⚠️ Important:
408
+ • Code runs in browser sandbox (no access to host system)
409
+ • Result is JSON-serialized (functions/DOM nodes won't serialize)
410
+ • Return primitive values, objects, or arrays
411
+
412
+ Example:
413
+ browser_evaluate({ code: 'document.title' })
414
+ browser_evaluate({ code: 'window.location.href' })
415
+ browser_evaluate({ code: '[...document.querySelectorAll("a")].length' })
416
+ `,
417
+
418
+ browser_get_dom: `
419
+ 📖 browser_get_dom(selector?)
420
+
421
+ Get DOM structure of document or specific element.
422
+
423
+ Parameters:
424
+ • selector (string, optional) - Selector for specific element (omit for full document)
425
+
426
+ Returns:
427
+ { content: [{ type: 'text', text: JSON }] }
428
+
429
+ Return Structure:
430
+ {
431
+ outerHTML: string, // Full HTML of element
432
+ textContent: string, // Text content
433
+ attributes: [ // Array of {name, value}
434
+ { name: 'class', value: '...' },
435
+ { name: 'id', value: '...' }
436
+ ],
437
+ children: number // Number of child elements
438
+ }
439
+
440
+ Example:
441
+ browser_get_dom({}) // Entire document
442
+ browser_get_dom({ selector: '.container' }) // Specific element
443
+ `,
444
+
445
+ browser_read_page: `
446
+ 📖 browser_read_page()
447
+
448
+ Get metadata about the current page.
449
+
450
+ Parameters:
451
+ None
452
+
453
+ Returns:
454
+ { content: [{ type: 'text', text: JSON }] }
455
+
456
+ Return Structure:
457
+ {
458
+ title: string, // Page title
459
+ url: string, // Current URL
460
+ viewport: { // Viewport size
461
+ width: number,
462
+ height: number
463
+ },
464
+ contentLength: number // Length of HTML content
465
+ }
466
+
467
+ Example:
468
+ browser_read_page({})
469
+ `,
470
+
471
+ // Media
472
+ browser_get_media_summary: `
473
+ 📖 browser_get_media_summary()
474
+
475
+ Get summary of all audio and video elements on the page.
476
+
477
+ Parameters:
478
+ None
479
+
480
+ Returns:
481
+ { content: [{ type: 'text', text: JSON array }] }
482
+
483
+ Return Structure (array of):
484
+ {
485
+ index: number,
486
+ tagName: 'audio' | 'video',
487
+ id: string | null,
488
+ src: string,
489
+ state: {
490
+ paused: boolean,
491
+ muted: boolean,
492
+ ended: boolean,
493
+ loop: boolean,
494
+ playbackRate: number,
495
+ volume: number
496
+ },
497
+ timing: {
498
+ currentTime: number, // Seconds
499
+ duration: number // Seconds
500
+ },
501
+ buffer: {
502
+ readyState: number,
503
+ buffered: [[start, end], ...] // Buffered time ranges
504
+ },
505
+ videoSpecs: { // Only for video elements
506
+ videoWidth: number,
507
+ videoHeight: number
508
+ }
509
+ }
510
+
511
+ Example:
512
+ browser_get_media_summary({})
513
+ `,
514
+
515
+ browser_get_audio_analysis: `
516
+ 📖 browser_get_audio_analysis(durationMs?, selector?)
517
+
518
+ Analyze audio output from media elements.
519
+
520
+ Parameters:
521
+ • durationMs (number, optional) - Duration to analyze in milliseconds (default: 2000)
522
+ • selector (string, optional) - Selector for specific media element (uses first playing element if omitted)
523
+
524
+ Returns:
525
+ { content: [{ type: 'text', text: JSON }] }
526
+
527
+ Return Structure:
528
+ {
529
+ element: {
530
+ tagName: string,
531
+ id: string,
532
+ src: string
533
+ },
534
+ isSilent: boolean, // true if max volume < 5
535
+ averageVolume: number, // 0-255
536
+ peakVolume: number, // 0-255
537
+ activeFrequencies: [ // Array of active frequency ranges
538
+ 'bass' | 'mid' | 'treble'
539
+ ]
540
+ }
541
+
542
+ ⚠️ Important:
543
+ • Requires CORS headers for cross-origin media
544
+ • May return { error: "Cannot connect to media source: ... (Check CORS headers)" }
545
+ • Samples audio 10 times per second during analysis period
546
+
547
+ Example:
548
+ browser_get_audio_analysis({ durationMs: 2000 })
549
+ browser_get_audio_analysis({ selector: 'video', durationMs: 3000 })
550
+ `,
551
+
552
+ browser_control_media: `
553
+ 📖 browser_control_media(selector, action, value?)
554
+
555
+ Control a media element (play, pause, seek, mute).
556
+
557
+ Parameters:
558
+ • selector (string, required) - Selector for audio/video element
559
+ • action (string, required) - 'play' | 'pause' | 'mute' | 'unmute' | 'seek'
560
+ • value (number, optional) - Time in seconds (required for 'seek' action)
561
+
562
+ Returns:
563
+ { content: [{ type: 'text', text: JSON }] }
564
+
565
+ Return Structure:
566
+ { status: 'playing' | 'paused' | 'muted' | 'unmuted' | 'seeked', newTime?: number }
567
+ or
568
+ { error: string }
569
+
570
+ Example:
571
+ browser_control_media({ selector: 'video', action: 'play' })
572
+ browser_control_media({ selector: 'audio', action: 'seek', value: 30 })
573
+ browser_control_media({ selector: 'video', action: 'mute' })
574
+ `,
575
+
576
+ // Console
577
+ browser_console_start: `
578
+ 📖 browser_console_start(level?)
579
+
580
+ Start capturing browser console logs.
581
+
582
+ Parameters:
583
+ • level (string, optional) - Filter: 'log' | 'error' | 'warn' | 'info' | 'debug' | 'all'
584
+
585
+ Returns:
586
+ { content: [{ type: 'text', text: 'Console logging started...' }] }
587
+
588
+ ⚠️ Important:
589
+ • Stateful: Captures ALL subsequent console output until browser_console_clear is called
590
+ • Logs include timestamp and source location
591
+ • Use browser_console_get to retrieve captured logs
592
+
593
+ Example:
594
+ browser_console_start({})
595
+ browser_console_start({ level: 'error' }) // Only capture errors
596
+ `,
597
+
598
+ browser_console_get: `
599
+ 📖 browser_console_get(filter?)
600
+
601
+ Get all captured console logs.
602
+
603
+ Parameters:
604
+ • filter (string, optional) - Filter by level: 'log' | 'error' | 'warn' | 'info' | 'debug' | 'all'
605
+
606
+ Returns:
607
+ { content: [{ type: 'text', text: 'Formatted log entries...' }] }
608
+
609
+ Return Format:
610
+ 📋 Captured N console logs:
611
+
612
+ 1. ❌ [ERROR] 2025-12-27T10:30:45.123Z
613
+ Error message text
614
+ Location: file.js:42
615
+
616
+ 2. 📝 [LOG] 2025-12-27T10:30:46.456Z
617
+ Log message text
618
+
619
+ ⚠️ Important:
620
+ • Returns empty message if browser_console_start hasn't been called
621
+ • Use filter to narrow down results after capture
622
+
623
+ Example:
624
+ browser_console_get({})
625
+ browser_console_get({ filter: 'error' })
626
+ `,
627
+
628
+ browser_console_clear: `
629
+ 📖 browser_console_clear()
630
+
631
+ Clear all captured console logs and stop listening.
632
+
633
+ Parameters:
634
+ None
635
+
636
+ Returns:
637
+ { content: [{ type: 'text', text: 'Cleared N console logs...' }] }
638
+
639
+ ⚠️ Important:
640
+ • Stops console capture completely
641
+ • Clears all previously captured logs
642
+ • Must call browser_console_start again to resume capture
643
+
644
+ Example:
645
+ browser_console_clear({})
646
+ `,
647
+
648
+ // System
649
+ browser_wait: `
650
+ 📖 browser_wait(ms)
651
+
652
+ Pause execution for a duration.
653
+
654
+ Parameters:
655
+ • ms (number, required) - Milliseconds to wait
656
+
657
+ Returns:
658
+ { content: [{ type: 'text', text: 'Waited <ms>ms' }] }
659
+
660
+ Example:
661
+ browser_wait({ ms: 1000 }) // Wait 1 second
662
+ `,
663
+
664
+ browser_resize_window: `
665
+ 📖 browser_resize_window(width, height)
666
+
667
+ Resize the browser window.
668
+
669
+ Parameters:
670
+ • width (number, required) - Window width in pixels
671
+ • height (number, required) - Window height in pixels
672
+
673
+ Returns:
674
+ { content: [{ type: 'text', text: 'Resized window...' }] }
675
+
676
+ Use Cases:
677
+ • Testing responsive designs
678
+ • Triggering mobile/tablet layouts
679
+ • Capturing screenshots at specific sizes
680
+
681
+ Example:
682
+ browser_resize_window({ width: 375, height: 667 }) // iPhone size
683
+ browser_resize_window({ width: 1920, height: 1080 }) // Full HD
684
+ `,
685
+
686
+ browser_wait_for_selector: `
687
+ 📖 browser_wait_for_selector(selector, timeout?)
688
+
689
+ Wait for an element to appear on the page.
690
+
691
+ Parameters:
692
+ • selector (string, required) - Playwright selector to wait for
693
+ • timeout (number, optional) - Timeout in milliseconds (default: 30000)
694
+
695
+ Returns:
696
+ { content: [{ type: 'text', text: 'Element appeared: <selector>' }] }
697
+
698
+ ⚠️ Important:
699
+ • Throws error if element doesn't appear within timeout
700
+ • Useful after navigation or when waiting for dynamic content
701
+
702
+ Example:
703
+ browser_wait_for_selector({ selector: '.loaded-content' })
704
+ browser_wait_for_selector({ selector: '#modal', timeout: 5000 })
705
+ `,
706
+
707
+ browser_start_video_recording: `
708
+ 📖 browser_start_video_recording(path?)
709
+
710
+ Start recording browser session as video.
711
+
712
+ Parameters:
713
+ • path (string, optional) - Path to save video file
714
+
715
+ Returns:
716
+ { content: [{ type: 'text', text: 'Started video recording...' }] }
717
+
718
+ ⚠️ Important:
719
+ • Records all browser interactions until browser_stop_video_recording is called
720
+ • Must call stop to finalize the video file
721
+
722
+ Example:
723
+ browser_start_video_recording({ path: '/tmp/session.webm' })
724
+ `,
725
+
726
+ browser_stop_video_recording: `
727
+ 📖 browser_stop_video_recording()
728
+
729
+ Stop video recording and save the file.
730
+
731
+ Parameters:
732
+ None
733
+
734
+ Returns:
735
+ { content: [{ type: 'text', text: 'Stopped video recording...' }] }
736
+
737
+ Example:
738
+ browser_stop_video_recording({})
739
+ `,
740
+
741
+ browser_health_check: `
742
+ 📖 browser_health_check()
743
+
744
+ Check browser connection status and environment info.
745
+
746
+ Parameters:
747
+ None
748
+
749
+ Returns:
750
+ { content: [{ type: 'text', text: 'Browser health status...' }] }
751
+
752
+ Information Returned:
753
+ • Connection mode (Antigravity / System Chrome / Playwright Chromium)
754
+ • Browser profile location
755
+ • Current page URL
756
+ • Playwright version
757
+
758
+ Example:
759
+ browser_health_check({})
760
+ `,
761
+
762
+ // ========================================
763
+ // Performance Profiling Tools (CDP)
764
+ // ========================================
765
+
766
+ browser_perf_start_profile: `
767
+ 📖 browser_perf_start_profile(sampleInterval?)
768
+
769
+ Start CPU profiling to track JavaScript execution performance.
770
+
771
+ Parameters:
772
+ • sampleInterval (number, optional) - Microseconds between samples (default: 100)
773
+
774
+ Returns:
775
+ { content: [{ type: 'text', text: 'CPU profiling started...' }] }
776
+
777
+ Behavior:
778
+ • Uses Chrome DevTools Protocol Profiler domain
779
+ • Captures JavaScript call stacks at regular intervals
780
+ • Must call browser_perf_stop_profile to get results
781
+ • Profiling remains active across page navigations
782
+
783
+ ⚠️ Important:
784
+ • Profiling adds performance overhead
785
+ • Profile data can be very large (10,000+ nodes for complex apps)
786
+ • Use for debugging/optimization, not production monitoring
787
+ • Only one profile session can be active at a time
788
+
789
+ Example:
790
+ browser_perf_start_profile({})
791
+ browser_perf_start_profile({ sampleInterval: 50 }) // More granular sampling
792
+ `,
793
+
794
+ browser_perf_stop_profile: `
795
+ 📖 browser_perf_stop_profile()
796
+
797
+ Stop CPU profiling and get profile data with summary statistics.
798
+
799
+ Parameters:
800
+ None
801
+
802
+ Returns:
803
+ { content: [{ type: 'text', text: 'CPU Profile Results: {...summary...}' }] }
804
+
805
+ Return Structure:
806
+ {
807
+ totalNodes: number,
808
+ totalSamples: number,
809
+ durationMicroseconds: number,
810
+ durationMs: string,
811
+ topFunctions: [
812
+ { function: string, url: string, line: number }
813
+ ]
814
+ }
815
+
816
+ ⚠️ Important:
817
+ • Must call browser_perf_start_profile first
818
+ • Returns summarized data - full profile too large to display
819
+ • Top 15 functions shown by default
820
+ • Use Chrome DevTools for detailed profile analysis
821
+
822
+ Example:
823
+ browser_perf_stop_profile({})
824
+ `,
825
+
826
+ browser_perf_take_heap_snapshot: `
827
+ 📖 browser_perf_take_heap_snapshot(reportProgress?)
828
+
829
+ Capture a heap snapshot for memory analysis and leak detection.
830
+
831
+ Parameters:
832
+ • reportProgress (boolean, optional) - Report progress events (default: false)
833
+
834
+ Returns:
835
+ { content: [{ type: 'text', text: 'Heap Snapshot Captured: X KB...' }] }
836
+
837
+ Return Structure:
838
+ {
839
+ size: string, // In KB
840
+ chunks: number
841
+ }
842
+
843
+ ⚠️ Important:
844
+ • Snapshot can be very large (10+ MB for complex apps)
845
+ • May freeze browser briefly during capture
846
+ • Full snapshot data not returned (use Chrome DevTools to analyze)
847
+ • Useful for detecting memory leaks
848
+
849
+ Example:
850
+ browser_perf_take_heap_snapshot({})
851
+ browser_perf_take_heap_snapshot({ reportProgress: true })
852
+ `,
853
+
854
+ browser_perf_get_heap_usage: `
855
+ 📖 browser_perf_get_heap_usage()
856
+
857
+ Get current JavaScript heap usage statistics.
858
+
859
+ Parameters:
860
+ None
861
+
862
+ Returns:
863
+ { content: [{ type: 'text', text: 'JavaScript Heap Usage: {...}' }] }
864
+
865
+ Return Structure:
866
+ {
867
+ usedSize: number, // Bytes
868
+ usedSizeMB: string,
869
+ totalSize: number, // Bytes
870
+ totalSizeMB: string,
871
+ limit: number, // Max heap size
872
+ limitMB: string,
873
+ usagePercent: string
874
+ }
875
+
876
+ Use Case:
877
+ • Monitor memory usage in real-time
878
+ • Detect potential memory leaks
879
+ • Track memory growth over time
880
+
881
+ Example:
882
+ browser_perf_get_heap_usage({})
883
+ `,
884
+
885
+ browser_perf_get_metrics: `
886
+ 📖 browser_perf_get_metrics()
887
+
888
+ Get runtime performance metrics (DOM nodes, event listeners, JS heap).
889
+
890
+ Parameters:
891
+ None
892
+
893
+ Returns:
894
+ { content: [{ type: 'text', text: 'Runtime Performance Metrics: [...]' }] }
895
+
896
+ Return Structure:
897
+ [
898
+ { name: 'Timestamp', value: number },
899
+ { name: 'Documents', value: number },
900
+ { name: 'Frames', value: number },
901
+ { name: 'JSEventListeners', value: number },
902
+ { name: 'Nodes', value: number },
903
+ { name: 'LayoutCount', value: number },
904
+ { name: 'RecalcStyleCount', value: number },
905
+ { name: 'JSHeapUsedSize', value: number },
906
+ { name: 'JSHeapTotalSize', value: number }
907
+ ]
908
+
909
+ Use Case:
910
+ • Track DOM complexity
911
+ • Monitor event listener count
912
+ • Measure layout/style recalculations
913
+
914
+ Example:
915
+ browser_perf_get_metrics({})
916
+ `,
917
+
918
+ browser_perf_get_performance_metrics: `
919
+ 📖 browser_perf_get_performance_metrics()
920
+
921
+ Get web vitals and navigation timing (FCP, LCP, CLS, TTFB).
922
+
923
+ Parameters:
924
+ None
925
+
926
+ Returns:
927
+ { content: [{ type: 'text', text: 'Web Performance Metrics: {...}' }] }
928
+
929
+ Return Structure:
930
+ {
931
+ navigation: {
932
+ domContentLoaded: number, // ms
933
+ loadComplete: number,
934
+ domInteractive: number,
935
+ ttfb: number // Time to First Byte
936
+ },
937
+ paint: {
938
+ 'first-paint': number,
939
+ 'first-contentful-paint': number
940
+ },
941
+ webVitals: {
942
+ lcp: number, // Largest Contentful Paint
943
+ cls: number // Cumulative Layout Shift
944
+ }
945
+ }
946
+
947
+ ⚠️ Note:
948
+ • Some metrics may not be available depending on page state
949
+ • Web vitals require user interaction for accuracy
950
+ • Metrics based on Performance API
951
+
952
+ Example:
953
+ browser_perf_get_performance_metrics({})
954
+ `,
955
+
956
+ browser_perf_start_coverage: `
957
+ 📖 browser_perf_start_coverage(resetOnNavigation?)
958
+
959
+ Start tracking CSS and JavaScript code coverage.
960
+
961
+ Parameters:
962
+ • resetOnNavigation (boolean, optional) - Reset coverage on navigation (default: true)
963
+
964
+ Returns:
965
+ { content: [{ type: 'text', text: 'Code coverage started...' }] }
966
+
967
+ Behavior:
968
+ • Tracks which CSS rules and JS code are executed
969
+ • Helps identify unused code for optimization
970
+ • Must call browser_perf_stop_coverage to get results
971
+
972
+ Use Case:
973
+ • Find unused CSS/JS for code splitting
974
+ • Optimize bundle size
975
+ • Identify dead code
976
+
977
+ Example:
978
+ browser_perf_start_coverage({})
979
+ browser_perf_start_coverage({ resetOnNavigation: false })
980
+ `,
981
+
982
+ browser_perf_stop_coverage: `
983
+ 📖 browser_perf_stop_coverage()
984
+
985
+ Stop coverage tracking and get results showing used vs unused code.
986
+
987
+ Parameters:
988
+ None
989
+
990
+ Returns:
991
+ { content: [{ type: 'text', text: 'Code Coverage Results: {...}' }] }
992
+
993
+ Return Structure:
994
+ {
995
+ javascript: {
996
+ filesAnalyzed: number,
997
+ topFiles: [
998
+ { url: string, usedBytes: number, totalBytes: number, coverage: string }
999
+ ]
1000
+ },
1001
+ css: {
1002
+ rulesAnalyzed: number,
1003
+ topRules: [
1004
+ { used: boolean, styleSheetId: string, ... }
1005
+ ]
1006
+ }
1007
+ }
1008
+
1009
+ ⚠️ Important:
1010
+ • Must call browser_perf_start_coverage first
1011
+ • Shows top 10 files by default
1012
+ • Full coverage data available via CDP
1013
+
1014
+ Example:
1015
+ browser_perf_stop_coverage({})
1016
+ `,
1017
+
1018
+ // ========================================
1019
+ // Network Analysis Tools (CDP)
1020
+ // ========================================
1021
+
1022
+ browser_net_start_monitoring: `
1023
+ 📖 browser_net_start_monitoring(patterns?)
1024
+
1025
+ Start monitoring network requests with detailed timing.
1026
+
1027
+ Parameters:
1028
+ • patterns (array, optional) - URL patterns to monitor (default: all)
1029
+
1030
+ Returns:
1031
+ { content: [{ type: 'text', text: 'Network monitoring started...' }] }
1032
+
1033
+ Behavior:
1034
+ • Captures all network requests and responses
1035
+ • Records detailed timing information
1036
+ • Tracks WebSocket frames
1037
+ • Limited to 500 requests to prevent memory issues
1038
+
1039
+ Use Case:
1040
+ • Debug API calls
1041
+ • Analyze network performance
1042
+ • Inspect request/response details
1043
+
1044
+ Example:
1045
+ browser_net_start_monitoring({})
1046
+ browser_net_start_monitoring({ patterns: ['https://api.example.com/*'] })
1047
+ `,
1048
+
1049
+ browser_net_get_requests: `
1050
+ 📖 browser_net_get_requests(filter?)
1051
+
1052
+ Get captured network requests with timing breakdown.
1053
+
1054
+ Parameters:
1055
+ • filter (string, optional) - Filter by URL substring
1056
+
1057
+ Returns:
1058
+ { content: [{ type: 'text', text: 'Network Requests: {...}' }] }
1059
+
1060
+ Return Structure:
1061
+ {
1062
+ totalCaptured: number,
1063
+ filtered: number,
1064
+ requests: [
1065
+ {
1066
+ method: string,
1067
+ url: string,
1068
+ status: number,
1069
+ type: string,
1070
+ size: string,
1071
+ timing: string,
1072
+ failed: boolean,
1073
+ fromCache: boolean
1074
+ }
1075
+ ]
1076
+ }
1077
+
1078
+ ⚠️ Important:
1079
+ • Must call browser_net_start_monitoring first
1080
+ • Limited to 50 requests in output for readability
1081
+ • Use filter parameter to narrow results
1082
+
1083
+ Example:
1084
+ browser_net_get_requests({})
1085
+ browser_net_get_requests({ filter: 'api' })
1086
+ `,
1087
+
1088
+ browser_net_stop_monitoring: `
1089
+ 📖 browser_net_stop_monitoring()
1090
+
1091
+ Stop network monitoring and clear request log.
1092
+
1093
+ Parameters:
1094
+ None
1095
+
1096
+ Returns:
1097
+ { content: [{ type: 'text', text: 'Network monitoring stopped. Captured X requests...' }] }
1098
+
1099
+ Behavior:
1100
+ • Disables network tracking
1101
+ • Clears all captured requests
1102
+ • Removes event listeners
1103
+
1104
+ Example:
1105
+ browser_net_stop_monitoring({})
1106
+ `,
1107
+
1108
+ browser_net_export_har: `
1109
+ 📖 browser_net_export_har(includeContent?)
1110
+
1111
+ Export full network activity log in HAR (HTTP Archive) format.
1112
+
1113
+ Parameters:
1114
+ • includeContent (boolean, optional) - Include response bodies (default: false)
1115
+
1116
+ Returns:
1117
+ { content: [{ type: 'text', text: 'HAR Export: {...}' }] }
1118
+
1119
+ Return Structure:
1120
+ {
1121
+ log: {
1122
+ version: '1.2',
1123
+ creator: { name: string, version: string },
1124
+ entries: [
1125
+ {
1126
+ startedDateTime: string,
1127
+ time: number,
1128
+ request: { method: string, url: string, headers: [...] },
1129
+ response: { status: number, headers: [...], content: {...} },
1130
+ timings: { send: number, wait: number, receive: number }
1131
+ }
1132
+ ]
1133
+ }
1134
+ }
1135
+
1136
+ ⚠️ Important:
1137
+ • Must have network monitoring active
1138
+ • HAR data can be very large
1139
+ • Compatible with HAR viewers and analysis tools
1140
+
1141
+ Example:
1142
+ browser_net_export_har({})
1143
+ browser_net_export_har({ includeContent: true })
1144
+ `,
1145
+
1146
+ browser_net_get_websocket_frames: `
1147
+ 📖 browser_net_get_websocket_frames(requestId)
1148
+
1149
+ Get WebSocket frames for inspecting real-time communication.
1150
+
1151
+ Parameters:
1152
+ • requestId (string, required) - Request ID from network monitoring
1153
+
1154
+ Returns:
1155
+ { content: [{ type: 'text', text: 'WebSocket Frames: [...]' }] }
1156
+
1157
+ Return Structure:
1158
+ [
1159
+ {
1160
+ direction: 'sent' | 'received',
1161
+ opcode: number,
1162
+ payloadLength: number,
1163
+ payload: string, // First 100 chars
1164
+ timestamp: string
1165
+ }
1166
+ ]
1167
+
1168
+ Use Case:
1169
+ • Debug WebSocket communication
1170
+ • Inspect real-time message flow
1171
+ • Analyze WebSocket protocols
1172
+
1173
+ Example:
1174
+ browser_net_get_websocket_frames({ requestId: '1234.5' })
1175
+ `,
1176
+
1177
+ browser_net_set_request_blocking: `
1178
+ 📖 browser_net_set_request_blocking(patterns)
1179
+
1180
+ Block requests matching URL patterns.
1181
+
1182
+ Parameters:
1183
+ • patterns (array, required) - URL patterns to block (e.g., ["*.jpg", "*analytics*"])
1184
+
1185
+ Returns:
1186
+ { content: [{ type: 'text', text: 'Request blocking enabled...' }] }
1187
+
1188
+ Behavior:
1189
+ • Blocks requests before they're sent
1190
+ • Supports wildcard patterns
1191
+ • Useful for testing without certain resources
1192
+
1193
+ Use Case:
1194
+ • Block ads and trackers
1195
+ • Test page without images
1196
+ • Simulate missing resources
1197
+
1198
+ Example:
1199
+ browser_net_set_request_blocking({ patterns: ['*.jpg', '*.png'] })
1200
+ browser_net_set_request_blocking({ patterns: ['*analytics*', '*tracking*'] })
1201
+ `,
1202
+
1203
+ browser_net_emulate_conditions: `
1204
+ 📖 browser_net_emulate_conditions(offline, latency, downloadThroughput, uploadThroughput)
1205
+
1206
+ Emulate network conditions (throttling).
1207
+
1208
+ Parameters:
1209
+ • offline (boolean, required) - Emulate offline mode
1210
+ • latency (number, required) - Round-trip latency in ms
1211
+ • downloadThroughput (number, required) - Download speed in bytes/second (-1 for unlimited)
1212
+ • uploadThroughput (number, required) - Upload speed in bytes/second (-1 for unlimited)
1213
+
1214
+ Returns:
1215
+ { content: [{ type: 'text', text: 'Network conditions applied: {...}' }] }
1216
+
1217
+ Common Presets:
1218
+ • Fast 3G: { offline: false, latency: 562.5, downloadThroughput: 180000, uploadThroughput: 84000 }
1219
+ • Slow 3G: { offline: false, latency: 2000, downloadThroughput: 50000, uploadThroughput: 50000 }
1220
+ • Offline: { offline: true, latency: 0, downloadThroughput: 0, uploadThroughput: 0 }
1221
+
1222
+ Use Case:
1223
+ • Test on slow connections
1224
+ • Simulate offline behavior
1225
+ • Performance testing
1226
+
1227
+ Example:
1228
+ browser_net_emulate_conditions({ offline: false, latency: 100, downloadThroughput: 1000000, uploadThroughput: 500000 })
1229
+ `,
1230
+
1231
+ // ========================================
1232
+ // Security Testing Tools (CDP)
1233
+ // ========================================
1234
+
1235
+ browser_sec_get_security_headers: `
1236
+ 📖 browser_sec_get_security_headers()
1237
+
1238
+ Inspect security-related HTTP headers.
1239
+
1240
+ Parameters:
1241
+ None
1242
+
1243
+ Returns:
1244
+ { content: [{ type: 'text', text: 'Security Headers: {...}' }] }
1245
+
1246
+ Return Structure:
1247
+ {
1248
+ 'content-security-policy': string,
1249
+ 'strict-transport-security': string,
1250
+ 'x-frame-options': string,
1251
+ 'x-content-type-options': string,
1252
+ 'referrer-policy': string,
1253
+ 'permissions-policy': string
1254
+ }
1255
+
1256
+ Use Case:
1257
+ • Security audits
1258
+ • Verify CSP configuration
1259
+ • Check HTTPS enforcement
1260
+
1261
+ ⚠️ Note:
1262
+ • May require network monitoring for some headers
1263
+ • Shows 'Not set' for missing headers
1264
+
1265
+ Example:
1266
+ browser_sec_get_security_headers({})
1267
+ `,
1268
+
1269
+ browser_sec_get_certificate_info: `
1270
+ 📖 browser_sec_get_certificate_info()
1271
+
1272
+ Get TLS/SSL certificate details for HTTPS sites.
1273
+
1274
+ Parameters:
1275
+ None
1276
+
1277
+ Returns:
1278
+ { content: [{ type: 'text', text: 'Certificate Information: {...}' }] }
1279
+
1280
+ ⚠️ Important:
1281
+ • Only works on HTTPS pages
1282
+ • Returns error on HTTP pages
1283
+ • Detailed certificate info requires monitoring during page load
1284
+
1285
+ Use Case:
1286
+ • Verify certificate validity
1287
+ • Check TLS configuration
1288
+ • Security compliance testing
1289
+
1290
+ Example:
1291
+ browser_sec_get_certificate_info({})
1292
+ `,
1293
+
1294
+ browser_sec_detect_mixed_content: `
1295
+ 📖 browser_sec_detect_mixed_content()
1296
+
1297
+ Detect mixed content warnings (HTTPS page loading HTTP resources).
1298
+
1299
+ Parameters:
1300
+ None
1301
+
1302
+ Returns:
1303
+ { content: [{ type: 'text', text: 'Mixed Content Detected: {...}' }] }
1304
+
1305
+ Return Structure:
1306
+ {
1307
+ total: number,
1308
+ blocked: number,
1309
+ issues: [
1310
+ { url: string, type: 'script' | 'image' | 'stylesheet', blocked: boolean }
1311
+ ]
1312
+ }
1313
+
1314
+ ⚠️ Important:
1315
+ • Only applies to HTTPS pages
1316
+ • Scripts are usually blocked by browser
1317
+ • Images/stylesheets may load with warning
1318
+
1319
+ Use Case:
1320
+ • Security audits
1321
+ • HTTPS migration testing
1322
+ • Find insecure resources
1323
+
1324
+ Example:
1325
+ browser_sec_detect_mixed_content({})
1326
+ `,
1327
+
1328
+ browser_sec_start_csp_monitoring: `
1329
+ 📖 browser_sec_start_csp_monitoring()
1330
+
1331
+ Monitor Content Security Policy violations.
1332
+
1333
+ Parameters:
1334
+ None
1335
+
1336
+ Returns:
1337
+ { content: [{ type: 'text', text: 'CSP violation monitoring started...' }] }
1338
+
1339
+ Behavior:
1340
+ • Captures CSP violation console messages
1341
+ • Must call browser_sec_get_csp_violations to view
1342
+ • Call browser_sec_stop_csp_monitoring to stop
1343
+
1344
+ Use Case:
1345
+ • Debug CSP configuration
1346
+ • Find policy violations
1347
+ • Security testing
1348
+
1349
+ Example:
1350
+ browser_sec_start_csp_monitoring({})
1351
+ `,
1352
+
1353
+ browser_sec_get_csp_violations: `
1354
+ 📖 browser_sec_get_csp_violations()
1355
+
1356
+ Get captured CSP violations.
1357
+
1358
+ Parameters:
1359
+ None
1360
+
1361
+ Returns:
1362
+ { content: [{ type: 'text', text: 'CSP Violations: {...}' }] }
1363
+
1364
+ Return Structure:
1365
+ {
1366
+ total: number,
1367
+ violations: [
1368
+ {
1369
+ timestamp: string,
1370
+ message: string,
1371
+ level: string,
1372
+ source: string
1373
+ }
1374
+ ]
1375
+ }
1376
+
1377
+ ⚠️ Important:
1378
+ • Must call browser_sec_start_csp_monitoring first
1379
+ • Violations captured in real-time
1380
+
1381
+ Example:
1382
+ browser_sec_get_csp_violations({})
1383
+ `,
1384
+
1385
+ browser_sec_stop_csp_monitoring: `
1386
+ 📖 browser_sec_stop_csp_monitoring()
1387
+
1388
+ Stop CSP monitoring and clear violations.
1389
+
1390
+ Parameters:
1391
+ None
1392
+
1393
+ Returns:
1394
+ { content: [{ type: 'text', text: 'CSP monitoring stopped. Captured X violations...' }] }
1395
+
1396
+ Behavior:
1397
+ • Stops monitoring
1398
+ • Clears violation log
1399
+ • Removes event listeners
1400
+
1401
+ Example:
1402
+ browser_sec_stop_csp_monitoring({})
1403
+ `,
1404
+
1405
+ // ========================================
1406
+ // Storage & Service Workers Tools (CDP)
1407
+ // ========================================
1408
+
1409
+ browser_storage_get_indexeddb: `
1410
+ 📖 browser_storage_get_indexeddb(databaseName?, objectStoreName?)
1411
+
1412
+ Inspect IndexedDB databases and their data.
1413
+
1414
+ Parameters:
1415
+ • databaseName (string, optional) - Specific database to inspect
1416
+ • objectStoreName (string, optional) - Specific object store to query (requires databaseName)
1417
+
1418
+ Returns:
1419
+ { content: [{ type: 'text', text: 'IndexedDB Databases/Data: {...}' }] }
1420
+
1421
+ Return Structure (no params):
1422
+ { origin: string, databases: string[] }
1423
+
1424
+ Return Structure (databaseName only):
1425
+ {
1426
+ name: string,
1427
+ version: number,
1428
+ objectStores: [
1429
+ { name: string, keyPath: any, autoIncrement: boolean, indexes: [...] }
1430
+ ]
1431
+ }
1432
+
1433
+ Return Structure (both params):
1434
+ {
1435
+ objectStore: string,
1436
+ entries: number,
1437
+ hasMore: boolean,
1438
+ data: [ { key: any, primaryKey: any, value: any } ]
1439
+ }
1440
+
1441
+ ⚠️ Important:
1442
+ • Limited to 100 entries per query
1443
+ • May require page to have used IndexedDB first
1444
+
1445
+ Example:
1446
+ browser_storage_get_indexeddb({})
1447
+ browser_storage_get_indexeddb({ databaseName: 'myDB' })
1448
+ browser_storage_get_indexeddb({ databaseName: 'myDB', objectStoreName: 'users' })
1449
+ `,
1450
+
1451
+ browser_storage_get_cache_storage: `
1452
+ 📖 browser_storage_get_cache_storage(cacheName?)
1453
+
1454
+ List Cache Storage API caches and their entries.
1455
+
1456
+ Parameters:
1457
+ • cacheName (string, optional) - Specific cache to inspect
1458
+
1459
+ Returns:
1460
+ { content: [{ type: 'text', text: 'Cache Storage Caches/Entries: {...}' }] }
1461
+
1462
+ Return Structure (no cacheName):
1463
+ { origin: string, caches: string[] }
1464
+
1465
+ Return Structure (with cacheName):
1466
+ {
1467
+ cacheName: string,
1468
+ entryCount: number,
1469
+ entries: [
1470
+ {
1471
+ requestURL: string,
1472
+ requestMethod: string,
1473
+ responseStatus: number,
1474
+ responseType: string
1475
+ }
1476
+ ]
1477
+ }
1478
+
1479
+ ⚠️ Important:
1480
+ • Limited to 50 entries per cache
1481
+ • Requires page to use Cache Storage API
1482
+
1483
+ Example:
1484
+ browser_storage_get_cache_storage({})
1485
+ browser_storage_get_cache_storage({ cacheName: 'my-cache-v1' })
1486
+ `,
1487
+
1488
+ browser_storage_delete_cache: `
1489
+ 📖 browser_storage_delete_cache(cacheName)
1490
+
1491
+ Delete a specific cache from Cache Storage.
1492
+
1493
+ Parameters:
1494
+ • cacheName (string, required) - Cache name to delete
1495
+
1496
+ Returns:
1497
+ { content: [{ type: 'text', text: 'Cache deleted successfully: ...' }] }
1498
+
1499
+ ⚠️ Warning:
1500
+ • This permanently deletes the cache
1501
+ • Cannot be undone
1502
+ • May affect offline functionality
1503
+
1504
+ Example:
1505
+ browser_storage_delete_cache({ cacheName: 'old-cache-v1' })
1506
+ `,
1507
+
1508
+ browser_storage_get_service_workers: `
1509
+ 📖 browser_storage_get_service_workers()
1510
+
1511
+ Get service worker registrations and their state.
1512
+
1513
+ Parameters:
1514
+ None
1515
+
1516
+ Returns:
1517
+ { content: [{ type: 'text', text: 'Service Workers: {...}' }] }
1518
+
1519
+ Return Structure:
1520
+ [
1521
+ {
1522
+ scope: string,
1523
+ active: { scriptURL: string, state: string },
1524
+ installing: { scriptURL: string, state: string },
1525
+ waiting: { scriptURL: string, state: string }
1526
+ }
1527
+ ]
1528
+
1529
+ States:
1530
+ • installing - Being installed
1531
+ • installed - Installed, waiting to activate
1532
+ • activating - Being activated
1533
+ • activated - Active and running
1534
+ • redundant - Replaced by newer version
1535
+
1536
+ Example:
1537
+ browser_storage_get_service_workers({})
1538
+ `,
1539
+
1540
+ browser_storage_unregister_service_worker: `
1541
+ 📖 browser_storage_unregister_service_worker(scopeURL)
1542
+
1543
+ Unregister a service worker.
1544
+
1545
+ Parameters:
1546
+ • scopeURL (string, required) - Scope URL of service worker to unregister
1547
+
1548
+ Returns:
1549
+ { content: [{ type: 'text', text: 'Service worker unregistered successfully...' }] }
1550
+
1551
+ ⚠️ Warning:
1552
+ • This removes the service worker registration
1553
+ • May affect offline functionality
1554
+ • Page may need reload to take effect
1555
+
1556
+ Example:
1557
+ browser_storage_unregister_service_worker({ scopeURL: 'https://example.com/' })
1558
+ `
1559
+ };
1560
+
1561
+ const handlers = {
1562
+ browser_docs: async (args) => {
1563
+ const toolName = args.toolName;
1564
+
1565
+ if (!toolName) {
1566
+ const toolList = Object.keys(toolDocs).sort().join('\n • ');
1567
+ return {
1568
+ content: [{
1569
+ type: 'text',
1570
+ text: `📚 Browser Tools Documentation
1571
+
1572
+ Available tools:
1573
+ • ${toolList}
1574
+
1575
+ Usage:
1576
+ browser_docs({ toolName: 'browser_navigate' })
1577
+
1578
+ Tip: Tool names use the prefix 'browser_' followed by the action.`
1579
+ }]
1580
+ };
1581
+ }
1582
+
1583
+ const doc = toolDocs[toolName];
1584
+
1585
+ if (!doc) {
1586
+ const suggestions = Object.keys(toolDocs)
1587
+ .filter(name => name.includes(toolName.replace('browser_', '')))
1588
+ .slice(0, 5);
1589
+
1590
+ return {
1591
+ content: [{
1592
+ type: 'text',
1593
+ text: `❌ No documentation found for '${toolName}'
1594
+
1595
+ ${suggestions.length > 0 ? `Did you mean:\n • ${suggestions.join('\n • ')}` : ''}
1596
+
1597
+ Use browser_docs({}) to see all available tools.`
1598
+ }]
1599
+ };
1600
+ }
1601
+
1602
+ return {
1603
+ content: [{
1604
+ type: 'text',
1605
+ text: doc.trim()
1606
+ }]
1607
+ };
1608
+ }
1609
+ };
1610
+
1611
+ module.exports = { definitions, handlers };