safari-devtools-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +268 -0
  3. package/build/src/SafariDriver.d.ts +56 -0
  4. package/build/src/SafariDriver.d.ts.map +1 -0
  5. package/build/src/SafariDriver.js +475 -0
  6. package/build/src/SafariDriver.js.map +1 -0
  7. package/build/src/bin/safari-devtools-mcp.d.ts +9 -0
  8. package/build/src/bin/safari-devtools-mcp.d.ts.map +1 -0
  9. package/build/src/bin/safari-devtools-mcp.js +42 -0
  10. package/build/src/bin/safari-devtools-mcp.js.map +1 -0
  11. package/build/src/formatters/ConsoleFormatter.d.ts +7 -0
  12. package/build/src/formatters/ConsoleFormatter.d.ts.map +1 -0
  13. package/build/src/formatters/ConsoleFormatter.js +47 -0
  14. package/build/src/formatters/ConsoleFormatter.js.map +1 -0
  15. package/build/src/formatters/NetworkFormatter.d.ts +7 -0
  16. package/build/src/formatters/NetworkFormatter.d.ts.map +1 -0
  17. package/build/src/formatters/NetworkFormatter.js +70 -0
  18. package/build/src/formatters/NetworkFormatter.js.map +1 -0
  19. package/build/src/formatters/SnapshotFormatter.d.ts +6 -0
  20. package/build/src/formatters/SnapshotFormatter.d.ts.map +1 -0
  21. package/build/src/formatters/SnapshotFormatter.js +34 -0
  22. package/build/src/formatters/SnapshotFormatter.js.map +1 -0
  23. package/build/src/index.d.ts +13 -0
  24. package/build/src/index.d.ts.map +1 -0
  25. package/build/src/index.js +81 -0
  26. package/build/src/index.js.map +1 -0
  27. package/build/src/injected/console.d.ts +9 -0
  28. package/build/src/injected/console.d.ts.map +1 -0
  29. package/build/src/injected/console.js +119 -0
  30. package/build/src/injected/console.js.map +1 -0
  31. package/build/src/injected/network.d.ts +14 -0
  32. package/build/src/injected/network.d.ts.map +1 -0
  33. package/build/src/injected/network.js +273 -0
  34. package/build/src/injected/network.js.map +1 -0
  35. package/build/src/injected/snapshot.d.ts +9 -0
  36. package/build/src/injected/snapshot.d.ts.map +1 -0
  37. package/build/src/injected/snapshot.js +217 -0
  38. package/build/src/injected/snapshot.js.map +1 -0
  39. package/build/src/tools/console.d.ts +17 -0
  40. package/build/src/tools/console.d.ts.map +1 -0
  41. package/build/src/tools/console.js +76 -0
  42. package/build/src/tools/console.js.map +1 -0
  43. package/build/src/tools/input.d.ts +59 -0
  44. package/build/src/tools/input.d.ts.map +1 -0
  45. package/build/src/tools/input.js +220 -0
  46. package/build/src/tools/input.js.map +1 -0
  47. package/build/src/tools/network.d.ts +17 -0
  48. package/build/src/tools/network.d.ts.map +1 -0
  49. package/build/src/tools/network.js +74 -0
  50. package/build/src/tools/network.js.map +1 -0
  51. package/build/src/tools/pages.d.ts +36 -0
  52. package/build/src/tools/pages.d.ts.map +1 -0
  53. package/build/src/tools/pages.js +236 -0
  54. package/build/src/tools/pages.js.map +1 -0
  55. package/build/src/tools/screenshot.d.ts +15 -0
  56. package/build/src/tools/screenshot.d.ts.map +1 -0
  57. package/build/src/tools/screenshot.js +70 -0
  58. package/build/src/tools/screenshot.js.map +1 -0
  59. package/build/src/tools/script.d.ts +12 -0
  60. package/build/src/tools/script.d.ts.map +1 -0
  61. package/build/src/tools/script.js +48 -0
  62. package/build/src/tools/script.js.map +1 -0
  63. package/build/src/tools/snapshot.d.ts +17 -0
  64. package/build/src/tools/snapshot.d.ts.map +1 -0
  65. package/build/src/tools/snapshot.js +75 -0
  66. package/build/src/tools/snapshot.js.map +1 -0
  67. package/build/src/tools/types.d.ts +17 -0
  68. package/build/src/tools/types.d.ts.map +1 -0
  69. package/build/src/tools/types.js +5 -0
  70. package/build/src/tools/types.js.map +1 -0
  71. package/build/src/types.d.ts +74 -0
  72. package/build/src/types.d.ts.map +1 -0
  73. package/build/src/types.js +11 -0
  74. package/build/src/types.js.map +1 -0
  75. package/package.json +66 -0
