browser-devtools-mcp 0.0.1 → 0.0.3

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 (47) hide show
  1. package/README.md +177 -50
  2. package/dist/browser.js +162 -22
  3. package/dist/browser.js.map +1 -1
  4. package/dist/config.js +46 -1
  5. package/dist/config.js.map +1 -1
  6. package/dist/context.js +72 -12
  7. package/dist/context.js.map +1 -1
  8. package/dist/index.js +77 -42
  9. package/dist/index.js.map +1 -1
  10. package/dist/otel/otel-controller.js +319 -0
  11. package/dist/otel/otel-controller.js.map +1 -0
  12. package/dist/otel/otel-initializer.bundle.js +2 -0
  13. package/dist/otel/otel-initializer.bundle.js.map +7 -0
  14. package/dist/otel/otel-proxy.js +407 -0
  15. package/dist/otel/otel-proxy.js.map +1 -0
  16. package/dist/server-info.js +48 -10
  17. package/dist/server-info.js.map +1 -1
  18. package/dist/server.js +47 -32
  19. package/dist/server.js.map +1 -1
  20. package/dist/tools/a11y/index.js +7 -0
  21. package/dist/tools/a11y/index.js.map +1 -0
  22. package/dist/tools/{content → a11y}/take-aria-snapshot.js +6 -1
  23. package/dist/tools/a11y/take-aria-snapshot.js.map +1 -0
  24. package/dist/tools/a11y/take-ax-tree-snapshot.js +850 -0
  25. package/dist/tools/a11y/take-ax-tree-snapshot.js.map +1 -0
  26. package/dist/tools/content/index.js +0 -2
  27. package/dist/tools/content/index.js.map +1 -1
  28. package/dist/tools/content/save-as-pdf.js +9 -36
  29. package/dist/tools/content/save-as-pdf.js.map +1 -1
  30. package/dist/tools/content/take-screenshot.js +14 -37
  31. package/dist/tools/content/take-screenshot.js.map +1 -1
  32. package/dist/tools/index.js +2 -0
  33. package/dist/tools/index.js.map +1 -1
  34. package/dist/tools/monitoring/get-trace-id.js +30 -0
  35. package/dist/tools/monitoring/get-trace-id.js.map +1 -0
  36. package/dist/tools/monitoring/index.js +10 -1
  37. package/dist/tools/monitoring/index.js.map +1 -1
  38. package/dist/tools/monitoring/new-trace-id.js +32 -0
  39. package/dist/tools/monitoring/new-trace-id.js.map +1 -0
  40. package/dist/tools/monitoring/set-trace-id.js +28 -0
  41. package/dist/tools/monitoring/set-trace-id.js.map +1 -0
  42. package/dist/tools/tool-executor.js +26 -4
  43. package/dist/tools/tool-executor.js.map +1 -1
  44. package/dist/utils.js +38 -0
  45. package/dist/utils.js.map +1 -1
  46. package/package.json +7 -2
  47. package/dist/tools/content/take-aria-snapshot.js.map +0 -1
