brms-host 1.0.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 (61) hide show
  1. package/build/bin/install.d.ts +13 -0
  2. package/build/bin/install.js +124 -0
  3. package/build/bin/install.js.map +1 -0
  4. package/build/bridge/native-messaging.d.ts +27 -0
  5. package/build/bridge/native-messaging.js +118 -0
  6. package/build/bridge/native-messaging.js.map +1 -0
  7. package/build/browser/connection.d.ts +12 -0
  8. package/build/browser/connection.js +57 -0
  9. package/build/browser/connection.js.map +1 -0
  10. package/build/browser/console.d.ts +16 -0
  11. package/build/browser/console.js +44 -0
  12. package/build/browser/console.js.map +1 -0
  13. package/build/browser/dom.d.ts +9 -0
  14. package/build/browser/dom.js +16 -0
  15. package/build/browser/dom.js.map +1 -0
  16. package/build/browser/network.d.ts +14 -0
  17. package/build/browser/network.js +47 -0
  18. package/build/browser/network.js.map +1 -0
  19. package/build/index.d.ts +8 -0
  20. package/build/index.js +111 -0
  21. package/build/index.js.map +1 -0
  22. package/build/server.d.ts +2 -0
  23. package/build/server.js +30 -0
  24. package/build/server.js.map +1 -0
  25. package/build/tools/connection.tools.d.ts +2 -0
  26. package/build/tools/connection.tools.js +28 -0
  27. package/build/tools/connection.tools.js.map +1 -0
  28. package/build/tools/console.tools.d.ts +2 -0
  29. package/build/tools/console.tools.js +25 -0
  30. package/build/tools/console.tools.js.map +1 -0
  31. package/build/tools/debug.tools.d.ts +2 -0
  32. package/build/tools/debug.tools.js +226 -0
  33. package/build/tools/debug.tools.js.map +1 -0
  34. package/build/tools/dom.tools.d.ts +2 -0
  35. package/build/tools/dom.tools.js +26 -0
  36. package/build/tools/dom.tools.js.map +1 -0
  37. package/build/tools/events.tools.d.ts +2 -0
  38. package/build/tools/events.tools.js +18 -0
  39. package/build/tools/events.tools.js.map +1 -0
  40. package/build/tools/layout.tools.d.ts +2 -0
  41. package/build/tools/layout.tools.js +20 -0
  42. package/build/tools/layout.tools.js.map +1 -0
  43. package/build/tools/network.tools.d.ts +2 -0
  44. package/build/tools/network.tools.js +29 -0
  45. package/build/tools/network.tools.js.map +1 -0
  46. package/build/tools/screenshot.tools.d.ts +2 -0
  47. package/build/tools/screenshot.tools.js +40 -0
  48. package/build/tools/screenshot.tools.js.map +1 -0
  49. package/build/tools/styles.tools.d.ts +2 -0
  50. package/build/tools/styles.tools.js +22 -0
  51. package/build/tools/styles.tools.js.map +1 -0
  52. package/build/types/index.d.ts +130 -0
  53. package/build/types/index.js +2 -0
  54. package/build/types/index.js.map +1 -0
  55. package/build/utils/errors.d.ts +16 -0
  56. package/build/utils/errors.js +29 -0
  57. package/build/utils/errors.js.map +1 -0
  58. package/build/utils/logger.d.ts +11 -0
  59. package/build/utils/logger.js +15 -0
  60. package/build/utils/logger.js.map +1 -0
  61. package/package.json +35 -0
