Arachne MCP
# Arachne MCP
**Arachne MCP** adalah web-intelligence server self-hosted untuk Hermes Agent dan klien MCP lain. Proyek ini merupakan penerus `web-crawler-mcp` versi ringan, dengan arsitektur hybrid HTTP + browser, parser dokumen, crawl budgets, search adapter, structured extraction, browser sessions, dan change detection.
> Target proyek ini bukan menjanjikan bahwa semua website pasti dapat diambil. CAPTCHA, login tanpa izin, paywall, anti-bot tingkat lanjut, dan pembatasan hukum tetap harus dihormati. Target yang realistis adalah menjadi crawler self-hosted yang lebih dapat dikendalikan dan lebih cocok untuk agent dibandingkan layanan generik.
## Fitur utama
- **Auto-escalation HTTP → Chromium**: mencoba request HTTP yang cepat, kemudian otomatis memakai Playwright bila HTML terlihat kosong atau bergantung pada JavaScript.
- **13 MCP tools**: scrape, crawl, batch, map, parse, search, structured extraction, browser interaction, diff, chunking, dan diagnostics.
- **Parser multi-format**: HTML, plain text, JSON, XML/RSS/Atom, PDF, DOCX, XLSX, CSV, dan TSV.
- **Main-content extraction**: Trafilatura sebagai extractor utama, lalu DOM/BeautifulSoup sebagai fallback untuk dokumentasi dan tabel.
- **Recursive sitemap discovery**: membaca sitemap index bertingkat dan menggabungkannya dengan shallow link discovery.
- **Strict crawl budgets**: `max_pages`, `max_requests`, `max_errors`, `max_depth`, `max_total_chars`, dan `max_response_bytes` berdiri sendiri.
- **Per-host rate limiter**: jeda diterapkan sebelum request berikutnya, termasuk crawl delay dari `robots.txt`.
- **Retry yang terkontrol**: exponential backoff serta dukungan `Retry-After` untuk 429 dan error sementara.
- **Persistent SQLite cache**: mengurangi request dan token untuk halaman yang sama.
- **Change detection**: menyimpan snapshot dan mengembalikan unified diff.
- **Persistent browser session**: menyimpan cookie/storage state dengan `session_id` untuk alur login yang memang diotorisasi.
- **Search adapter**: SearXNG self-hosted atau Brave Search.
- **Structured JSON extraction**: memakai endpoint LLM OpenAI-compatible, termasuk 9Router/OpenRouter/OpenAI.
- **Agent safety**: hasil web ditandai sebagai untrusted content dan dipindai untuk pola prompt injection umum.
- **SSRF baseline protection**: memblokir localhost, IP privat, link-local, reserved, dan memvalidasi setiap redirect.
- **Proxy support**: satu proxy HTTP/HTTPS dapat dikonfigurasi untuk HTTP dan browser engine.
- **Content deduplication**: halaman duplikat dikenali melalui SHA-256 agar output crawl tidak boros konteks.
## Tool MCP
| Tool | Fungsi |
|---|---|
| `health` | Memeriksa engine, parser, search, proxy, dan security policy |
| `crawl_url` | Mengambil satu URL dengan mode `auto`, `http`, atau `browser` |
| `parse_url` | Memproses PDF, DOCX, XLSX, JSON, XML, CSV, dan dokumen lain |
| `crawl_site` | Menjelajahi website dengan BFS dan crawl budgets keras |
| `batch_scrape` | Mengambil sampai 500 URL dengan concurrency dan shared output budget |
| `map_site` | Menemukan URL melalui sitemap recursive dan shallow crawl |
| `extract_links` | Mengambil link yang sudah dinormalisasi |
| `check_robots` | Memeriksa izin, crawl delay, request rate, dan sitemap |
| `browser_interact` | Click, fill, press, select, wait, scroll, goto, dan screenshot |
| `search_web` | Search melalui SearXNG atau Brave, opsional scrape hasil |
| `extract_structured` | Menghasilkan JSON sesuai JSON Schema melalui LLM compatible |
| `crawl_diff` | Membandingkan halaman dengan snapshot sebelumnya |
| `chunk_content` | Memecah teks menjadi chunk overlap yang stabil untuk RAG |
## Instalasi lokal
Persyaratan:
- Python 3.11+
- macOS, Linux, atau Windows
- Chromium Playwright untuk mode browser
```bash
unzip arachne-mcp.zip
cd arachne-mcp
cp .env.example .env
python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[full]'
playwright install chromium
arachne-mcp
```
Default transport adalah STDIO. Untuk Streamable HTTP:
```bash
MCP_TRANSPORT=streamable-http MCP_HOST=0.0.0.0 MCP_PORT=8000 arachne-mcp
```
Endpoint-nya:
```text
http://127.0.0.1:8000/mcp
```
## Menjalankan dengan Docker
Buat external network bersama Hermes sekali saja:
```bash
docker network create hermes-net
```
Kemudian:
```bash
cp .env.example .env
docker compose up -d --build
```
Pemeriksaan:
```bash
docker compose ps
docker logs arachne-mcp --tail 100
```
Port hanya dipublikasikan ke `127.0.0.1`. Container Hermes berkomunikasi melalui network internal menggunakan:
```text
http://arachne-mcp:8000/mcp
```
## Hubungkan ke Hermes Agent
Tambahkan pada `config.yaml` Hermes:
```yaml
mcp_servers:
arachne:
url: "http://arachne-mcp:8000/mcp"
enabled: true
connect_timeout: 30
timeout: 300
supports_parallel_tool_calls: false
tools:
include:
- health
- crawl_url
- parse_url
- crawl_site
- batch_scrape
- map_site
- extract_links
- check_robots
- browser_interact
- search_web
- extract_structured
- crawl_diff
- chunk_content
resources: false
prompts: false
```
Restart Hermes:
```bash
cd /srv/hermes
docker compose up -d
docker logs hermes_container --tail 100
```
Contoh prompt Telegram:
```text
Gunakan Arachne untuk crawl dokumentasi https://example.com/docs.
Gunakan maksimum 20 halaman, 50 request, kedalaman 3, dan total output 80.000 karakter.
Rangkum hasilnya dan sertakan halaman sumber untuk setiap bagian.
```
Untuk halaman JavaScript:
```text
Gunakan crawl_url Arachne dengan render_mode browser untuk membuka URL ini.
Tunggu 2 detik, ambil Markdown dan daftar link internalnya.
```
## Browser actions
Contoh input `browser_interact`:
```json
{
"url": "https://example.com/products",
"actions": [
{"type": "fill", "selector": "input[name=q]", "value": "keyboard"},
{"type": "press", "selector": "input[name=q]", "key": "Enter"},
{"type": "wait", "selector": ".results", "state": "visible"},
{"type": "scroll", "pixels": 1200}
],
"screenshot": false
}
```
Action yang tersedia:
- `click`: membutuhkan `selector`
- `fill`: `selector`, `value`
- `press`: opsional `selector`, serta `key`
- `select`: `selector`, `value`
- `wait`: `selector` atau `ms`
- `scroll`: `pixels`
- `goto`: `url`
- `evaluate`: `script`, tetapi default **dinonaktifkan**
Arachne tidak menyediakan action untuk melewati CAPTCHA atau access control.
## Persistent browser session
Gunakan `session_id` dan `persist_session=true`:
```json
{
"url": "https://portal.example.com/login",
"session_id": "portal-example",
"persist_session": true,
"actions": [
{"type": "fill", "selector": "#email", "value": "user@example.com"},
{"type": "fill", "selector": "#password", "value": "..."},
{"type": "click", "selector": "button[type=submit]"},
{"type": "wait", "selector": ".dashboard"}
]
}
```
Storage state disimpan di `data/browser-sessions`. Lindungi folder tersebut karena dapat mengandung cookie autentikasi. Jangan mengirim password melalui prompt pada channel yang tidak privat; lebih aman menyediakan session state secara manual.
## Search self-hosted
### SearXNG
Atur:
```dotenv
SEARXNG_URL=http://searxng:8080
```
Arachne memakai output JSON SearXNG, lalu dapat melakukan scrape terhadap hasil yang dipilih.
### Brave Search
```dotenv
BRAVE_SEARCH_API_KEY=your-key
```
SearXNG lebih cocok bila prioritasnya adalah kontrol dan self-hosting penuh.
## Structured extraction melalui 9Router
Contoh `.env`:
```dotenv
LLM_BASE_URL=http://9router:20128/v1
LLM_API_KEY=your-9router-key
LLM_MODEL=kr/qwen3-coder-next
```
Contoh tool input:
```json
{
"url": "https://example.com/product/1",
"instruction": "Ambil informasi produk yang terlihat pada halaman.",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"price": {"type": ["number", "null"]},
"currency": {"type": ["string", "null"]}
},
"required": ["name", "price", "currency"],
"additionalProperties": false
}
}
```
Model harus mendukung endpoint `/chat/completions`. Jika model tidak mendukung `json_schema`, Arachne otomatis mencoba ulang tanpa `response_format`, lalu memvalidasi JSON yang dihasilkan.
## Crawl budgets yang disarankan untuk Hermes
Penggunaan interaktif ringan:
```yaml
max_pages: 10
max_requests: 25
max_errors: 8
max_depth: 2
max_chars_per_page: 5000
max_total_chars: 40000
concurrency: 3
```
Dokumentasi menengah:
```yaml
max_pages: 50
max_requests: 120
max_errors: 20
max_depth: 4
max_chars_per_page: 8000
max_total_chars: 200000
concurrency: 6
```
Jangan menaikkan semua batas sekaligus. Output MCP yang terlalu besar dapat mengurangi kemampuan reasoning model walaupun crawler berhasil.
## Konfigurasi penting
| Environment variable | Default | Keterangan |
|---|---:|---|
| `ARACHNE_RESPECT_ROBOTS` | `true` | Mematuhi robots.txt |
| `ARACHNE_ALLOW_IGNORE_ROBOTS` | `false` | Mengizinkan caller memilih `respect_robots=false` |
| `ARACHNE_BLOCK_PRIVATE_NETWORKS` | `true` | Proteksi SSRF |
| `ARACHNE_MAX_REQUESTS` | `200` | Batas maksimum request per crawl |
| `ARACHNE_MAX_TOTAL_CHARS` | `250000` | Batas output agregat |
| `ARACHNE_BROWSER_CONCURRENCY` | `2` | Jumlah context Chromium bersamaan |
| `ARACHNE_CACHE_TTL_SECONDS` | `3600` | TTL cache |
| `ARACHNE_PROXY_URL` | kosong | Proxy HTTP/HTTPS opsional |
| `ARACHNE_ALLOW_BROWSER_EVAL` | `false` | Mengizinkan arbitrary browser JS |
Lihat seluruh opsi di `.env.example`.
## Perbandingan sasaran dengan Firecrawl
Arachne sengaja dioptimalkan untuk **self-hosted agent stack**:
| Area | Arachne | Firecrawl hosted |
|---|---|---|
| Source code dan modifikasi | Sepenuhnya lokal dan modular | Open source core + hosted infrastructure |
| Biaya per halaman | Infrastruktur sendiri | Credit-based |
| HTTP → browser escalation | Dapat diatur dan diperiksa | Otomatis |
| Parser dokumen | Lokal | Tersedia melalui API |
| Persistent crawl cache | SQLite lokal | Dikelola layanan |
| Change diff | Built-in unified diff | Monitoring tersedia pada layanan |
| Prompt-injection wrapping | Built-in untuk respons MCP | Bergantung workflow agent |
| Crawl output budget | Hard character budget untuk konteks LLM | Page/concurrency controls |
| Search | SearXNG/Brave adapter | Hosted search index |
| Anti-bot/proxy reliability | Bergantung proxy/infrastruktur Anda | Infrastruktur proprietary lebih matang |
Arachne dapat unggul dalam privasi, kontrol, extensibility, biaya marginal, dan integrasi Hermes. Firecrawl hosted kemungkinan tetap unggul untuk coverage internet luas, managed proxy rotation, anti-bot, SLA, dan skala besar tanpa operasi sendiri.
## Benchmark terhadap Firecrawl
Masukkan URL ke file, satu URL per baris:
```bash
cat > urls.txt <<'EOF'
https://example.com
https://docs.python.org/3/
EOF
```
Jalankan benchmark Arachne:
```bash
PYTHONPATH=src python scripts/benchmark.py --urls urls.txt --output benchmark.json
```
Bandingkan dengan Firecrawl bila memiliki API key:
```bash
export FIRECRAWL_API_KEY=fc-...
PYTHONPATH=src python scripts/benchmark.py \
--urls urls.txt \
--compare-firecrawl \
--output benchmark.json
```
Metric yang dicatat:
- keberhasilan per URL
- latency
- panjang konten
- engine HTTP/browser
- status code
- error
Tambahkan dataset website Anda sendiri: docs statis, SPA, blog, PDF, tabel, e-commerce, dan halaman yang sering gagal. Klaim lebih unggul hanya masuk akal setelah hasil pada dataset Anda menunjukkan demikian.
## Testing
```bash
pytest -q
```
Pengujian yang disertakan mencakup:
- canonical URL normalization
- private-network blocking
- HTML metadata dan link extraction
- prompt-injection detection/wrapping
- content chunking
- hard request budget
- SQLite cache dan snapshots
- local HTTP crawling dan recursive sitemap
## Keterbatasan yang disengaja
Arachne tidak secara otomatis:
- melewati CAPTCHA
- membobol login atau paywall
- mengakali access control
- memakai akun tanpa izin
- menjamin halaman yang memblokir data center IP dapat diambil
- mengabaikan `robots.txt` kecuali administrator mengaktifkannya
- menjamin DNS-rebinding protection sempurna pada semua network stack
Untuk reliability setara layanan hosted pada web yang sangat protektif, Anda tetap memerlukan proxy pool berkualitas, observability, distributed queue, autoscaling browser workers, dan maintenance selector/anti-bot secara berkelanjutan.
## Struktur proyek
```text
src/arachne_mcp/
├── cache.py # SQLite cache dan snapshots
├── config.py # Environment settings
├── crawler.py # Orchestration, crawl, map, search, diff
├── errors.py
├── extractors.py # HTML dan document extraction
├── fetchers.py # HTTPX, robots, Playwright, actions
├── models.py
├── rate_limit.py
├── security.py # URL/IP guard
├── server.py # MCP tools
└── url_utils.py
```
Dokumen tambahan:
- `docs/ARCHITECTURE.md`
- `docs/SECURITY.md`
- `docs/HERMES.md`
## Lisensi
MIT.
TDQS
Scored across 13 tools
Each tool serves a distinct purpose in the web scraping pipeline, from health checks to link extraction, crawling, parsing, site mapping, robots inspection, browser interaction, batch scraping, search, structured extraction, diffing, and chunking. No two tools have overlapping functionality.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., extract_links, crawl_url, parse_url). The only exception is 'health', which is a noun but serves as a status probe and fits the convention of a single-word command.
13 tools is appropriate for a comprehensive web scraping and content extraction server. Each tool covers a necessary operation without redundancy, balancing breadth and focus.
The tool surface covers the full lifecycle of web data acquisition: discovery (map_site, search_web), fetching (crawl_url, crawl_site, batch_scrape), parsing (parse_url, extract_links), interaction (browser_interact), compliance (check_robots), processing (chunk_content, extract_structured), and monitoring (health, crawl_diff). No obvious gaps.