mcp-web-inspector 0.1.3 → 0.2.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 (148) hide show
  1. package/README.md +68 -9
  2. package/dist/index.js +6 -1
  3. package/dist/toolConstants.d.ts +7 -0
  4. package/dist/toolConstants.js +46 -0
  5. package/dist/toolHandler.d.ts +6 -6
  6. package/dist/toolHandler.js +71 -202
  7. package/dist/tools/browser/ancestorInspection.d.ts +2 -0
  8. package/dist/tools/browser/ancestorInspection.js +159 -29
  9. package/dist/tools/browser/base.d.ts +65 -0
  10. package/dist/tools/browser/base.js +147 -0
  11. package/dist/tools/browser/computedStyles.d.ts +1 -0
  12. package/dist/tools/browser/computedStyles.js +8 -21
  13. package/dist/tools/browser/console/__tests__/console.test.d.ts +1 -0
  14. package/dist/tools/browser/console/__tests__/console.test.js +200 -0
  15. package/dist/tools/browser/console/__tests__/tabSwitchConsole.test.d.ts +8 -0
  16. package/dist/tools/browser/console/__tests__/tabSwitchConsole.test.js +83 -0
  17. package/dist/tools/browser/console/get_console_logs.d.ts +33 -0
  18. package/dist/tools/browser/console/get_console_logs.js +133 -0
  19. package/dist/tools/browser/console/index.d.ts +1 -0
  20. package/dist/tools/browser/console/index.js +1 -0
  21. package/dist/tools/browser/content/__tests__/output.test.d.ts +1 -0
  22. package/dist/tools/browser/content/__tests__/output.test.js +108 -0
  23. package/dist/tools/browser/content/__tests__/screenshot.test.d.ts +1 -0
  24. package/dist/tools/browser/content/__tests__/screenshot.test.js +167 -0
  25. package/dist/tools/browser/content/__tests__/visiblePage.test.d.ts +1 -0
  26. package/dist/tools/browser/content/__tests__/visiblePage.test.js +381 -0
  27. package/dist/tools/browser/content/get_html.d.ts +9 -0
  28. package/dist/tools/browser/content/get_html.js +121 -0
  29. package/dist/tools/browser/content/get_text.d.ts +9 -0
  30. package/dist/tools/browser/content/get_text.js +96 -0
  31. package/dist/tools/browser/content/index.d.ts +3 -0
  32. package/dist/tools/browser/content/index.js +3 -0
  33. package/dist/tools/browser/content/screenshot.d.ts +14 -0
  34. package/dist/tools/browser/content/screenshot.js +106 -0
  35. package/dist/tools/browser/elementVisibility.js +9 -13
  36. package/dist/tools/browser/evaluation/evaluate.d.ts +13 -0
  37. package/dist/tools/browser/evaluation/evaluate.js +97 -0
  38. package/dist/tools/browser/evaluation/index.d.ts +1 -0
  39. package/dist/tools/browser/evaluation/index.js +1 -0
  40. package/dist/tools/browser/inspectDom.js +34 -14
  41. package/dist/tools/browser/inspection/__tests__/compareElementAlignment.test.d.ts +1 -0
  42. package/dist/tools/browser/inspection/__tests__/compareElementAlignment.test.js +173 -0
  43. package/dist/tools/browser/inspection/__tests__/computedStyles.test.d.ts +1 -0
  44. package/dist/tools/browser/inspection/__tests__/computedStyles.test.js +146 -0
  45. package/dist/tools/browser/inspection/__tests__/elementExists.test.d.ts +1 -0
  46. package/dist/tools/browser/inspection/__tests__/elementExists.test.js +149 -0
  47. package/dist/tools/browser/inspection/__tests__/elementVisibility.test.d.ts +1 -0
  48. package/dist/tools/browser/inspection/__tests__/elementVisibility.test.js +405 -0
  49. package/dist/tools/browser/inspection/__tests__/findByText.test.d.ts +1 -0
  50. package/dist/tools/browser/inspection/__tests__/findByText.test.js +199 -0
  51. package/dist/tools/browser/inspection/__tests__/getTestIds.test.d.ts +1 -0
  52. package/dist/tools/browser/inspection/__tests__/getTestIds.test.js +251 -0
  53. package/dist/tools/browser/inspection/__tests__/inspectAncestors.test.d.ts +1 -0
  54. package/dist/tools/browser/inspection/__tests__/inspectAncestors.test.js +354 -0
  55. package/dist/tools/browser/inspection/__tests__/inspectDom.test.d.ts +1 -0
  56. package/dist/tools/browser/inspection/__tests__/inspectDom.test.js +1070 -0
  57. package/dist/tools/browser/inspection/__tests__/measureElement.test.d.ts +1 -0
  58. package/dist/tools/browser/inspection/__tests__/measureElement.test.js +333 -0
  59. package/dist/tools/browser/inspection/__tests__/querySelectorAll.test.d.ts +1 -0
  60. package/dist/tools/browser/inspection/__tests__/querySelectorAll.test.js +480 -0
  61. package/dist/tools/browser/inspection/check_visibility.d.ts +13 -0
  62. package/dist/tools/browser/inspection/check_visibility.js +245 -0
  63. package/dist/tools/browser/inspection/compare_element_alignment.d.ts +12 -0
  64. package/dist/tools/browser/inspection/compare_element_alignment.js +200 -0
  65. package/dist/tools/browser/inspection/element_exists.d.ts +10 -0
  66. package/dist/tools/browser/inspection/element_exists.js +73 -0
  67. package/dist/tools/browser/inspection/find_by_text.d.ts +14 -0
  68. package/dist/tools/browser/inspection/find_by_text.js +240 -0
  69. package/dist/tools/browser/inspection/get_computed_styles.d.ts +13 -0
  70. package/dist/tools/browser/inspection/get_computed_styles.js +139 -0
  71. package/dist/tools/browser/inspection/get_test_ids.d.ts +13 -0
  72. package/dist/tools/browser/inspection/get_test_ids.js +168 -0
  73. package/dist/tools/browser/inspection/index.d.ts +10 -0
  74. package/dist/tools/browser/inspection/index.js +10 -0
  75. package/dist/tools/browser/inspection/inspect_ancestors.d.ts +19 -0
  76. package/dist/tools/browser/inspection/inspect_ancestors.js +396 -0
  77. package/dist/tools/browser/inspection/inspect_dom.d.ts +13 -0
  78. package/dist/tools/browser/inspection/inspect_dom.js +649 -0
  79. package/dist/tools/browser/inspection/measure_element.d.ts +11 -0
  80. package/dist/tools/browser/inspection/measure_element.js +154 -0
  81. package/dist/tools/browser/inspection/query_selector.d.ts +13 -0
  82. package/dist/tools/browser/inspection/query_selector.js +229 -0
  83. package/dist/tools/browser/interaction/__tests__/advancedInteraction.test.d.ts +1 -0
  84. package/dist/tools/browser/interaction/__tests__/advancedInteraction.test.js +204 -0
  85. package/dist/tools/browser/interaction/__tests__/interaction.test.d.ts +1 -0
  86. package/dist/tools/browser/interaction/__tests__/interaction.test.js +396 -0
  87. package/dist/tools/browser/interaction/click.d.ts +9 -0
  88. package/dist/tools/browser/interaction/click.js +34 -0
  89. package/dist/tools/browser/interaction/drag.d.ts +9 -0
  90. package/dist/tools/browser/interaction/drag.js +49 -0
  91. package/dist/tools/browser/interaction/fill.d.ts +9 -0
  92. package/dist/tools/browser/interaction/fill.js +35 -0
  93. package/dist/tools/browser/interaction/hover.d.ts +9 -0
  94. package/dist/tools/browser/interaction/hover.js +34 -0
  95. package/dist/tools/browser/interaction/index.d.ts +7 -0
  96. package/dist/tools/browser/interaction/index.js +7 -0
  97. package/dist/tools/browser/interaction/press_key.d.ts +9 -0
  98. package/dist/tools/browser/interaction/press_key.js +38 -0
  99. package/dist/tools/browser/interaction/select.d.ts +9 -0
  100. package/dist/tools/browser/interaction/select.js +35 -0
  101. package/dist/tools/browser/interaction/upload_file.d.ts +9 -0
  102. package/dist/tools/browser/interaction/upload_file.js +35 -0
  103. package/dist/tools/browser/interaction.js +63 -26
  104. package/dist/tools/browser/lifecycle/close.d.ts +9 -0
  105. package/dist/tools/browser/lifecycle/close.js +47 -0
  106. package/dist/tools/browser/lifecycle/index.d.ts +1 -0
  107. package/dist/tools/browser/lifecycle/index.js +1 -0
  108. package/dist/tools/browser/measureElement.d.ts +1 -0
  109. package/dist/tools/browser/measureElement.js +8 -21
  110. package/dist/tools/browser/navigation/__tests__/goNavigation.test.d.ts +1 -0
  111. package/dist/tools/browser/navigation/__tests__/goNavigation.test.js +90 -0
  112. package/dist/tools/browser/navigation/__tests__/navigation.test.d.ts +1 -0
  113. package/dist/tools/browser/navigation/__tests__/navigation.test.js +113 -0
  114. package/dist/tools/browser/navigation/go_back.d.ts +9 -0
  115. package/dist/tools/browser/navigation/go_back.js +25 -0
  116. package/dist/tools/browser/navigation/go_forward.d.ts +9 -0
  117. package/dist/tools/browser/navigation/go_forward.js +25 -0
  118. package/dist/tools/browser/navigation/index.d.ts +3 -0
  119. package/dist/tools/browser/navigation/index.js +3 -0
  120. package/dist/tools/browser/navigation/navigate.d.ts +9 -0
  121. package/dist/tools/browser/navigation/navigate.js +80 -0
  122. package/dist/tools/browser/network/__tests__/networkMonitoring.test.d.ts +1 -0
  123. package/dist/tools/browser/network/__tests__/networkMonitoring.test.js +127 -0
  124. package/dist/tools/browser/network/get_request_details.d.ts +10 -0
  125. package/dist/tools/browser/network/get_request_details.js +153 -0
  126. package/dist/tools/browser/network/index.d.ts +2 -0
  127. package/dist/tools/browser/network/index.js +2 -0
  128. package/dist/tools/browser/network/list_network_requests.d.ts +11 -0
  129. package/dist/tools/browser/network/list_network_requests.js +94 -0
  130. package/dist/tools/browser/register.d.ts +2 -0
  131. package/dist/tools/browser/register.js +79 -0
  132. package/dist/tools/browser/visiblePage.js +120 -85
  133. package/dist/tools/browser/waiting/__tests__/waitForElement.test.d.ts +1 -0
  134. package/dist/tools/browser/waiting/__tests__/waitForElement.test.js +139 -0
  135. package/dist/tools/browser/waiting/index.d.ts +2 -0
  136. package/dist/tools/browser/waiting/index.js +2 -0
  137. package/dist/tools/browser/waiting/wait_for_element.d.ts +11 -0
  138. package/dist/tools/browser/waiting/wait_for_element.js +63 -0
  139. package/dist/tools/browser/waiting/wait_for_network_idle.d.ts +9 -0
  140. package/dist/tools/browser/waiting/wait_for_network_idle.js +48 -0
  141. package/dist/tools/common/registry.d.ts +8 -0
  142. package/dist/tools/common/registry.js +48 -0
  143. package/dist/tools/common/types.d.ts +12 -1
  144. package/dist/tools/index.d.ts +0 -1
  145. package/dist/tools/index.js +0 -1
  146. package/dist/tools.d.ts +9 -551
  147. package/dist/tools.js +11 -575
  148. package/package.json +2 -3