@@ -0,0 +1,407 @@
1
+ "use strict";
2
+ /**
3
+ * -----------------------------------------------------------------------------
4
+ * WHY THIS OTEL PROXY EXISTS
5
+ * -----------------------------------------------------------------------------
6
+ *
7
+ * Problem:
8
+ * --------
9
+ * When OpenTelemetry Web SDK runs inside a real browser page, it exports traces
10
+ * via OTLP/HTTP using `fetch` or `XMLHttpRequest`.
11
+ *
12
+ * In Playwright-driven debugging sessions this causes multiple issues:
13
+ *
14
+ * 1) CORS restrictions
15
+ * -----------------
16
+ * Browsers enforce CORS. If the page origin (e.g. https://remote-site.com)
17
+ * tries to POST traces to a collector like:
18
+ *
19
+ * http://localhost:4318/v1/traces
20
+ *
21
+ * the request is blocked unless the collector explicitly enables
22
+ * Access-Control-Allow-Origin for that site.
23
+ *
24
+ * We often do NOT control the collector configuration (Jaeger, Tempo, etc),
25
+ * especially in local or remote debugging setups.
26
+ *
27
+ * 2) Remote pages + local tools
28
+ * ---------------------------
29
+ * A very common setup is:
30
+ * - Playwright + MCP server running locally
31
+ * - A remote production/staging website loaded in the browser
32
+ *
33
+ * That remote website has no way to directly talk to a local OTLP endpoint
34
+ * due to browser security rules.
35
+ *
36
+ * 3) Collector incompatibilities
37
+ * -----------------------------
38
+ * Different collectors behave differently:
39
+ * - Some support CORS, some don’t
40
+ * - Some only support OTLP/gRPC
41
+ * - Some reject preflight OPTIONS requests
42
+ *
43
+ * Solution:
44
+ * ---------
45
+ * We introduce a SAME-ORIGIN OTEL PROXY using Playwright's `context.route`.
46
+ *
47
+ * Instead of exporting directly to the real collector, the browser sends OTLP to:
48
+ *
49
+ * https://<page-origin>/__mcp_otel/v1/traces
50
+ *
51
+ * From the browser perspective this is SAME-ORIGIN → no CORS issues.
52
+ *
53
+ * Playwright intercepts that request *outside* the browser via `context.route`
54
+ * and forwards the payload to the real upstream collector.
55
+ *
56
+ * Why `context.route` (and not a local HTTP server)?
57
+ * --------------------------------------------------
58
+ * - Zero CORS by construction (browser thinks it's same-origin)
59
+ * - Works for ANY remote site origin
60
+ * - No port exposure / firewall issues
61
+ * - Lifecycle tied to BrowserContext (session-friendly)
62
+ *
63
+ * Path-based fan-out:
64
+ * -------------------
65
+ * Browser sends:
66
+ * /__mcp_otel/v1/traces
67
+ * /__mcp_otel/v1/metrics
68
+ * /__mcp_otel/v1/logs
69
+ *
70
+ * Proxy strips base path and forwards:
71
+ * <upstreamBase>/v1/traces
72
+ * <upstreamBase>/v1/metrics
73
+ * <upstreamBase>/v1/logs
74
+ *
75
+ * Performance considerations:
76
+ * ---------------------------
77
+ * - Browser is ACKed immediately (204/200)
78
+ * - Forwarding happens asynchronously in a bounded queue
79
+ * - Slow/failing collectors do NOT block the page
80
+ * -----------------------------------------------------------------------------
81
+ */
82
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
83
+ if (k2 === undefined) k2 = k;
84
+ var desc = Object.getOwnPropertyDescriptor(m, k);
85
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
86
+ desc = { enumerable: true, get: function() { return m[k]; } };
87
+ }
88
+ Object.defineProperty(o, k2, desc);
89
+ }) : (function(o, m, k, k2) {
90
+ if (k2 === undefined) k2 = k;
91
+ o[k2] = m[k];
92
+ }));
93
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
94
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
95
+ }) : function(o, v) {
96
+ o["default"] = v;
97
+ });
98
+ var __importStar = (this && this.__importStar) || (function () {
99
+ var ownKeys = function(o) {
100
+ ownKeys = Object.getOwnPropertyNames || function (o) {
101
+ var ar = [];
102
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
103
+ return ar;
104
+ };
105
+ return ownKeys(o);
106
+ };
107
+ return function (mod) {
108
+ if (mod && mod.__esModule) return mod;
109
+ var result = {};
110
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
111
+ __setModuleDefault(result, mod);
112
+ return result;
113
+ };
114
+ })();
115
+ Object.defineProperty(exports, "__esModule", { value: true });
116
+ exports.OTELProxy = void 0;
117
+ const logger = __importStar(require("../logger"));
118
+ function _normalizeBasePath(input) {
119
+ let p = input.trim();
120
+ if (!p.startsWith('/')) {
121
+ p = '/' + p;
122
+ }
123
+ if (!p.endsWith('/')) {
124
+ p = p + '/';
125
+ }
126
+ return p;
127
+ }
128
+ function _normalizeUpstreamBaseUrl(input) {
129
+ const u = input.trim();
130
+ if (!u) {
131
+ return u;
132
+ }
133
+ // Remove trailing slash to avoid double slashes when appending suffix
134
+ if (u.endsWith('/')) {
135
+ return u.slice(0, -1);
136
+ }
137
+ return u;
138
+ }
139
+ /**
140
+ * Extracts the pathname suffix after basePath.
141
+ *
142
+ * basePath is normalized to always end with '/', so for:
143
+ * basePath = '/__mcp_otel/'
144
+ * pathname = '/__mcp_otel/v1/traces'
145
+ *
146
+ * we return '/v1/traces'.
147
+ */
148
+ function _computeSuffixPath(fullUrl, basePath) {
149
+ try {
150
+ const u = new URL(fullUrl);
151
+ const pathname = u.pathname;
152
+ if (!pathname.startsWith(basePath)) {
153
+ return null;
154
+ }
155
+ const raw = pathname.slice(basePath.length); // e.g. 'v1/traces'
156
+ if (!raw) {
157
+ // If someone POSTs directly to '/__mcp_otel/' without suffix,
158
+ // treat as invalid (we don't know where to fan-out).
159
+ return null;
160
+ }
161
+ return raw.startsWith('/') ? raw : '/' + raw;
162
+ }
163
+ catch {
164
+ return null;
165
+ }
166
+ }
167
+ function _appendSuffixToUpstream(upstreamBaseUrl, suffixPath, originalUrl) {
168
+ try {
169
+ const u = new URL(originalUrl);
170
+ const qs = u.search ?? '';
171
+ return upstreamBaseUrl + suffixPath + qs;
172
+ }
173
+ catch {
174
+ return upstreamBaseUrl + suffixPath;
175
+ }
176
+ }
177
+ class OTELProxy {
178
+ config;
179
+ queue;
180
+ workers;
181
+ isRunning;
182
+ isInstalled;
183
+ metrics;
184
+ constructor(config) {
185
+ const maxQueueSize = config.maxQueueSize ?? 200;
186
+ const concurrency = config.concurrency ?? 2;
187
+ const respondNoContent = config.respondNoContent ?? true;
188
+ const normalizedLocalPath = _normalizeBasePath(config.localPath);
189
+ const normalizedUpstreamUrl = _normalizeUpstreamBaseUrl(config.upstreamUrl);
190
+ this.config = {
191
+ ...config,
192
+ localPath: normalizedLocalPath,
193
+ upstreamUrl: normalizedUpstreamUrl,
194
+ maxQueueSize,
195
+ concurrency,
196
+ respondNoContent,
197
+ };
198
+ this.queue = [];
199
+ this.workers = [];
200
+ this.isRunning = false;
201
+ this.isInstalled = false;
202
+ this.metrics = {
203
+ routedRequests: 0,
204
+ acceptedBatches: 0,
205
+ droppedBatches: 0,
206
+ forwardedBatches: 0,
207
+ failedBatches: 0,
208
+ inFlight: 0,
209
+ queueSize: 0,
210
+ lastError: null,
211
+ };
212
+ }
213
+ getMetrics() {
214
+ return { ...this.metrics, queueSize: this.queue.length };
215
+ }
216
+ /**
217
+ * Install the route handler and start background workers.
218
+ * Call this once per BrowserContext.
219
+ */
220
+ async install(context) {
221
+ if (this.isInstalled) {
222
+ return;
223
+ }
224
+ const basePath = this.config.localPath;
225
+ if (!basePath.startsWith('/')) {
226
+ throw new Error('localPath must start with "/" (e.g. "/__mcp_otel/").');
227
+ }
228
+ // Match any origin that contains the base path in the pathname.
229
+ const pattern = `**${basePath}**`;
230
+ await context.route(pattern, async (route) => {
231
+ await this._handleRoute(route);
232
+ });
233
+ this.isInstalled = true;
234
+ if (!this.isRunning) {
235
+ await this.start();
236
+ }
237
+ logger.debug(`[otel-proxy] installed route pattern: ${pattern} (basePath=${basePath}, upstreamBase=${this.config.upstreamUrl})`);
238
+ }
239
+ /**
240
+ * Uninstall route handler and stop workers.
241
+ */
242
+ async uninstall(context) {
243
+ if (!this.isInstalled) {
244
+ return;
245
+ }
246
+ const pattern = `**${this.config.localPath}**`;
247
+ try {
248
+ await context.unroute(pattern);
249
+ }
250
+ catch {
251
+ // Ignore if not supported or already removed.
252
+ }
253
+ this.isInstalled = false;
254
+ await this.stop();
255
+ }
256
+ /**
257
+ * Start worker loop(s) that flush the queue to upstream.
258
+ */
259
+ async start() {
260
+ if (this.isRunning) {
261
+ return;
262
+ }
263
+ this.isRunning = true;
264
+ const workerCount = Math.max(1, this.config.concurrency);
265
+ for (let i = 0; i < workerCount; i++) {
266
+ const w = this._workerLoop(i);
267
+ this.workers.push(w);
268
+ }
269
+ logger.debug(`[otel-proxy] started with concurrency=${workerCount}, maxQueueSize=${this.config.maxQueueSize}`);
270
+ }
271
+ /**
272
+ * Stop workers. Any queued items will be dropped.
273
+ */
274
+ async stop() {
275
+ if (!this.isRunning) {
276
+ return;
277
+ }
278
+ this.isRunning = false;
279
+ // Drop queue immediately to avoid memory growth on shutdown.
280
+ this.queue.length = 0;
281
+ try {
282
+ await Promise.allSettled(this.workers);
283
+ }
284
+ finally {
285
+ this.workers.length = 0;
286
+ }
287
+ logger.debug('[otel-proxy] stopped');
288
+ }
289
+ async _handleRoute(route) {
290
+ const req = route.request();
291
+ this.metrics.routedRequests++;
292
+ // ACK preflight quickly (do not forward).
293
+ // Some setups / collectors choke on OPTIONS anyway.
294
+ if (req.method().toUpperCase() === 'OPTIONS') {
295
+ await this._fulfillFast(route);
296
+ return;
297
+ }
298
+ if (this.config.shouldForward) {
299
+ const should = this.config.shouldForward(req);
300
+ if (!should) {
301
+ await this._fulfillFast(route);
302
+ return;
303
+ }
304
+ }
305
+ const requestUrl = req.url();
306
+ const basePath = this.config.localPath;
307
+ const suffixPath = _computeSuffixPath(requestUrl, basePath);
308
+ if (!suffixPath) {
309
+ // Pattern matched but URL parsing/path extraction failed; fallback so we don't break the page.
310
+ await route.fallback();
311
+ return;
312
+ }
313
+ const upstreamFullUrl = _appendSuffixToUpstream(this.config.upstreamUrl, suffixPath, requestUrl);
314
+ const buf = await req.postDataBuffer();
315
+ const body = buf ?? Buffer.alloc(0);
316
+ const contentTypeHeader = req.headers()['content-type'];
317
+ const contentType = contentTypeHeader ?? 'application/x-protobuf';
318
+ const method = req.method();
319
+ const headers = {
320
+ 'content-type': contentType,
321
+ };
322
+ if (this.config.upstreamHeaders) {
323
+ for (const [k, v] of Object.entries(this.config.upstreamHeaders)) {
324
+ headers[k] = v;
325
+ }
326
+ }
327
+ if (this.queue.length >= this.config.maxQueueSize) {
328
+ this.metrics.droppedBatches++;
329
+ await this._fulfillFast(route);
330
+ logger.warn(`[otel-proxy] dropped batch (queue full: ${this.queue.length}/${this.config.maxQueueSize}) suffix=${suffixPath}`);
331
+ return;
332
+ }
333
+ const item = {
334
+ body,
335
+ contentType,
336
+ createdAtMs: Date.now(),
337
+ upstreamUrl: upstreamFullUrl,
338
+ method,
339
+ headers,
340
+ };
341
+ this.queue.push(item);
342
+ this.metrics.acceptedBatches++;
343
+ await this._fulfillFast(route);
344
+ }
345
+ async _fulfillFast(route) {
346
+ const status = this.config.respondNoContent ? 204 : 200;
347
+ if (status === 204) {
348
+ await route.fulfill({ status });
349
+ return;
350
+ }
351
+ await route.fulfill({
352
+ status,
353
+ headers: { 'content-type': 'text/plain; charset=utf-8' },
354
+ body: '',
355
+ });
356
+ }
357
+ async _workerLoop(workerIndex) {
358
+ while (this.isRunning) {
359
+ const item = this.queue.shift();
360
+ if (!item) {
361
+ await this._sleep(25);
362
+ continue;
363
+ }
364
+ this.metrics.inFlight++;
365
+ try {
366
+ await this._forwardUpstream(item);
367
+ this.metrics.forwardedBatches++;
368
+ }
369
+ catch (e) {
370
+ this.metrics.failedBatches++;
371
+ const msg = e instanceof Error ? e.message : String(e);
372
+ this.metrics.lastError = msg;
373
+ logger.warn(`[otel-proxy] worker=${workerIndex} forward failed: ${msg}`);
374
+ }
375
+ finally {
376
+ this.metrics.inFlight--;
377
+ }
378
+ }
379
+ }
380
+ async _forwardUpstream(item) {
381
+ const res = await fetch(item.upstreamUrl, {
382
+ method: item.method,
383
+ headers: item.headers,
384
+ body: new Uint8Array(item.body),
385
+ });
386
+ if (res.status < 200 || res.status >= 300) {
387
+ const text = await this._safeReadText(res);
388
+ throw new Error(`upstream returned ${res.status} for ${item.upstreamUrl}: ${text}`);
389
+ }
390
+ }
391
+ async _safeReadText(res) {
392
+ try {
393
+ const t = await res.text();
394
+ return t.slice(0, 500);
395
+ }
396
+ catch {
397
+ return '';
398
+ }
399
+ }
400
+ async _sleep(ms) {
401
+ await new Promise((resolve) => {
402
+ setTimeout(() => resolve(), ms);
403
+ });
404
+ }
405
+ }
406
+ exports.OTELProxy = OTELProxy;
407
+ //# sourceMappingURL=otel-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel-proxy.js","sourceRoot":"","sources":["../../src/otel/otel-proxy.ts"],"names":[],"mappings":"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"}
@@ -1,32 +1,70 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SERVER_VERSION = exports.SERVER_NAME = void 0;
3
+ exports.UI_DEBUGGING_POLICY = exports.SERVER_INSTRUCTIONS = exports.SERVER_VERSION = exports.SERVER_NAME = void 0;
4
4
  exports.getServerInstructions = getServerInstructions;