package/build/index.js ADDED
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * BRMS Host entry point.
4
+ *
5
+ * - Starts an HTTP server on port 3100 exposing MCP via Streamable HTTP
6
+ * - Starts the native messaging bridge to communicate with the Chrome extension
7
+ */
8
+ import { createServer as createHttpServer } from 'node:http';
9
+ import { writeFileSync, appendFileSync } from 'node:fs';
10
+ import { randomUUID } from 'node:crypto';
11
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
12
+ import { createServer } from './server.js';
13
+ import { bridge } from './bridge/native-messaging.js';
14
+ import { log } from './utils/logger.js';
15
+ const PORT = parseInt(process.env.BRMS_PORT ?? '3100', 10);
16
+ const DEBUG_LOG = '/tmp/brms-host-debug.log';
17
+ function debugLog(msg) {
18
+ const line = `[${new Date().toISOString()}] ${msg}\n`;
19
+ try {
20
+ appendFileSync(DEBUG_LOG, line);
21
+ }
22
+ catch { }
23
+ log.info(msg);
24
+ }
25
+ // Catch everything that might kill the process
26
+ process.on('exit', (code) => {
27
+ debugLog(`Process exiting with code ${code}`);
28
+ });
29
+ process.on('uncaughtException', (err) => {
30
+ debugLog(`UNCAUGHT EXCEPTION: ${err.stack ?? err.message}`);
31
+ });
32
+ process.on('unhandledRejection', (reason) => {
33
+ debugLog(`UNHANDLED REJECTION: ${reason}`);
34
+ });
35
+ process.on('SIGTERM', () => debugLog('Received SIGTERM'));
36
+ process.on('SIGINT', () => debugLog('Received SIGINT'));
37
+ // Keep process alive even if stdin closes
38
+ process.stdin.on('end', () => {
39
+ debugLog('stdin ended — keeping process alive');
40
+ });
41
+ process.stdin.resume();
42
+ async function main() {
43
+ writeFileSync(DEBUG_LOG, `=== BRMS Host starting at ${new Date().toISOString()} ===\n`);
44
+ debugLog(`PID: ${process.pid}, Node: ${process.version}`);
45
+ debugLog(`stdin isTTY: ${process.stdin.isTTY}, stdout isTTY: ${process.stdout.isTTY}`);
46
+ bridge.start();
47
+ debugLog('Bridge started');
48
+ const mcpServer = createServer();
49
+ debugLog('MCP server created');
50
+ const transport = new StreamableHTTPServerTransport({
51
+ sessionIdGenerator: () => randomUUID(),
52
+ });
53
+ const httpServer = createHttpServer(async (req, res) => {
54
+ const url = new URL(req.url ?? '/', `http://localhost:${PORT}`);
55
+ if (url.pathname === '/mcp') {
56
+ try {
57
+ // Parse body for POST requests before passing to transport
58
+ if (req.method === 'POST') {
59
+ const body = await new Promise((resolve, reject) => {
60
+ let data = '';
61
+ req.on('data', (chunk) => { data += chunk.toString(); });
62
+ req.on('end', () => resolve(data));
63
+ req.on('error', reject);
64
+ });
65
+ const parsedBody = JSON.parse(body);
66
+ await transport.handleRequest(req, res, parsedBody);
67
+ }
68
+ else {
69
+ await transport.handleRequest(req, res);
70
+ }
71
+ }
72
+ catch (err) {
73
+ debugLog(`MCP request error: ${err instanceof Error ? err.stack : err}`);
74
+ if (!res.headersSent) {
75
+ res.writeHead(500, { 'Content-Type': 'application/json' });
76
+ res.end(JSON.stringify({ error: String(err) }));
77
+ }
78
+ }
79
+ return;
80
+ }
81
+ if (url.pathname === '/health') {
82
+ res.writeHead(200, { 'Content-Type': 'application/json' });
83
+ res.end(JSON.stringify({ status: 'ok', extensionConnected: bridge.isConnected() }));
84
+ return;
85
+ }
86
+ res.writeHead(404);
87
+ res.end('Not found');
88
+ });
89
+ await mcpServer.connect(transport);
90
+ debugLog('MCP connected to transport');
91
+ httpServer.on('error', (err) => {
92
+ if (err.code === 'EADDRINUSE') {
93
+ debugLog(`Port ${PORT} in use, retrying in 1s...`);
94
+ setTimeout(() => {
95
+ httpServer.close();
96
+ httpServer.listen(PORT);
97
+ }, 1000);
98
+ }
99
+ else {
100
+ debugLog(`HTTP server error: ${err.message}`);
101
+ }
102
+ });
103
+ httpServer.listen(PORT, () => {
104
+ debugLog(`HTTP server listening on :${PORT}`);
105
+ });
106
+ }
107
+ main().catch((err) => {
108
+ debugLog(`Fatal error in main: ${err.stack ?? err.message}`);
109
+ process.exit(1);
110
+ });
111
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAC3D,MAAM,SAAS,GAAG,0BAA0B,CAAC;AAE7C,SAAS,QAAQ,CAAC,GAAW;IAC3B,MAAM,IAAI,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC;IACtD,IAAI,CAAC;QAAC,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACjD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChB,CAAC;AAED,+CAA+C;AAC/C,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;IAC1B,QAAQ,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,QAAQ,CAAC,uBAAuB,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,QAAQ,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAC1D,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAExD,0CAA0C;AAC1C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;IAC3B,QAAQ,CAAC,qCAAqC,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;AAEvB,KAAK,UAAU,IAAI;IACjB,aAAa,CAAC,SAAS,EAAE,6BAA6B,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACxF,QAAQ,CAAC,QAAQ,OAAO,CAAC,GAAG,WAAW,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1D,QAAQ,CAAC,gBAAgB,OAAO,CAAC,KAAK,CAAC,KAAK,mBAAmB,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAEvF,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAE3B,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAE/B,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;QAClD,kBAAkB,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;KACvC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACrD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;QAEhE,IAAI,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,2DAA2D;gBAC3D,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;oBAC1B,MAAM,IAAI,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBACzD,IAAI,IAAI,GAAG,EAAE,CAAC;wBACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;wBACjE,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;wBACnC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;oBAC1B,CAAC,CAAC,CAAC;oBACH,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACpC,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;gBACtD,CAAC;qBAAM,CAAC;oBACN,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,QAAQ,CAAC,sBAAsB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBACzE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;oBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;oBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC/B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;YACpF,OAAO;QACT,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,QAAQ,CAAC,4BAA4B,CAAC,CAAC;IAEvC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;QACpD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9B,QAAQ,CAAC,QAAQ,IAAI,4BAA4B,CAAC,CAAC;YACnD,UAAU,CAAC,GAAG,EAAE;gBACd,UAAU,CAAC,KAAK,EAAE,CAAC;gBACnB,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC,EAAE,IAAI,CAAC,CAAC;QACX,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QAC3B,QAAQ,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,QAAQ,CAAC,wBAAwB,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function createServer(): McpServer;
@@ -0,0 +1,30 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { registerConnectionTools } from './tools/connection.tools.js';
3
+ import { registerNetworkTools } from './tools/network.tools.js';
4
+ import { registerDOMTools } from './tools/dom.tools.js';
5
+ import { registerConsoleTools } from './tools/console.tools.js';
6
+ import { registerStyleTools } from './tools/styles.tools.js';
7
+ import { registerLayoutTools } from './tools/layout.tools.js';
8
+ import { registerScreenshotTools } from './tools/screenshot.tools.js';
9
+ import { registerEventTools } from './tools/events.tools.js';
10
+ import { registerDebugTools } from './tools/debug.tools.js';
11
+ export function createServer() {
12
+ const server = new McpServer({
13
+ name: 'brms',
14
+ version: '1.0.0',
15
+ });
16
+ // Phase 1 — core browser inspection
17
+ registerConnectionTools(server);
18
+ registerNetworkTools(server);
19
+ registerDOMTools(server);
20
+ registerConsoleTools(server);
21
+ // Phase 2 — styles, layout, screenshots, event listeners
22
+ registerStyleTools(server);
23
+ registerLayoutTools(server);
24
+ registerScreenshotTools(server);
25
+ registerEventTools(server);
26
+ // Phase 3 — AI debugging layer
27
+ registerDebugTools(server);
28
+ return server;
29
+ }
30
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,oCAAoC;IACpC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,yDAAyD;IACzD,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE3B,+BAA+B;IAC/B,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE3B,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerConnectionTools(server: McpServer): void;
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ import { browserManager } from '../browser/connection.js';
3
+ import { networkMonitor } from '../browser/network.js';
4
+ import { consoleCapture } from '../browser/console.js';
5
+ import { safeResult } from '../utils/errors.js';
6
+ export function registerConnectionTools(server) {
7
+ server.tool('connect_browser', 'Connect to the browser via the BRMS Chrome Extension. The extension must be installed and active.', {}, async () => {
8
+ return safeResult(async () => {
9
+ const pages = await browserManager.connect();
10
+ networkMonitor.attach();
11
+ consoleCapture.attach();
12
+ return JSON.stringify({ connected: true, pages }, null, 2);
13
+ });
14
+ });
15
+ server.tool('list_pages', 'List all open tabs/pages in the connected browser.', {}, async () => {
16
+ return safeResult(async () => {
17
+ const pages = await browserManager.getPages();
18
+ return JSON.stringify(pages, null, 2);
19
+ });
20
+ });
21
+ server.tool('select_page', 'Select an open browser tab by index for subsequent inspection.', { index: z.number().int().min(0).describe('Zero-based index of the page to select') }, async ({ index }) => {
22
+ return safeResult(async () => {
23
+ const info = await browserManager.selectPage(index);
24
+ return JSON.stringify(info, null, 2);
25
+ });
26
+ });
27
+ }
28
+ //# sourceMappingURL=connection.tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.tools.js","sourceRoot":"","sources":["../../src/tools/connection.tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,mGAAmG,EACnG,EAAE,EACF,KAAK,IAAI,EAAE;QACT,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,CAAC;YAE7C,cAAc,CAAC,MAAM,EAAE,CAAC;YACxB,cAAc,CAAC,MAAM,EAAE,CAAC;YAExB,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,oDAAoD,EACpD,EAAE,EACF,KAAK,IAAI,EAAE;QACT,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,aAAa,EACb,gEAAgE,EAChE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,wCAAwC,CAAC,EAAE,EACrF,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACpD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerConsoleTools(server: McpServer): void;
@@ -0,0 +1,25 @@
1
+ import { z } from 'zod';
2
+ import { consoleCapture } from '../browser/console.js';
3
+ import { safeResult } from '../utils/errors.js';
4
+ export function registerConsoleTools(server) {
5
+ server.tool('get_console_errors', 'Return console errors (and optionally warnings) captured from the active page.', {
6
+ limit: z.number().int().min(1).max(200).optional().describe('Max number of entries to return'),
7
+ includeWarnings: z.boolean().optional().describe('Also include console warnings (default: false)'),
8
+ }, async ({ limit, includeWarnings }) => {
9
+ return safeResult(async () => {
10
+ const errors = consoleCapture.getErrors(limit);
11
+ let results = [...errors];
12
+ if (includeWarnings) {
13
+ const warnings = consoleCapture.getEntries('warn', limit);
14
+ results = [...results, ...warnings].sort((a, b) => a.timestamp - b.timestamp);
15
+ if (limit)
16
+ results = results.slice(-limit);
17
+ }
18
+ if (results.length === 0) {
19
+ return 'No console errors captured.';
20
+ }
21
+ return JSON.stringify(results, null, 2);
22
+ });
23
+ });
24
+ }
25
+ //# sourceMappingURL=console.tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.tools.js","sourceRoot":"","sources":["../../src/tools/console.tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,gFAAgF,EAChF;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QAC9F,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;KACnG,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,EAAE;QACnC,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC/C,IAAI,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;YAE1B,IAAI,eAAe,EAAE,CAAC;gBACpB,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBAC1D,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;gBAC9E,IAAI,KAAK;oBAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;YAC7C,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,6BAA6B,CAAC;YACvC,CAAC;YAED,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerDebugTools(server: McpServer): void;
@@ -0,0 +1,226 @@
1
+ import { z } from 'zod';
2
+ import { bridge } from '../bridge/native-messaging.js';
3
+ import { networkMonitor } from '../browser/network.js';
4
+ import { consoleCapture } from '../browser/console.js';
5
+ import { safeResult } from '../utils/errors.js';
6
+ export function registerDebugTools(server) {
7
+ // ───────────────────────────────────────────────
8
+ // debug_element
9
+ // ───────────────────────────────────────────────
10
+ server.tool('debug_element', 'Comprehensive diagnosis of why an element may not be clickable, visible, or behaving as expected. Checks the element and its entire ancestor chain for CSS issues, overlaps, disabled state, stacking context, and clickability.', {
11
+ selector: z.string().describe('CSS selector of the element to debug'),
12
+ }, async ({ selector }) => {
13
+ return safeResult(async () => {
14
+ const analysis = await bridge.sendRequest('debug_element', { selector });
15
+ if (!analysis.found) {
16
+ const result = { issue: 'Element not found', reasons: [`No element matches selector: ${selector}`], confidence: 1.0 };
17
+ return JSON.stringify(result);
18
+ }
19
+ const failedChecks = analysis.checks.filter((c) => !c.passed);
20
+ const diagnosis = {
21
+ issue: failedChecks.length > 0 ? failedChecks[0].detail : 'No obvious issues detected',
22
+ reasons: failedChecks.map((c) => c.detail),
23
+ confidence: failedChecks.length > 0 ? Math.min(0.95, 0.7 + failedChecks.length * 0.05) : 0.4,
24
+ };
25
+ return JSON.stringify({ ...analysis, diagnosis }, null, 2);
26
+ });
27
+ });
28
+ // ───────────────────────────────────────────────
29
+ // diagnose_network
30
+ // ───────────────────────────────────────────────
31
+ server.tool('diagnose_network', 'Diagnose network issues: failed requests, slow responses, CORS problems, rate limiting, and error body parsing. Groups failures by domain.', {
32
+ urlPattern: z.string().optional().describe('Regex pattern to filter by URL'),
33
+ }, async ({ urlPattern }) => {
34
+ return safeResult(async () => {
35
+ const entries = networkMonitor.getEntries({ urlPattern });
36
+ const consoleErrors = consoleCapture.getErrors();
37
+ const durations = entries.map((e) => e.timing.duration).filter((d) => d > 0).sort((a, b) => a - b);
38
+ const p95Index = Math.floor(durations.length * 0.95);
39
+ const p95 = durations[p95Index] ?? 0;
40
+ const timingBuckets = { fast: 0, normal: 0, slow: 0, verySlow: 0 };
41
+ for (const d of durations) {
42
+ if (d < 200)
43
+ timingBuckets.fast++;
44
+ else if (d < 1000)
45
+ timingBuckets.normal++;
46
+ else if (d < 3000)
47
+ timingBuckets.slow++;
48
+ else
49
+ timingBuckets.verySlow++;
50
+ }
51
+ const failedRequests = entries
52
+ .filter((e) => e.status !== null && e.status >= 400)
53
+ .map((e) => {
54
+ let errorBody = null;
55
+ if (e.responseBody) {
56
+ try {
57
+ const parsed = JSON.parse(e.responseBody);
58
+ errorBody = parsed.message || parsed.error || parsed.detail || e.responseBody.slice(0, 500);
59
+ }
60
+ catch {
61
+ errorBody = e.responseBody.slice(0, 500);
62
+ }
63
+ }
64
+ return { url: e.url, status: e.status, method: e.method, errorBody };
65
+ });
66
+ const corsIssues = entries
67
+ .filter((e) => e.status === null && !e.resourceType.match(/^(image|stylesheet|font|media)$/i))
68
+ .map((e) => ({ url: e.url, method: e.method }));
69
+ const rateLimited = entries
70
+ .filter((e) => e.status === 429)
71
+ .map((e) => {
72
+ let domain = '';
73
+ try {
74
+ domain = new URL(e.url).hostname;
75
+ }
76
+ catch { }
77
+ return { url: e.url, domain };
78
+ });
79
+ const failuresByDomain = {};
80
+ for (const f of failedRequests) {
81
+ try {
82
+ const domain = new URL(f.url).hostname;
83
+ failuresByDomain[domain] = (failuresByDomain[domain] || 0) + 1;
84
+ }
85
+ catch { }
86
+ }
87
+ const parts = [];
88
+ parts.push(`${entries.length} total requests captured`);
89
+ if (failedRequests.length > 0)
90
+ parts.push(`${failedRequests.length} failed (4xx/5xx)`);
91
+ if (corsIssues.length > 0)
92
+ parts.push(`${corsIssues.length} possible CORS issues`);
93
+ if (rateLimited.length > 0)
94
+ parts.push(`${rateLimited.length} rate-limited (429)`);
95
+ if (timingBuckets.verySlow > 0)
96
+ parts.push(`${timingBuckets.verySlow} very slow requests (>3s)`);
97
+ if (p95 > 1000)
98
+ parts.push(`P95 response time: ${Math.round(p95)}ms`);
99
+ if (failedRequests.length === 0 && corsIssues.length === 0)
100
+ parts.push('No issues detected');
101
+ const diagnosis = {
102
+ totalRequests: entries.length,
103
+ timingBuckets,
104
+ p95ResponseTime: Math.round(p95),
105
+ failedRequests: failedRequests.slice(-30),
106
+ corsIssues: corsIssues.slice(-10),
107
+ rateLimited: rateLimited.slice(-10),
108
+ failuresByDomain,
109
+ relatedConsoleErrors: consoleErrors.slice(-10).map((e) => e.text),
110
+ summary: parts.join('. ') + '.',
111
+ };
112
+ return JSON.stringify(diagnosis, null, 2);
113
+ });
114
+ });
115
+ // ───────────────────────────────────────────────
116
+ // correlate_issues
117
+ // ───────────────────────────────────────────────
118
+ server.tool('correlate_issues', 'Cross-reference network errors, console errors, and DOM state. Detects broken resources, auth failure chains, repeated errors, and ranks by severity.', {}, async () => {
119
+ return safeResult(async () => {
120
+ const allNetworkEntries = networkMonitor.getEntries();
121
+ const networkErrors = allNetworkEntries.filter((e) => e.status !== null && e.status >= 400);
122
+ const consoleErrors = consoleCapture.getErrors(100);
123
+ const allConsole = consoleCapture.getEntries(undefined, 200);
124
+ const correlations = [];
125
+ // 1. Network <-> Console: URL pathname matching
126
+ for (const netErr of networkErrors.slice(-30)) {
127
+ let pathname = '';
128
+ try {
129
+ pathname = new URL(netErr.url).pathname;
130
+ }
131
+ catch {
132
+ continue;
133
+ }
134
+ const related = consoleErrors.filter((ce) => ce.text.includes(pathname));
135
+ if (related.length > 0) {
136
+ correlations.push({
137
+ domain: 'network <-> console',
138
+ severity: netErr.status >= 500 ? 'critical' : 'warning',
139
+ details: `Failed ${netErr.method} ${netErr.url} (${netErr.status}) has ${related.length} related console error(s)`,
140
+ evidence: related.slice(0, 3).map((r) => r.text.slice(0, 200)),
141
+ });
142
+ }
143
+ }
144
+ // 2. Network -> DOM: broken images, failed scripts/stylesheets
145
+ const brokenResources = allNetworkEntries.filter((e) => (e.status !== null && e.status >= 400) &&
146
+ ['script', 'stylesheet', 'image'].includes(e.resourceType));
147
+ for (const res of brokenResources.slice(-10)) {
148
+ let severity = 'warning';
149
+ if (res.resourceType === 'script')
150
+ severity = 'critical';
151
+ correlations.push({
152
+ domain: 'network -> DOM',
153
+ severity,
154
+ details: `Broken ${res.resourceType}: ${res.url} (${res.status})`,
155
+ evidence: [`Resource type: ${res.resourceType}`, `Status: ${res.status}`],
156
+ });
157
+ }
158
+ // 3. Console -> DOM: check if element IDs from console errors exist
159
+ const errorTexts = consoleErrors.slice(-20).map((e) => e.text);
160
+ const domCorrelations = await bridge.sendRequest('correlate_dom_check', { errors: errorTexts });
161
+ const domResults = (domCorrelations.results ?? []);
162
+ for (const dc of domResults) {
163
+ correlations.push({
164
+ domain: 'console -> DOM',
165
+ severity: dc.exists ? 'info' : 'warning',
166
+ details: `Console error references ${dc.selector} (${dc.exists ? 'element exists' : 'element NOT found'})`,
167
+ evidence: [dc.error],
168
+ });
169
+ }
170
+ // 4. Auth failure chains (401 -> redirect pattern)
171
+ const authFailures = networkErrors.filter((e) => e.status === 401 || e.status === 403);
172
+ if (authFailures.length > 0) {
173
+ const redirectsAfter = allNetworkEntries.filter((e) => (e.status === 302 || e.status === 301) &&
174
+ e.timestamp > authFailures[0].timestamp);
175
+ correlations.push({
176
+ domain: 'auth chain',
177
+ severity: 'critical',
178
+ details: `${authFailures.length} auth failure(s) (401/403)${redirectsAfter.length > 0 ? ` followed by ${redirectsAfter.length} redirect(s)` : ''}`,
179
+ evidence: authFailures.slice(0, 5).map((a) => `${a.method} ${a.url} -> ${a.status}`),
180
+ });
181
+ }
182
+ // 5. Repeated errors
183
+ const errorCounts = {};
184
+ for (const ce of consoleErrors) {
185
+ const key = ce.text.slice(0, 100);
186
+ errorCounts[key] = (errorCounts[key] || 0) + 1;
187
+ }
188
+ const repeated = Object.entries(errorCounts).filter(([, count]) => count >= 3);
189
+ for (const [text, count] of repeated) {
190
+ correlations.push({
191
+ domain: 'repeated errors',
192
+ severity: 'warning',
193
+ details: `Console error repeated ${count} times`,
194
+ evidence: [text],
195
+ });
196
+ }
197
+ // 6. Timeline (last 30 events chronologically)
198
+ const timeline = [
199
+ ...allNetworkEntries.slice(-15).map((e) => ({
200
+ type: 'network',
201
+ time: e.timestamp,
202
+ summary: `${e.method} ${e.url.slice(0, 80)} -> ${e.status ?? 'aborted'}`,
203
+ })),
204
+ ...allConsole.slice(-15).map((e) => ({
205
+ type: 'console',
206
+ time: e.timestamp,
207
+ summary: `[${e.level}] ${e.text.slice(0, 100)}`,
208
+ })),
209
+ ].sort((a, b) => a.time - b.time);
210
+ const severityOrder = { critical: 0, warning: 1, info: 2 };
211
+ correlations.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
212
+ const critical = correlations.filter((c) => c.severity === 'critical').length;
213
+ const warning = correlations.filter((c) => c.severity === 'warning').length;
214
+ return JSON.stringify({
215
+ networkErrors: networkErrors.length,
216
+ consoleErrors: consoleErrors.length,
217
+ correlations,
218
+ timeline: timeline.slice(-30),
219
+ summary: correlations.length > 0
220
+ ? `Found ${correlations.length} correlation(s): ${critical} critical, ${warning} warning, ${correlations.length - critical - warning} info`
221
+ : 'No cross-domain correlations found',
222
+ }, null, 2);
223
+ });
224
+ });
225
+ }
226
+ //# sourceMappingURL=debug.tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.tools.js","sourceRoot":"","sources":["../../src/tools/debug.tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerDOMTools(server: McpServer): void;
@@ -0,0 +1,26 @@
1
+ import { z } from 'zod';
2
+ import { getSnapshot, queryDOM } from '../browser/dom.js';
3
+ import { safeResult } from '../utils/errors.js';
4
+ export function registerDOMTools(server) {
5
+ server.tool('get_dom_tree', 'Return the DOM tree structure of the active page. Optionally scope to a CSS selector and limit tree depth.', {
6
+ selector: z.string().optional().describe('CSS selector to scope the tree (default: entire document)'),
7
+ depth: z.number().int().min(1).max(20).optional().describe('Max tree depth (default: 10)'),
8
+ }, async ({ selector, depth }) => {
9
+ return safeResult(async () => {
10
+ const tree = await getSnapshot(selector, depth);
11
+ return JSON.stringify(tree, null, 2);
12
+ });
13
+ });
14
+ server.tool('query_dom', 'Query the active page DOM using a CSS selector. Returns matching elements with tag, id, classes, text content, and attributes.', {
15
+ selector: z.string().describe('CSS selector to query'),
16
+ }, async ({ selector }) => {
17
+ return safeResult(async () => {
18
+ const elements = await queryDOM(selector);
19
+ if (elements.length === 0) {
20
+ return `No elements found matching selector: ${selector}`;
21
+ }
22
+ return JSON.stringify(elements, null, 2);
23
+ });
24
+ });
25
+ }
26
+ //# sourceMappingURL=dom.tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.tools.js","sourceRoot":"","sources":["../../src/tools/dom.tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,IAAI,CACT,cAAc,EACd,4GAA4G,EAC5G;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2DAA2D,CAAC;QACrG,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;KAC3F,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;QAC5B,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,WAAW,EACX,gIAAgI,EAChI;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;KACvD,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAE1C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,wCAAwC,QAAQ,EAAE,CAAC;YAC5D,CAAC;YAED,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerEventTools(server: McpServer): void;
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ import { bridge } from '../bridge/native-messaging.js';
3
+ import { safeResult } from '../utils/errors.js';
4
+ export function registerEventTools(server) {
5
+ server.tool('get_event_listeners', 'Get event listeners attached to elements matching a selector via Chrome DevTools Protocol. Returns event type, handler source preview, and listener options.', {
6
+ selector: z.string().describe('CSS selector to query'),
7
+ }, async ({ selector }) => {
8
+ return safeResult(async () => {
9
+ const result = await bridge.sendRequest('get_event_listeners', { selector });
10
+ const results = result.results;
11
+ if (!results || results.length === 0) {
12
+ return `No elements found for selector: ${selector}`;
13
+ }
14
+ return JSON.stringify(results, null, 2);
15
+ });
16
+ });
17
+ }
18
+ //# sourceMappingURL=events.tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.tools.js","sourceRoot":"","sources":["../../src/tools/events.tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,8JAA8J,EAC9J;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;KACvD,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,qBAAqB,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC7E,MAAM,OAAO,GAAG,MAAM,CAAC,OAAyC,CAAC;YAEjE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrC,OAAO,mCAAmC,QAAQ,EAAE,CAAC;YACvD,CAAC;YAED,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerLayoutTools(server: McpServer): void;
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ import { bridge } from '../bridge/native-messaging.js';
3
+ import { safeResult } from '../utils/errors.js';
4
+ export function registerLayoutTools(server) {
5
+ server.tool('get_layout_info', 'Get bounding box, visibility, viewport status, overlap detection, parent clipping, and scroll context for elements matching a selector.', {
6
+ selector: z.string().describe('CSS selector to query'),
7
+ }, async ({ selector }) => {
8
+ return safeResult(async () => {
9
+ const result = await bridge.sendRequest('get_layout', { selector });
10
+ return JSON.stringify(result.results ?? result, null, 2);
11
+ });
12
+ });
13
+ server.tool('get_visible_elements', 'Return all interactive elements currently visible in the viewport with accessibility info (role, aria-label, disabled state).', {}, async () => {
14
+ return safeResult(async () => {
15
+ const result = await bridge.sendRequest('get_visible', {});
16
+ return JSON.stringify(result.elements ?? result, null, 2);
17
+ });
18
+ });
19
+ }
20
+ //# sourceMappingURL=layout.tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.tools.js","sourceRoot":"","sources":["../../src/tools/layout.tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,yIAAyI,EACzI;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;KACvD,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,+HAA+H,EAC/H,EAAE,EACF,KAAK,IAAI,EAAE;QACT,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;YAC3D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerNetworkTools(server: McpServer): void;
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { networkMonitor } from '../browser/network.js';
3
+ import { safeResult } from '../utils/errors.js';
4
+ export function registerNetworkTools(server) {
5
+ server.tool('get_network_calls', 'Return captured network requests from the active page. Supports filtering by URL pattern, status code, and resource type.', {
6
+ urlPattern: z.string().optional().describe('Regex pattern to filter by URL'),
7
+ statusCode: z.number().int().optional().describe('Filter by exact HTTP status code'),
8
+ resourceType: z.string().optional().describe('Filter by resource type (xhr, fetch, document, stylesheet, image, script, etc.)'),
9
+ limit: z.number().int().min(1).max(100).optional().describe('Max number of entries to return (default: all, max 100)'),
10
+ }, async ({ urlPattern, statusCode, resourceType, limit }) => {
11
+ return safeResult(async () => {
12
+ const entries = networkMonitor.getEntries({ urlPattern, statusCode, resourceType, limit });
13
+ if (entries.length === 0) {
14
+ return 'No network calls captured yet. Browse some pages first, then try again.';
15
+ }
16
+ const summary = entries.map((e) => ({
17
+ url: e.url,
18
+ method: e.method,
19
+ status: e.status,
20
+ resourceType: e.resourceType,
21
+ timing: e.timing,
22
+ requestBody: e.requestBody,
23
+ responseBody: e.responseBody?.slice(0, 2000) ?? null,
24
+ }));
25
+ return JSON.stringify(summary, null, 2);
26
+ });
27
+ });
28
+ }
29
+ //# sourceMappingURL=network.tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.tools.js","sourceRoot":"","sources":["../../src/tools/network.tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,2HAA2H,EAC3H;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAC5E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;QACpF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iFAAiF,CAAC;QAC/H,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;KACvH,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE;QACxD,OAAO,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;YAE3F,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,yEAAyE,CAAC;YACnF,CAAC;YAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAClC,GAAG,EAAE,CAAC,CAAC,GAAG;gBACV,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI;aACrD,CAAC,CAAC,CAAC;YAEJ,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerScreenshotTools(server: McpServer): void;