package/README.md CHANGED
@@ -39,6 +39,33 @@ npm install -g mcp-web-inspector
39
39
 
40
40
  All configurations below use `npx` which automatically downloads and runs the latest version. Click to expand installation instructions for your AI tool:
41
41
 
42
+ <details>
43
+ <summary><b>🚀 Codex CLI</b></summary>
44
+
45
+ ### Installation via CLI
46
+
47
+ ```bash
48
+ # Add the server globally
49
+ codex mcp add web-inspector -- npx -y mcp-web-inspector
50
+
51
+ # Verify it was registered
52
+ codex mcp list
53
+ ```
54
+
55
+ ### Manual Configuration
56
+
57
+ Codex stores MCP server definitions in `~/.codex/config.toml`. Add (or create) an entry under the `[mcp.servers]` table:
58
+
59
+ ```toml
60
+ [mcp.servers.web-inspector]
61
+ command = "npx"
62
+ args = ["-y", "mcp-web-inspector"]
63
+ ```
64
+
65
+ Restart Codex CLI to make sure the new server is available in future sessions.
66
+
67
+ </details>
68
+
42
69
  <details>
43
70
  <summary><b>🤖 Claude Code (CLI)</b></summary>
44
71
 
@@ -109,10 +136,10 @@ Restart Claude Desktop after saving the configuration.
109
136
 