5
5
  exports.SERVER_NAME = 'browser-devtools-mcp';
6
6
  exports.SERVER_VERSION = require('../package.json').version;
7
- const SERVER_INSTRUCTIONS = `
8
- This MCP server exposes a Playwright-powered browser runtime to AI agents, enabling deep, bidirectional debugging and interaction with live web pages.
7
+ exports.SERVER_INSTRUCTIONS = `
8
+ This MCP server exposes a Playwright-powered browser runtime to AI agents,
9
+ enabling deep, bidirectional debugging and interaction with live web pages.
9
10
 
10
- It supports both visual understanding and code-level inspection of browser state, similar to existing Playwright and Chrome DevTools–based MCP servers, with a focus on AI-driven exploration, diagnosis, and action.
11
+ It supports both visual understanding and code-level inspection of browser state,
12
+ similar to existing Playwright and Chrome DevTools–based MCP servers, with a focus on AI-driven exploration, diagnosis, and action.
11
13
 
12
14
  Core capabilities include:
13
-
14
- - Visual inspection of pages, layout, geometry, visibility, and styles
15
+ - Visual inspection of pages, layout, geometry, visibility, stacking, and styles
15
16
  - DOM and code-level debugging, including attributes, computed styles, and accessibility data
16
- - Correlation between rendered visuals and underlying DOM structure
17
- - JavaScript evaluation in page context
17
+ - Correlation between rendered visuals and underlying DOM / accessibility structure
18
+ - JavaScript evaluation in page context for advanced diagnostics
18
19
  - Browser control and automation (navigation, input, scrolling, viewport control)
