browser-ipc-cdp 1.5.0 → 1.7.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.
- package/lib/mcp.js +4 -2
- package/lib/network.js +93 -112
- package/package.json +1 -1
package/lib/mcp.js
CHANGED
|
@@ -47,9 +47,11 @@ function getWslHostIp() {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
function updateMcpJson(port, wslIp) {
|
|
50
|
+
// Estrategia: ejecutar el MCP desde Windows via cmd.exe
|
|
51
|
+
// Asi usa 127.0.0.1 directo, sin portproxy ni firewall
|
|
50
52
|
const braveEntry = {
|
|
51
|
-
command: '
|
|
52
|
-
args: ['-y', 'chrome-devtools-mcp@latest', '--browserUrl', `http
|
|
53
|
+
command: 'cmd.exe',
|
|
54
|
+
args: ['/c', 'npx', '-y', 'chrome-devtools-mcp@latest', '--browserUrl', `http://127.0.0.1:${port}`],
|
|
53
55
|
};
|
|
54
56
|
|
|
55
57
|
// Rutas base donde buscar .mcp.json
|
package/lib/network.js
CHANGED
|
@@ -1,147 +1,128 @@
|
|
|
1
1
|
const { execSync } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
2
4
|
const { log, success, warn } = require('./logger');
|
|
3
5
|
|
|
4
6
|
const IS_WIN = process.platform === 'win32';
|
|
5
7
|
let IS_WSL = false;
|
|
6
|
-
try {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
IS_WSL = v.includes('microsoft') || v.includes('wsl');
|
|
11
|
-
} catch (e2) {}
|
|
12
|
-
}
|
|
8
|
+
try {
|
|
9
|
+
const v = fs.readFileSync('/proc/version', 'utf-8').toLowerCase();
|
|
10
|
+
IS_WSL = v.includes('microsoft') || v.includes('wsl');
|
|
11
|
+
} catch (e) {}
|
|
13
12
|
|
|
14
|
-
const NEEDS_NETSH = IS_WIN; // WSL no necesita netsh, usa host IP directo
|
|
15
13
|
const FIREWALL_RULE = 'CDP All Ports (IPC)';
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
success('Firewall: regla universal creada (elevado)');
|
|
50
|
-
return true;
|
|
51
|
-
} catch (e) {
|
|
52
|
-
warn('Firewall: no se pudo crear regla (ejecuta como Admin en Windows)');
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
15
|
+
/**
|
|
16
|
+
* Ejecuta netsh con permisos elevados usando Python ctypes.
|
|
17
|
+
* Python puede usar ctypes.windll.shell32.ShellExecuteW para elevar sin .bat
|
|
18
|
+
* O si ya tiene permisos, ejecuta directo.
|
|
19
|
+
*/
|
|
20
|
+
function runNetshElevated(netshCommand) {
|
|
21
|
+
// Python script inline que ejecuta como admin sin UAC visible
|
|
22
|
+
const pyScript = `
|
|
23
|
+
import subprocess, sys, os
|
|
24
|
+
cmd = r'${netshCommand}'
|
|
25
|
+
try:
|
|
26
|
+
r = subprocess.run(cmd, shell=True, capture_output=True, timeout=10)
|
|
27
|
+
if r.returncode == 0:
|
|
28
|
+
sys.exit(0)
|
|
29
|
+
except:
|
|
30
|
+
pass
|
|
31
|
+
# Si fallo, intentar con ctypes (elevation silenciosa)
|
|
32
|
+
try:
|
|
33
|
+
import ctypes
|
|
34
|
+
if not ctypes.windll.shell32.IsUserAnAdmin():
|
|
35
|
+
ctypes.windll.shell32.ShellExecuteW(None, "runas", "cmd.exe", f"/c {cmd}", None, 0)
|
|
36
|
+
import time; time.sleep(3)
|
|
37
|
+
sys.exit(0)
|
|
38
|
+
except:
|
|
39
|
+
pass
|
|
40
|
+
sys.exit(1)
|
|
41
|
+
`.trim();
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const pythonCmd = IS_WSL ? 'python3' : 'python';
|
|
45
|
+
execSync(`${pythonCmd} -c "${pyScript.replace(/"/g, '\\"').replace(/\n/g, ';')}"`,
|
|
46
|
+
{ timeout: 15000, stdio: 'pipe' });
|
|
56
47
|
return true;
|
|
57
|
-
}
|
|
48
|
+
} catch (e) {}
|
|
58
49
|
|
|
59
|
-
//
|
|
50
|
+
// Fallback: powershell directo
|
|
60
51
|
try {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
{ timeout:
|
|
64
|
-
|
|
52
|
+
const ps = IS_WSL ? 'powershell.exe' : 'powershell';
|
|
53
|
+
execSync(`${ps} -Command "Start-Process cmd -ArgumentList '/c ${netshCommand}' -Verb RunAs -Wait -WindowStyle Hidden"`,
|
|
54
|
+
{ timeout: 30000, stdio: 'pipe' });
|
|
55
|
+
return true;
|
|
56
|
+
} catch (e) {}
|
|
57
|
+
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function setupFirewall() {
|
|
62
|
+
if (!IS_WIN && !IS_WSL) return true;
|
|
63
|
+
|
|
64
|
+
// Verificar si ya existe
|
|
65
|
+
try {
|
|
66
|
+
const cmd = IS_WSL
|
|
67
|
+
? `cmd.exe /c netsh advfirewall firewall show rule name="${FIREWALL_RULE}"`
|
|
68
|
+
: `netsh advfirewall firewall show rule name="${FIREWALL_RULE}"`;
|
|
69
|
+
const check = execSync(cmd, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
|
|
65
70
|
if (check.includes(FIREWALL_RULE)) return true;
|
|
66
71
|
} catch (e) {}
|
|
67
72
|
|
|
73
|
+
const fwCmd = `netsh advfirewall firewall add rule name="${FIREWALL_RULE}" dir=in action=allow protocol=TCP localport=1024-65535`;
|
|
74
|
+
|
|
75
|
+
// Intento 1: directo
|
|
68
76
|
try {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
);
|
|
73
|
-
success('Firewall: regla universal creada');
|
|
77
|
+
const cmd = IS_WSL ? `cmd.exe /c ${fwCmd}` : fwCmd;
|
|
78
|
+
execSync(cmd, { timeout: 10000, stdio: 'pipe' });
|
|
79
|
+
success('Firewall: regla creada');
|
|
74
80
|
return true;
|
|
75
|
-
} catch (e) {
|
|
76
|
-
warn('Firewall: no se pudo crear regla (ejecuta como Admin)');
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
81
|
+
} catch (e) {}
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
// Intento 2: elevado
|
|
84
|
+
if (runNetshElevated(fwCmd)) {
|
|
85
|
+
success('Firewall: regla creada (elevado)');
|
|
84
86
|
return true;
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
log(` Portproxy ya existe para puerto ${port}`);
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
} catch (e) {}
|
|
97
|
-
|
|
98
|
-
// Intento 1: cmd.exe directo (si WSL tiene permisos)
|
|
99
|
-
try {
|
|
100
|
-
execSync(
|
|
101
|
-
`cmd.exe /c netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`,
|
|
102
|
-
{ timeout: 10000, stdio: 'pipe' }
|
|
103
|
-
);
|
|
104
|
-
success(`Portproxy: 0.0.0.0:${port} -> 127.0.0.1:${port} (via WSL)`);
|
|
105
|
-
return true;
|
|
106
|
-
} catch (e) {}
|
|
107
|
-
|
|
108
|
-
// Intento 2: elevar con powershell -Verb RunAs
|
|
109
|
-
try {
|
|
110
|
-
const netshCmd = `netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`;
|
|
111
|
-
execSync(
|
|
112
|
-
`powershell.exe -Command "Start-Process cmd -ArgumentList '/c ${netshCmd}' -Verb RunAs -Wait"`,
|
|
113
|
-
{ timeout: 30000, stdio: 'pipe' }
|
|
114
|
-
);
|
|
115
|
-
success(`Portproxy: 0.0.0.0:${port} -> 127.0.0.1:${port} (elevado)`);
|
|
116
|
-
return true;
|
|
117
|
-
} catch (e) {
|
|
118
|
-
warn(`Portproxy: fallo. Ejecuta manualmente como Admin en Windows:`);
|
|
119
|
-
warn(` netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`);
|
|
120
|
-
return false;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
89
|
+
warn('Firewall: no se pudo crear regla');
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function setupPortproxy(port) {
|
|
94
|
+
if (!IS_WIN && !IS_WSL) return true;
|
|
123
95
|
|
|
124
|
-
//
|
|
96
|
+
// Verificar si ya existe
|
|
125
97
|
try {
|
|
126
|
-
const
|
|
127
|
-
|
|
98
|
+
const cmd = IS_WSL
|
|
99
|
+
? 'cmd.exe /c netsh interface portproxy show all'
|
|
100
|
+
: 'netsh interface portproxy show all';
|
|
101
|
+
const check = execSync(cmd, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
|
|
128
102
|
if (check.includes(`0.0.0.0 ${port}`)) {
|
|
129
103
|
log(` Portproxy ya existe para puerto ${port}`);
|
|
130
104
|
return true;
|
|
131
105
|
}
|
|
132
106
|
} catch (e) {}
|
|
133
107
|
|
|
108
|
+
const proxyCmd = `netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`;
|
|
109
|
+
|
|
110
|
+
// Intento 1: directo
|
|
134
111
|
try {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
{ timeout: 10000, stdio: 'pipe' }
|
|
138
|
-
);
|
|
112
|
+
const cmd = IS_WSL ? `cmd.exe /c ${proxyCmd}` : proxyCmd;
|
|
113
|
+
execSync(cmd, { timeout: 10000, stdio: 'pipe' });
|
|
139
114
|
success(`Portproxy: 0.0.0.0:${port} -> 127.0.0.1:${port}`);
|
|
140
115
|
return true;
|
|
141
|
-
} catch (e) {
|
|
142
|
-
|
|
143
|
-
|
|
116
|
+
} catch (e) {}
|
|
117
|
+
|
|
118
|
+
// Intento 2: elevado
|
|
119
|
+
if (runNetshElevated(proxyCmd)) {
|
|
120
|
+
success(`Portproxy: 0.0.0.0:${port} -> 127.0.0.1:${port} (elevado)`);
|
|
121
|
+
return true;
|
|
144
122
|
}
|
|
123
|
+
|
|
124
|
+
warn(`Portproxy: fallo para puerto ${port}`);
|
|
125
|
+
return false;
|
|
145
126
|
}
|
|
146
127
|
|
|
147
128
|
module.exports = { setupFirewall, setupPortproxy };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browser-ipc-cdp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Control remoto de navegadores Chromium (Brave, Chrome, Edge) via IPC + CDP dinamico. Un comando para conectar Claude Code a tu navegador real.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"browser-ipc-cdp": "bin/cli.js"
|