110
137
  ```bash
111
138
  # VS Code Stable
112
- code --add-mcp '{"name":"web-inspector","command":"npx","args":["mcp-web-inspector"]}'
139
+ code --add-mcp '{"name":"web-inspector","command":"npx","args":["-y","mcp-web-inspector"]}'
113
140
 
114
141
  # VS Code Insiders
115
- code-insiders --add-mcp '{"name":"web-inspector","command":"npx","args":["mcp-web-inspector"]}'
142
+ code-insiders --add-mcp '{"name":"web-inspector","command":"npx","args":["-y","mcp-web-inspector"]}'
116
143
  ```
117
144
 
118
145
  ### Manual Configuration
@@ -277,6 +304,8 @@ Most MCP-compatible tools use a similar configuration format. Look for:
277
304
  }
278
305
  ```
279
306
 
307
+ CLI-first assistants such as GitHub Copilot CLI, Copylot CLI, Continue CLI, and other emerging AI coders follow the same pattern—either run their `mcp add` command with `npx -y mcp-web-inspector` or drop the snippet above into their MCP config file.
308
+
280
309
  If your tool supports MCP but isn't listed here, consult its documentation for the exact configuration file location.
281
310
 
282
311
  </details>
@@ -289,6 +318,7 @@ Customize server behavior with command line flags:
289
318
 
290
319
  - **`--no-save-session`** - Disable automatic session persistence (start with fresh browser state each time)
291
320
  - **`--user-data-dir <path>`** - Custom directory for session data (default: `./.mcp-web-inspector`)
321
+ - **`--headless`** - Run browser in headless mode by default (no visible window)
292
322
 
293
323
  **Example usage:**
294
324
  ```json
@@ -302,6 +332,30 @@ Customize server behavior with command line flags:
302
332
  }