19
20
  - Long-lived, session-based debugging backed by real Playwright browser instances
20
21
  - Streamable responses and server-initiated notifications for interactive analysis
21
22
  - Clean lifecycle management and teardown on connection close
22
23
 
23
- This server is designed for AI coding assistants, visual debugging agents, and automated analysis tools that need to reason about what a page looks like, how it is structured, and how it behaves — all through a single MCP interface.
24
+ UI debugging guidance for AI agents:
25
+ - Prefer Accessibility (AX) and ARIA snapshots over raw DOM dumps when diagnosing UI problems.
26
+ These snapshots provide higher-signal, semantically meaningful anchors (roles, names, states) that
27
+ map more reliably to what users perceive and what assistive tech can interact with.
28
+ - Use the AX Tree Snapshot tool to correlate interactive semantics with runtime visual truth:
29
+ bounding boxes, visibility, viewport intersection, and (optionally) computed styles.
30
+ - If a UI control appears present but interactions fail (e.g., clicks do nothing), suspect overlap/occlusion.
31
+ In such cases, enable occlusion checking ("elementFromPoint") to identify which element is actually on top.
32
+ - Use ARIA snapshots to reason about accessibility roles/states and to validate that the intended
33
+ semantics (labels, roles, disabled state, focusability) match the visible UI.
34
+
35
+ This server is designed for AI coding assistants, visual debugging agents, and automated analysis tools
36
+ that need to reason about what a page looks like, how it is structured, and how it behaves — all through a single MCP interface.
24
37
 
