chrome-bridge-mcp 1.31.1 → 1.31.2
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.
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/server/index.js +32 -2
- package/server/protocol.js +1 -1
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-bridge-mcp",
|
|
3
|
-
"version": "1.31.
|
|
3
|
+
"version": "1.31.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "chrome-bridge-mcp",
|
|
9
|
-
"version": "1.31.
|
|
9
|
+
"version": "1.31.2",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@jridgewell/trace-mapping": "^0.3.31",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-bridge-mcp",
|
|
3
3
|
"mcpName": "io.github.frsorrentino/chrome-bridge",
|
|
4
|
-
"version": "1.31.
|
|
4
|
+
"version": "1.31.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Chrome Bridge by frsorrentino: MCP server that lets Claude Code borrow a tab from your own logged-in Chrome and hand it back — logins, 2FA and CAPTCHAs stay with you (handoff). 69 tools; 2.8-4.3× cheaper and up to 9.3× fewer turns than Claude in Chrome, measured; ChromeOS included.",
|
|
7
7
|
"main": "server/index.js",
|
package/server/index.js
CHANGED
|
@@ -44,6 +44,9 @@ function parseSecurity() {
|
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
const SHUTDOWN_DEADLINE_MS = 10000;
|
|
48
|
+
const PARENT_CHECK_MS = 1000;
|
|
49
|
+
|
|
47
50
|
function parseCaps() {
|
|
48
51
|
const i = process.argv.indexOf('--caps');
|
|
49
52
|
if (i !== -1 && process.argv[i + 1]) return process.argv[i + 1];
|
|
@@ -78,6 +81,9 @@ async function main() {
|
|
|
78
81
|
// segnale arrivano insieme.
|
|
79
82
|
let closing = null;
|
|
80
83
|
const shutdown = () => (closing ??= (async () => {
|
|
84
|
+
// Uno shutdown bloccato non deve tenere vivo il processo: dopo la
|
|
85
|
+
// scadenza, o al secondo segnale, si esce comunque.
|
|
86
|
+
setTimeout(forceExit, SHUTDOWN_DEADLINE_MS);
|
|
81
87
|
console.error('[chrome-bridge] Shutting down...');
|
|
82
88
|
// Il browser di --launch per primo: su Windows Claude Code chiude stdin e
|
|
83
89
|
// dopo 300 ms uccide l'albero dei processi (2.1.296). Le sue schede
|
|
@@ -91,14 +97,38 @@ async function main() {
|
|
|
91
97
|
try { await mcpServer.close(); } catch {}
|
|
92
98
|
process.exit(0);
|
|
93
99
|
})());
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
const forceExit = () => {
|
|
101
|
+
if (browser) { try { process.kill(browser.pid, 'SIGKILL'); } catch {} }
|
|
102
|
+
process.exit(1);
|
|
103
|
+
};
|
|
104
|
+
const onSignal = () => (closing ? forceExit() : shutdown());
|
|
105
|
+
process.on('SIGINT', onSignal);
|
|
106
|
+
process.on('SIGTERM', onSignal);
|
|
107
|
+
// Client sparito: stdout e stderr restano pipe senza lettore e ogni
|
|
108
|
+
// scrittura dà EPIPE. Senza questi ascoltatori l'errore arrivava a
|
|
109
|
+
// uncaughtException, che riscriveva su stderr: un ciclo di errori che non
|
|
110
|
+
// lasciava girare l'event loop, neanche per SIGTERM (28/10/2026: un server
|
|
111
|
+
// --launch orfano da 2 h al 46% di CPU, chiuso solo con SIGKILL).
|
|
112
|
+
process.stdout.on('error', shutdown);
|
|
113
|
+
process.stderr.on('error', shutdown);
|
|
96
114
|
// Su Windows SIGINT e SIGTERM non arrivano, e un client terminato di colpo
|
|
97
115
|
// non manda segnali: in entrambi i casi resta solo la fine di stdin. L'SDK
|
|
98
116
|
// non la ascolta, e il WebSocket teneva vivo il processo.
|
|
99
117
|
process.stdin.once('end', shutdown);
|
|
100
118
|
process.stdin.once('close', shutdown);
|
|
101
119
|
mcpServer.server.onclose = shutdown;
|
|
120
|
+
// Prima di mcpServer.connect() nessuno legge stdin e la sua fine non
|
|
121
|
+
// arriva; un client che muore durante l'avvio a freddo di Chrome lascia un
|
|
122
|
+
// orfano adottato da init (o da systemd, su Crostini). Il cambio di padre
|
|
123
|
+
// lo rivela anche quando stdin resta aperto in un altro processo.
|
|
124
|
+
if (LAUNCH) {
|
|
125
|
+
const parent = process.ppid;
|
|
126
|
+
const parentGone = () => {
|
|
127
|
+
if (process.ppid !== parent) return true;
|
|
128
|
+
try { process.kill(parent, 0); return false; } catch (e) { return e.code !== 'EPERM'; }
|
|
129
|
+
};
|
|
130
|
+
setInterval(() => { if (parentGone()) shutdown(); }, PARENT_CHECK_MS).unref();
|
|
131
|
+
}
|
|
102
132
|
process.on('uncaughtException', (err) => {
|
|
103
133
|
console.error('[chrome-bridge] Uncaught exception:', err);
|
|
104
134
|
shutdown().catch(() => process.exit(1));
|