ultimate-playwright-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 (131) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +286 -0
  3. package/dist/browser/cdp.d.ts +37 -0
  4. package/dist/browser/cdp.d.ts.map +1 -0
  5. package/dist/browser/cdp.helpers.d.ts +13 -0
  6. package/dist/browser/cdp.helpers.d.ts.map +1 -0
  7. package/dist/browser/cdp.helpers.js +38 -0
  8. package/dist/browser/cdp.helpers.js.map +1 -0
  9. package/dist/browser/cdp.js +77 -0
  10. package/dist/browser/cdp.js.map +1 -0
  11. package/dist/browser/chrome-tab-groups.d.ts +93 -0
  12. package/dist/browser/chrome-tab-groups.d.ts.map +1 -0
  13. package/dist/browser/chrome-tab-groups.js +458 -0
  14. package/dist/browser/chrome-tab-groups.js.map +1 -0
  15. package/dist/browser/chrome.d.ts +11 -0
  16. package/dist/browser/chrome.d.ts.map +1 -0
  17. package/dist/browser/chrome.js +74 -0
  18. package/dist/browser/chrome.js.map +1 -0
  19. package/dist/browser/pw-role-snapshot.d.ts +41 -0
  20. package/dist/browser/pw-role-snapshot.d.ts.map +1 -0
  21. package/dist/browser/pw-role-snapshot.js +346 -0
  22. package/dist/browser/pw-role-snapshot.js.map +1 -0
  23. package/dist/browser/pw-session.d.ts +145 -0
  24. package/dist/browser/pw-session.d.ts.map +1 -0
  25. package/dist/browser/pw-session.js +468 -0
  26. package/dist/browser/pw-session.js.map +1 -0
  27. package/dist/browser/pw-tools-activity.d.ts +27 -0
  28. package/dist/browser/pw-tools-activity.d.ts.map +1 -0
  29. package/dist/browser/pw-tools-activity.js +52 -0
  30. package/dist/browser/pw-tools-activity.js.map +1 -0
  31. package/dist/browser/pw-tools-downloads.d.ts +40 -0
  32. package/dist/browser/pw-tools-downloads.d.ts.map +1 -0
  33. package/dist/browser/pw-tools-downloads.js +191 -0
  34. package/dist/browser/pw-tools-downloads.js.map +1 -0
  35. package/dist/browser/pw-tools-interactions.d.ts +122 -0
  36. package/dist/browser/pw-tools-interactions.d.ts.map +1 -0
  37. package/dist/browser/pw-tools-interactions.js +434 -0
  38. package/dist/browser/pw-tools-interactions.js.map +1 -0
  39. package/dist/browser/pw-tools-responses.d.ts +19 -0
  40. package/dist/browser/pw-tools-responses.d.ts.map +1 -0
  41. package/dist/browser/pw-tools-responses.js +98 -0
  42. package/dist/browser/pw-tools-responses.js.map +1 -0
  43. package/dist/browser/pw-tools-shared.d.ts +12 -0
  44. package/dist/browser/pw-tools-shared.d.ts.map +1 -0
  45. package/dist/browser/pw-tools-shared.js +55 -0
  46. package/dist/browser/pw-tools-shared.js.map +1 -0
  47. package/dist/browser/pw-tools-snapshot.d.ts +70 -0
  48. package/dist/browser/pw-tools-snapshot.d.ts.map +1 -0
  49. package/dist/browser/pw-tools-snapshot.js +151 -0
  50. package/dist/browser/pw-tools-snapshot.js.map +1 -0
  51. package/dist/browser/pw-tools-state.d.ts +52 -0
  52. package/dist/browser/pw-tools-state.d.ts.map +1 -0
  53. package/dist/browser/pw-tools-state.js +159 -0
  54. package/dist/browser/pw-tools-state.js.map +1 -0
  55. package/dist/browser/pw-tools-storage.d.ts +53 -0
  56. package/dist/browser/pw-tools-storage.d.ts.map +1 -0
  57. package/dist/browser/pw-tools-storage.js +81 -0
  58. package/dist/browser/pw-tools-storage.js.map +1 -0
  59. package/dist/browser/pw-tools-trace.d.ts +18 -0
  60. package/dist/browser/pw-tools-trace.d.ts.map +1 -0
  61. package/dist/browser/pw-tools-trace.js +31 -0
  62. package/dist/browser/pw-tools-trace.js.map +1 -0
  63. package/dist/browser/tab-groups.d.ts +94 -0
  64. package/dist/browser/tab-groups.d.ts.map +1 -0
  65. package/dist/browser/tab-groups.js +303 -0
  66. package/dist/browser/tab-groups.js.map +1 -0
  67. package/dist/browser/target-id.d.ts +20 -0
  68. package/dist/browser/target-id.d.ts.map +1 -0
  69. package/dist/browser/target-id.js +29 -0
  70. package/dist/browser/target-id.js.map +1 -0
  71. package/dist/cli.d.ts +6 -0
  72. package/dist/cli.d.ts.map +1 -0
  73. package/dist/cli.js +35 -0
  74. package/dist/cli.js.map +1 -0
  75. package/dist/config.d.ts +32 -0
  76. package/dist/config.d.ts.map +1 -0
  77. package/dist/config.js +7 -0
  78. package/dist/config.js.map +1 -0
  79. package/dist/daemon/chrome-daemon.d.ts +7 -0
  80. package/dist/daemon/chrome-daemon.d.ts.map +1 -0
  81. package/dist/daemon/chrome-daemon.js +264 -0
  82. package/dist/daemon/chrome-daemon.js.map +1 -0
  83. package/dist/daemon/cli.d.ts +6 -0
  84. package/dist/daemon/cli.d.ts.map +1 -0
  85. package/dist/daemon/cli.js +110 -0
  86. package/dist/daemon/cli.js.map +1 -0
  87. package/dist/daemon/manager.d.ts +22 -0
  88. package/dist/daemon/manager.d.ts.map +1 -0
  89. package/dist/daemon/manager.js +89 -0
  90. package/dist/daemon/manager.js.map +1 -0
  91. package/dist/index.d.ts +9 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +9 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/mcp/server.d.ts +41 -0
  96. package/dist/mcp/server.d.ts.map +1 -0
  97. package/dist/mcp/server.js +122 -0
  98. package/dist/mcp/server.js.map +1 -0
  99. package/dist/mcp/tools/actions.d.ts +6 -0
  100. package/dist/mcp/tools/actions.d.ts.map +1 -0
  101. package/dist/mcp/tools/actions.js +214 -0
  102. package/dist/mcp/tools/actions.js.map +1 -0
  103. package/dist/mcp/tools/navigate.d.ts +6 -0
  104. package/dist/mcp/tools/navigate.d.ts.map +1 -0
  105. package/dist/mcp/tools/navigate.js +31 -0
  106. package/dist/mcp/tools/navigate.js.map +1 -0
  107. package/dist/mcp/tools/snapshot.d.ts +6 -0
  108. package/dist/mcp/tools/snapshot.d.ts.map +1 -0
  109. package/dist/mcp/tools/snapshot.js +26 -0
  110. package/dist/mcp/tools/snapshot.js.map +1 -0
  111. package/dist/mcp/tools/tab-group.d.ts +9 -0
  112. package/dist/mcp/tools/tab-group.d.ts.map +1 -0
  113. package/dist/mcp/tools/tab-group.js +173 -0
  114. package/dist/mcp/tools/tab-group.js.map +1 -0
  115. package/dist/mcp/tools/tabs.d.ts +6 -0
  116. package/dist/mcp/tools/tabs.d.ts.map +1 -0
  117. package/dist/mcp/tools/tabs.js +209 -0
  118. package/dist/mcp/tools/tabs.js.map +1 -0
  119. package/dist/utils/command-format.d.ts +6 -0
  120. package/dist/utils/command-format.d.ts.map +1 -0
  121. package/dist/utils/command-format.js +8 -0
  122. package/dist/utils/command-format.js.map +1 -0
  123. package/dist/utils/errors.d.ts +6 -0
  124. package/dist/utils/errors.d.ts.map +1 -0
  125. package/dist/utils/errors.js +22 -0
  126. package/dist/utils/errors.js.map +1 -0
  127. package/dist/utils/extension-installer.d.ts +16 -0
  128. package/dist/utils/extension-installer.d.ts.map +1 -0
  129. package/dist/utils/extension-installer.js +134 -0
  130. package/dist/utils/extension-installer.js.map +1 -0
  131. package/package.json +75 -0
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Chrome Daemon - Singleton process that manages Chrome browser
4
+ * Ensures only one Chrome instance runs and keeps it alive
5
+ */
6
+ import { spawn } from "node:child_process";
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import os from "node:os";
10
+ import { globSync } from "glob";
11
+ import { resolveExtensions } from "../utils/extension-installer.js";
12
+ const DAEMON_LOCK_FILE = path.join(os.tmpdir(), "ultimate-playwright-mcp-daemon.lock");
13
+ const DAEMON_LOG_FILE = path.join(os.tmpdir(), "ultimate-playwright-mcp-daemon.log");
14
+ const CDP_PORT = 9223; // Use dedicated port to avoid conflicts with existing Chrome
15
+ const DEFAULT_CHROME_PROFILE = path.join(os.homedir(), ".ultimate-playwright-mcp", "chrome-profile");
16
+ class ChromeDaemon {
17
+ chromeProcess = null;
18
+ shuttingDown = false;
19
+ config;
20
+ constructor(config) {
21
+ this.config = config || {};
22
+ }
23
+ async start() {
24
+ // Check if daemon is already running
25
+ if (this.isDaemonRunning()) {
26
+ this.log("Daemon already running, exiting");
27
+ process.exit(0);
28
+ }
29
+ // Create lock file
30
+ this.createLockFile();
31
+ // Handle cleanup on exit
32
+ process.on("SIGINT", () => this.shutdown());
33
+ process.on("SIGTERM", () => this.shutdown());
34
+ process.on("exit", () => this.cleanup());
35
+ this.log("Chrome daemon started");
36
+ // Start Chrome and keep it alive
37
+ await this.ensureChromeRunning();
38
+ // Monitor Chrome process
39
+ setInterval(() => this.ensureChromeRunning(), 5000);
40
+ }
41
+ isDaemonRunning() {
42
+ if (!fs.existsSync(DAEMON_LOCK_FILE)) {
43
+ return false;
44
+ }
45
+ try {
46
+ const pid = parseInt(fs.readFileSync(DAEMON_LOCK_FILE, "utf-8").trim());
47
+ // Check if process is still running
48
+ process.kill(pid, 0);
49
+ return true;
50
+ }
51
+ catch {
52
+ // Process not running, remove stale lock file
53
+ fs.unlinkSync(DAEMON_LOCK_FILE);
54
+ return false;
55
+ }
56
+ }
57
+ createLockFile() {
58
+ fs.writeFileSync(DAEMON_LOCK_FILE, String(process.pid));
59
+ }
60
+ async ensureChromeRunning() {
61
+ if (this.chromeProcess && !this.chromeProcess.killed) {
62
+ return; // Chrome is running
63
+ }
64
+ // Always launch our own Chrome (don't reuse existing instances)
65
+ this.log("Starting Chrome...");
66
+ await this.startChrome();
67
+ }
68
+ async isChromeReachable() {
69
+ try {
70
+ const response = await fetch(`http://localhost:${CDP_PORT}/json/version`, {
71
+ signal: AbortSignal.timeout(1000),
72
+ });
73
+ return response.ok;
74
+ }
75
+ catch {
76
+ return false;
77
+ }
78
+ }
79
+ async startChrome() {
80
+ const chromePath = this.config.chromeExecutable || this.findChromePath();
81
+ if (!chromePath) {
82
+ this.log("ERROR: Chrome not found");
83
+ return;
84
+ }
85
+ // Use configured profile or default persistent profile
86
+ const userDataDir = this.config.chromeUserDataDir || DEFAULT_CHROME_PROFILE;
87
+ // Ensure user data directory exists
88
+ if (!fs.existsSync(userDataDir)) {
89
+ fs.mkdirSync(userDataDir, { recursive: true });
90
+ this.log(`Created Chrome profile directory: ${userDataDir}`);
91
+ }
92
+ // Enable developer mode for extensions if loading extensions
93
+ if (this.config.chromeExtensions && this.config.chromeExtensions.length > 0) {
94
+ this.enableDeveloperMode(userDataDir);
95
+ }
96
+ const args = [
97
+ `--remote-debugging-port=${CDP_PORT}`,
98
+ `--user-data-dir=${userDataDir}`,
99
+ "--no-first-run",
100
+ "--no-default-browser-check",
101
+ "--no-startup-window",
102
+ "--disable-background-networking",
103
+ "--disable-background-timer-throttling",
104
+ "--disable-backgrounding-occluded-windows",
105
+ "--disable-renderer-backgrounding",
106
+ ];
107
+ // Add extensions if configured (requires Chrome for Testing)
108
+ if (this.config.chromeExtensions && this.config.chromeExtensions.length > 0) {
109
+ try {
110
+ const extensionPaths = await resolveExtensions(this.config.chromeExtensions);
111
+ if (extensionPaths.length > 0) {
112
+ const pathsStr = extensionPaths.join(",");
113
+ args.push(`--load-extension=${pathsStr}`);
114
+ this.log(`Loading extensions: ${pathsStr}`);
115
+ // Warn if using branded Chrome 137+
116
+ if (chromePath.includes("Google Chrome.app") && !chromePath.includes("Chrome for Testing")) {
117
+ this.log("WARNING: Using branded Chrome may not support --load-extension in version 137+");
118
+ this.log(" Recommend installing Chrome for Testing for guaranteed extension support");
119
+ }
120
+ }
121
+ }
122
+ catch (error) {
123
+ this.log(`WARNING: Failed to resolve extensions: ${error instanceof Error ? error.message : String(error)}`);
124
+ }
125
+ }
126
+ this.chromeProcess = spawn(chromePath, args, {
127
+ detached: true,
128
+ stdio: "ignore",
129
+ });
130
+ this.chromeProcess.on("exit", (code) => {
131
+ this.log(`Chrome exited with code ${code}`);
132
+ this.chromeProcess = null;
133
+ if (!this.shuttingDown) {
134
+ this.log("Chrome crashed, will restart...");
135
+ }
136
+ });
137
+ this.chromeProcess.unref();
138
+ this.log(`Chrome started (PID: ${this.chromeProcess.pid})`);
139
+ // Wait for Chrome to be ready
140
+ for (let i = 0; i < 30; i++) {
141
+ await new Promise((resolve) => setTimeout(resolve, 500));
142
+ if (await this.isChromeReachable()) {
143
+ this.log("Chrome is ready");
144
+ return;
145
+ }
146
+ }
147
+ this.log("WARNING: Chrome started but not responding on CDP port");
148
+ }
149
+ enableDeveloperMode(userDataDir) {
150
+ const prefsPath = path.join(userDataDir, "Default", "Preferences");
151
+ const defaultDir = path.join(userDataDir, "Default");
152
+ try {
153
+ // Ensure Default directory exists
154
+ if (!fs.existsSync(defaultDir)) {
155
+ fs.mkdirSync(defaultDir, { recursive: true });
156
+ }
157
+ // Read existing preferences or create new
158
+ let prefs = {};
159
+ if (fs.existsSync(prefsPath)) {
160
+ const prefsContent = fs.readFileSync(prefsPath, "utf-8");
161
+ prefs = JSON.parse(prefsContent);
162
+ }
163
+ // Set developer mode for extensions
164
+ if (!prefs.extensions) {
165
+ prefs.extensions = {};
166
+ }
167
+ if (!prefs.extensions.ui) {
168
+ prefs.extensions.ui = {};
169
+ }
170
+ prefs.extensions.ui.developer_mode = true;
171
+ // Write preferences
172
+ fs.writeFileSync(prefsPath, JSON.stringify(prefs, null, 2));
173
+ this.log("Enabled developer mode for extensions");
174
+ }
175
+ catch (error) {
176
+ this.log(`Warning: Could not enable developer mode: ${error instanceof Error ? error.message : String(error)}`);
177
+ }
178
+ }
179
+ findChromePath() {
180
+ const platform = process.platform;
181
+ const paths = [];
182
+ if (platform === "darwin") {
183
+ // Chrome for Testing locations (prioritized for --load-extension support)
184
+ paths.push(path.join(os.homedir(), ".cache/puppeteer/chrome/mac_arm-*/chrome-mac*/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"), path.join(os.homedir(), ".cache/puppeteer/chrome/mac-*/chrome-mac*/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"), path.join(os.homedir(), "Library/Caches/ms-playwright/chromium-*/chrome-mac/Chromium.app/Contents/MacOS/Chromium"), "/Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing",
185
+ // Chromium and standard Chrome (fallback, may not support --load-extension)
186
+ "/Applications/Chromium.app/Contents/MacOS/Chromium", "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", "/Applications/Comet.app/Contents/MacOS/Comet");
187
+ }
188
+ else if (platform === "linux") {
189
+ paths.push(path.join(os.homedir(), ".cache/puppeteer/chrome/linux-*/chrome-linux*/chrome"), path.join(os.homedir(), ".cache/ms-playwright/chromium-*/chrome-linux/chrome"), "/usr/bin/chromium", "/usr/bin/chromium-browser", "/usr/bin/google-chrome");
190
+ }
191
+ else if (platform === "win32") {
192
+ paths.push(path.join(os.homedir(), ".cache\\puppeteer\\chrome\\win64-*\\chrome-win64\\chrome.exe"), path.join(os.homedir(), ".cache\\ms-playwright\\chromium-*\\chrome-win\\chrome.exe"), "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe");
193
+ }
194
+ // Resolve glob patterns and find first existing path
195
+ for (const pathPattern of paths) {
196
+ if (pathPattern.includes("*")) {
197
+ // Use glob to resolve wildcards
198
+ const matches = globSync(pathPattern);
199
+ if (matches.length > 0) {
200
+ // Sort to get latest version
201
+ matches.sort().reverse();
202
+ if (fs.existsSync(matches[0])) {
203
+ this.log(`Found Chrome at: ${matches[0]}`);
204
+ return matches[0];
205
+ }
206
+ }
207
+ }
208
+ else if (fs.existsSync(pathPattern)) {
209
+ this.log(`Found Chrome at: ${pathPattern}`);
210
+ return pathPattern;
211
+ }
212
+ }
213
+ return null;
214
+ }
215
+ shutdown() {
216
+ if (this.shuttingDown)
217
+ return;
218
+ this.shuttingDown = true;
219
+ this.log("Shutting down daemon...");
220
+ if (this.chromeProcess && !this.chromeProcess.killed) {
221
+ this.log("Stopping Chrome...");
222
+ this.chromeProcess.kill();
223
+ }
224
+ this.cleanup();
225
+ process.exit(0);
226
+ }
227
+ cleanup() {
228
+ if (fs.existsSync(DAEMON_LOCK_FILE)) {
229
+ fs.unlinkSync(DAEMON_LOCK_FILE);
230
+ }
231
+ }
232
+ log(message) {
233
+ const timestamp = new Date().toISOString();
234
+ const logLine = `[${timestamp}] ${message}\n`;
235
+ // Log to console
236
+ console.error(logLine.trim());
237
+ // Log to file
238
+ fs.appendFileSync(DAEMON_LOG_FILE, logLine);
239
+ }
240
+ }
241
+ // Parse CLI args with commander (only runs if this file is executed directly)
242
+ if (import.meta.url === `file://${process.argv[1]}`) {
243
+ const { program } = await import("commander");
244
+ program
245
+ .name("chrome-daemon")
246
+ .description("Chrome daemon process for ultimate-playwright-mcp")
247
+ .version("0.1.0")
248
+ .option("--config <json>", "Configuration JSON string")
249
+ .parse();
250
+ const options = program.opts();
251
+ let daemonConfig;
252
+ if (options.config) {
253
+ try {
254
+ daemonConfig = JSON.parse(options.config);
255
+ }
256
+ catch (e) {
257
+ console.error('Failed to parse daemon config:', e);
258
+ }
259
+ }
260
+ // Start daemon
261
+ const daemon = new ChromeDaemon(daemonConfig);
262
+ daemon.start();
263
+ }
264
+ //# sourceMappingURL=chrome-daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chrome-daemon.js","sourceRoot":"","sources":["../../src/daemon/chrome-daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Daemon CLI - Manually control Chrome daemon
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/daemon/cli.ts"],"names":[],"mappings":";AAEA;;GAEG"}
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Daemon CLI - Manually control Chrome daemon
4
+ */
5
+ import { program } from "commander";
6
+ import { spawn } from "node:child_process";
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import os from "node:os";
10
+ import { fileURLToPath } from "node:url";
11
+ const DAEMON_LOCK_FILE = path.join(os.tmpdir(), "ultimate-playwright-mcp-daemon.lock");
12
+ const DAEMON_LOG_FILE = path.join(os.tmpdir(), "ultimate-playwright-mcp-daemon.log");
13
+ function isDaemonRunning() {
14
+ if (!fs.existsSync(DAEMON_LOCK_FILE)) {
15
+ return false;
16
+ }
17
+ try {
18
+ const pid = parseInt(fs.readFileSync(DAEMON_LOCK_FILE, "utf-8").trim());
19
+ process.kill(pid, 0);
20
+ return true;
21
+ }
22
+ catch {
23
+ fs.unlinkSync(DAEMON_LOCK_FILE);
24
+ return false;
25
+ }
26
+ }
27
+ function getDaemonPid() {
28
+ if (!fs.existsSync(DAEMON_LOCK_FILE)) {
29
+ return null;
30
+ }
31
+ return parseInt(fs.readFileSync(DAEMON_LOCK_FILE, "utf-8").trim());
32
+ }
33
+ function startDaemon() {
34
+ if (isDaemonRunning()) {
35
+ console.log("Daemon already running (PID:", getDaemonPid() + ")");
36
+ return;
37
+ }
38
+ const __filename = fileURLToPath(import.meta.url);
39
+ const __dirname = path.dirname(__filename);
40
+ const daemonScript = path.join(__dirname, "chrome-daemon.js");
41
+ const daemon = spawn("node", [daemonScript], {
42
+ detached: true,
43
+ stdio: "ignore",
44
+ });
45
+ daemon.unref();
46
+ console.log("Chrome daemon started (PID:", daemon.pid + ")");
47
+ console.log("Log file:", DAEMON_LOG_FILE);
48
+ }
49
+ function stopDaemon() {
50
+ const pid = getDaemonPid();
51
+ if (!pid) {
52
+ console.log("Daemon not running");
53
+ return;
54
+ }
55
+ try {
56
+ process.kill(pid, "SIGTERM");
57
+ console.log("Daemon stopped (PID:", pid + ")");
58
+ }
59
+ catch (error) {
60
+ console.error("Failed to stop daemon:", error);
61
+ }
62
+ }
63
+ function statusDaemon() {
64
+ const pid = getDaemonPid();
65
+ if (!pid) {
66
+ console.log("Status: Not running");
67
+ return;
68
+ }
69
+ console.log("Status: Running");
70
+ console.log("PID:", pid);
71
+ console.log("Lock file:", DAEMON_LOCK_FILE);
72
+ console.log("Log file:", DAEMON_LOG_FILE);
73
+ }
74
+ function showLogs() {
75
+ if (!fs.existsSync(DAEMON_LOG_FILE)) {
76
+ console.log("No logs found");
77
+ return;
78
+ }
79
+ const logs = fs.readFileSync(DAEMON_LOG_FILE, "utf-8");
80
+ console.log(logs);
81
+ }
82
+ program
83
+ .name("upmcp-daemon")
84
+ .description("Chrome Daemon Control for ultimate-playwright-mcp")
85
+ .version("0.1.0");
86
+ program
87
+ .command("start")
88
+ .description("Start the Chrome daemon")
89
+ .action(startDaemon);
90
+ program
91
+ .command("stop")
92
+ .description("Stop the Chrome daemon")
93
+ .action(stopDaemon);
94
+ program
95
+ .command("restart")
96
+ .description("Restart the Chrome daemon")
97
+ .action(() => {
98
+ stopDaemon();
99
+ setTimeout(startDaemon, 1000);
100
+ });
101
+ program
102
+ .command("status")
103
+ .description("Show daemon status")
104
+ .action(statusDaemon);
105
+ program
106
+ .command("logs")
107
+ .description("Show daemon logs")
108
+ .action(showLogs);
109
+ program.parse();
110
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/daemon/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Daemon manager - Ensures Chrome daemon is running before MCP server starts
3
+ */
4
+ export interface DaemonConfig {
5
+ chromeUserDataDir?: string;
6
+ chromeExtensions?: string[];
7
+ chromeExecutable?: string;
8
+ }
9
+ export declare class DaemonManager {
10
+ /**
11
+ * Ensure daemon is running, start if needed
12
+ */
13
+ static ensureDaemonRunning(config?: DaemonConfig): Promise<void>;
14
+ private static isDaemonRunning;
15
+ private static startDaemon;
16
+ private static isChromeReachable;
17
+ /**
18
+ * Get CDP endpoint URL
19
+ */
20
+ static getCdpEndpoint(): string;
21
+ }
22
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/daemon/manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,MAAM,WAAW,YAAY;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,aAAa;IACxB;;OAEG;WACU,mBAAmB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBtE,OAAO,CAAC,MAAM,CAAC,eAAe;mBAiBT,WAAW;mBA6BX,iBAAiB;IAWtC;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,MAAM;CAGhC"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Daemon manager - Ensures Chrome daemon is running before MCP server starts
3
+ */
4
+ import { spawn } from "node:child_process";
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ import os from "node:os";
8
+ import { fileURLToPath } from "node:url";
9
+ const DAEMON_LOCK_FILE = path.join(os.tmpdir(), "ultimate-playwright-mcp-daemon.lock");
10
+ const CDP_PORT = 9223; // Use dedicated port to avoid conflicts with existing Chrome
11
+ export class DaemonManager {
12
+ /**
13
+ * Ensure daemon is running, start if needed
14
+ */
15
+ static async ensureDaemonRunning(config) {
16
+ // Check if daemon is already running
17
+ if (this.isDaemonRunning()) {
18
+ console.error("✓ Chrome daemon already running");
19
+ return;
20
+ }
21
+ console.error("Starting Chrome daemon...");
22
+ await this.startDaemon(config);
23
+ // Wait for daemon to be ready
24
+ for (let i = 0; i < 60; i++) {
25
+ await new Promise((resolve) => setTimeout(resolve, 500));
26
+ if (await this.isChromeReachable()) {
27
+ console.error("✓ Chrome daemon ready");
28
+ return;
29
+ }
30
+ }
31
+ throw new Error("Chrome daemon failed to start within 30 seconds");
32
+ }
33
+ static isDaemonRunning() {
34
+ if (!fs.existsSync(DAEMON_LOCK_FILE)) {
35
+ return false;
36
+ }
37
+ try {
38
+ const pid = parseInt(fs.readFileSync(DAEMON_LOCK_FILE, "utf-8").trim());
39
+ // Check if process is still running
40
+ process.kill(pid, 0);
41
+ return true;
42
+ }
43
+ catch {
44
+ // Process not running, remove stale lock file
45
+ fs.unlinkSync(DAEMON_LOCK_FILE);
46
+ return false;
47
+ }
48
+ }
49
+ static async startDaemon(config) {
50
+ // Find the daemon script path
51
+ const __filename = fileURLToPath(import.meta.url);
52
+ const __dirname = path.dirname(__filename);
53
+ const daemonScript = path.join(__dirname, "chrome-daemon.js");
54
+ if (!fs.existsSync(daemonScript)) {
55
+ throw new Error(`Daemon script not found: ${daemonScript}\n` +
56
+ "Make sure to run 'npm run build' first");
57
+ }
58
+ // Prepare daemon args with config
59
+ const args = [daemonScript];
60
+ if (config) {
61
+ args.push(`--config=${JSON.stringify(config)}`);
62
+ }
63
+ // Start daemon as detached process
64
+ const daemon = spawn("node", args, {
65
+ detached: true,
66
+ stdio: "ignore",
67
+ });
68
+ daemon.unref();
69
+ console.error(`Chrome daemon started (PID: ${daemon.pid})`);
70
+ }
71
+ static async isChromeReachable() {
72
+ try {
73
+ const response = await fetch(`http://localhost:${CDP_PORT}/json/version`, {
74
+ signal: AbortSignal.timeout(1000),
75
+ });
76
+ return response.ok;
77
+ }
78
+ catch {
79
+ return false;
80
+ }
81
+ }
82
+ /**
83
+ * Get CDP endpoint URL
84
+ */
85
+ static getCdpEndpoint() {
86
+ return `http://localhost:${CDP_PORT}`;
87
+ }
88
+ }
89
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/daemon/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Main entry point for ultimate-playwright-mcp
3
+ * Exports server creation function for programmatic use
4
+ */
5
+ export { createMCPServer, runServer } from "./mcp/server.js";
6
+ export type { ServerConfig } from "./config.js";
7
+ export { validateConfig } from "./config.js";
8
+ export { getPageForTargetId, listPagesViaPlaywright, createPageViaPlaywright, closePageByTargetIdViaPlaywright, focusPageByTargetIdViaPlaywright, } from "./browser/pw-session.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Main entry point for ultimate-playwright-mcp
3
+ * Exports server creation function for programmatic use
4
+ */
5
+ export { createMCPServer, runServer } from "./mcp/server.js";
6
+ export { validateConfig } from "./config.js";
7
+ // Re-export browser functions for advanced use cases
8
+ export { getPageForTargetId, listPagesViaPlaywright, createPageViaPlaywright, closePageByTargetIdViaPlaywright, focusPageByTargetIdViaPlaywright, } from "./browser/pw-session.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,qDAAqD;AACrD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * MCP server implementation with Playwright browser control via CDP
3
+ */
4
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
5
+ import type { ServerConfig } from "../config.js";
6
+ export declare function createMCPServer(config: ServerConfig): Promise<Server<{
7
+ method: string;
8
+ params?: {
9
+ [x: string]: unknown;
10
+ _meta?: {
11
+ [x: string]: unknown;
12
+ progressToken?: string | number | undefined;
13
+ "io.modelcontextprotocol/related-task"?: {
14
+ taskId: string;
15
+ } | undefined;
16
+ } | undefined;
17
+ } | undefined;
18
+ }, {
19
+ method: string;
20
+ params?: {
21
+ [x: string]: unknown;
22
+ _meta?: {
23
+ [x: string]: unknown;
24
+ progressToken?: string | number | undefined;
25
+ "io.modelcontextprotocol/related-task"?: {
26
+ taskId: string;
27
+ } | undefined;
28
+ } | undefined;
29
+ } | undefined;
30
+ }, {
31
+ [x: string]: unknown;
32
+ _meta?: {
33
+ [x: string]: unknown;
34
+ progressToken?: string | number | undefined;
35
+ "io.modelcontextprotocol/related-task"?: {
36
+ taskId: string;
37
+ } | undefined;
38
+ } | undefined;
39
+ }>>;
40
+ export declare function runServer(config: ServerConfig): Promise<void>;
41
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAYjD,wBAAsB,eAAe,CAAC,MAAM,EAAE,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkFzD;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,YAAY,iBA4CnD"}