25
38
  It treats the browser as a queryable, inspectable, and controllable execution environment rather than a static screenshot source.
26
39
  `;
40
+ exports.UI_DEBUGGING_POLICY = `
41
+ <ui_debugging_policy>
42
+ When asked to check for UI problems, layout issues, or visual bugs, ALWAYS follow this policy:
43
+
44
+ 1. **Visual Inspection**: Take screenshot for general aesthetics and layout overview
45
+ 2. **Accessibility Tree Analysis**: Call "a11y_take-ax-tree-snapshot" tool with "checkOcclusion:true"
46
+ - Provides precise bounding boxes, runtime visual data, and occlusion detection
47
+ - Best for detecting overlaps and measuring exact positions
48
+ 3. **ARIA Snapshot**: Call "a11y_take-aria-snapshot" tool (full page or specific selector)
49
+ - Provides semantic structure and accessibility roles
50
+ - Best for understanding page hierarchy and accessibility issues
51
+ 4. **Manual Verification**: Calculate bounding box overlaps:
52
+ - Horizontal: (element1.x + element1.width) ≤ element2.x
53
+ - Vertical: (element1.y + element1.height) ≤ element2.y
54
+ 5. **Report ALL findings**: aesthetic issues, overlaps, spacing problems, alignment issues,
55
+ accessibility problems, semantic structure issues
56
+
57
+ **Why both tools?**
58
+ - AX tree: Technical measurements, occlusion, precise positioning
59
+ - ARIA snapshot: Semantic understanding, accessibility structure, role hierarchy
60
+
61
+ Never assume "looks good visually" = "no problems". Overlaps and accessibility issues
62
+ can be functionally broken while appearing visually correct.
63
+ </ui_debugging_policy>
64
+ `;
27
65
  function getServerInstructions() {
28
66
  const parts = [];
29
- parts.push(SERVER_INSTRUCTIONS);
67
+ parts.push(exports.SERVER_INSTRUCTIONS);
30
68
  const result = parts.join('\n\n');
31
69
  return result.trim();
32
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server-info.js","sourceRoot":"","sources":["../src/server-info.ts"],"names":[],"mappings":";;;AAwBA,sDAOC;AA/BY,QAAA,WAAW,GAAG,sBAAsB,CAAC;AAC1B,sBAAc,GAAK,OAAO,CAAC,iBAAiB,CAAC,SAAC;AAEtE,MAAM,mBAAmB,GAAW;;;;;;;;;;;;;;;;;;;CAmBnC,CAAC;AAEF,SAAgB,qBAAqB;IACjC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAW,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"server-info.js","sourceRoot":"","sources":["../src/server-info.ts"],"names":[],"mappings":";;;AA+DA,sDAOC;AAtEY,QAAA,WAAW,GAAG,sBAAsB,CAAC;AAC1B,sBAAc,GAAK,OAAO,CAAC,iBAAiB,CAAC,SAAC;AAEzD,QAAA,mBAAmB,GAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgC1C,CAAC;AAEW,QAAA,mBAAmB,GAAW;;;;;;;;;;;;;;;;;;;;;;;;CAwB1C,CAAC;AAEF,SAAgB,qBAAqB;IACjC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,2BAAmB,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAW,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC"}
package/dist/server.js CHANGED
@@ -35,19 +35,53 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.createServer = createServer;
37
37
  exports.createSession = createSession;
38
- const browser_1 = require("./browser");
39
- const context_1 = require("./context");
40
38
  const logger = __importStar(require("./logger"));
41
39
  const server_info_1 = require("./server-info");
42
40
  const tools_1 = require("./tools");
43
41
  const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
44
- async function _createSessionContext(sessionIdProvider) {
45
- const browser = await (0, browser_1.getBrowser)();
46
- const browserContext = await (0, browser_1.newBrowserContext)(browser);
47
- const page = await (0, browser_1.newPage)(browserContext);
48
- return new context_1.McpSessionContext(sessionIdProvider, browser, browserContext, page);
42
+ function _getImage(response) {
43
+ if ('image' in response &&
44
+ response.image !== null &&
45
+ typeof response.image === 'object' &&
46
+ 'data' in response.image &&
47
+ 'mimeType' in response.image &&
48
+ Buffer.isBuffer(response.image.data) &&
49
+ typeof response.image.mimeType === 'string') {
50
+ const image = response.image;
51
+ delete response.image;
52
+ return image;
53
+ }
49
54
  }
50
- async function createServer(opts) {
55
+ function _toResponse(response) {
56
+ const image = _getImage(response);
57
+ const contents = [];
58
+ contents.push({
59
+ type: 'text',
60
+ text: JSON.stringify(response, null, 2),
61
+ });
62
+ if (image) {
63
+ if (image.mimeType === 'image/svg+xml') {
64
+ contents.push({
65
+ type: 'text',
66
+ text: image.data.toString(),
67
+ mimeType: image.mimeType,
68
+ });
69
+ }
70
+ else {
71
+ contents.push({
72
+ type: 'image',
73
+ data: image.data.toString('base64'),
74
+ mimeType: image.mimeType,
75
+ });
76
+ }
77
+ }
78
+ return {
79
+ content: contents,
80
+ structuredContent: response,
81
+ isError: false,
82
+ };
83
+ }
84
+ async function createServer(transport, opts) {
51
85
  const server = new mcp_js_1.McpServer({
52
86
  name: server_info_1.SERVER_NAME,
53
87
  version: server_info_1.SERVER_VERSION,
@@ -59,16 +93,13 @@ async function createServer(opts) {
59
93
  instructions: (0, server_info_1.getServerInstructions)(),
60
94
  });
61
95
  const messages = [];
62
- // TODO Add policies as prompts here
63
- /*
64
96
  messages.push({
65
97
  role: 'user',
66
98
  content: {
67
99
  type: 'text',
68
- text: <POLICY>,
100
+ text: server_info_1.UI_DEBUGGING_POLICY,
69
101
  },
70
102
  });
71
- */
72
103
  server.registerPrompt('default_system', {
73
104
  title: 'Default System Prompt',
74
105
  description: 'General behavior for the AI assistant',
@@ -76,21 +107,12 @@ async function createServer(opts) {
76
107
  description: "Defines the assistant's general reasoning and tool usage rules.",
77
108
  messages,
78
109
  }));
79
- const toolExecutor = new tools_1.ToolExecutor(opts.context);
110
+ const toolExecutor = new tools_1.ToolExecutor(() => transport.sessionId);
80
111
  const createToolCallback = (tool) => {
81
112
  return async (args) => {
82
113
  try {
83
114
  const response = await toolExecutor.executeTool(tool, args);
84
- return {
85
- content: [
86
- {
87
- type: 'text',
88
- text: JSON.stringify(response, null, 2),
89
- },
90
- ],
91
- structuredContent: response,
92
- isError: false,
93
- };
115
+ return _toResponse(response);
94
116
  }
95
117
  catch (error) {
96
118
  return {
@@ -110,20 +132,13 @@ async function createServer(opts) {
110
132
  outputSchema: t.outputSchema(),
111
133
  }, createToolCallback(t));
112
134
  });
135
+ await server.connect(transport);
113
136
  return server;
114
137
  }
115
- async function createSession(config, transport) {
116
- const sessionContext = await _createSessionContext(() => transport.sessionId);
117
- const server = await createServer({
118
- config,
119
- context: sessionContext,
120
- });
121
- await server.connect(transport);
138
+ function createSession(transport, server) {
122
139
  return {
123
140
  transport,
124
141
  server,
125
- context: sessionContext,
126
- initialized: false,
127
142
  closed: false,
128
143
  lastActiveAt: Date.now(),
129
144
  };
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tools = void 0;
4
+ const take_aria_snapshot_1 = require("./take-aria-snapshot");
5
+ const take_ax_tree_snapshot_1 = require("./take-ax-tree-snapshot");
6
+ exports.tools = [new take_aria_snapshot_1.TakeAriaSnapshot(), new take_ax_tree_snapshot_1.TakeAxTreeSnapshot()];
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/a11y/index.ts"],"names":[],"mappings":";;;AACA,6DAAwD;AACxD,mEAA6D;AAEhD,QAAA,KAAK,GAAW,CAAC,IAAI,qCAAgB,EAAE,EAAE,IAAI,0CAAkB,EAAE,CAAC,CAAC"}