303
333
  ```
304
334
 
335
+ **Run in headless mode for automation/CI:**
336
+ ```json
337
+ {
338
+ "mcpServers": {
339
+ "web-inspector": {
340
+ "command": "npx",
341
+ "args": ["-y", "mcp-web-inspector", "--headless"]
342
+ }
343
+ }
344
+ }
345
+ ```
346
+
347
+ **Combine multiple flags:**
348
+ ```json
349
+ {
350
+ "mcpServers": {
351
+ "web-inspector": {
352
+ "command": "npx",
353
+ "args": ["-y", "mcp-web-inspector", "--headless", "--no-save-session"]
354
+ }
355
+ }
356
+ }
357
+ ```
358
+
305
359
  ---
306
360
 
307
361
  ## Session Persistence & Data Storage
@@ -395,8 +449,8 @@ rm -rf ./.mcp-web-inspector/screenshots # Clear screenshots only
395
449
  - Session files can be large and bloat your git history
396
450
 
397
451
  **Best practices:**
398
- - Use `headless: true` for automation and CI/CD environments
399
- - Use `headless: false` only when debugging interactively
452
+ - **Default is visible browser** (`headless: false`) for interactive debugging
453
+ - Use `headless: true` explicitly for automation and CI/CD environments
400
454
  - Clear session data after testing sensitive applications
401
455
  - Use `--no-save-session` flag when testing on shared/public sites
402
456
 
@@ -570,11 +624,16 @@ Ultra-lightweight existence check. Returns simple ✓ exists or ✗ not found st
570
624
  Navigate to a URL with full browser configuration options.
571
625
 
572
626
  **Parameters:**
573
- - `browserType` - chromium, firefox, or webkit
574
- - `width`, `height` - Viewport dimensions
575
- - `headless` - Run in headless mode
576
- - `timeout` - Navigation timeout
577
- - `waitUntil` - Navigation wait condition
627
+ - `browserType` - chromium, firefox, or webkit (default: chromium)
628
+ - `width`, `height` - Viewport dimensions (default: auto-detected screen size)
629
+ - `headless` - Run in headless mode (default: **false** - browser window visible)
630
+ - `timeout` - Navigation timeout in ms (default: 30000)
631
+ - `waitUntil` - Navigation wait condition (default: "load")
632
+
633
+ **Default Behavior:**
634
+ - Browser window is **visible by default** for interactive debugging
635
+ - Use `headless: true` for automation, CI/CD, or when you don't need visual feedback
636
+ - Use `headless: false` (or omit) when debugging interactively
578
637
 
579
638
  #### `go_back`
580
639
  Navigate back in browser history. Essential for testing navigation flows and multi-step forms.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { createToolDefinitions } from "./tools.js";
4
+ import { createToolDefinitions } from "./tools/common/registry.js";
5
5
  import { setupRequestHandlers } from "./requestHandler.js";
6
6
  import { parseArgs } from "node:util";
7
7
  import { setSessionConfig } from "./toolHandler.js";
@@ -16,6 +16,10 @@ const { values } = parseArgs({
16
16
  type: 'string',
17
17
  default: './.mcp-web-inspector',
18
18
  },
19
+ 'headless': {
20
+ type: 'boolean',
21
+ default: false,
22
+ },
19
23
  },
20
24
  strict: false,
21
25
  });
@@ -25,6 +29,7 @@ const sessionConfig = {
25
29
  saveSession: !Boolean(values['no-save-session']),
26
30
  userDataDir: `${baseDir}/user-data`,
27
31
  screenshotsDir: `${baseDir}/screenshots`,
32
+ headlessDefault: Boolean(values['headless']),
28
33
  };
29
34
  setSessionConfig(sessionConfig);
30
35
  async function runServer() {
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Tool constants - separate file to avoid circular dependencies
3
+ */
4
+ /**
5
+ * Get list of all browser tool names
6
+ */
7
+ export declare const BROWSER_TOOLS: string[];
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Tool constants - separate file to avoid circular dependencies
3
+ */
4
+ /**
5
+ * Get list of all browser tool names
6
+ */
7
+ export const BROWSER_TOOLS = [
8
+ // Navigation & Control
9
+ "navigate",
10
+ "go_back",
11
+ "go_forward",
12
+ "screenshot",
13
+ // DOM Inspection (PRIMARY)
14
+ "inspect_dom",
15
+ "get_test_ids",
16
+ "query_selector",
17
+ "find_by_text",
18
+ // Visibility & Position
19
+ "check_visibility",
20
+ "compare_element_alignment",
21
+ "inspect_ancestors",
22
+ "element_exists",
23
+ "wait_for_element",
24
+ "wait_for_network_idle",
25
+ // Style & Content
26
+ "get_computed_styles",
27
+ "measure_element",
28
+ "get_text",
29
+ "get_html",
30
+ "get_console_logs",
31
+ // Network Monitoring
32
+ "list_network_requests",
33
+ "get_request_details",
34
+ // Interactions (for debugging/testing workflows)
35
+ "click",
36
+ "fill",
37
+ "hover",
38
+ "select",
39
+ "upload_file",
40
+ "drag",
41
+ "press_key",
42
+ // JavaScript Execution
43
+ "evaluate",
44
+ // Cleanup
45
+ "close"
46
+ ];
@@ -1,5 +1,6 @@
1
1
  import type { Page } from 'playwright';
2
2
  import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
3
+ import type { SessionConfig } from './tools/common/types.js';
3
4
  export interface NetworkRequest {
4
5
  index: number;
5
6
  method: string;
@@ -18,11 +19,6 @@ export interface NetworkRequest {
18
19
  body: string | null;
19
20
  };
20
21
  }
21
- interface SessionConfig {
22
- saveSession: boolean;
23
- userDataDir: string;
24
- screenshotsDir: string;
25
- }
26
22
  /**
27
23
  * Sets the session configuration
28
24
  */
@@ -31,6 +27,10 @@ export declare function setSessionConfig(config: Partial<SessionConfig>): void;
31
27
  * Gets the screenshots directory
32
28
  */
33
29
  export declare function getScreenshotsDir(): string;
30
+ /**
31
+ * Gets the default headless setting
32
+ */
33
+ export declare function getHeadlessDefault(): boolean;
34
34
  /**
35
35
  * Resets browser and page variables
36
36
  * Used when browser is closed
@@ -48,7 +48,7 @@ export declare function clearNetworkLog(): void;
48
48
  * Sets the provided page to the global page variable
49
49
  * @param newPage The Page object to set as the global page
50
50
  */
51
- export declare function setGlobalPage(newPage: Page): void;
51
+ export declare function setGlobalPage(newPage: Page): Promise<void>;
52
52
  interface BrowserSettings {
53
53
  viewport?: {
54
54
  width?: number;
@@ -1,25 +1,6 @@
1
1
  import { chromium, firefox, webkit, devices } from 'playwright';
2
- import { BROWSER_TOOLS } from './tools.js';
3
2
  import { checkBrowsersInstalled, getInstallationInstructions } from './utils/browserCheck.js';
4
- import { ScreenshotTool, NavigationTool, CloseBrowserTool, ConsoleLogsTool } from './tools/browser/index.js';
5
- import { ClickTool, FillTool, SelectTool, HoverTool, EvaluateTool, UploadFileTool } from './tools/browser/interaction.js';
6
- import { VisibleTextTool, VisibleHtmlTool } from './tools/browser/visiblePage.js';
7
- import { ElementVisibilityTool } from './tools/browser/elementVisibility.js';
8
- import { InspectDomTool } from './tools/browser/inspectDom.js';
9
- import { GetTestIdsTool } from './tools/browser/getTestIds.js';
10
- import { QuerySelectorAllTool } from './tools/browser/querySelectorAll.js';
11
- import { FindByTextTool } from './tools/browser/findByText.js';
12
- import { GetComputedStylesTool } from './tools/browser/computedStyles.js';
13
- import { MeasureElementTool } from './tools/browser/measureElement.js';
14
- import { ElementExistsTool } from './tools/browser/elementExists.js';
15
- import { CompareElementAlignmentTool } from './tools/browser/compareElementAlignment.js';
16
- import { InspectAncestorsTool } from './tools/browser/ancestorInspection.js';
17
- import { GoBackTool, GoForwardTool } from './tools/browser/navigation.js';
18
- import { DragTool, PressKeyTool } from './tools/browser/interaction.js';
19
- import { WaitForElementTool } from './tools/browser/waitForElement.js';
20
- import { WaitForNetworkIdleTool } from './tools/browser/waitForNetworkIdle.js';
21
- import { ListNetworkRequestsTool } from './tools/browser/listNetworkRequests.js';
22
- import { GetRequestDetailsTool } from './tools/browser/getRequestDetails.js';
3
+ import { getToolInstance, isBrowserTool, executeTool } from './tools/common/registry.js';
23
4
  // Global state
24
5
  let browser;
25
6
  let page;
@@ -29,6 +10,7 @@ let sessionConfig = {
29
10
  saveSession: false,
30
11
  userDataDir: './.mcp-web-inspector/user-data',
31
12
  screenshotsDir: './.mcp-web-inspector/screenshots',
13
+ headlessDefault: false,
32
14
  };
33
15
  /**
34
16
  * Sets the session configuration
@@ -42,6 +24,12 @@ export function setSessionConfig(config) {
42
24
  export function getScreenshotsDir() {
43
25
  return sessionConfig.screenshotsDir;
44
26
  }
27
+ /**
28
+ * Gets the default headless setting
29
+ */
30
+ export function getHeadlessDefault() {
31
+ return sessionConfig.headlessDefault;
32
+ }
45
33
  /**
46
34
  * Resets browser and page variables
47
35
  * Used when browser is closed
@@ -68,52 +56,61 @@ export function clearNetworkLog() {
68
56
  * Sets the provided page to the global page variable
69
57
  * @param newPage The Page object to set as the global page
70
58
  */
71
- export function setGlobalPage(newPage) {
59
+ export async function setGlobalPage(newPage) {
72
60
  page = newPage;
61
+ // Register console message handlers and network listeners for the new page
62
+ await registerConsoleMessage(page);
63
+ await registerNetworkListeners(page);
73
64
  page.bringToFront(); // Bring the new tab to the front
74
- console.log("Global page has been updated.");
65
+ console.log("Global page has been updated with listeners registered.");
75
66
  }
76
- // Tool instances
77
- let screenshotTool;
78
- let navigationTool;
79
- let closeBrowserTool;
80
- let consoleLogsTool;
81
- let clickTool;
82
- let fillTool;
83
- let selectTool;
84
- let hoverTool;
85
- let uploadFileTool;
86
- let evaluateTool;
87
- let visibleTextTool;
88
- let visibleHtmlTool;
89
- let goBackTool;
90
- let goForwardTool;
91
- let dragTool;
92
- let pressKeyTool;
93
- let elementVisibilityTool;
94
- let inspectDomTool;
95
- let getTestIdsTool;
96
- let querySelectorAllTool;
97
- let findByTextTool;
98
- let getComputedStylesTool;
99
- let measureElementTool;
100
- let elementExistsTool;
101
- let compareElementAlignmentTool;
102
- let inspectAncestorsTool;
103
- let waitForElementTool;
104
- let waitForNetworkIdleTool;
105
- let listNetworkRequestsTool;
106
- let getRequestDetailsTool;
107
67
  /**
108
68
  * Device preset mapping to Playwright device descriptors
109
69
  */
110
70
  const DEVICE_PRESETS = {
71
+ // Mobile devices
111
72
  'iphone-se': 'iPhone SE',
112
73
  'iphone-14': 'iPhone 14',
113
74
  'iphone-14-pro': 'iPhone 14 Pro',
114
75
  'pixel-5': 'Pixel 5',
115
76
  'ipad': 'iPad (gen 7)',
116
- 'samsung-s21': 'Galaxy S21'
77
+ 'samsung-s21': 'Galaxy S21',
78
+ // Desktop devices (custom configs)
79
+ 'desktop-1080p': 'Desktop 1080p',
80
+ 'desktop-2k': 'Desktop 2K',
81
+ 'laptop-hd': 'Laptop HD'
82
+ };
83
+ /**
84
+ * Custom device configurations for presets not in Playwright's built-in devices
85
+ */
86
+ const CUSTOM_DEVICE_CONFIGS = {
87
+ 'Desktop 1080p': {
88
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.7204.23 Safari/537.36',
89
+ viewport: { width: 1920, height: 1080 },
90
+ screen: { width: 1920, height: 1080 },
91
+ deviceScaleFactor: 1,
92
+ isMobile: false,
93
+ hasTouch: false,
94
+ defaultBrowserType: 'chromium'
95
+ },
96
+ 'Desktop 2K': {
97
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.7204.23 Safari/537.36',
98
+ viewport: { width: 2560, height: 1440 },
99
+ screen: { width: 2560, height: 1440 },
100
+ deviceScaleFactor: 1,
101
+ isMobile: false,
102
+ hasTouch: false,
103
+ defaultBrowserType: 'chromium'
104
+ },
105
+ 'Laptop HD': {
106
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.7204.23 Safari/537.36',
107
+ viewport: { width: 1366, height: 768 },
108
+ screen: { width: 1366, height: 768 },
109
+ deviceScaleFactor: 1,
110
+ isMobile: false,
111
+ hasTouch: false,
112
+ defaultBrowserType: 'chromium'
113
+ }
117
114
  };
118
115
  /**
119
116
  * Register network event listeners
@@ -163,6 +160,7 @@ async function registerNetworkListeners(page) {
163
160
  }
164
161
  async function registerConsoleMessage(page) {
165
162
  page.on("console", (msg) => {
163
+ const consoleLogsTool = getToolInstance("get_console_logs", null);
166
164
  if (consoleLogsTool) {
167
165
  const type = msg.type();
168
166
  let text = msg.text();
@@ -186,6 +184,7 @@ async function registerConsoleMessage(page) {
186
184
  });
187
185
  // Uncaught exception
188
186
  page.on("pageerror", (error) => {
187
+ const consoleLogsTool = getToolInstance("get_console_logs", null);
189
188
  if (consoleLogsTool) {
190
189
  const message = error.message;
191
190
  const stack = error.stack || "";
@@ -300,7 +299,7 @@ export async function ensureBrowser(browserSettings) {
300
299
  }
301
300
  // Launch new browser if needed
302
301
  if (!browser) {
303
- const { viewport, userAgent, headless = false, browserType = 'chromium', device } = browserSettings ?? {};
302
+ const { viewport, userAgent, headless = sessionConfig.headlessDefault, browserType = 'chromium', device } = browserSettings ?? {};
304
303
  // If browser type is changing, force a new browser instance
305
304
  if (browser && currentBrowserType !== browserType) {
306
305
  try {
@@ -315,12 +314,13 @@ export async function ensureBrowser(browserSettings) {
315
314
  let deviceConfig = null;
316
315
  if (device && DEVICE_PRESETS[device]) {
317
316
  const playwrightDeviceName = DEVICE_PRESETS[device];
318
- deviceConfig = devices[playwrightDeviceName];
317
+ // Check custom configs first, then Playwright's built-in devices
318
+ deviceConfig = CUSTOM_DEVICE_CONFIGS[playwrightDeviceName] || devices[playwrightDeviceName];
319
319
  if (deviceConfig) {
320
320
  console.error(`Using device preset: ${device} (${playwrightDeviceName})`);
321
321
  }
322
322
  else {
323
- console.error(`Warning: Device preset ${playwrightDeviceName} not found in Playwright devices`);
323
+ console.error(`Warning: Device preset ${playwrightDeviceName} not found`);
324
324
  }
325
325
  }
326
326
  console.error(`Launching new ${browserType} browser instance...`);
@@ -451,12 +451,13 @@ export async function ensureBrowser(browserSettings) {
451
451
  }
452
452
  resetBrowserState();
453
453
  // Try one more time from scratch
454
- const { viewport, userAgent, headless = false, browserType = 'chromium', device } = browserSettings ?? {};
454
+ const { viewport, userAgent, headless = sessionConfig.headlessDefault, browserType = 'chromium', device } = browserSettings ?? {};
455
455
  // Get device configuration if device preset is specified
456
456
  let deviceConfig = null;
457
457
  if (device && DEVICE_PRESETS[device]) {
458
458
  const playwrightDeviceName = DEVICE_PRESETS[device];
459
- deviceConfig = devices[playwrightDeviceName];
459
+ // Check custom configs first, then Playwright's built-in devices
460
+ deviceConfig = CUSTOM_DEVICE_CONFIGS[playwrightDeviceName] || devices[playwrightDeviceName];
460
461
  }
461
462
  // Use the appropriate browser engine
462
463
  let browserInstance;
@@ -554,78 +555,10 @@ export async function ensureBrowser(browserSettings) {
554
555
  return page;
555
556
  }
556
557
  }
557
- /**
558
- * Initialize all tool instances
559
- */
560
- function initializeTools(server) {
561
- // Browser tools
562
- if (!screenshotTool)
563
- screenshotTool = new ScreenshotTool(server);
564
- if (!navigationTool)
565
- navigationTool = new NavigationTool(server);
566
- if (!closeBrowserTool)
567
- closeBrowserTool = new CloseBrowserTool(server);
568
- if (!consoleLogsTool)
569
- consoleLogsTool = new ConsoleLogsTool(server);
570
- if (!clickTool)
571
- clickTool = new ClickTool(server);
572
- if (!fillTool)
573
- fillTool = new FillTool(server);
574
- if (!selectTool)
575
- selectTool = new SelectTool(server);
576
- if (!hoverTool)
577
- hoverTool = new HoverTool(server);
578
- if (!uploadFileTool)
579
- uploadFileTool = new UploadFileTool(server);
580
- if (!evaluateTool)
581
- evaluateTool = new EvaluateTool(server);
582
- if (!visibleTextTool)
583
- visibleTextTool = new VisibleTextTool(server);
584
- if (!visibleHtmlTool)
585
- visibleHtmlTool = new VisibleHtmlTool(server);
586
- if (!goBackTool)
587
- goBackTool = new GoBackTool(server);
588
- if (!goForwardTool)
589
- goForwardTool = new GoForwardTool(server);
590
- if (!dragTool)
591
- dragTool = new DragTool(server);
592
- if (!pressKeyTool)
593
- pressKeyTool = new PressKeyTool(server);
594
- if (!elementVisibilityTool)
595
- elementVisibilityTool = new ElementVisibilityTool(server);
596
- if (!inspectDomTool)
597
- inspectDomTool = new InspectDomTool(server);
598
- if (!getTestIdsTool)
599
- getTestIdsTool = new GetTestIdsTool(server);
600
- if (!querySelectorAllTool)
601
- querySelectorAllTool = new QuerySelectorAllTool(server);
602
- if (!findByTextTool)
603
- findByTextTool = new FindByTextTool(server);
604
- if (!getComputedStylesTool)
605
- getComputedStylesTool = new GetComputedStylesTool(server);
606
- if (!measureElementTool)
607
- measureElementTool = new MeasureElementTool(server);
608
- if (!elementExistsTool)
609
- elementExistsTool = new ElementExistsTool(server);
610
- if (!compareElementAlignmentTool)
611
- compareElementAlignmentTool = new CompareElementAlignmentTool(server);
612
- if (!inspectAncestorsTool)
613
- inspectAncestorsTool = new InspectAncestorsTool(server);
614
- if (!waitForElementTool)
615
- waitForElementTool = new WaitForElementTool(server);
616
- if (!waitForNetworkIdleTool)
617
- waitForNetworkIdleTool = new WaitForNetworkIdleTool(server);
618
- if (!listNetworkRequestsTool)
619
- listNetworkRequestsTool = new ListNetworkRequestsTool(server);
620
- if (!getRequestDetailsTool)
621
- getRequestDetailsTool = new GetRequestDetailsTool(server);
622
- }
623
558
  /**
624
559
  * Main handler for tool calls
625
560
  */
626
561
  export async function handleToolCall(name, args, server) {
627
- // Initialize tools
628
- initializeTools(server);
629
562
  try {
630
563
  // Special case for browser close to ensure it always works
631
564
  if (name === "close") {
@@ -657,8 +590,9 @@ export async function handleToolCall(name, args, server) {
657
590
  isError: false,
658
591
  };
659
592
  }
593
+ const requiresBrowser = isBrowserTool(name);
660
594
  // Check if we have a disconnected browser that needs cleanup
661
- if (browser && !browser.isConnected() && BROWSER_TOOLS.includes(name)) {
595
+ if (browser && !browser.isConnected() && requiresBrowser) {
662
596
  console.error("Detected disconnected browser before tool execution, cleaning up...");
663
597
  try {
664
598
  await browser.close().catch(() => { }); // Ignore errors
@@ -673,7 +607,7 @@ export async function handleToolCall(name, args, server) {
673
607
  server
674
608
  };
675
609
  // Set up browser if needed
676
- if (BROWSER_TOOLS.includes(name)) {
610
+ if (requiresBrowser) {
677
611
  const browserSettings = {
678
612
  viewport: {
679
613
  width: args.width,
@@ -699,83 +633,13 @@ export async function handleToolCall(name, args, server) {
699
633
  };
700
634
  }
701
635
  }
702
- // Route to appropriate tool
703
- switch (name) {
704
- // Browser tools
705
- case "navigate":
706
- return await navigationTool.execute(args, context);
707
- case "screenshot":
708
- return await screenshotTool.execute(args, context);
709
- case "close":
710
- return await closeBrowserTool.execute(args, context);
711
- case "get_console_logs":
712
- return await consoleLogsTool.execute(args, context);
713
- case "click":
714
- return await clickTool.execute(args, context);
715
- case "fill":
716
- return await fillTool.execute(args, context);
717
- case "select":
718
- return await selectTool.execute(args, context);
719
- case "hover":
720
- return await hoverTool.execute(args, context);
721
- case "upload_file":
722
- return await uploadFileTool.execute(args, context);
723
- case "evaluate":
724
- return await evaluateTool.execute(args, context);
725
- case "get_text":
726
- return await visibleTextTool.execute(args, context);
727
- case "get_html":
728
- return await visibleHtmlTool.execute(args, context);
729
- case "go_back":
730
- return await goBackTool.execute(args, context);
731
- case "go_forward":
732
- return await goForwardTool.execute(args, context);
733
- case "drag":
734
- return await dragTool.execute(args, context);
735
- case "press_key":
736
- return await pressKeyTool.execute(args, context);
737
- case "check_visibility":
738
- return await elementVisibilityTool.execute(args, context);
739
- case "inspect_dom":
740
- return await inspectDomTool.execute(args, context);
741
- case "get_test_ids":
742
- return await getTestIdsTool.execute(args, context);
743
- case "query_selector":
744
- return await querySelectorAllTool.execute(args, context);
745
- case "find_by_text":
746
- return await findByTextTool.execute(args, context);
747
- case "get_computed_styles":
748
- return await getComputedStylesTool.execute(args, context);
749
- case "measure_element":
750
- return await measureElementTool.execute(args, context);
751
- case "element_exists":
752
- return await elementExistsTool.execute(args, context);
753
- case "compare_element_alignment":
754
- return await compareElementAlignmentTool.execute(args, context);
755
- case "inspect_ancestors":
756
- return await inspectAncestorsTool.execute(args, context);
757
- case "wait_for_element":
758
- return await waitForElementTool.execute(args, context);
759
- case "wait_for_network_idle":
760
- return await waitForNetworkIdleTool.execute(args, context);
761
- case "list_network_requests":
762
- return await listNetworkRequestsTool.execute(args, context);
763
- case "get_request_details":
764
- return await getRequestDetailsTool.execute(args, context);
765
- default:
766
- return {
767
- content: [{
768
- type: "text",
769
- text: `Unknown tool: ${name}`,
770
- }],
771
- isError: true,
772
- };
773
- }
636
+ // Route to appropriate tool using registry
637
+ return await executeTool(name, args, context, server);
774
638
  }
775
639
  catch (error) {
776
640
  console.error(`Error handling tool ${name}:`, error);
777
641
  // Handle browser-specific errors at the top level
778
- if (BROWSER_TOOLS.includes(name)) {
642
+ if (isBrowserTool(name)) {
779
643
  const errorMessage = error.message;
780
644
  if (errorMessage.includes("Target page, context or browser has been closed") ||
781
645
  errorMessage.includes("Browser has been disconnected") ||
@@ -806,30 +670,35 @@ export async function handleToolCall(name, args, server) {
806
670
  * Get console logs
807
671
  */
808
672
  export function getConsoleLogs() {
673
+ const consoleLogsTool = getToolInstance("get_console_logs", null);
809
674
  return consoleLogsTool?.getConsoleLogs() ?? [];
810
675
  }
811
676
  /**
812
677
  * Get screenshots
813
678
  */
814
679
  export function getScreenshots() {
680
+ const screenshotTool = getToolInstance("screenshot", null);
815
681
  return screenshotTool?.getScreenshots() ?? new Map();
816
682
  }
817
683
  /**
818
684
  * Update last interaction timestamp
819
685
  */
820
686
  export function updateLastInteractionTimestamp() {
687
+ const consoleLogsTool = getToolInstance("get_console_logs", null);
821
688
  consoleLogsTool?.updateLastInteractionTimestamp();
822
689
  }
823
690
  /**
824
691
  * Update last navigation timestamp
825
692
  */
826
693
  export function updateLastNavigationTimestamp() {
694
+ const consoleLogsTool = getToolInstance("get_console_logs", null);
827
695
  consoleLogsTool?.updateLastNavigationTimestamp();
828
696
  }
829
697
  /**
830
698
  * Clear console logs
831
699
  */
832
700
  export function clearConsoleLogs() {
701
+ const consoleLogsTool = getToolInstance("get_console_logs", null);
833
702
  consoleLogsTool?.clearConsoleLogs();
834
703
  }
835
704
  export { registerConsoleMessage };
@@ -12,5 +12,7 @@ export declare class InspectAncestorsTool extends BrowserToolBase {
12
12
  private formatAncestorChain;
13
13
  private formatBorder;
14
14
  private formatOverflow;
15
+ private formatLayoutContext;
16
+ private formatMarginDetails;
15
17
  private generateDiagnostics;
16
18
  }