@natchs/browser-mcp 2.3.1 → 2.4.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/README.md +295 -15
- package/dist/core/audit-logger.d.ts +3 -0
- package/dist/core/audit-logger.d.ts.map +1 -0
- package/dist/core/audit-logger.js +5 -0
- package/dist/core/audit-logger.js.map +1 -0
- package/dist/core/auth.d.ts.map +1 -1
- package/dist/core/auth.js +29 -1
- package/dist/core/auth.js.map +1 -1
- package/dist/core/body-fetch.d.ts.map +1 -1
- package/dist/core/body-fetch.js +26 -2
- package/dist/core/body-fetch.js.map +1 -1
- package/dist/core/browser-lifecycle.d.ts +29 -0
- package/dist/core/browser-lifecycle.d.ts.map +1 -0
- package/dist/core/browser-lifecycle.js +107 -0
- package/dist/core/browser-lifecycle.js.map +1 -0
- package/dist/core/browser-provider.d.ts +7 -3
- package/dist/core/browser-provider.d.ts.map +1 -1
- package/dist/core/browser-provider.js +65 -10
- package/dist/core/browser-provider.js.map +1 -1
- package/dist/core/config.d.ts +22 -6
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +6 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/errors.d.ts +0 -12
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +4 -13
- package/dist/core/errors.js.map +1 -1
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/network-capture-utils.d.ts +49 -0
- package/dist/core/network-capture-utils.d.ts.map +1 -0
- package/dist/core/network-capture-utils.js +56 -0
- package/dist/core/network-capture-utils.js.map +1 -0
- package/dist/core/network-capture.d.ts +2 -39
- package/dist/core/network-capture.d.ts.map +1 -1
- package/dist/core/network-capture.js +17 -54
- package/dist/core/network-capture.js.map +1 -1
- package/dist/core/network-export.d.ts +3 -3
- package/dist/core/network-export.d.ts.map +1 -1
- package/dist/core/network-export.js +13 -21
- package/dist/core/network-export.js.map +1 -1
- package/dist/core/output.d.ts +0 -28
- package/dist/core/output.d.ts.map +1 -1
- package/dist/core/registry.d.ts +2 -0
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +14 -3
- package/dist/core/registry.js.map +1 -1
- package/dist/core/sandbox.d.ts +4 -5
- package/dist/core/sandbox.d.ts.map +1 -1
- package/dist/core/sandbox.js +31 -23
- package/dist/core/sandbox.js.map +1 -1
- package/dist/core/session.d.ts +4 -3
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +43 -22
- package/dist/core/session.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +2 -1
- package/dist/prompts/index.js.map +1 -1
- package/dist/tools/admin/cache.js +3 -3
- package/dist/tools/admin/cache.js.map +1 -1
- package/dist/tools/admin/server-status.js +2 -2
- package/dist/tools/admin/server-status.js.map +1 -1
- package/dist/tools/browser/cookies.js +4 -4
- package/dist/tools/browser/cookies.js.map +1 -1
- package/dist/tools/browser/download.js +2 -2
- package/dist/tools/browser/download.js.map +1 -1
- package/dist/tools/browser/evaluate.d.ts.map +1 -1
- package/dist/tools/browser/evaluate.js +23 -6
- package/dist/tools/browser/evaluate.js.map +1 -1
- package/dist/tools/browser/index.d.ts.map +1 -1
- package/dist/tools/browser/index.js +2 -0
- package/dist/tools/browser/index.js.map +1 -1
- package/dist/tools/browser/page-info.js +2 -2
- package/dist/tools/browser/page-info.js.map +1 -1
- package/dist/tools/browser/pdf.js +4 -4
- package/dist/tools/browser/pdf.js.map +1 -1
- package/dist/tools/browser/screenshot.js +3 -3
- package/dist/tools/browser/screenshot.js.map +1 -1
- package/dist/tools/browser/scroll.d.ts +17 -0
- package/dist/tools/browser/scroll.d.ts.map +1 -0
- package/dist/tools/browser/scroll.js +30 -0
- package/dist/tools/browser/scroll.js.map +1 -0
- package/dist/tools/extraction/extract-css.js +7 -7
- package/dist/tools/extraction/extract-css.js.map +1 -1
- package/dist/tools/extraction/extract.js +4 -4
- package/dist/tools/extraction/extract.js.map +1 -1
- package/dist/tools/interaction/click.d.ts +1 -2
- package/dist/tools/interaction/click.d.ts.map +1 -1
- package/dist/tools/interaction/click.js +9 -15
- package/dist/tools/interaction/click.js.map +1 -1
- package/dist/tools/interaction/drag.js +4 -4
- package/dist/tools/interaction/drag.js.map +1 -1
- package/dist/tools/interaction/file-upload.d.ts.map +1 -1
- package/dist/tools/interaction/file-upload.js +11 -5
- package/dist/tools/interaction/file-upload.js.map +1 -1
- package/dist/tools/interaction/fill.d.ts.map +1 -1
- package/dist/tools/interaction/fill.js +5 -7
- package/dist/tools/interaction/fill.js.map +1 -1
- package/dist/tools/interaction/hover.js +3 -3
- package/dist/tools/interaction/hover.js.map +1 -1
- package/dist/tools/interaction/press-key.js +3 -3
- package/dist/tools/interaction/press-key.js.map +1 -1
- package/dist/tools/interaction/select.js +4 -4
- package/dist/tools/interaction/select.js.map +1 -1
- package/dist/tools/interaction/type.d.ts +1 -1
- package/dist/tools/interaction/type.js +4 -4
- package/dist/tools/interaction/type.js.map +1 -1
- package/dist/tools/navigation/back.js +2 -2
- package/dist/tools/navigation/back.js.map +1 -1
- package/dist/tools/navigation/forward.js +2 -2
- package/dist/tools/navigation/forward.js.map +1 -1
- package/dist/tools/navigation/navigate.js +2 -2
- package/dist/tools/navigation/navigate.js.map +1 -1
- package/dist/tools/navigation/refresh.js +2 -2
- package/dist/tools/navigation/refresh.js.map +1 -1
- package/dist/tools/navigation/wait-for.js +2 -2
- package/dist/tools/navigation/wait-for.js.map +1 -1
- package/dist/tools/network/console.js +2 -2
- package/dist/tools/network/console.js.map +1 -1
- package/dist/tools/network/dialog.js +2 -2
- package/dist/tools/network/dialog.js.map +1 -1
- package/dist/tools/network/network-clear.js +2 -2
- package/dist/tools/network/network-clear.js.map +1 -1
- package/dist/tools/network/network-entries.js +2 -2
- package/dist/tools/network/network-entries.js.map +1 -1
- package/dist/tools/network/network-export.d.ts +2 -2
- package/dist/tools/network/network-export.js +2 -2
- package/dist/tools/network/network-export.js.map +1 -1
- package/dist/tools/network/network-requests.js +2 -2
- package/dist/tools/network/network-requests.js.map +1 -1
- package/dist/tools/network/network-response.js +2 -2
- package/dist/tools/network/network-response.js.map +1 -1
- package/dist/tools/network/network-save.js +2 -2
- package/dist/tools/network/network-save.js.map +1 -1
- package/dist/tools/network/wait-nav.js +2 -2
- package/dist/tools/network/wait-nav.js.map +1 -1
- package/dist/tools/network/websocket-frames.js +2 -2
- package/dist/tools/network/websocket-frames.js.map +1 -1
- package/dist/tools/re/api-discover.d.ts +3 -3
- package/dist/tools/re/api-discover.d.ts.map +1 -1
- package/dist/tools/re/api-discover.js +32 -11
- package/dist/tools/re/api-discover.js.map +1 -1
- package/dist/tools/re/auth-analyze.d.ts +3 -3
- package/dist/tools/re/auth-analyze.d.ts.map +1 -1
- package/dist/tools/re/auth-analyze.js +43 -6
- package/dist/tools/re/auth-analyze.js.map +1 -1
- package/dist/tools/re/js-beautify.js +3 -3
- package/dist/tools/re/js-beautify.js.map +1 -1
- package/dist/tools/re/js-deobfuscate.js +3 -3
- package/dist/tools/re/js-deobfuscate.js.map +1 -1
- package/dist/tools/session/close.js +2 -2
- package/dist/tools/session/close.js.map +1 -1
- package/dist/tools/session/list.js +2 -2
- package/dist/tools/session/list.js.map +1 -1
- package/dist/tools/session/open.js +2 -2
- package/dist/tools/session/open.js.map +1 -1
- package/dist/tools/stealth/fingerprint.d.ts +13 -0
- package/dist/tools/stealth/fingerprint.d.ts.map +1 -1
- package/dist/tools/stealth/fingerprint.js +16 -3
- package/dist/tools/stealth/fingerprint.js.map +1 -1
- package/dist/tools/stealth/human-behavior.js +2 -2
- package/dist/tools/stealth/human-behavior.js.map +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# @natchs/browser-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@natchs/browser-mcp)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](package.json)
|
|
4
6
|
|
|
5
7
|
---
|
|
6
8
|
|
|
7
|
-
##
|
|
9
|
+
## 🇹🇷 Türkçe
|
|
10
|
+
|
|
11
|
+
**Browser automation MCP server** — reverse engineering, web scraping ve data extraction için tasarlanmış, AI ajanların tarayıcıyı tam kontrol etmesini sağlayan bir Model Context Protocol sunucusu.
|
|
12
|
+
|
|
13
|
+
### Quick Start
|
|
8
14
|
|
|
9
15
|
```bash
|
|
10
16
|
# 1. Install
|
|
@@ -14,7 +20,7 @@ npm install @natchs/browser-mcp
|
|
|
14
20
|
npx @natchs/browser-mcp
|
|
15
21
|
```
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
#### MCP Client Config
|
|
18
24
|
|
|
19
25
|
Claude Desktop, Cursor, VS Code veya herhangi bir MCP istemcisine eklemek için:
|
|
20
26
|
|
|
@@ -39,7 +45,7 @@ npm run build
|
|
|
39
45
|
npx @natchs/browser-mcp
|
|
40
46
|
```
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
#### Browser Profili: 3 Mod
|
|
43
49
|
|
|
44
50
|
Ajanın hangi tarayıcıyı kullanacağını `BROWSER_MODE` ortam değişkeni belirler:
|
|
45
51
|
|
|
@@ -96,9 +102,86 @@ BROWSER_MODE=connect npx @natchs/browser-mcp
|
|
|
96
102
|
|
|
97
103
|
---
|
|
98
104
|
|
|
99
|
-
|
|
105
|
+
### Ortam Değişkenleri
|
|
106
|
+
|
|
107
|
+
Tüm yapılandırma, ortam değişkenleri aracılığıyla yapılabilir. Aşağıdaki tablo, desteklenen tüm değişkenleri listeler.
|
|
108
|
+
|
|
109
|
+
#### Browser
|
|
110
|
+
|
|
111
|
+
| Variable | Default | Description | Required |
|
|
112
|
+
|----------|---------|-------------|----------|
|
|
113
|
+
| `BROWSER_MODE` | `fresh` | Browser modu: `fresh`, `persistent`, `connect` | No |
|
|
114
|
+
| `BROWSER_HEADLESS` | `true` | Headless modda çalıştır (`true`/`false`/`1`/`0`/`yes`/`no`) | No |
|
|
115
|
+
| `BROWSER_USER_DATA_DIR` | — | Chrome kullanıcı veri dizini (mutlak yol) | No |
|
|
116
|
+
| `BROWSER_CHANNEL` | `""` | Browser kanalı (`chrome`, `msedge`, `chromium`, vb.) | No |
|
|
117
|
+
| `BROWSER_DEBUG_PORT` | `9222` | CDP debug port numarası | No |
|
|
118
|
+
| `BROWSER_AUTO_DETECT_PROFILE` | `true` | Chrome profilini otomatik tespit et | No |
|
|
119
|
+
| `BROWSER_VIEWPORT_WIDTH` | `1280` | Görüntü alanı genişliği (px) | No |
|
|
120
|
+
| `BROWSER_VIEWPORT_HEIGHT` | `720` | Görüntü alanı yüksekliği (px) | No |
|
|
121
|
+
| `BROWSER_USER_AGENT` | — | Özel User-Agent string'i | No |
|
|
122
|
+
| `BROWSER_LOCALE` | — | Tarayıcı locale değeri (örn. `tr-TR`) | No |
|
|
123
|
+
| `BROWSER_TIMEOUT` | `30000` | Browser işlemleri için timeout (ms) | No |
|
|
124
|
+
| `BROWSER_AUTO_INSTALL` | `true` | Chromium'u otomatik kur (`false` ile devre dışı) | No |
|
|
125
|
+
|
|
126
|
+
#### Network & Download
|
|
127
|
+
|
|
128
|
+
| Variable | Default | Description | Required |
|
|
129
|
+
|----------|---------|-------------|----------|
|
|
130
|
+
| `NETWORK_HAR_ENABLED` | `1` | HAR yakalamayı etkinleştir (`0` ile devre dışı) | No |
|
|
131
|
+
| `NETWORK_MAX_ENTRIES` | `5000` | Maksimum network kaydı sayısı | No |
|
|
132
|
+
| `NETWORK_MAX_RESPONSE_BODY_SIZE` | `262144` | Maksimum response body boyutu (bytes) | No |
|
|
133
|
+
| `NETWORK_STORE_RESPONSE_BODIES` | `false` | Response body'leri hafızada tut | No |
|
|
134
|
+
| `NETWORK_EXCLUDE_BODY_TYPES` | `["image","media","font","stylesheet"]` | Body kaydı dışı bırakılacak tipler (JSON array) | No |
|
|
135
|
+
| `NETWORK_EXPORT_DIR` | `./network-logs` | Network log dışa aktarma dizini | No |
|
|
136
|
+
| `NETWORK_CAPTURE_FAILED` | `true` | Başarısız istekleri de yakala | No |
|
|
137
|
+
| `NETWORK_CAPTURE_WS` | `true` | WebSocket frame'lerini yakala | No |
|
|
138
|
+
| `NETWORK_WS_MAX_FRAMES` | `1000` | Maksimum WS frame sayısı | No |
|
|
139
|
+
| `NETWORK_WS_MAX_FRAME_SIZE` | `65536` | Maksimum WS frame payload boyutu | No |
|
|
140
|
+
| `NETWORK_MAX_MEMORY_MB` | `256` | Network capture için maksimum bellek (MB) | No |
|
|
141
|
+
| `NETWORK_CAPTURE_REQUEST_BODY` | `false` | Request body'lerini de yakala | No |
|
|
142
|
+
| `NETWORK_DOWNLOAD_DIR` | `./downloads` | İndirilen dosyalar için dizin | No |
|
|
143
|
+
| `NETWORK_MAX_DOWNLOAD_SIZE` | `104857600` | Maksimum indirme boyutu (bytes, varsayılan 100MB) | No |
|
|
144
|
+
| `NETWORK_DOWNLOAD_ENABLED` | `false` | Dosya indirme özelliğini etkinleştir | No |
|
|
145
|
+
| `NETWORK_SAVE_ENABLED` | `false` | Network capture kaydetme özelliğini etkinleştir (`network_save` tool'u) | No |
|
|
146
|
+
|
|
147
|
+
#### Rate Limiting
|
|
148
|
+
|
|
149
|
+
| Variable | Default | Description | Required |
|
|
150
|
+
|----------|---------|-------------|----------|
|
|
151
|
+
| `RATE_LIMIT_ENABLED` | `true` | Rate limiting'i etkinleştir | No |
|
|
152
|
+
| `RATE_LIMIT_GLOBAL_RPM` | `120` | Global dakikalık istek limiti | No |
|
|
153
|
+
| `RATE_LIMIT_PER_TOOL_RPM` | `30` | Tool başına dakikalık istek limiti | No |
|
|
154
|
+
| `RATE_LIMIT_BURST_SIZE` | `10` | Maksimum burst boyutu | No |
|
|
155
|
+
|
|
156
|
+
#### Cache
|
|
157
|
+
|
|
158
|
+
| Variable | Default | Description | Required |
|
|
159
|
+
|----------|---------|-------------|----------|
|
|
160
|
+
| `CACHE_MAX_ENTRIES` | `100` | Maksimum önbellek girişi sayısı | No |
|
|
161
|
+
| `CACHE_TTL_SECONDS` | `300` | Önbellek TTL değeri (saniye) | No |
|
|
162
|
+
|
|
163
|
+
#### Security
|
|
164
|
+
|
|
165
|
+
| Variable | Default | Description | Required |
|
|
166
|
+
|----------|---------|-------------|----------|
|
|
167
|
+
| `SECURITY_API_KEY` | `""` | API anahtarı (boş = auth kapalı) | No |
|
|
168
|
+
| `SECURITY_ALLOWED_DIRS` | `[]` | İzin verilen dizinler (JSON array) | No |
|
|
169
|
+
| `SECURITY_MAX_MEMORY_MB` | `512` | Maksimum bellek kullanımı (MB) | No |
|
|
170
|
+
| `SECURITY_DEFAULT_TIMEOUT` | `30000` | Varsayılan işlem timeout'u (ms) | No |
|
|
171
|
+
| `SECURITY_MAX_TIMEOUT` | `120000` | Maksimum timeout (ms) | No |
|
|
172
|
+
| `SECURITY_MAX_SESSIONS` | `10` | Maksimum eşzamanlı browser session sayısı | No |
|
|
173
|
+
|
|
174
|
+
#### Config
|
|
175
|
+
|
|
176
|
+
| Variable | Default | Description | Required |
|
|
177
|
+
|----------|---------|-------------|----------|
|
|
178
|
+
| `BROWSER_MCP_CONFIG` | — | Yapılandırma dosyası yolu (JSON) | No |
|
|
100
179
|
|
|
101
|
-
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### Detaylı Özellikler
|
|
183
|
+
|
|
184
|
+
#### Mevcut Yetenekler
|
|
102
185
|
|
|
103
186
|
| Kategori | Tool Sayısı | Neler Yapabilir? |
|
|
104
187
|
|----------|------------|-------------------|
|
|
@@ -114,7 +197,7 @@ BROWSER_MODE=connect npx @natchs/browser-mcp
|
|
|
114
197
|
|
|
115
198
|
**Toplam: 40+ tool, 9 kategori, production-grade mimari**
|
|
116
199
|
|
|
117
|
-
|
|
200
|
+
#### Ne Yapabilir?
|
|
118
201
|
|
|
119
202
|
- **Reverse Engineering**: JS deobfuscation, API auth analizi, network isteklerini HAR formatında export
|
|
120
203
|
- **Web Scraping**: Cloudflare koruması olmayan sitelerden HTML/Markdown/text çekme, tablo ve Schema.org yapılandırılmış veri extraction
|
|
@@ -126,7 +209,7 @@ BROWSER_MODE=connect npx @natchs/browser-mcp
|
|
|
126
209
|
- **Observability**: Structured JSON logging, tool metrikleri (call count, süre, hata), LRU cache + TTL
|
|
127
210
|
- **Rate Limiting**: Token bucket, global + per-tool, yapılandırılabilir RPM
|
|
128
211
|
|
|
129
|
-
|
|
212
|
+
#### Browser Profil Yönetimi (v2.3.0)
|
|
130
213
|
|
|
131
214
|
Ajan, 3 farklı browser modundan biriyle çalışır:
|
|
132
215
|
|
|
@@ -134,7 +217,7 @@ Ajan, 3 farklı browser modundan biriyle çalışır:
|
|
|
134
217
|
- **`persistent`:** Gerçek Chrome profilinizi kullanır. Oturum açtığınız tüm sitelere (Gmail, GitHub, ChatGPT, kurumsal VPN) ajan da "sizmiş gibi" erişir. v2.3.0 ile profil otomatik tespit edilir — `BROWSER_MODE=persistent` yazmanız yeterli.
|
|
135
218
|
- **`connect`:** Halihazırda `--remote-debugging-port` ile açılmış Chrome'unuza bağlanır. Mevcut sekmeleri ve oturumları ajanla paylaşırsınız.
|
|
136
219
|
|
|
137
|
-
|
|
220
|
+
#### Ne Yapamaz? (Mevcut Sınırlamalar)
|
|
138
221
|
|
|
139
222
|
- **Cloudflare/anti-bot korumalı siteler**: Challenge sayfalarını geçemez, manuel çözüm gerekir
|
|
140
223
|
- **Captcha çözümü**: Dahili captcha çözücü yoktur (üçüncü parti servislerle entegre edilebilir)
|
|
@@ -143,23 +226,23 @@ Ajan, 3 farklı browser modundan biriyle çalışır:
|
|
|
143
226
|
- **Canvas/WebGL fingerprinting**: Temel fingerprint değişir ama gelişmiş anti-bot sistemlerini geçemeyebilir
|
|
144
227
|
- **Mobil browser simülasyonu**: Sadece Chromium desktop, mobile viewport taklidi yapabilir
|
|
145
228
|
|
|
146
|
-
|
|
229
|
+
#### Güvenlik Özellikleri
|
|
147
230
|
|
|
148
231
|
- `redirect: 'manual'` tüm URL fetch çağrılarında — SSRF redirect bypass koruması
|
|
149
232
|
- `validateUrlAsync` DNS lookup — DNS rebind saldırılarına karşı
|
|
150
233
|
- `DANGEROUS_EXTENSIONS` blocklist (.exe, .bat, .sh vb) → güvenli `.bin` fallback
|
|
151
234
|
- Pseudo-FS path blocking (`/proc/`, `/sys/`, `/etc/` vb)
|
|
152
235
|
- Cookie header filtresi — Stage 3 HTTP re-fetch'te cross-origin credential sızıntısı önlenir
|
|
153
|
-
- `downloadEnabled` varsayılan **false** — kullanıcı açıkça enable etmeden
|
|
236
|
+
- `downloadEnabled` (download) ve `networkSaveEnabled` (network_save) varsayılan **false** — kullanıcı açıkça enable etmeden çalışmaz
|
|
154
237
|
- Input sanitizasyonu (null byte, path traversal, fileName injection)
|
|
155
238
|
|
|
156
|
-
|
|
239
|
+
#### MCP Client Uyumluluğu
|
|
157
240
|
|
|
158
241
|
Claude Desktop, Cursor, VS Code (Cline, Roo Code), Continue.dev, özel MCP istemcileri — protocol uyumlu tüm platformlar.
|
|
159
242
|
|
|
160
243
|
---
|
|
161
244
|
|
|
162
|
-
|
|
245
|
+
### Daha Fazlası Yolda
|
|
163
246
|
|
|
164
247
|
Bu proje aktif geliştirme aşamasındadır. Kısa süre içinde:
|
|
165
248
|
|
|
@@ -171,7 +254,204 @@ Bu proje aktif geliştirme aşamasındadır. Kısa süre içinde:
|
|
|
171
254
|
|
|
172
255
|
---
|
|
173
256
|
|
|
174
|
-
|
|
257
|
+
### Geliştirme
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
# Test
|
|
261
|
+
npm test
|
|
262
|
+
npm run test:coverage
|
|
263
|
+
|
|
264
|
+
# Type check (tsc --noEmit)
|
|
265
|
+
npm run lint
|
|
266
|
+
|
|
267
|
+
# Build
|
|
268
|
+
npm run build
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Lisans
|
|
272
|
+
|
|
273
|
+
MIT
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 🇬🇧 English
|
|
278
|
+
|
|
279
|
+
**Browser automation MCP server** — a Model Context Protocol server designed for reverse engineering, web scraping, and data extraction. It gives AI agents full control over a browser.
|
|
280
|
+
|
|
281
|
+
### Quick Start
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# 1. Install
|
|
285
|
+
npm install @natchs/browser-mcp
|
|
286
|
+
|
|
287
|
+
# 2. Run (Chromium installs automatically ~30s on first run)
|
|
288
|
+
npx @natchs/browser-mcp
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
#### MCP Client Config
|
|
292
|
+
|
|
293
|
+
Add to Claude Desktop, Cursor, VS Code, or any MCP client:
|
|
294
|
+
|
|
295
|
+
```json
|
|
296
|
+
{
|
|
297
|
+
"mcpServers": {
|
|
298
|
+
"browser-mcp": {
|
|
299
|
+
"command": "npx",
|
|
300
|
+
"args": ["@natchs/browser-mcp"]
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
You can also clone and build locally:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
git clone https://github.com/natchs/browser-mcp.git
|
|
310
|
+
cd browser-mcp
|
|
311
|
+
npm ci
|
|
312
|
+
npm run build
|
|
313
|
+
npx @natchs/browser-mcp
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
#### Browser Profile: 3 Modes
|
|
317
|
+
|
|
318
|
+
The `BROWSER_MODE` environment variable determines which browser the agent uses:
|
|
319
|
+
|
|
320
|
+
| Mode | Description | When to Use |
|
|
321
|
+
|------|-------------|-------------|
|
|
322
|
+
| `fresh` (default) | Playwright's own Chromium. Fresh profile every time, no cookies/extensions/logins | Clean environment, leave no trace |
|
|
323
|
+
| `persistent` | **Your Chrome profile.** Real cookies, history, extensions, logged-in accounts — all available to the agent | When the agent needs to act "as you" on sites |
|
|
324
|
+
| `connect` | Connects to your already-open Chrome via CDP | When manually controlling Chrome alongside the agent |
|
|
325
|
+
|
|
326
|
+
**Example — persistent (auto-detect profile):**
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
BROWSER_MODE=persistent npx @natchs/browser-mcp
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Since v2.3.0 the Chrome profile is auto-detected. No path needed. Works on Windows/macOS/Linux. To specify a manual path:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
BROWSER_MODE=persistent BROWSER_USER_DATA_DIR=C:\Users\...\User Data\Default npx @natchs/browser-mcp
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Example — connect (attach to existing Chrome):**
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
# First open Chrome with debug port:
|
|
342
|
+
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
|
|
343
|
+
|
|
344
|
+
# Then start the agent:
|
|
345
|
+
BROWSER_MODE=connect npx @natchs/browser-mcp
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**MCP Client Config — separate profiles per mode:**
|
|
349
|
+
|
|
350
|
+
```json
|
|
351
|
+
{
|
|
352
|
+
"mcpServers": {
|
|
353
|
+
"browser-mcp-persistent": {
|
|
354
|
+
"command": "npx",
|
|
355
|
+
"args": ["@natchs/browser-mcp"],
|
|
356
|
+
"env": {
|
|
357
|
+
"BROWSER_MODE": "persistent"
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
"browser-mcp-fresh": {
|
|
361
|
+
"command": "npx",
|
|
362
|
+
"args": ["@natchs/browser-mcp"],
|
|
363
|
+
"env": {
|
|
364
|
+
"BROWSER_MODE": "fresh"
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
### Environment Variables
|
|
374
|
+
|
|
375
|
+
All configuration can be done via environment variables. The table below lists all supported variables. (Same as the Turkish table above — see the Turkish section for the full list.)
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
### Detailed Features
|
|
380
|
+
|
|
381
|
+
#### Current Capabilities
|
|
382
|
+
|
|
383
|
+
| Category | Tools | Capabilities |
|
|
384
|
+
|----------|-------|--------------|
|
|
385
|
+
| **Navigation** | 5 | Open page, back/forward, refresh, wait for element/URL |
|
|
386
|
+
| **Interaction** | 8 | Click, fill form, select box, hover, drag-drop, keyboard, file upload |
|
|
387
|
+
| **Extraction** | 7 | HTML, Markdown, plain text, CSS selector, tables, Schema.org, Open Graph |
|
|
388
|
+
| **Network** | 10 | Request/response tracking, HAR/JSON/CSV export, WebSocket frame capture, body save, console log |
|
|
389
|
+
| **Browser Control** | 8 | Screenshot, PDF, cookie management, JavaScript execution, file download |
|
|
390
|
+
| **Session** | 3 | Multi-session open/close/list, automatic TTL cleanup |
|
|
391
|
+
| **Admin** | 3 | Server status, cache statistics, cache clear |
|
|
392
|
+
| **RE Tools** | 4 | JavaScript beautify/deobfuscate, API endpoint discovery, auth analysis |
|
|
393
|
+
| **Stealth** | 2 | Fingerprint rotation, human behavior simulation |
|
|
394
|
+
|
|
395
|
+
**Total: 40+ tools, 9 categories, production-grade architecture**
|
|
396
|
+
|
|
397
|
+
#### What It Can Do
|
|
398
|
+
|
|
399
|
+
- **Reverse Engineering**: JS deobfuscation, API auth analysis, network request export in HAR format
|
|
400
|
+
- **Web Scraping**: HTML/Markdown/text extraction from non-Cloudflare sites, table and Schema.org structured data extraction
|
|
401
|
+
- **Network Monitoring**: Real-time HTTP/HTTPS interception, WebSocket frame inspection, binary body save to disk
|
|
402
|
+
- **Form Automation**: Login forms, search, multi-step form filling, file upload
|
|
403
|
+
- **Session Management**: Each isolated, concurrent browser sessions with automatic TTL cleanup
|
|
404
|
+
- **Security**: SSRF protection (internal IP blocking, DNS rebind prevention, redirect bypass guard), path traversal prevention, MIME-based extension blocklist, cookie leak protection
|
|
405
|
+
- **Data Export**: Network captures as HAR/JSON/CSV, body save, WS frame save (.jsonl)
|
|
406
|
+
- **Observability**: Structured JSON logging, tool metrics (call count, duration, errors), LRU cache + TTL
|
|
407
|
+
- **Rate Limiting**: Token bucket, global + per-tool, configurable RPM
|
|
408
|
+
|
|
409
|
+
#### Browser Profile Management (v2.3.0)
|
|
410
|
+
|
|
411
|
+
The agent works in one of 3 browser modes:
|
|
412
|
+
|
|
413
|
+
- **`fresh` (default):** Uses Playwright's own Chromium, fresh profile every time. No cookies, history, or extensions are carried over.
|
|
414
|
+
- **`persistent`:** Uses your real Chrome profile. The agent accesses all your logged-in sites (Gmail, GitHub, ChatGPT, corporate VPN) as "you." Since v2.3.0, profiles are auto-detected — just set `BROWSER_MODE=persistent`.
|
|
415
|
+
- **`connect`:** Connects to your already-running Chrome via `--remote-debugging-port`. Share existing tabs and sessions with the agent.
|
|
416
|
+
|
|
417
|
+
#### Limitations
|
|
418
|
+
|
|
419
|
+
- **Cloudflare/anti-bot sites**: Cannot bypass challenge pages, manual solving required
|
|
420
|
+
- **Captcha solving**: No built-in captcha solver (third-party services can be integrated)
|
|
421
|
+
- **Visual recognition**: Can take screenshots but cannot interpret content
|
|
422
|
+
- **Native file download**: `browser_download` is URL-based, does not cover Playwright native download events
|
|
423
|
+
- **Canvas/WebGL fingerprinting**: Basic fingerprint changes but may not bypass advanced anti-bot systems
|
|
424
|
+
- **Mobile browser simulation**: Chromium desktop only, can emulate mobile viewport
|
|
425
|
+
|
|
426
|
+
#### Security Features
|
|
427
|
+
|
|
428
|
+
- `redirect: 'manual'` on all URL fetch calls — SSRF redirect bypass protection
|
|
429
|
+
- `validateUrlAsync` DNS lookup — DNS rebind attack prevention
|
|
430
|
+
- `DANGEROUS_EXTENSIONS` blocklist (.exe, .bat, .sh etc.) → safe `.bin` fallback
|
|
431
|
+
- Pseudo-FS path blocking (`/proc/`, `/sys/`, `/etc/` etc.)
|
|
432
|
+
- Cookie header filter — prevents cross-origin credential leakage in Stage 3 HTTP re-fetch
|
|
433
|
+
- `downloadEnabled` and `networkSaveEnabled` default to **false** — must be explicitly enabled
|
|
434
|
+
- Input sanitization (null byte, path traversal, fileName injection)
|
|
435
|
+
|
|
436
|
+
#### MCP Client Compatibility
|
|
437
|
+
|
|
438
|
+
Claude Desktop, Cursor, VS Code (Cline, Roo Code), Continue.dev, custom MCP clients — all protocol-compliant platforms.
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
### Roadmap
|
|
443
|
+
|
|
444
|
+
This project is under active development. Coming soon:
|
|
445
|
+
|
|
446
|
+
- **New tools**: PDF extraction, screenshot annotation, form detection, cookie manager, session snapshot/restore
|
|
447
|
+
- **Cloudflare bypass**: Playwright Stealth integration, rotatable proxy support
|
|
448
|
+
- **Batch scraping**: Multi-page scraping pipeline, queue system
|
|
449
|
+
- **Performance**: Ring buffer optimization, streaming response, lazy evaluation
|
|
450
|
+
- **Developer Experience**: Interactive CLI, playground UI, type-safe client SDK
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
### Development
|
|
175
455
|
|
|
176
456
|
```bash
|
|
177
457
|
# Test
|
|
@@ -185,6 +465,6 @@ npm run lint
|
|
|
185
465
|
npm run build
|
|
186
466
|
```
|
|
187
467
|
|
|
188
|
-
|
|
468
|
+
### License
|
|
189
469
|
|
|
190
470
|
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-logger.d.ts","sourceRoot":"","sources":["../../src/core/audit-logger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,mBAAmB,GAAG,aAAa,GAAG,YAAY,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAEhI,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAElF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-logger.js","sourceRoot":"","sources":["../../src/core/audit-logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,MAAM,UAAU,QAAQ,CAAC,KAAiB,EAAE,OAAgC;IAC1E,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/core/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAIhD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CA2ChE"}
|
package/dist/core/auth.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as crypto from 'node:crypto';
|
|
2
|
+
import { auditLog } from './audit-logger.js';
|
|
1
3
|
/**
|
|
2
4
|
* Creates an auth middleware that checks apiKey.
|
|
3
5
|
* If apiKey is not set, the middleware passes through (no auth).
|
|
@@ -5,7 +7,33 @@
|
|
|
5
7
|
export function createAuthMiddleware(apiKey) {
|
|
6
8
|
return async (pc, next) => {
|
|
7
9
|
if (apiKey) {
|
|
8
|
-
if (!pc.args.api_key
|
|
10
|
+
if (!pc.args.api_key) {
|
|
11
|
+
auditLog('AUTH_FAILURE', { reason: 'missing_key', tool: pc.toolName });
|
|
12
|
+
return {
|
|
13
|
+
...pc,
|
|
14
|
+
response: {
|
|
15
|
+
content: [{
|
|
16
|
+
type: 'text',
|
|
17
|
+
text: JSON.stringify({ ok: false, error: { code: 'UNAUTHORIZED', message: 'Invalid or missing API key' } }),
|
|
18
|
+
}],
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const providedKey = String(pc.args.api_key);
|
|
23
|
+
if (providedKey.length !== apiKey.length) {
|
|
24
|
+
auditLog('AUTH_FAILURE', { reason: 'length_mismatch', tool: pc.toolName });
|
|
25
|
+
return {
|
|
26
|
+
...pc,
|
|
27
|
+
response: {
|
|
28
|
+
content: [{
|
|
29
|
+
type: 'text',
|
|
30
|
+
text: JSON.stringify({ ok: false, error: { code: 'UNAUTHORIZED', message: 'Invalid or missing API key' } }),
|
|
31
|
+
}],
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (!crypto.timingSafeEqual(Buffer.from(providedKey), Buffer.from(apiKey))) {
|
|
36
|
+
auditLog('AUTH_FAILURE', { reason: 'key_mismatch', tool: pc.toolName });
|
|
9
37
|
return {
|
|
10
38
|
...pc,
|
|
11
39
|
response: {
|
package/dist/core/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAe;IAClD,OAAO,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;QACxB,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACrB,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACvE,OAAO;oBACL,GAAG,EAAE;oBACL,QAAQ,EAAE;wBACR,OAAO,EAAE,CAAC;gCACR,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,4BAA4B,EAAE,EAAE,CAAC;6BAC5G,CAAC;qBACH;iBACF,CAAC;YACJ,CAAC;YACD,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,WAAW,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;gBACzC,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC3E,OAAO;oBACL,GAAG,EAAE;oBACL,QAAQ,EAAE;wBACR,OAAO,EAAE,CAAC;gCACR,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,4BAA4B,EAAE,EAAE,CAAC;6BAC5G,CAAC;qBACH;iBACF,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBAC3E,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACxE,OAAO;oBACL,GAAG,EAAE;oBACL,QAAQ,EAAE;wBACR,OAAO,EAAE,CAAC;gCACR,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,4BAA4B,EAAE,EAAE,CAAC;6BAC5G,CAAC;qBACH;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body-fetch.d.ts","sourceRoot":"","sources":["../../src/core/body-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"body-fetch.d.ts","sourceRoot":"","sources":["../../src/core/body-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAMxC,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACjC,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,qBAAa,gBAAgB;IACf,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEnC,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,eAAe,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;CAgFrK"}
|
package/dist/core/body-fetch.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ErrorCode } from './errors.js';
|
|
2
|
-
import { validateUrl } from './sandbox.js';
|
|
2
|
+
import { validateUrl, isInternalIP } from './sandbox.js';
|
|
3
3
|
import { logger } from './logger.js';
|
|
4
|
+
import { auditLog } from './audit-logger.js';
|
|
5
|
+
import * as dns from 'node:dns';
|
|
4
6
|
export class BodyFetchService {
|
|
5
7
|
config;
|
|
6
8
|
constructor(config) {
|
|
@@ -38,12 +40,34 @@ export class BodyFetchService {
|
|
|
38
40
|
}
|
|
39
41
|
const urlCheck = validateUrl(entry.url);
|
|
40
42
|
if (!urlCheck.valid) {
|
|
43
|
+
auditLog('DNS_REBIND', { url: entry.url, reason: urlCheck.error });
|
|
41
44
|
return { error: 'SSRF blocked: ' + urlCheck.error, code: ErrorCode.NETWORK_RESPONSE_FAILED };
|
|
42
45
|
}
|
|
46
|
+
const parsedUrl = new URL(entry.url);
|
|
47
|
+
let fetchUrl = entry.url;
|
|
48
|
+
try {
|
|
49
|
+
const addresses = await dns.promises.lookup(parsedUrl.hostname, { all: true });
|
|
50
|
+
for (const addr of addresses) {
|
|
51
|
+
if (isInternalIP(addr.address)) {
|
|
52
|
+
auditLog('INTERNAL_IP', { url: entry.url, ip: addr.address });
|
|
53
|
+
return { error: `DNS rebind blocked: ${entry.url} resolves to internal IP ${addr.address}`, code: ErrorCode.INTERNAL_IP };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// TOCTOU DNS rebind fix: use resolved IP directly for HTTP
|
|
57
|
+
if (parsedUrl.protocol === 'http:' && addresses.length > 0) {
|
|
58
|
+
fetchUrl = `http://${addresses[0].address}${parsedUrl.pathname}${parsedUrl.search}`;
|
|
59
|
+
headers['Host'] = parsedUrl.hostname;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
64
|
+
auditLog('DNS_REBIND', { url: entry.url, reason: `DNS lookup failed for ${parsedUrl.hostname}: ${errMsg}` });
|
|
65
|
+
throw new Error(`DNS lookup failed for ${parsedUrl.hostname}: ${errMsg}`);
|
|
66
|
+
}
|
|
43
67
|
const controller = new AbortController();
|
|
44
68
|
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
45
69
|
try {
|
|
46
|
-
const response = await fetch(
|
|
70
|
+
const response = await fetch(fetchUrl, {
|
|
47
71
|
method: entry.method,
|
|
48
72
|
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
49
73
|
signal: controller.signal,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body-fetch.js","sourceRoot":"","sources":["../../src/core/body-fetch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"body-fetch.js","sourceRoot":"","sources":["../../src/core/body-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Browser, BrowserContext, Page } from 'playwright';
|
|
2
|
+
import { BrowserProvider } from './browser-provider.js';
|
|
3
|
+
export declare class BrowserLifecycle {
|
|
4
|
+
private provider;
|
|
5
|
+
private headless;
|
|
6
|
+
private browser;
|
|
7
|
+
private context;
|
|
8
|
+
private pages;
|
|
9
|
+
private nextPageId;
|
|
10
|
+
private _maxPages;
|
|
11
|
+
constructor(provider: BrowserProvider | undefined, headless: boolean, maxPages?: number);
|
|
12
|
+
set maxPages(value: number);
|
|
13
|
+
get maxPages(): number;
|
|
14
|
+
get hasProvider(): boolean;
|
|
15
|
+
ensureBrowser(): Promise<Browser>;
|
|
16
|
+
createContext(): Promise<BrowserContext>;
|
|
17
|
+
getOrCreateContext(): Promise<BrowserContext>;
|
|
18
|
+
createPage(): Promise<{
|
|
19
|
+
page: Page;
|
|
20
|
+
id: string;
|
|
21
|
+
}>;
|
|
22
|
+
getPage(id: string): Page | undefined;
|
|
23
|
+
closePage(id: string): Promise<void>;
|
|
24
|
+
shutdown(): Promise<void>;
|
|
25
|
+
isRunning(): boolean;
|
|
26
|
+
getCurrentContext(): BrowserContext | null;
|
|
27
|
+
getCurrentBrowser(): Browser | null;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=browser-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-lifecycle.d.ts","sourceRoot":"","sources":["../../src/core/browser-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIxD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,UAAU,CAAK;IAEvB,OAAO,CAAC,SAAS,CAAM;gBAEX,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,SAAK;IAMnF,IAAI,QAAQ,CAAC,KAAK,EAAE,MAAM,EAEzB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAEK,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAWjC,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC;IAQxC,kBAAkB,IAAI,OAAO,CAAC,cAAc,CAAC;IAM7C,UAAU,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAWvD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAI/B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB/B,SAAS,IAAI,OAAO;IAIpB,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C,iBAAiB,IAAI,OAAO,GAAG,IAAI;CAGpC"}
|