@@ -0,0 +1,475 @@
1
+ /**
2
+ * Safari WebDriver manager.
3
+ * Handles browser automation via safaridriver + Selenium WebDriver.
4
+ */
5
+ import { Builder } from 'selenium-webdriver';
6
+ import safari from 'selenium-webdriver/safari.js';
7
+ import { CONSOLE_CAPTURE_SCRIPT } from './injected/console.js';
8
+ import { NETWORK_CAPTURE_SCRIPT } from './injected/network.js';
9
+ import { SNAPSHOT_SCRIPT } from './injected/snapshot.js';
10
+ export class SafariDriver {
11
+ driver = null;
12
+ initialized = false;
13
+ injectedOnPages = new Set();
14
+ async ensureDriver() {
15
+ if (!this.driver) {
16
+ const options = new safari.Options();
17
+ this.driver = new Builder()
18
+ .forBrowser('safari')
19
+ .setSafariOptions(options)
20
+ .build();
21
+ this.initialized = true;
22
+ }
23
+ return this.driver;
24
+ }
25
+ async isReady() {
26
+ return this.initialized && this.driver !== null;
27
+ }
28
+ /**
29
+ * Inject console and network capture scripts into the current page.
30
+ * Uses a page-URL-based guard so we re-inject after navigations.
31
+ */
32
+ async injectCaptureScripts() {
33
+ const driver = await this.ensureDriver();
34
+ const currentUrl = await driver.getCurrentUrl();
35
+ // Always check if scripts are still present (page may have navigated)
36
+ const isInjected = await driver.executeScript('return !!window.__safariDevToolsConsoleInitialized;');
37
+ if (!isInjected) {
38
+ await driver.executeScript(CONSOLE_CAPTURE_SCRIPT);
39
+ await driver.executeScript(NETWORK_CAPTURE_SCRIPT);
40
+ this.injectedOnPages.add(currentUrl);
41
+ }
42
+ }
43
+ // ---- Navigation ----
44
+ async navigate(url) {
45
+ const driver = await this.ensureDriver();
46
+ await driver.get(url);
47
+ await this.injectCaptureScripts();
48
+ }
49
+ async goBack() {
50
+ const driver = await this.ensureDriver();
51
+ await driver.navigate().back();
52
+ // Small delay for page to settle, then re-inject
53
+ await new Promise(r => setTimeout(r, 500));
54
+ await this.injectCaptureScripts();
55
+ }
56
+ async goForward() {
57
+ const driver = await this.ensureDriver();
58
+ await driver.navigate().forward();
59
+ await new Promise(r => setTimeout(r, 500));
60
+ await this.injectCaptureScripts();
61
+ }
62
+ async reload() {
63
+ const driver = await this.ensureDriver();
64
+ await driver.navigate().refresh();
65
+ await new Promise(r => setTimeout(r, 500));
66
+ await this.injectCaptureScripts();
67
+ }
68
+ async getCurrentUrl() {
69
+ const driver = await this.ensureDriver();
70
+ return driver.getCurrentUrl();
71
+ }
72
+ async getTitle() {
73
+ const driver = await this.ensureDriver();
74
+ return driver.getTitle();
75
+ }
76
+ // ---- Console ----
77
+ async getConsoleLogs(options) {
78
+ const driver = await this.ensureDriver();
79
+ await this.injectCaptureScripts();
80
+ let logs = await driver.executeScript('return window.__safariDevToolsConsoleLogs || [];');
81
+ if (options?.types && options.types.length > 0) {
82
+ logs = logs.filter(l => options.types.includes(l.level));
83
+ }
84
+ if (options?.pageSize !== undefined) {
85
+ const idx = options.pageIdx ?? 0;
86
+ const start = idx * options.pageSize;
87
+ logs = logs.slice(start, start + options.pageSize);
88
+ }
89
+ return logs;
90
+ }
91
+ async getConsoleMessage(msgid) {
92
+ const driver = await this.ensureDriver();
93
+ await this.injectCaptureScripts();
94
+ const log = await driver.executeScript(`return (window.__safariDevToolsConsoleLogs || []).find(l => l.msgid === ${msgid}) || null;`);
95
+ return log;
96
+ }
97
+ // ---- Network ----
98
+ async getNetworkLogs(options) {
99
+ const driver = await this.ensureDriver();
100
+ await this.injectCaptureScripts();
101
+ let logs = await driver.executeScript('return window.__safariDevToolsNetworkLogs || [];');
102
+ if (options?.resourceTypes && options.resourceTypes.length > 0) {
103
+ logs = logs.filter(l => options.resourceTypes.includes(l.resourceType));
104
+ }
105
+ if (options?.pageSize !== undefined) {
106
+ const idx = options.pageIdx ?? 0;
107
+ const start = idx * options.pageSize;
108
+ logs = logs.slice(start, start + options.pageSize);
109
+ }
110
+ return logs;
111
+ }
112
+ async getNetworkRequest(reqid) {
113
+ const driver = await this.ensureDriver();
114
+ await this.injectCaptureScripts();
115
+ const log = await driver.executeScript(`return (window.__safariDevToolsNetworkLogs || []).find(l => l.reqid === ${reqid}) || null;`);
116
+ return log;
117
+ }
118
+ // ---- JavaScript Evaluation ----
119
+ async evaluateScript(fn, args) {
120
+ const driver = await this.ensureDriver();
121
+ await this.injectCaptureScripts();
122
+ // If args are UIDs, resolve them to elements first
123
+ if (args && args.length > 0) {
124
+ const argsScript = args
125
+ .map(uid => `document.querySelector('[data-safari-uid="${uid}"]')`)
126
+ .join(', ');
127
+ const result = await driver.executeScript(`return JSON.stringify(await (${fn})(${argsScript}));`);
128
+ return String(result ?? 'undefined');
129
+ }
130
+ const result = await driver.executeScript(`return JSON.stringify(await (${fn})());`);
131
+ return String(result ?? 'undefined');
132
+ }
133
+ // ---- Screenshot ----
134
+ async takeScreenshot() {
135
+ const driver = await this.ensureDriver();
136
+ return driver.takeScreenshot();
137
+ }
138
+ async takeElementScreenshot(uid) {
139
+ const driver = await this.ensureDriver();
140
+ const element = await driver.findElement({
141
+ css: `[data-safari-uid="${uid}"]`,
142
+ });
143
+ return element.takeScreenshot();
144
+ }
145
+ // ---- DOM Snapshot ----
146
+ async takeSnapshot(verbose) {
147
+ const driver = await this.ensureDriver();
148
+ const result = await driver.executeScript(SNAPSHOT_SCRIPT + `\nreturn __safariDevToolsTakeSnapshot(${!!verbose});`);
149
+ return result;
150
+ }
151
+ // ---- Element Interaction ----
152
+ async clickElement(uid, dblClick) {
153
+ const driver = await this.ensureDriver();
154
+ const element = await driver.findElement({
155
+ css: `[data-safari-uid="${uid}"]`,
156
+ });
157
+ if (dblClick) {
158
+ const actions = driver.actions({ async: true });
159
+ await actions.doubleClick(element).perform();
160
+ }
161
+ else {
162
+ await element.click();
163
+ }
164
+ await this.injectCaptureScripts();
165
+ }
166
+ async clickAtCoordinates(x, y, dblClick) {
167
+ const driver = await this.ensureDriver();
168
+ const actions = driver.actions({ async: true });
169
+ if (dblClick) {
170
+ await actions
171
+ .move({ x: Math.round(x), y: Math.round(y) })
172
+ .doubleClick()
173
+ .perform();
174
+ }
175
+ else {
176
+ await actions
177
+ .move({ x: Math.round(x), y: Math.round(y) })
178
+ .click()
179
+ .perform();
180
+ }
181
+ }
182
+ async hoverElement(uid) {
183
+ const driver = await this.ensureDriver();
184
+ const element = await driver.findElement({
185
+ css: `[data-safari-uid="${uid}"]`,
186
+ });
187
+ const actions = driver.actions({ async: true });
188
+ await actions.move({ origin: element }).perform();
189
+ }
190
+ async fillElement(uid, value) {
191
+ const driver = await this.ensureDriver();
192
+ const element = await driver.findElement({
193
+ css: `[data-safari-uid="${uid}"]`,
194
+ });
195
+ // Check if it's a select element
196
+ const tagName = await element.getTagName();
197
+ if (tagName.toLowerCase() === 'select') {
198
+ // Find and click the option with matching text
199
+ await driver.executeScript(`
200
+ const select = document.querySelector('[data-safari-uid="${uid}"]');
201
+ const options = select.options;
202
+ for (let i = 0; i < options.length; i++) {
203
+ if (options[i].text === arguments[0] || options[i].value === arguments[0]) {
204
+ select.value = options[i].value;
205
+ select.dispatchEvent(new Event('change', { bubbles: true }));
206
+ break;
207
+ }
208
+ }
209
+ `, value);
210
+ }
211
+ else {
212
+ await element.clear();
213
+ await element.sendKeys(value);
214
+ }
215
+ }
216
+ async typeText(text, submitKey) {
217
+ const driver = await this.ensureDriver();
218
+ const actions = driver.actions({ async: true });
219
+ await actions.sendKeys(text).perform();
220
+ if (submitKey) {
221
+ await this.pressKey(submitKey);
222
+ }
223
+ }
224
+ async pressKey(key) {
225
+ const driver = await this.ensureDriver();
226
+ // Parse key combinations like "Control+A", "Meta+Shift+R"
227
+ const { Key } = await import('selenium-webdriver');
228
+ const parts = key.split('+');
229
+ const modifiers = [];
230
+ const mainKey = parts[parts.length - 1];
231
+ for (let i = 0; i < parts.length - 1; i++) {
232
+ const mod = parts[i].toLowerCase();
233
+ switch (mod) {
234
+ case 'control':
235
+ case 'ctrl':
236
+ modifiers.push(Key.CONTROL);
237
+ break;
238
+ case 'shift':
239
+ modifiers.push(Key.SHIFT);
240
+ break;
241
+ case 'alt':
242
+ case 'option':
243
+ modifiers.push(Key.ALT);
244
+ break;
245
+ case 'meta':
246
+ case 'command':
247
+ case 'cmd':
248
+ modifiers.push(Key.META);
249
+ break;
250
+ }
251
+ }
252
+ // Map special key names to Key constants
253
+ const keyMap = {
254
+ enter: Key.ENTER,
255
+ return: Key.RETURN,
256
+ tab: Key.TAB,
257
+ escape: Key.ESCAPE,
258
+ esc: Key.ESCAPE,
259
+ backspace: Key.BACK_SPACE,
260
+ delete: Key.DELETE,
261
+ arrowup: Key.ARROW_UP,
262
+ arrowdown: Key.ARROW_DOWN,
263
+ arrowleft: Key.ARROW_LEFT,
264
+ arrowright: Key.ARROW_RIGHT,
265
+ home: Key.HOME,
266
+ end: Key.END,
267
+ pageup: Key.PAGE_UP,
268
+ pagedown: Key.PAGE_DOWN,
269
+ space: Key.SPACE,
270
+ f1: Key.F1,
271
+ f2: Key.F2,
272
+ f3: Key.F3,
273
+ f4: Key.F4,
274
+ f5: Key.F5,
275
+ f6: Key.F6,
276
+ f7: Key.F7,
277
+ f8: Key.F8,
278
+ f9: Key.F9,
279
+ f10: Key.F10,
280
+ f11: Key.F11,
281
+ f12: Key.F12,
282
+ };
283
+ const resolvedKey = keyMap[mainKey.toLowerCase()] ?? mainKey;
284
+ const actions = driver.actions({ async: true });
285
+ for (const mod of modifiers) {
286
+ await actions.keyDown(mod).perform();
287
+ }
288
+ await actions.sendKeys(resolvedKey).perform();
289
+ for (const mod of modifiers.reverse()) {
290
+ await actions.keyUp(mod).perform();
291
+ }
292
+ }
293
+ async dragElement(fromUid, toUid) {
294
+ const driver = await this.ensureDriver();
295
+ const from = await driver.findElement({
296
+ css: `[data-safari-uid="${fromUid}"]`,
297
+ });
298
+ const to = await driver.findElement({
299
+ css: `[data-safari-uid="${toUid}"]`,
300
+ });
301
+ const actions = driver.actions({ async: true });
302
+ await actions.dragAndDrop(from, to).perform();
303
+ }
304
+ async uploadFile(uid, filePath) {
305
+ const driver = await this.ensureDriver();
306
+ const element = await driver.findElement({
307
+ css: `[data-safari-uid="${uid}"]`,
308
+ });
309
+ await element.sendKeys(filePath);
310
+ }
311
+ // ---- Page/Window Management ----
312
+ async resizePage(width, height) {
313
+ const driver = await this.ensureDriver();
314
+ const window = driver.manage().window();
315
+ await window.setRect({ width, height });
316
+ }
317
+ // ---- Wait ----
318
+ async waitForText(texts, timeout) {
319
+ const driver = await this.ensureDriver();
320
+ const timeoutMs = timeout ?? 30000;
321
+ const startTime = Date.now();
322
+ while (Date.now() - startTime < timeoutMs) {
323
+ for (const text of texts) {
324
+ const found = await driver.executeScript(`return document.body && document.body.innerText.includes(${JSON.stringify(text)});`);
325
+ if (found) {
326
+ return text;
327
+ }
328
+ }
329
+ await new Promise(r => setTimeout(r, 250));
330
+ }
331
+ throw new Error(`Timeout waiting for text: ${JSON.stringify(texts)} after ${timeoutMs}ms`);
332
+ }
333
+ // ---- Tab management via AppleScript ----
334
+ async listPages() {
335
+ const { execSync } = await import('child_process');
336
+ try {
337
+ const script = `
338
+ tell application "Safari"
339
+ set tabList to {}
340
+ set windowList to every window
341
+ repeat with w in windowList
342
+ set tabItems to every tab of w
343
+ repeat with t in tabItems
344
+ set tabURL to URL of t
345
+ set tabName to name of t
346
+ set end of tabList to tabURL & "|||" & tabName
347
+ end repeat
348
+ end repeat
349
+ set AppleScript's text item delimiters to "\\n"
350
+ return tabList as text
351
+ end tell
352
+ `;
353
+ const result = execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, {
354
+ encoding: 'utf-8',
355
+ timeout: 5000,
356
+ }).trim();
357
+ if (!result)
358
+ return [];
359
+ const currentUrl = await this.getCurrentUrl();
360
+ return result.split('\n').map((line, idx) => {
361
+ const [url, title] = line.split('|||');
362
+ return {
363
+ pageId: idx,
364
+ url: url || '',
365
+ title: title || '',
366
+ isSelected: url === currentUrl,
367
+ };
368
+ });
369
+ }
370
+ catch {
371
+ // Fallback: return current page only
372
+ const url = await this.getCurrentUrl();
373
+ const title = await this.getTitle();
374
+ return [{ pageId: 0, url, title, isSelected: true }];
375
+ }
376
+ }
377
+ async selectPage(pageId) {
378
+ const { execSync } = await import('child_process');
379
+ const tabIndex = pageId + 1; // AppleScript is 1-indexed
380
+ try {
381
+ const script = `
382
+ tell application "Safari"
383
+ set tabCount to 0
384
+ set windowList to every window
385
+ repeat with w in windowList
386
+ set tabItems to every tab of w
387
+ repeat with idx from 1 to count of tabItems
388
+ if tabCount + idx is equal to ${tabIndex} then
389
+ set current tab of w to item idx of tabItems
390
+ set index of w to 1
391
+ return
392
+ end if
393
+ end repeat
394
+ set tabCount to tabCount + (count of tabItems)
395
+ end repeat
396
+ end tell
397
+ `;
398
+ execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, {
399
+ encoding: 'utf-8',
400
+ timeout: 5000,
401
+ });
402
+ }
403
+ catch {
404
+ throw new Error(`Failed to select page with ID ${pageId}`);
405
+ }
406
+ }
407
+ async newPage(url) {
408
+ const { execSync } = await import('child_process');
409
+ try {
410
+ const script = `
411
+ tell application "Safari"
412
+ tell window 1
413
+ set newTab to make new tab with properties {URL:"${url}"}
414
+ set current tab to newTab
415
+ end tell
416
+ end tell
417
+ `;
418
+ execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, {
419
+ encoding: 'utf-8',
420
+ timeout: 5000,
421
+ });
422
+ }
423
+ catch {
424
+ // Fallback to WebDriver navigation
425
+ await this.navigate(url);
426
+ }
427
+ }
428
+ async closePage(pageId) {
429
+ const { execSync } = await import('child_process');
430
+ const tabIndex = pageId + 1;
431
+ try {
432
+ const script = `
433
+ tell application "Safari"
434
+ set tabCount to 0
435
+ set windowList to every window
436
+ repeat with w in windowList
437
+ set tabItems to every tab of w
438
+ if (count of tabItems) is 1 and (count of windowList) is 1 then
439
+ error "Cannot close the last open page."
440
+ end if
441
+ repeat with idx from 1 to count of tabItems
442
+ if tabCount + idx is equal to ${tabIndex} then
443
+ close item idx of tabItems
444
+ return
445
+ end if
446
+ end repeat
447
+ set tabCount to tabCount + (count of tabItems)
448
+ end repeat
449
+ end tell
450
+ `;
451
+ execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, {
452
+ encoding: 'utf-8',
453
+ timeout: 5000,
454
+ });
455
+ }
456
+ catch (e) {
457
+ throw new Error(e instanceof Error ? e.message : `Failed to close page ${pageId}`);
458
+ }
459
+ }
460
+ // ---- Cleanup ----
461
+ async close() {
462
+ if (this.driver) {
463
+ try {
464
+ await this.driver.quit();
465
+ }
466
+ catch {
467
+ // Ignore close errors
468
+ }
469
+ this.driver = null;
470
+ this.initialized = false;
471
+ this.injectedOnPages.clear();
472
+ }
473
+ }
474
+ }
475
+ //# sourceMappingURL=SafariDriver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SafariDriver.js","sourceRoot":"","sources":["../../src/SafariDriver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Safari DevTools MCP Server — CLI entry point.
4
+ *
5
+ * Starts the MCP server with stdio transport for use with
6
+ * Claude Desktop, Claude Code, or any MCP client.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=safari-devtools-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safari-devtools-mcp.d.ts","sourceRoot":"","sources":["../../../src/bin/safari-devtools-mcp.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Safari DevTools MCP Server — CLI entry point.
4
+ *
5
+ * Starts the MCP server with stdio transport for use with
6
+ * Claude Desktop, Claude Code, or any MCP client.
7
+ */
8
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9
+ import { createSafariMcpServer } from '../index.js';
10
+ async function main() {
11
+ const { server, driver } = createSafariMcpServer();
12
+ const transport = new StdioServerTransport();
13
+ // Graceful shutdown
14
+ const cleanup = async () => {
15
+ console.error('Shutting down Safari DevTools MCP Server...');
16
+ await driver.close();
17
+ process.exit(0);
18
+ };
19
+ process.on('SIGINT', cleanup);
20
+ process.on('SIGTERM', cleanup);
21
+ // Handle uncaught errors
22
+ process.on('uncaughtException', error => {
23
+ console.error('Uncaught exception:', error);
24
+ });
25
+ process.on('unhandledRejection', reason => {
26
+ console.error('Unhandled rejection:', reason);
27
+ });
28
+ await server.connect(transport);
29
+ console.error('Safari DevTools MCP Server running on stdio');
30
+ console.error('');
31
+ console.error('Prerequisites:');
32
+ console.error(' 1. Enable Developer menu: Safari → Settings → Advanced → "Show features for web developers"');
33
+ console.error(' 2. Enable Remote Automation: Develop → Allow Remote Automation');
34
+ console.error(' 3. Authorize SafariDriver: sudo safaridriver --enable');
35
+ console.error('');
36
+ console.error('Note: Safari only supports one WebDriver session at a time.');
37
+ }
38
+ main().catch(error => {
39
+ console.error('Fatal error:', error);
40
+ process.exit(1);
41
+ });
42
+ //# sourceMappingURL=safari-devtools-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safari-devtools-mcp.js","sourceRoot":"","sources":["../../../src/bin/safari-devtools-mcp.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAC,oBAAoB,EAAC,MAAM,2CAA2C,CAAC;AAC/E,OAAO,EAAC,qBAAqB,EAAC,MAAM,aAAa,CAAC;AAElD,KAAK,UAAU,IAAI;IACjB,MAAM,EAAC,MAAM,EAAE,MAAM,EAAC,GAAG,qBAAqB,EAAE,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,oBAAoB;IACpB,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE/B,yBAAyB;IACzB,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,CAAC,EAAE;QACtC,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,MAAM,CAAC,EAAE;QACxC,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC7D,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CACX,+FAA+F,CAChG,CAAC;IACF,OAAO,CAAC,KAAK,CACX,kEAAkE,CACnE,CAAC;IACF,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IACzE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;AAC/E,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Formats console log entries for MCP response output.
3
+ */
4
+ import type { ConsoleLogEntry } from '../types.js';
5
+ export declare function formatConsoleMessages(logs: ConsoleLogEntry[], total: number): string;
6
+ export declare function formatConsoleMessage(log: ConsoleLogEntry): string;
7
+ //# sourceMappingURL=ConsoleFormatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsoleFormatter.d.ts","sourceRoot":"","sources":["../../../src/formatters/ConsoleFormatter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,aAAa,CAAC;AAEjD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,EAAE,EACvB,KAAK,EAAE,MAAM,GACZ,MAAM,CAmBR;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CA8BjE"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Formats console log entries for MCP response output.
3
+ */
4
+ export function formatConsoleMessages(logs, total) {
5
+ if (logs.length === 0) {
6
+ return 'No console messages captured.';
7
+ }
8
+ const lines = [];
9
+ lines.push(`Console messages (${logs.length} of ${total} total):`);
10
+ lines.push('');
11
+ for (const log of logs) {
12
+ const time = new Date(log.timestamp).toISOString().split('T')[1];
13
+ const levelTag = `[${log.level.toUpperCase()}]`;
14
+ lines.push(` msgid=${log.msgid} ${time} ${levelTag} ${log.message}`);
15
+ if (log.source) {
16
+ lines.push(` at ${log.source}`);
17
+ }
18
+ }
19
+ return lines.join('\n');
20
+ }
21
+ export function formatConsoleMessage(log) {
22
+ const lines = [];
23
+ const time = new Date(log.timestamp).toISOString();
24
+ lines.push(`Console Message (msgid=${log.msgid})`);
25
+ lines.push(` Level: ${log.level}`);
26
+ lines.push(` Time: ${time}`);
27
+ lines.push(` Message: ${log.message}`);
28
+ if (log.source) {
29
+ lines.push(` Source: ${log.source}`);
30
+ }
31
+ if (log.args && log.args.length > 0) {
32
+ lines.push(' Arguments:');
33
+ for (let i = 0; i < log.args.length; i++) {
34
+ lines.push(` [${i}]: ${log.args[i]}`);
35
+ }
36
+ }
37
+ if (log.stackTrace) {
38
+ lines.push(' Stack Trace:');
39
+ for (const line of log.stackTrace.split('\n')) {
40
+ if (line.trim()) {
41
+ lines.push(` ${line.trim()}`);
42
+ }
43
+ }
44
+ }
45
+ return lines.join('\n');
46
+ }
47
+ //# sourceMappingURL=ConsoleFormatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsoleFormatter.js","sourceRoot":"","sources":["../../../src/formatters/ConsoleFormatter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,UAAU,qBAAqB,CACnC,IAAuB,EACvB,KAAa;IAEb,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,+BAA+B,CAAC;IACzC,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,MAAM,OAAO,KAAK,UAAU,CAAC,CAAC;IACnE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI,QAAQ,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAoB;IACvD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IAEnD,KAAK,CAAC,IAAI,CAAC,0BAA0B,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;IACnD,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACpC,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAC9B,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAExC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Formats network log entries for MCP response output.
3
+ */
4
+ import type { NetworkLogEntry } from '../types.js';
5
+ export declare function formatNetworkRequests(logs: NetworkLogEntry[], total: number): string;
6
+ export declare function formatNetworkRequest(log: NetworkLogEntry): string;
7
+ //# sourceMappingURL=NetworkFormatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NetworkFormatter.d.ts","sourceRoot":"","sources":["../../../src/formatters/NetworkFormatter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,aAAa,CAAC;AAEjD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,EAAE,EACvB,KAAK,EAAE,MAAM,GACZ,MAAM,CAqBR;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CA6CjE"}