mcpbrowser 0.2.6 → 0.2.8

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.
@@ -2,7 +2,7 @@
2
2
  "name": "mcpbrowser",
3
3
  "displayName": "MCP Browser",
4
4
  "description": "Extends Copilot's web access to protected pages - handles login, SSO, and anti-crawler restrictions",
5
- "version": "0.1.6",
5
+ "version": "0.2.8",
6
6
  "publisher": "cherchyk",
7
7
  "icon": "icon.png",
8
8
  "engines": {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  { "name": "mcpbrowser",
2
- "version": "0.2.6",
2
+ "version": "0.2.8",
3
3
  "mcpName": "io.github.cherchyk/browser",
4
4
  "type": "module",
5
5
  "description": "MCP server that loads authenticated web pages using Chrome DevTools Protocol",
package/server.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/cherchyk/MCPBrowser",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.2.6",
9
+ "version": "0.2.7",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
@@ -60,6 +60,7 @@ const defaultChromePaths = getDefaultChromePaths();
60
60
 
61
61
  let cachedBrowser = null;
62
62
  let lastKeptPage = null; // reuse the same tab when requested
63
+ let chromeLaunchPromise = null; // prevent multiple simultaneous launches
63
64
 
64
65
  async function devtoolsAvailable() {
65
66
  try {
@@ -80,24 +81,47 @@ function findChromePath() {
80
81
 
81
82
  async function launchChromeIfNeeded() {
82
83
  if (explicitWSEndpoint) return; // user provided explicit endpoint; assume managed externally
84
+
85
+ // If Chrome is already available, don't launch
83
86
  if (await devtoolsAvailable()) return;
84
-
85
- const chromePath = findChromePath();
86
- if (!chromePath) {
87
- throw new Error("Chrome/Edge not found. Set CHROME_PATH to your browser executable.");
87
+
88
+ // If a launch is already in progress, wait for it
89
+ if (chromeLaunchPromise) {
90
+ return await chromeLaunchPromise;
88
91
  }
92
+
93
+ // Create a new launch promise to prevent multiple simultaneous launches
94
+ chromeLaunchPromise = (async () => {
95
+ try {
96
+ // Double-check after acquiring the launch lock
97
+ if (await devtoolsAvailable()) return;
98
+
99
+ const chromePath = findChromePath();
100
+ if (!chromePath) {
101
+ throw new Error("Chrome/Edge not found. Set CHROME_PATH to your browser executable.");
102
+ }
89
103
 
90
- const args = [`--remote-debugging-port=${chromePort}`, `--user-data-dir=${userDataDir}`];
91
- const child = spawn(chromePath, args, { detached: true, stdio: "ignore" });
92
- child.unref();
104
+ const args = [
105
+ `--remote-debugging-port=${chromePort}`,
106
+ `--user-data-dir=${userDataDir}`,
107
+ 'about:blank' // Open with a blank page
108
+ ];
109
+ const child = spawn(chromePath, args, { detached: true, stdio: "ignore" });
110
+ child.unref();
93
111
 
94
- // Wait for DevTools to come up
95
- const deadline = Date.now() + 20000;
96
- while (Date.now() < deadline) {
97
- if (await devtoolsAvailable()) return;
98
- await new Promise((r) => setTimeout(r, 500));
99
- }
100
- throw new Error("Chrome did not become available on DevTools port; check CHROME_PATH/port/profile.");
112
+ // Wait for DevTools to come up
113
+ const deadline = Date.now() + 20000;
114
+ while (Date.now() < deadline) {
115
+ if (await devtoolsAvailable()) return;
116
+ await new Promise((r) => setTimeout(r, 500));
117
+ }
118
+ throw new Error("Chrome did not become available on DevTools port; check CHROME_PATH/port/profile.");
119
+ } finally {
120
+ chromeLaunchPromise = null;
121
+ }
122
+ })();
123
+
124
+ return await chromeLaunchPromise;
101
125
  }
102
126
 
103
127
  async function resolveWSEndpoint() {
@@ -173,9 +197,17 @@ async function fetchPage({
173
197
  }
174
198
  }
175
199
 
176
- // Create new tab if no reuse
200
+ // Try to reuse existing pages first (when Chrome opened with profile)
177
201
  if (!page) {
178
- page = await browser.newPage();
202
+ const pages = await browser.pages();
203
+ // Find an existing page that's not being used
204
+ if (pages.length > 0) {
205
+ // Use the first available page (usually the blank tab Chrome opens with)
206
+ page = pages[0];
207
+ } else {
208
+ // Create new tab if no existing pages
209
+ page = await browser.newPage();
210
+ }
179
211
  }
180
212
 
181
213
  let shouldKeepOpen = keepPageOpen || page === lastKeptPage;