mcp-web-inspector 0.1.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 (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1017 -0
  3. package/dist/evals/evals.d.ts +5 -0
  4. package/dist/evals/evals.js +41 -0
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.js +62 -0
  7. package/dist/requestHandler.d.ts +3 -0
  8. package/dist/requestHandler.js +53 -0
  9. package/dist/toolHandler.d.ts +91 -0
  10. package/dist/toolHandler.js +725 -0
  11. package/dist/tools/api/base.d.ts +33 -0
  12. package/dist/tools/api/base.js +49 -0
  13. package/dist/tools/api/index.d.ts +2 -0
  14. package/dist/tools/api/index.js +3 -0
  15. package/dist/tools/api/requests.d.ts +47 -0
  16. package/dist/tools/api/requests.js +168 -0
  17. package/dist/tools/browser/base.d.ts +51 -0
  18. package/dist/tools/browser/base.js +111 -0
  19. package/dist/tools/browser/cleanSession.d.ts +10 -0
  20. package/dist/tools/browser/cleanSession.js +42 -0
  21. package/dist/tools/browser/comparePositions.d.ts +11 -0
  22. package/dist/tools/browser/comparePositions.js +149 -0
  23. package/dist/tools/browser/computedStyles.d.ts +11 -0
  24. package/dist/tools/browser/computedStyles.js +128 -0
  25. package/dist/tools/browser/console.d.ts +37 -0
  26. package/dist/tools/browser/console.js +106 -0
  27. package/dist/tools/browser/elementExists.d.ts +9 -0
  28. package/dist/tools/browser/elementExists.js +57 -0
  29. package/dist/tools/browser/elementInspection.d.ts +21 -0
  30. package/dist/tools/browser/elementInspection.js +151 -0
  31. package/dist/tools/browser/elementPosition.d.ts +11 -0
  32. package/dist/tools/browser/elementPosition.js +107 -0
  33. package/dist/tools/browser/elementVisibility.d.ts +12 -0
  34. package/dist/tools/browser/elementVisibility.js +224 -0
  35. package/dist/tools/browser/findByText.d.ts +13 -0
  36. package/dist/tools/browser/findByText.js +207 -0
  37. package/dist/tools/browser/getRequestDetails.d.ts +9 -0
  38. package/dist/tools/browser/getRequestDetails.js +137 -0
  39. package/dist/tools/browser/getTestIds.d.ts +12 -0
  40. package/dist/tools/browser/getTestIds.js +148 -0
  41. package/dist/tools/browser/index.d.ts +7 -0
  42. package/dist/tools/browser/index.js +7 -0
  43. package/dist/tools/browser/inspectDom.d.ts +12 -0
  44. package/dist/tools/browser/inspectDom.js +447 -0
  45. package/dist/tools/browser/interaction.d.ts +104 -0
  46. package/dist/tools/browser/interaction.js +259 -0
  47. package/dist/tools/browser/listNetworkRequests.d.ts +10 -0
  48. package/dist/tools/browser/listNetworkRequests.js +74 -0
  49. package/dist/tools/browser/measureElement.d.ts +9 -0
  50. package/dist/tools/browser/measureElement.js +139 -0
  51. package/dist/tools/browser/navigation.d.ts +38 -0
  52. package/dist/tools/browser/navigation.js +109 -0
  53. package/dist/tools/browser/output.d.ts +11 -0
  54. package/dist/tools/browser/output.js +29 -0
  55. package/dist/tools/browser/querySelectorAll.d.ts +12 -0
  56. package/dist/tools/browser/querySelectorAll.js +201 -0
  57. package/dist/tools/browser/response.d.ts +29 -0
  58. package/dist/tools/browser/response.js +67 -0
  59. package/dist/tools/browser/screenshot.d.ts +16 -0
  60. package/dist/tools/browser/screenshot.js +70 -0
  61. package/dist/tools/browser/useragent.d.ts +15 -0
  62. package/dist/tools/browser/useragent.js +32 -0
  63. package/dist/tools/browser/visiblePage.d.ts +20 -0
  64. package/dist/tools/browser/visiblePage.js +170 -0
  65. package/dist/tools/browser/waitForElement.d.ts +10 -0
  66. package/dist/tools/browser/waitForElement.js +38 -0
  67. package/dist/tools/browser/waitForNetworkIdle.d.ts +8 -0
  68. package/dist/tools/browser/waitForNetworkIdle.js +32 -0
  69. package/dist/tools/codegen/generator.d.ts +21 -0
  70. package/dist/tools/codegen/generator.js +158 -0
  71. package/dist/tools/codegen/index.d.ts +11 -0
  72. package/dist/tools/codegen/index.js +187 -0
  73. package/dist/tools/codegen/recorder.d.ts +14 -0
  74. package/dist/tools/codegen/recorder.js +62 -0
  75. package/dist/tools/codegen/types.d.ts +28 -0
  76. package/dist/tools/codegen/types.js +1 -0
  77. package/dist/tools/common/types.d.ts +17 -0
  78. package/dist/tools/common/types.js +20 -0
  79. package/dist/tools/index.d.ts +2 -0
  80. package/dist/tools/index.js +2 -0
  81. package/dist/tools.d.ts +557 -0
  82. package/dist/tools.js +554 -0
  83. package/dist/types.d.ts +16 -0
  84. package/dist/types.js +1 -0
  85. package/package.json +60 -0
package/README.md ADDED
@@ -0,0 +1,1017 @@
1
+ # Web Inspector MCP 🔍
2
+
3
+ > **Give LLMs visual superpowers to see, debug, and test any web page.**
4
+
5
+ A Model Context Protocol (MCP) server that provides comprehensive web inspection and debugging capabilities. Built on Playwright, it enables AI assistants to deeply understand web page structure, debug element visibility issues, validate layouts, and inspect DOM in real browser environments.
6
+
7
+ ## Why Web Inspector MCP?
8
+
9
+ Modern web applications are complex. Elements are hidden, layouts break, selectors fail, and debugging feels like detective work. **Web Inspector MCP** gives your AI assistant the tools to:
10
+
11
+ - 🔍 **Understand any page structure** - Progressive DOM inspection that drills through wrapper divs to find semantic elements
12
+ - 🎯 **Debug visibility issues** - Detailed diagnostics showing exactly why clicks fail (clipped, covered, scrolled out of view)
13
+ - 📐 **Validate layouts** - Compare element positions to ensure consistent alignment and spacing
14
+ - 🧪 **Test selector reliability** - See all matching elements with their visibility status before writing tests
15
+ - 🎨 **Inspect styles** - Get computed CSS to understand why elements behave unexpectedly
16
+ - 📝 **Find elements without IDs** - Locate elements by text content when test IDs aren't available
17
+
18
+ ## Perfect For
19
+
20
+ - **QA Engineers** - Debug failing automated tests and understand why selectors break
21
+ - **Frontend Developers** - Investigate layout issues and CSS problems across browsers
22
+ - **Test Automation** - Build robust selectors and validate page structure before writing tests
23
+ - **Accessibility Audits** - Inspect ARIA roles, semantic HTML, and element visibility
24
+ - **Web Scraping** - Understand page structure and find the right selectors for data extraction
25
+
26
+ ## Installation
27
+
28
+ **No manual installation required!** Your AI coding assistant will automatically install the server via `npx` when configured.
29
+
30
+ If you prefer global installation for faster startup:
31
+ ```bash
32
+ npm install -g mcp-web-inspector
33
+ ```
34
+
35
+ ---
36
+
37
+ ## AI Tool Setup
38
+
39
+ All configurations below use `npx` which automatically downloads and runs the latest version. Click to expand installation instructions for your AI tool:
40
+
41
+ <details>
42
+ <summary><b>🤖 Claude Code (CLI)</b></summary>
43
+
44
+ ### Installation via CLI
45
+
46
+ ```bash
47
+ # Add MCP server using Claude Code CLI
48
+ claude mcp add web-inspector --scope user -- npx -y mcp-web-inspector
49
+
50
+ # Verify installation
51
+ claude mcp list
52
+ ```
53
+
54
+ ### Manual Configuration
55
+
56
+ Edit `~/.config/claude/mcp.json` (Linux/macOS) or `%APPDATA%\Claude\mcp.json` (Windows):
57
+
58
+ ```json
59
+ {
60
+ "mcpServers": {
61
+ "web-inspector": {
62
+ "command": "npx",
63
+ "args": ["-y", "mcp-web-inspector"]
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ After installation, restart Claude Code to load the server.
70
+
71
+ </details>
72
+
73
+ <details>
74
+ <summary><b>💻 Claude Desktop</b></summary>
75
+
76
+ ### Configuration File Location
77
+
78
+ - **MacOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
79
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
80
+ - **Linux**: `~/.config/Claude/claude_desktop_config.json`
81
+
82
+ ### Add to Configuration
83
+
84
+ ```json
85
+ {
86
+ "mcpServers": {
87
+ "web-inspector": {
88
+ "command": "npx",
89
+ "args": ["-y", "mcp-web-inspector"]
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ Restart Claude Desktop after saving the configuration.
96
+
97
+ </details>
98
+
99
+ <details>
100
+ <summary><b>🔷 VS Code with GitHub Copilot</b></summary>
101
+
102
+ ### Prerequisites
103
+
104
+ - VS Code version 1.101 or later
105
+ - GitHub Copilot extension installed
106
+
107
+ ### Installation via CLI
108
+
109
+ ```bash
110
+ # VS Code Stable
111
+ code --add-mcp '{"name":"web-inspector","command":"npx","args":["mcp-web-inspector"]}'
112
+
113
+ # VS Code Insiders
114
+ code-insiders --add-mcp '{"name":"web-inspector","command":"npx","args":["mcp-web-inspector"]}'
115
+ ```
116
+
117
+ ### Manual Configuration
118
+
119
+ 1. Open VS Code Settings (JSON)
120
+ 2. Add MCP server configuration to `mcp.json`:
121
+
122
+ ```json
123
+ {
124
+ "servers": {
125
+ "web-inspector": {
126
+ "type": "stdio",
127
+ "command": "npx",
128
+ "args": ["-y", "mcp-web-inspector"]
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ ### Enable MCP in VS Code
135
+
136
+ 1. Open VS Code Settings (UI)
137
+ 2. Search for "MCP"
138
+ 3. Enable **Chat > MCP** option
139
+ 4. MCP only works in **Agent mode** - switch to agent mode in the chat interface
140
+ 5. Open the `mcp.json` file and click the **"Start"** button next to the server
141
+
142
+ ### Note about Embedded Browser
143
+
144
+ GitHub Copilot and VS Code may have an embedded browser feature. If you experience conflicts or prefer using Web Inspector MCP for all web inspection tasks, you may want to disable the built-in browser:
145
+
146
+ 1. Open VS Code Settings
147
+ 2. Search for "browser preview" or "simple browser"
148
+ 3. Disable relevant browser-related extensions if needed
149
+
150
+ Web Inspector MCP provides more powerful inspection capabilities than the embedded browser.
151
+
152
+ </details>
153
+
154
+ <details>
155
+ <summary><b>🎯 Cursor</b></summary>
156
+
157
+ ### Configuration File Location
158
+
159
+ - **MacOS/Linux**: `~/.cursor/mcp.json` or check Cursor's settings directory
160
+ - **Windows**: `%APPDATA%\Cursor\mcp.json`
161
+
162
+ ### Add to Configuration
163
+
164
+ ```json
165
+ {
166
+ "mcpServers": {
167
+ "web-inspector": {
168
+ "command": "npx",
169
+ "args": ["-y", "mcp-web-inspector"]
170
+ }
171
+ }
172
+ }
173
+ ```
174
+
175
+ ### Steps
176
+
177
+ 1. Open Cursor Settings (Cmd/Ctrl + ,)
178
+ 2. Search for "MCP" settings
179
+ 3. Edit the MCP configuration file
180
+ 4. Add the web-inspector server configuration
181
+ 5. Restart Cursor
182
+ 6. Verify the server is available in the MCP panel
183
+
184
+ </details>
185
+
186
+ <details>
187
+ <summary><b>🌊 Windsurf</b></summary>
188
+
189
+ ### Configuration
190
+
191
+ Windsurf uses the same configuration format as Claude Desktop. You can literally copy your Claude Desktop config!
192
+
193
+ **Configuration File**: Check Windsurf's settings for the exact path (typically in app data directory)
194
+
195
+ ```json
196
+ {
197
+ "mcpServers": {
198
+ "web-inspector": {
199
+ "command": "npx",
200
+ "args": ["-y", "mcp-web-inspector"]
201
+ }
202
+ }
203
+ }
204
+ ```
205
+
206
+ ### Steps
207
+
208
+ 1. Open Windsurf settings
209
+ 2. Navigate to MCP configuration
210
+ 3. Add the web-inspector server
211
+ 4. Restart Windsurf
212
+ 5. Verify server availability in the tools panel
213
+
214
+ Windsurf handles MCP tools very well - configuration is straightforward!
215
+
216
+ </details>
217
+
218
+ <details>
219
+ <summary><b>🔧 Cline (VS Code Extension)</b></summary>
220
+
221
+ ### Prerequisites
222
+
223
+ - VS Code with Cline extension installed
224
+ - Node.js installed on your system
225
+
226
+ ### Configuration
227
+
228
+ 1. Open Cline's settings in VS Code
229
+ 2. Locate the MCP configuration section
230
+ 3. Add the server configuration:
231
+
232
+ ```json
233
+ {
234
+ "mcpServers": {
235
+ "web-inspector": {
236
+ "command": "npx",
237
+ "args": ["-y", "mcp-web-inspector"]
238
+ }
239
+ }
240
+ }
241
+ ```
242
+
243
+ 4. Restart VS Code or reload the Cline extension
244
+ 5. The Web Inspector MCP tools will be available in Cline's tool panel
245
+
246
+ </details>
247
+
248
+ <details>
249
+ <summary><b>⚙️ Other MCP-Compatible Tools</b></summary>
250
+
251
+ Most MCP-compatible tools use a similar configuration format. Look for:
252
+
253
+ 1. MCP settings or configuration file
254
+ 2. Server/Tools configuration section
255
+ 3. Add the standard configuration:
256
+
257
+ ```json
258
+ {
259
+ "mcpServers": {
260
+ "web-inspector": {
261
+ "command": "npx",
262
+ "args": ["-y", "mcp-web-inspector"]
263
+ }
264
+ }
265
+ }
266
+ ```
267
+
268
+ If your tool supports MCP but isn't listed here, consult its documentation for the exact configuration file location.
269
+
270
+ </details>
271
+
272
+ ---
273
+
274
+ ## Command Line Options
275
+
276
+ Customize server behavior with command line flags:
277
+
278
+ - **`--no-save-session`** - Disable automatic session persistence (start with fresh browser state each time)
279
+ - **`--user-data-dir <path>`** - Custom directory for session data (default: `./.mcp-web-inspector`)
280
+
281
+ **Example usage:**
282
+ ```json
283
+ {
284
+ "mcpServers": {
285
+ "web-inspector": {
286
+ "command": "npx",
287
+ "args": ["-y", "mcp-web-inspector", "--user-data-dir", "./my-sessions"]
288
+ }
289
+ }
290
+ }
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Session Persistence & Data Storage
296
+
297
+ **By default**, browser session data and screenshots are automatically saved and organized in `./.mcp-web-inspector/`:
298
+
299
+ ```
300
+ .mcp-web-inspector/
301
+ ├── user-data/ # Browser sessions (cookies, localStorage, sessionStorage)
302
+ └── screenshots/ # Screenshot files
303
+ ```
304
+
305
+ ### How It Works
306
+
307
+ - Session data persists across browser restarts
308
+ - Screenshots are saved to the screenshots directory
309
+ - Browser maintains logged-in state between sessions
310
+ - Works out of the box - just navigate and your data is saved
311
+
312
+ ### Benefits
313
+
314
+ - ✅ Test authenticated features without re-logging in each time
315
+ - ✅ Maintain shopping cart state across sessions
316
+ - ✅ Preserve user preferences and settings
317
+ - ✅ Debug logged-in user workflows efficiently
318
+
319
+ ### Disabling Session Persistence
320
+
321
+ If you prefer the browser to start fresh each time (no persistent state), use the `--no-save-session` flag:
322
+
323
+ **Claude Code CLI:**
324
+ ```bash
325
+ claude mcp add web-inspector --scope user -- npx -y mcp-web-inspector --no-save-session
326
+ ```
327
+
328
+ **Claude Desktop / Windsurf / Cline:**
329
+ ```json
330
+ {
331
+ "mcpServers": {
332
+ "web-inspector": {
333
+ "command": "npx",
334
+ "args": ["-y", "mcp-web-inspector", "--no-save-session"]
335
+ }
336
+ }
337
+ }
338
+ ```
339
+
340
+ **Cursor:**
341
+ ```json
342
+ {
343
+ "mcpServers": {
344
+ "web-inspector": {
345
+ "command": "npx",
346
+ "args": ["-y", "mcp-web-inspector", "--no-save-session"],
347
+ "env": {}
348
+ }
349
+ }
350
+ }
351
+ ```
352
+
353
+ ### Clearing Data
354
+
355
+ To clear all saved data (sessions and screenshots):
356
+ ```bash
357
+ rm -rf ./.mcp-web-inspector
358
+ ```
359
+
360
+ To clear only sessions or screenshots:
361
+ ```bash
362
+ rm -rf ./.mcp-web-inspector/user-data # Clear sessions only
363
+ rm -rf ./.mcp-web-inspector/screenshots # Clear screenshots only
364
+ ```
365
+
366
+ ### Security Best Practices
367
+
368
+ **⚠️ IMPORTANT**: Add `.mcp-web-inspector/` to your `.gitignore` file to prevent committing:
369
+ - Browser session data (cookies, localStorage, sessionStorage)
370
+ - Saved screenshots (may contain sensitive information)
371
+ - Authentication tokens and credentials
372
+
373
+ **Add to your `.gitignore`:**
374
+ ```gitignore
375
+ # MCP Web Inspector data
376
+ .mcp-web-inspector/
377
+ ```
378
+
379
+ **Why this matters:**
380
+ - Session data contains cookies and authentication tokens
381
+ - Screenshots may capture sensitive user data
382
+ - Committing this data could leak credentials to your repository
383
+ - Session files can be large and bloat your git history
384
+
385
+ **Best practices:**
386
+ - Use `headless: true` for automation and CI/CD environments
387
+ - Use `headless: false` only when debugging interactively
388
+ - Clear session data after testing sensitive applications
389
+ - Use `--no-save-session` flag when testing on shared/public sites
390
+
391
+ ---
392
+
393
+ ## Core Tools
394
+
395
+ ### 🔍 DOM Inspection & Discovery
396
+
397
+ #### `inspect_dom` ⭐ **PRIMARY TOOL**
398
+ Progressive DOM inspection with semantic filtering and automatic wrapper drilling. Returns only meaningful elements (semantic HTML, test IDs, ARIA roles, interactive elements) while automatically skipping non-semantic wrapper divs.
399
+
400
+ **Key Features:**
401
+ - Drills through nested wrapper elements (up to 5 levels deep by default)
402
+ - Shows spatial layout information (position, size, visibility)
403
+ - Detects layout patterns automatically
404
+ - Supports progressive exploration (inspect → drill down → inspect children)
405
+
406
+ **Use Cases:**
407
+ - Understanding page structure at a glance
408
+ - Finding semantic landmarks (header, main, nav, footer)
409
+ - Discovering interactive elements in complex UIs
410
+ - Navigating deeply nested component libraries (Material-UI, Ant Design)
411
+
412
+ **Example Workflow:**
413
+ ```
414
+ 1. inspect_dom({}) → See page sections
415
+ 2. inspect_dom({ selector: "main" }) → Explore main content
416
+ 3. inspect_dom({ selector: "[role=form]" }) → Inspect form fields
417
+ ```
418
+
419
+ #### `get_test_ids`
420
+ Discover all test identifiers on the page (data-testid, data-test, data-cy, etc.). Returns a compact list grouped by attribute type.
421
+
422
+ **Use Cases:**
423
+ - Finding elements with test IDs for reliable selectors
424
+ - Auditing test coverage
425
+ - Understanding naming conventions used in the codebase
426
+
427
+ #### `query_selector`
428
+ Test a selector and get detailed information about all matched elements. Shows tag, position, text content, visibility status, and why elements are hidden (display:none, opacity:0, zero size).
429
+
430
+ **Use Cases:**
431
+ - Debugging why selectors match unexpected elements
432
+ - Validating selector specificity before writing tests
433
+ - Finding the right element among multiple matches
434
+ - Understanding element state (visible, hidden, interactive)
435
+
436
+ **Parameters:**
437
+ - `limit` - Control how many matches to show (default: 10)
438
+ - `onlyVisible` - Filter by visibility (true/false/undefined)
439
+ - `showAttributes` - Display specific HTML attributes
440
+
441
+ ### 👁️ Visibility & Position Debugging
442
+
443
+ #### `check_visibility`
444
+ Detailed visibility diagnostics showing exactly why elements are or aren't visible. Checks viewport intersection, clipping by overflow:hidden, coverage by other elements, and scroll requirements.
445
+
446
+ **Use Cases:**
447
+ - Debugging why clicks fail ("element not visible")
448
+ - Understanding if scrolling is needed
449
+ - Detecting elements covered by modals or overlays
450
+ - Checking if elements are clipped by parent containers
451
+
452
+ #### `get_position`
453
+ Get precise element coordinates and dimensions (x, y, width, height). Shows position relative to viewport.
454
+
455
+ **Use Cases:**
456
+ - Finding exact click coordinates
457
+ - Checking element layout
458
+ - Calculating distances between elements
459
+ - Debugging overlapping elements
460
+
461
+ #### `compare_positions`
462
+ Compare positions and alignment of two elements. Validates if elements are aligned (top, left, right, bottom) or have matching dimensions (width, height).
463
+
464
+ **Use Cases:**
465
+ - Visual regression testing
466
+ - Ensuring consistent spacing across components
467
+ - Validating grid layouts
468
+ - Checking responsive design consistency
469
+
470
+ ### 🎨 Style & Content Inspection
471
+
472
+ #### `get_computed_styles`
473
+ Get computed CSS styles for an element, grouped by category (Layout, Visibility, Spacing, Typography). Request specific properties or get common layout properties.
474
+
475
+ **Use Cases:**
476
+ - Understanding why elements behave unexpectedly
477
+ - Debugging CSS property values (flexbox, grid, positioning)
478
+ - Investigating rendering differences across browsers
479
+ - Finding actual rendered values (not CSS source)
480
+
481
+ #### `measure_element`
482
+ Get box model measurements (position, size, margin, padding, border) with compact visual representation using directional arrows.
483
+
484
+ **Use Cases:**
485
+ - Debugging CSS spacing issues
486
+ - Validating design system spacing tokens
487
+ - Understanding box model layout
488
+ - Checking margin/padding/border values
489
+
490
+ #### `get_text`
491
+ Extract visible text content from the current page or specific element.
492
+
493
+ **Use Cases:**
494
+ - Content validation
495
+ - Scraping visible text
496
+ - Verifying page loaded correctly
497
+
498
+ #### `get_html`
499
+ Get HTML content with options to remove scripts, comments, styles, and meta tags. Supports minification and max length limits.
500
+
501
+ **Use Cases:**
502
+ - Analyzing page structure
503
+ - Extracting clean HTML for processing
504
+ - Debugging server-rendered content
505
+
506
+ #### `get_console_logs`
507
+ Retrieve browser console logs with filtering by type (error, warning, log, info, debug) and text search.
508
+
509
+ **Use Cases:**
510
+ - Debugging JavaScript errors
511
+ - Monitoring network issues
512
+ - Finding specific log messages
513
+ - Tracking console warnings
514
+
515
+ ### 🔎 Element Finding & Validation
516
+
517
+ #### `find_by_text`
518
+ Find elements by text content with exact/partial matching, case sensitivity options, and regex support.
519
+
520
+ **Use Cases:**
521
+ - Finding buttons without test IDs ("Click here", "Submit")
522
+ - Locating elements in pages with poor markup
523
+ - Searching for dynamic content
524
+ - Testing internationalized content
525
+
526
+ **Regex Examples:**
527
+ - `/sign.*in/i` - Case-insensitive "sign in" variations
528
+ - `/\d+ items?/` - Numbers followed by "item" or "items"
529
+
530
+ #### `element_exists`
531
+ Ultra-lightweight existence check. Returns simple ✓ exists or ✗ not found status.
532
+
533
+ **Use Cases:**
534
+ - Quick pre-interaction validation
535
+ - Polling for element appearance
536
+ - Conditional logic based on element presence
537
+
538
+ ### 🌐 Navigation & Control
539
+
540
+ #### `navigate`
541
+ Navigate to a URL with full browser configuration options.
542
+
543
+ **Parameters:**
544
+ - `browserType` - chromium, firefox, or webkit
545
+ - `width`, `height` - Viewport dimensions
546
+ - `headless` - Run in headless mode
547
+ - `timeout` - Navigation timeout
548
+ - `waitUntil` - Navigation wait condition
549
+
550
+ #### `go_back`
551
+ Navigate back in browser history. Essential for testing navigation flows and multi-step forms.
552
+
553
+ **Use Cases:**
554
+ - Testing back button behavior
555
+ - Debugging navigation state
556
+ - Verifying history management
557
+ - Testing multi-page workflows
558
+
559
+ #### `go_forward`
560
+ Navigate forward in browser history.
561
+
562
+ **Use Cases:**
563
+ - Testing forward navigation
564
+ - Verifying browser history state
565
+ - Debugging navigation flows
566
+
567
+ #### `screenshot`
568
+ Capture screenshots of the entire page or specific elements. Save as PNG file or return as base64.
569
+
570
+ **Options:**
571
+ - Full page screenshots
572
+ - Element-specific screenshots
573
+ - Custom viewport sizes
574
+ - Save to custom directory
575
+
576
+ #### `close`
577
+ Close the browser and release all resources.
578
+
579
+ ### 🎯 Essential Interactions (for Debugging Workflows)
580
+
581
+ #### `click`
582
+ Click an element on the page. Essential for debugging user workflows and testing interactive elements.
583
+
584
+ **Use Cases:**
585
+ - Testing button functionality
586
+ - Triggering dropdown menus
587
+ - Debugging click event handlers
588
+ - Simulating user interactions during inspection
589
+
590
+ #### `fill`
591
+ Fill out an input field with text. Critical for debugging form interactions.
592
+
593
+ **Use Cases:**
594
+ - Testing form validation
595
+ - Debugging input field behavior
596
+ - Simulating user data entry
597
+ - Testing autocomplete and search features
598
+
599
+ #### `hover`
600
+ Hover over an element to trigger hover states and tooltips.
601
+
602
+ **Use Cases:**
603
+ - Debugging CSS :hover states
604
+ - Triggering tooltip displays
605
+ - Testing dropdown menu visibility
606
+ - Inspecting hover-dependent UI elements
607
+
608
+ #### `select`
609
+ Select an option from a `<select>` dropdown element.
610
+
611
+ **Use Cases:**
612
+ - Testing dropdown functionality
613
+ - Debugging option selection
614
+ - Simulating user form completion
615
+ - Testing dependent field updates
616
+
617
+ #### `upload_file`
618
+ Upload a file to an `input[type='file']` element.
619
+
620
+ **Use Cases:**
621
+ - Testing file upload functionality
622
+ - Debugging file input behavior
623
+ - Simulating document/image uploads
624
+ - Testing upload validation
625
+
626
+ #### `drag`
627
+ Drag an element from source to target location.
628
+
629
+ **Use Cases:**
630
+ - Testing drag-and-drop interfaces
631
+ - Debugging sortable lists
632
+ - Testing reorderable components
633
+ - Validating drag interactions
634
+
635
+ #### `press_key`
636
+ Press a keyboard key, optionally focusing on a specific element first.
637
+
638
+ **Use Cases:**
639
+ - Testing keyboard shortcuts
640
+ - Debugging keyboard navigation
641
+ - Testing Enter/Escape key handlers
642
+ - Simulating Tab key navigation
643
+
644
+ ### ⚙️ Advanced Tools
645
+
646
+ #### `evaluate`
647
+ Execute JavaScript code in the browser console and return the result.
648
+
649
+ **Use Cases:**
650
+ - Running custom JavaScript for debugging
651
+ - Extracting complex data not available via other tools
652
+ - Testing JavaScript functions on the page
653
+ - Manipulating page state for testing
654
+
655
+ **Example:**
656
+ ```javascript
657
+ evaluate({ script: "return document.title" })
658
+ evaluate({ script: "return Array.from(document.querySelectorAll('a')).length" })
659
+ ```
660
+
661
+ ## Selector Shortcuts ⭐ Time-Saver
662
+
663
+ All browser tools support **convenient test ID shortcuts** that save typing and improve readability:
664
+
665
+ | Shorthand | Expands to | Saved Characters |
666
+ |-----------|-----------|------------------|
667
+ | `testid:submit-button` | `[data-testid="submit-button"]` | 17 chars |
668
+ | `data-test:login-form` | `[data-test="login-form"]` | 11 chars |
669
+ | `data-cy:username` | `[data-cy="username"]` | 9 chars |
670
+
671
+ **Before (verbose):**
672
+ ```javascript
673
+ click({ selector: '[data-testid="submit-button"]' })
674
+ fill({ selector: '[data-testid="email-input"]', value: 'user@example.com' })
675
+ check_visibility({ selector: '[data-testid="loading-spinner"]' })
676
+ ```
677
+
678
+ **After (with shortcuts):**
679
+ ```javascript
680
+ click({ selector: 'testid:submit-button' })
681
+ fill({ selector: 'testid:email-input', value: 'user@example.com' })
682
+ check_visibility({ selector: 'testid:loading-spinner' })
683
+ ```
684
+
685
+ **Why this matters:**
686
+ - ✅ **Cleaner, more readable tool calls** - No need to escape quotes or remember bracket syntax
687
+ - ✅ **Works across all browser tools** - Consistent syntax for click, fill, inspect_dom, etc.
688
+ - ✅ **Mix with other selectors** - Regular CSS selectors still work: `#login`, `.button`, `nav > a`
689
+
690
+ **All supported shortcuts:**
691
+ - `testid:*` → `[data-testid="*"]`
692
+ - `data-test:*` → `[data-test="*"]`
693
+ - `data-cy:*` → `[data-cy="*"]` (Cypress convention)
694
+
695
+ Regular CSS selectors, text selectors (`text=Login`), and Playwright selectors work unchanged.
696
+
697
+ ## Example Use Cases
698
+
699
+ ### Debugging a Failing Test
700
+ ```
701
+ 1. navigate({ url: "https://example.com" })
702
+ 2. query_selector({ selector: ".submit-button", limit: 5 })
703
+ → Found 3 matches, 2 are hidden (display:none)
704
+ 3. check_visibility({ selector: ".submit-button:nth-child(1)" })
705
+ → Element is clipped by parent overflow:hidden
706
+ 4. get_position({ selector: ".submit-button:nth-child(1)" })
707
+ → Element is at x:1500, y:300 (outside viewport)
708
+ ```
709
+
710
+ ### Understanding Page Structure
711
+ ```
712
+ 1. navigate({ url: "https://app.example.com" })
713
+ 2. inspect_dom({})
714
+ → Shows: header, nav, main, aside, footer
715
+ 3. inspect_dom({ selector: "main" })
716
+ → Shows: form[role=search], section.results, section.filters
717
+ 4. get_test_ids({})
718
+ → Discovers: search-input, filter-dropdown, result-card
719
+ ```
720
+
721
+ ### Validating Layout Consistency
722
+ ```
723
+ 1. navigate({ url: "https://dashboard.example.com" })
724
+ 2. compare_positions({
725
+ selector1: "testid:main-header",
726
+ selector2: "testid:chat-header",
727
+ checkAlignment: "top"
728
+ })
729
+ → ✓ Aligned (difference: 0px)
730
+ 3. compare_positions({
731
+ selector1: ".card:nth-child(1)",
732
+ selector2: ".card:nth-child(2)",
733
+ checkAlignment: "width"
734
+ })
735
+ → ✗ Not aligned (difference: 15px)
736
+ ```
737
+
738
+ ### Finding Elements Without Test IDs
739
+ ```
740
+ 1. find_by_text({ text: "Add to Cart", exact: false })
741
+ → Found 1 element: button.primary-action
742
+ 2. get_computed_styles({
743
+ selector: "button.primary-action",
744
+ properties: "background-color,padding,font-size"
745
+ })
746
+ → Shows: background-color: rgb(0,123,255), padding: 12px 24px
747
+ ```
748
+
749
+ ## Cookbook: Common Workflows
750
+
751
+ These step-by-step recipes show how to chain tools together for common testing and debugging scenarios.
752
+
753
+ ### Recipe 1: Testing a Login Flow
754
+
755
+ ```
756
+ 1. navigate({ url: "https://app.example.com/login" })
757
+ 2. screenshot({ name: "login-page" })
758
+ 3. fill({ selector: "testid:email-input", value: "user@example.com" })
759
+ 4. fill({ selector: "testid:password-input", value: "password123" })
760
+ 5. click({ selector: "testid:login-button" })
761
+ 6. wait_for_network_idle()
762
+ 7. get_console_logs({ type: "error" })
763
+ → Verify no JavaScript errors occurred
764
+ 8. screenshot({ name: "after-login" })
765
+ 9. get_text()
766
+ → Verify success message or dashboard content
767
+ ```
768
+
769
+ **Why this works**: Session persistence means you stay logged in for subsequent tests.
770
+
771
+ ### Recipe 2: Debugging Layout Issues
772
+
773
+ ```
774
+ 1. navigate({ url: "https://dashboard.example.com" })
775
+ 2. inspect_dom({ selector: "testid:sidebar" })
776
+ → Understand the structure of the problematic area
777
+ 3. get_position({ selector: "testid:logo" })
778
+ → @ (20,10) 150x40px
779
+ 4. get_position({ selector: "testid:menu" })
780
+ → @ (20,60) 200x300px
781
+ 5. compare_positions({
782
+ selector1: "testid:logo",
783
+ selector2: "testid:menu",
784
+ checkAlignment: "left"
785
+ })
786
+ → ✓ aligned (both at x=20)
787
+ 6. get_computed_styles({
788
+ selector: "testid:sidebar",
789
+ properties: "margin,padding,display,flex-direction"
790
+ })
791
+ → Shows: display: flex, flex-direction: column, padding: 20px
792
+ 7. screenshot({ name: "layout-debug" })
793
+ ```
794
+
795
+ **Why this works**: Progressive inspection + precise measurements reveal layout problems.
796
+
797
+ ### Recipe 3: API Response Testing
798
+
799
+ ```
800
+ 1. navigate({ url: "https://app.example.com/dashboard" })
801
+ 2. click({ selector: "testid:refresh-button" })
802
+ 3. wait_for_network_idle()
803
+ 4. list_network_requests({ type: "fetch", limit: 10 })
804
+ → [5] GET /api/users 200 OK | 45ms
805
+ 5. get_request_details({ index: 5 })
806
+ → Check headers, status, response body
807
+ 6. get_console_logs({ type: "error" })
808
+ → Verify no network errors
809
+ ```
810
+
811
+ **Why this works**: Network tools capture all requests for inspection after interactions.
812
+
813
+ ### Recipe 4: Finding Elements on Pages Without Test IDs
814
+
815
+ ```
816
+ 1. navigate({ url: "https://legacy-app.example.com" })
817
+ 2. inspect_dom()
818
+ → Get overall page structure
819
+ 3. get_test_ids()
820
+ → Check if any test IDs exist (spoiler: none)
821
+ 4. find_by_text({ text: "submit", caseSensitive: false })
822
+ → Found 2 buttons containing "submit"
823
+ 5. query_selector({ selector: "button", onlyVisible: true, limit: 10 })
824
+ → Shows all visible buttons with positions and text
825
+ 6. element_exists({ selector: "button:has-text('Submit Form')" })
826
+ → ✓ exists
827
+ 7. click({ selector: "button:has-text('Submit Form')" })
828
+ ```
829
+
830
+ **Why this works**: Multiple discovery tools (text search, query selector) help locate elements.
831
+
832
+ ### Recipe 5: Debugging "Element Not Visible" Errors
833
+
834
+ ```
835
+ 1. navigate({ url: "https://app.example.com" })
836
+ 2. element_exists({ selector: "testid:submit" })
837
+ → ✓ exists
838
+ 3. check_visibility({ selector: "testid:submit" })
839
+ → ✗ not visible: clipped by parent overflow:hidden
840
+ 4. inspect_dom({ selector: "form" })
841
+ → See parent container structure
842
+ 5. get_computed_styles({
843
+ selector: "form",
844
+ properties: "overflow,height,max-height"
845
+ })
846
+ → overflow: hidden, height: 300px, max-height: 300px
847
+ 6. evaluate({ script: "document.querySelector('[data-testid=submit]').scrollIntoView()" })
848
+ → Scroll element into view
849
+ 7. check_visibility({ selector: "testid:submit" })
850
+ → ✓ visible
851
+ 8. click({ selector: "testid:submit" })
852
+ ```
853
+
854
+ **Why this works**: Visibility diagnostics reveal the exact reason, enabling targeted fixes.
855
+
856
+ ### Recipe 6: Visual Regression Testing
857
+
858
+ ```
859
+ 1. navigate({ url: "https://dashboard.example.com" })
860
+ 2. screenshot({ name: "baseline", fullPage: true })
861
+ 3. compare_positions({
862
+ selector1: "testid:header",
863
+ selector2: "testid:footer",
864
+ checkAlignment: "width"
865
+ })
866
+ → ✓ aligned (both 1280px)
867
+ 4. compare_positions({
868
+ selector1: ".card:nth-child(1)",
869
+ selector2: ".card:nth-child(2)",
870
+ checkAlignment: "height"
871
+ })
872
+ → ✗ not aligned (difference: 20px)
873
+ 5. get_position({ selector: ".card:nth-child(1)" })
874
+ → @ (20,100) 400x300px
875
+ 6. get_position({ selector: ".card:nth-child(2)" })
876
+ → @ (440,100) 400x320px ← 20px taller!
877
+ ```
878
+
879
+ **Why this works**: Position comparison tools validate consistent spacing across components.
880
+
881
+ ### Recipe 7: Form Validation Testing
882
+
883
+ ```
884
+ 1. navigate({ url: "https://app.example.com/signup" })
885
+ 2. fill({ selector: "testid:email", value: "invalid-email" })
886
+ 3. fill({ selector: "testid:password", value: "short" })
887
+ 4. click({ selector: "testid:submit" })
888
+ 5. wait_for_element({ selector: ".error-message", state: "visible", timeout: 5000 })
889
+ 6. find_by_text({ text: "invalid", caseSensitive: false })
890
+ → Found 2 elements: .error-message spans
891
+ 7. get_text({ selector: ".error-message" })
892
+ → "Please enter a valid email address"
893
+ 8. screenshot({ name: "validation-errors" })
894
+ ```
895
+
896
+ **Why this works**: Wait for element ensures validation messages appear before checking.
897
+
898
+ ### Recipe 8: Mobile Responsive Testing
899
+
900
+ ```
901
+ 1. navigate({
902
+ url: "https://app.example.com",
903
+ width: 375,
904
+ height: 667
905
+ })
906
+ → iPhone SE viewport
907
+ 2. screenshot({ name: "mobile-view", fullPage: true })
908
+ 3. inspect_dom({ selector: "nav" })
909
+ → Check if mobile menu is used
910
+ 4. element_exists({ selector: "testid:hamburger-menu" })
911
+ → ✓ exists (mobile menu visible)
912
+ 5. element_exists({ selector: "testid:desktop-menu" })
913
+ → ✗ not found (desktop menu hidden on mobile)
914
+ 6. click({ selector: "testid:hamburger-menu" })
915
+ 7. wait_for_element({ selector: "testid:mobile-nav", state: "visible" })
916
+ 8. screenshot({ name: "mobile-menu-open" })
917
+ ```
918
+
919
+ **Why this works**: Viewport configuration in navigate enables mobile testing.
920
+
921
+ ### Recipe 9: Debugging Hover States
922
+
923
+ ```
924
+ 1. navigate({ url: "https://app.example.com" })
925
+ 2. hover({ selector: "testid:tooltip-trigger" })
926
+ 3. wait_for_element({ selector: "testid:tooltip", state: "visible", timeout: 2000 })
927
+ 4. check_visibility({ selector: "testid:tooltip" })
928
+ → ✓ visible
929
+ 5. get_position({ selector: "testid:tooltip" })
930
+ → @ (300,150) 200x50px
931
+ 6. get_computed_styles({
932
+ selector: "testid:tooltip",
933
+ properties: "display,opacity,visibility,z-index"
934
+ })
935
+ → display: block, opacity: 1, visibility: visible, z-index: 1000
936
+ 7. screenshot({ name: "tooltip-visible" })
937
+ ```
938
+
939
+ **Why this works**: Hover tool + visibility checks validate tooltip behavior.
940
+
941
+ ### Recipe 10: Accessibility Audit
942
+
943
+ ```
944
+ 1. navigate({ url: "https://app.example.com" })
945
+ 2. inspect_dom()
946
+ → Check for semantic HTML (header, nav, main, footer)
947
+ 3. query_selector({
948
+ selector: "[role]",
949
+ showAttributes: "role,aria-label,aria-labelledby"
950
+ })
951
+ → Shows all ARIA roles on page
952
+ 4. find_by_text({ text: "button", regex: true })
953
+ → Find buttons by text (should have accessible labels)
954
+ 5. query_selector({
955
+ selector: "button",
956
+ showAttributes: "aria-label,title"
957
+ })
958
+ → Check if buttons have accessible labels
959
+ 6. get_test_ids()
960
+ → Verify no duplicate test IDs (accessibility issue)
961
+ ```
962
+
963
+ **Why this works**: DOM inspection + attribute queries reveal accessibility issues.
964
+
965
+ ## Development
966
+
967
+ ### Testing
968
+ ```bash
969
+ npm test # Run tests
970
+ npm run test:coverage # Run with coverage
971
+ ```
972
+
973
+ ### Building
974
+ ```bash
975
+ npm run build # Compile TypeScript
976
+ npm run watch # Watch mode for development
977
+ ```
978
+
979
+ ## Technical Details
980
+
981
+ - **Protocol**: Model Context Protocol (MCP)
982
+ - **Browser Engine**: Playwright (Chromium, Firefox, WebKit)
983
+ - **Language**: TypeScript
984
+ - **Node Version**: 20+
985
+
986
+ ## Contributing
987
+
988
+ Contributions welcome! When adding new tools:
989
+
990
+ 1. Keep tool names short (some clients limit `server_name:tool_name` to 60 chars)
991
+ 2. Follow the atomic operation principle (one tool, one purpose)
992
+ 3. Use flat parameter structures with primitive types
993
+ 4. Add tests in `src/__tests__/`
994
+
995
+ ## License
996
+
997
+ MIT
998
+
999
+ ## Links
1000
+
1001
+ - **GitHub**: https://github.com/antonzherdev/mcp-web-inspector
1002
+ - **npm**: https://www.npmjs.com/package/mcp-web-inspector
1003
+ - **Issues**: https://github.com/antonzherdev/mcp-web-inspector/issues
1004
+
1005
+ ## Credits
1006
+
1007
+ This project is a focused fork of [executeautomation/mcp-playwright](https://github.com/executeautomation/mcp-playwright), specializing in web inspection and debugging capabilities. We're grateful to the ExecuteAutomation team for creating the excellent foundation that made this project possible.
1008
+
1009
+ **Key Differences:**
1010
+ - **Web Inspector MCP**: Focused on inspection, debugging, and layout validation with clean tool names
1011
+ - **Original mcp-playwright**: Full-featured browser automation including code generation, API testing, and comprehensive interaction tools
1012
+
1013
+ If you need full Playwright automation capabilities (code generation, advanced interactions, API testing), check out the [original mcp-playwright server](https://github.com/executeautomation/mcp-playwright).
1014
+
1015
+ ---
1016
+
1017
+ **Made for AI-assisted web development and testing** 🤖