browser-ipc-cdp 1.8.0 → 1.8.1
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/README.md +58 -0
- package/brave_mcp_launcher.js +51 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
Control remoto de navegadores Chromium (Brave, Chrome, Edge) via IPC con CDP dinamico. Abre tu navegador real con todas tus sesiones, detecta o asigna puerto automaticamente, configura portproxy/firewall para WSL, y actualiza el MCP de Claude Code. Sin puertos fijos, sin hacks de registry, sin configuracion manual.
|
|
4
4
|
|
|
5
|
+
```bash
|
|
6
|
+
npm i browser-ipc-cdp
|
|
7
|
+
npx browser-ipc-cdp
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Despues `/mcp` en Claude Code y listo. El wrapper resuelve el puerto dinamico solo, no hay que reescribir `.mcp.json` cuando cambia.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Por que usarlo
|
|
15
|
+
|
|
16
|
+
- **Mantiene tus sesiones reales**: cookies, 2FA, extensiones, tabs abiertas — nada se pierde
|
|
17
|
+
- **Pasa Cloudflare sin captcha**: usa tu cookie `cf_clearance` ya validada, no parece bot
|
|
18
|
+
- **Cross-browser**: Brave, Chrome, Edge, Chromium
|
|
19
|
+
- **Puerto dinamico**: cero conflictos, OS asigna puerto libre via DevToolsActivePort IPC
|
|
20
|
+
- **Auto-config WSL**: portproxy + firewall + .mcp.json sin pasos manuales
|
|
21
|
+
- **DevTools completo**: Network, Console, Performance, Lighthouse, Coverage, Heap snapshots
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Acceso completo a Red (CDP)
|
|
26
|
+
|
|
27
|
+
`browser-ipc-cdp` expone el subsistema **Network** del navegador. Cualquier request HTTP/HTTPS, WebSocket, XHR o fetch se puede observar, interceptar, modificar o bloquear.
|
|
28
|
+
|
|
29
|
+
| Capacidad | Metodo CDP |
|
|
30
|
+
|-----------|------------|
|
|
31
|
+
| Listar requests | `Network.requestWillBeSent` |
|
|
32
|
+
| Leer body response | `Network.getResponseBody` |
|
|
33
|
+
| Modificar headers | `Network.setExtraHTTPHeaders` |
|
|
34
|
+
| Bloquear URLs (ads/tracking) | `Network.setBlockedURLs` |
|
|
35
|
+
| Mock responses | `Fetch.fulfillRequest` |
|
|
36
|
+
| Interceptar requests | `Fetch.requestPaused` |
|
|
37
|
+
| Throttling (3G/offline) | `Network.emulateNetworkConditions` |
|
|
38
|
+
| Cookies CRUD | `Network.getCookies` / `setCookie` / `deleteCookies` |
|
|
39
|
+
| Espiar WebSockets | `Network.webSocketFrameSent/Received` |
|
|
40
|
+
| Auth challenge | `Fetch.authRequired` |
|
|
41
|
+
|
|
42
|
+
**[📖 Documentacion completa de Network + ejemplos](docs/CDP_NETWORK.md)**
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## ⚠️ Uso responsable
|
|
47
|
+
|
|
48
|
+
Esta herramienta esta destinada a **testing personal, automatizacion propia y desarrollo**. El usuario es responsable de:
|
|
49
|
+
|
|
50
|
+
- Usarla solo en navegadores y cuentas que le pertenecen
|
|
51
|
+
- Cumplir con los Terms of Service de los sitios que automatice
|
|
52
|
+
- Respetar leyes locales sobre privacidad y acceso a sistemas
|
|
53
|
+
|
|
54
|
+
**NO se autoriza el uso para:**
|
|
55
|
+
|
|
56
|
+
- Acceso no autorizado a sistemas ajenos
|
|
57
|
+
- Scraping que viole ToS de un servicio
|
|
58
|
+
- Bypass de protecciones de seguridad sin permiso del owner
|
|
59
|
+
- Automatizacion de cuentas de terceros sin consentimiento
|
|
60
|
+
|
|
61
|
+
Distribuida bajo licencia **MIT** — el autor (`Alexis Malambo`) no se hace responsable del mal uso por terceros (clausula `AS IS, WITHOUT WARRANTY OF ANY KIND`).
|
|
62
|
+
|
|
5
63
|
---
|
|
6
64
|
|
|
7
65
|
# Documentacion
|
package/brave_mcp_launcher.js
CHANGED
|
@@ -51,14 +51,51 @@ function readCdpInfo() {
|
|
|
51
51
|
return null;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
function
|
|
55
|
-
if (IS_WIN) return '127.0.0.1';
|
|
54
|
+
function getHostCandidates() {
|
|
55
|
+
if (IS_WIN) return ['127.0.0.1'];
|
|
56
|
+
|
|
57
|
+
const seen = new Set();
|
|
58
|
+
const candidates = [];
|
|
59
|
+
const add = (ip) => { if (ip && !seen.has(ip)) { seen.add(ip); candidates.push(ip); } };
|
|
60
|
+
|
|
61
|
+
// 1. Gateway IP via /proc/net/route — IP real del host Windows en WSL2 NAT
|
|
62
|
+
try {
|
|
63
|
+
const route = fs.readFileSync('/proc/net/route', 'utf-8');
|
|
64
|
+
for (const line of route.split('\n').slice(1)) {
|
|
65
|
+
const parts = line.split(/\s+/);
|
|
66
|
+
if (parts[1] === '00000000' && parts[2] && parts[2] !== '00000000') {
|
|
67
|
+
const hex = parts[2];
|
|
68
|
+
add([
|
|
69
|
+
parseInt(hex.slice(6, 8), 16),
|
|
70
|
+
parseInt(hex.slice(4, 6), 16),
|
|
71
|
+
parseInt(hex.slice(2, 4), 16),
|
|
72
|
+
parseInt(hex.slice(0, 2), 16),
|
|
73
|
+
].join('.'));
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
} catch (e) {}
|
|
78
|
+
|
|
79
|
+
// 2. Localhost (WSL2 mirrored networking mode)
|
|
80
|
+
add('127.0.0.1');
|
|
81
|
+
|
|
82
|
+
// 3. Nameservers de /etc/resolv.conf (último recurso)
|
|
56
83
|
try {
|
|
57
84
|
const resolv = fs.readFileSync('/etc/resolv.conf', 'utf-8');
|
|
58
|
-
const
|
|
59
|
-
|
|
85
|
+
const re = /nameserver\s+(\d+\.\d+\.\d+\.\d+)/g;
|
|
86
|
+
let m;
|
|
87
|
+
while ((m = re.exec(resolv))) add(m[1]);
|
|
60
88
|
} catch (e) {}
|
|
61
|
-
|
|
89
|
+
|
|
90
|
+
return candidates;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function tryCandidates(port, candidates, timeoutMs) {
|
|
94
|
+
for (const host of candidates) {
|
|
95
|
+
const url = `http://${host}:${port}`;
|
|
96
|
+
if (await testCdp(url, timeoutMs)) return url;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
62
99
|
}
|
|
63
100
|
|
|
64
101
|
function testCdp(url, timeoutMs = 3000) {
|
|
@@ -76,28 +113,21 @@ function testCdp(url, timeoutMs = 3000) {
|
|
|
76
113
|
}
|
|
77
114
|
|
|
78
115
|
async function ensureCdpReady() {
|
|
79
|
-
const
|
|
116
|
+
const candidates = getHostCandidates();
|
|
117
|
+
logErr(`Candidatos host: ${candidates.join(', ')}`);
|
|
80
118
|
let info = readCdpInfo();
|
|
81
119
|
let port = info && info.DEBUG_PORT;
|
|
82
120
|
|
|
83
|
-
// Intento 1:
|
|
121
|
+
// Intento 1: probar candidatos con el puerto en cdp_info.json
|
|
84
122
|
if (port) {
|
|
85
|
-
const url =
|
|
86
|
-
if (
|
|
123
|
+
const url = await tryCandidates(port, candidates, 3000);
|
|
124
|
+
if (url) {
|
|
87
125
|
logErr(`CDP activo en ${url}`);
|
|
88
126
|
return url;
|
|
89
127
|
}
|
|
90
|
-
// Intento 2: localhost (caso Windows nativo)
|
|
91
|
-
if (hostIP !== '127.0.0.1') {
|
|
92
|
-
const localUrl = `http://127.0.0.1:${port}`;
|
|
93
|
-
if (await testCdp(localUrl)) {
|
|
94
|
-
logErr(`CDP activo en ${localUrl} (fallback localhost)`);
|
|
95
|
-
return localUrl;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
128
|
}
|
|
99
129
|
|
|
100
|
-
// Intento
|
|
130
|
+
// Intento 2: auto-launch via brave_ipc.py
|
|
101
131
|
logErr('CDP no responde. Auto-lanzando Brave via brave_ipc.py...');
|
|
102
132
|
if (!fs.existsSync(BRAVE_IPC_PY)) {
|
|
103
133
|
logErr(`brave_ipc.py no encontrado en ${BRAVE_IPC_PY}`);
|
|
@@ -115,20 +145,15 @@ async function ensureCdpReady() {
|
|
|
115
145
|
logErr(`Auto-launch fallo: ${e.message}`);
|
|
116
146
|
}
|
|
117
147
|
|
|
118
|
-
// Releer y reverificar
|
|
148
|
+
// Releer y reverificar contra todos los candidatos
|
|
119
149
|
info = readCdpInfo();
|
|
120
150
|
port = info && info.DEBUG_PORT;
|
|
121
151
|
if (port) {
|
|
122
|
-
const url =
|
|
123
|
-
if (
|
|
152
|
+
const url = await tryCandidates(port, candidates, 5000);
|
|
153
|
+
if (url) {
|
|
124
154
|
logErr(`CDP activo despues de auto-launch en ${url}`);
|
|
125
155
|
return url;
|
|
126
156
|
}
|
|
127
|
-
const localUrl = `http://127.0.0.1:${port}`;
|
|
128
|
-
if (await testCdp(localUrl, 5000)) {
|
|
129
|
-
logErr(`CDP activo despues de auto-launch en ${localUrl}`);
|
|
130
|
-
return localUrl;
|
|
131
|
-
}
|
|
132
157
|
}
|
|
133
158
|
|
|
134
159
|
logErr('CDP sigue sin responder despues de auto-launch.');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browser-ipc-cdp",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.1",
|
|
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"
|