Skip to main content
Glama

escalator

Gib ihm eine URL, erhalte sauberes Markdown. Es klettert die günstigste Sprosse, die funktioniert – ein einfacher HTTP-Abruf, derselbe Abruf über einen Residential-Proxy, dann ein Stealth-Browser – und stoppt bei der ersten, die mit echtem Inhalt zurückkommt.

$ escalator scrape https://en.wikipedia.org/wiki/Web_scraping | head -3
# Web scraping

**Web scraping**, **web harvesting**, or **web data extraction** is [data scraping](...)

Quickstart

# 1. install uv (https://docs.astral.sh/uv/getting-started/installation/)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2. configure this machine -- finds your browser, or fetches one
uvx escalator init

# 3. use it
uvx escalator scrape https://en.wikipedia.org/wiki/Web_scraping

Das ist die gesamte Einstiegshilfe. init schreibt eine Konfigurationsdatei, und vor dem ersten Lauf muss nichts von Hand bearbeitet werden. Wenn etwas falsch aussieht: escalator doctor.

Auf einem minimalen Linux (einem nackten Container, einem frischen VPS) benötigt Chrome Systembibliotheken, die ein Desktop bereits hat. escalator installiert sie nicht für dich – es gibt die genaue apt-get-Zeile aus, und escalator doctor wiederholt sie. Ein Befehl, einmal:

sudo apt-get update && sudo apt-get install -y \
  libnss3 libnspr4 libatk1.0-0t64 libatk-bridge2.0-0t64 libcups2t64 libdrm2 \
  libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 \
  libgbm1 libglib2.0-0t64 libpango-1.0-0 libcairo2 libasound2t64 \
  libatspi2.0-0t64 libxcb1 libdbus-1-3 libexpat1

Keine Batterien, by design. escalator wird unkonfiguriert ausgeliefert – kein gebündelter Browser, keine gebündelten Proxys, keine Telemetrie, nichts wird außerhalb seiner eigenen Verzeichnisse geschrieben. init existiert, damit die Konfiguration ein Zwei-Minuten-Gespräch ist und keine README-Schnitzeljagd.

Related MCP server: Safer Fetch MCP Server

Installation

how

command

when

uv (no install)

uvx escalator init

zum Ausprobieren

uv (persistent)

uv tool install escalator

wenn du es im PATH haben möchtest

pipx

pipx install escalator

wenn du bereits pipx verwendest

pip

pip install escalator

innerhalb einer bestehenden venv

Docker

docker run --rm ghcr.io/ruslanstarikov/escalator doctor

Server

Alles, was für den Kernablauf benötigt wird, ist in der Standardinstallation enthalten, einschließlich der Browser-Sprosse – sie bringt keinen Browser mit, wofür escalator browser install gedacht ist. Ein Extra existiert: escalator[mcp] fügt die MCP-Oberfläche hinzu, und das Docker-Image enthält sie.

Docker

docker run --rm \
  -e ESCALATOR_SERVER_API_KEYS=your-key \
  -p 8000:8000 -v ./data:/data \
  ghcr.io/ruslanstarikov/escalator serve

Das Image enthält einen festgelegten Browser und wird vollständig über Umgebungsvariablen konfiguriert – siehe docker-compose.example.yml für die Proxy-Verdrahtung. Es läuft als UID 1000, daher muss ein bind-gemountetes ./data für es beschreibbar sein.

Commands

escalator init [--yes]     configure this machine; --yes for scripts
escalator doctor [--json]  check everything, one fix per failure
escalator browser list     every browser found, and which one wins
escalator browser install  download Chrome for Testing into the data dir
escalator scrape URL       one page to stdout, so it pipes
escalator serve            the HTTP API and the MCP face
escalator --version        tool, python, platform

The ladder

policy      robots.txt (cached) + rate limit  → may short-circuit (skip/deny/wait)
http        curl_cffi, impersonate=chrome     → ~100ms; clears undefended sites
http_proxy  same, routed via residential IP   → beats datacenter-IP bans
browser     nodriver, headless Chrome         → JS/SPA + Cloudflare-class defenses
                    │
                    └─ walled on the last rung? → status="challenged". Surrender.

Zwei Dinge machen das mehr als eine for-Schleife:

200 OK ist kein Erfolg. Eine Sprosse, die HTTP 200 mit einer Cloudflare-Zwischenseite zurückgibt, ist nicht erfolgreich. core/detect.py klassifiziert jede Antwort nach der Extraktion – content, thin oder blocked – und nur content zählt. Ohne das würde die Leiter nie eskalieren, und der Cache würde für eine Domain, die für immer Müll ausliefert, lernen, dass „http funktioniert“.

Der Cache vergisst. Eine gelernte Startsprosse, die nur nach oben klettert, würde jede Domain in Richtung Browser+Proxy treiben und deine Proxy-Rechnung leise aufblähen. Einträge tragen learned_at; nach ladder.tier_cache_ttl_hours versucht eine Domain eine Sprosse günstiger erneut.

Siehe DESIGN.md für den Grund, warum es so geformt ist – und für das, was es bewusst ablehnt zu tun.

Configuration

Eine Datei, geschrieben von init, im Plattform-Konfigurationsverzeichnis (~/.config/escalator/config.toml unter Linux, ~/Library/Application Support/escalator/config.toml unter macOS). Überschreibe den Speicherort mit --config.

Priorität, überall:

CLI flag  >  environment  >  config.toml  >  default

Jeder Schlüssel hat eine Umgebungsvariable, so wird das Docker-Image konfiguriert, ohne dass überhaupt eine Datei existiert:

config key

env var

default

what it does

browser.path

ESCALATOR_BROWSER_PATH

Absoluter Pfad zu einer Chrome/Chromium-Binärdatei. Leer = eine finden.

browser.headless

ESCALATOR_BROWSER_HEADLESS

true

false benötigt ein Display (oder Xvfb) und ist schwerer zu erkennen.

browser.via_proxy

ESCALATOR_BROWSER_VIA_PROXY

true

Leitet Renderings auch durch den Proxy. Kostet Bandbreite.

browser.max_concurrent

ESCALATOR_BROWSER_MAX_CONCURRENT

4

Chrome ist die RAM-Obergrenze auf einem kleinen Rechner.

browser.timeout_ms

ESCALATOR_BROWSER_TIMEOUT_MS

30000

Zeitlimit pro Abruf für die Browser-Sprosse.

proxy.enabled

ESCALATOR_PROXY_ENABLED

false

Der Schalter. Alles darunter wird ignoriert, solange dies false ist.

proxy.url

ESCALATOR_PROXY_URL

http://user:pass@host:port oder socks5://...

proxy.list

ESCALATOR_PROXY_LIST

Mehrere Ausgänge, im Round-Robin-Verfahren verwendet. Kombiniert mit url.

http.timeout_ms

ESCALATOR_HTTP_TIMEOUT_MS

10000

Zeitlimit pro Abruf für die beiden HTTP-Sprossen.

ladder.min_content_chars

ESCALATOR_LADDER_MIN_CONTENT_CHARS

200

Unter dieser Anzahl extrahierter Zeichen ist eine Seite 'dünn' und die Leiter klettert.

ladder.tier_cache_ttl_hours

ESCALATOR_LADDER_TIER_CACHE_TTL_HOURS

72

Wie lange eine gelernte Sprosse überlebt, bevor sie eine Stufe günstiger verfällt.

politeness.respect_robots

ESCALATOR_POLITENESS_RESPECT_ROBOTS

true

Dein Rechner, deine Entscheidung.

politeness.rate_limit_rps

ESCALATOR_POLITENESS_RATE_LIMIT_RPS

1.0

Pro Domain. 0 deaktiviert die Lücke vollständig.

politeness.user_agent

ESCALATOR_POLITENESS_USER_AGENT

a Chrome UA

Wird für das Abgleichen von robots.txt verwendet.

server.api_keys

ESCALATOR_SERVER_API_KEYS

Bearer-Schlüssel für escalator serve. Diese Liste IST die Wahrheit: Das Entfernen eines Schlüssels widerruft ihn.

server.host

ESCALATOR_SERVER_HOST

127.0.0.1

127.0.0.1 hält es vom lokalen Netzwerk fern. Container wollen 0.0.0.0.

server.port

ESCALATOR_SERVER_PORT

8000

Port für escalator serve.

storage.data_dir

ESCALATOR_STORAGE_DATA_DIR

Datenbank und verwaltete Browser. Leer = die Plattform-Standardeinstellung unten.

storage.request_log_limit

ESCALATOR_STORAGE_REQUEST_LOG_LIMIT

5000

Zeilen, die in request_log aufbewahrt werden; beim Einfügen gekürzt.

Daten – die SQLite-Datenbank und jeder heruntergeladene Browser – leben im Plattform-Datenverzeichnis, überschreibbar mit ESCALATOR_STORAGE_DATA_DIR. Außerhalb davon wird nie etwas geschrieben.

Where the browser comes from

escalator browser list zeigt die Suche in dieser Reihenfolge:

  1. ein expliziter Pfad – --browser-path, dann ESCALATOR_BROWSER_PATH, dann browser.path. Wenn er gesetzt und falsch ist, ist das ein Fehler, der den Pfad nennt, niemals ein stilles Durchfallen.

  2. auf diesem Rechner installierte Browser: zuerst echtes Google Chrome, dann Chromium, dann Edge und Brave.

  3. ein Browser, den escalator browser install früher heruntergeladen hat.

Wenn keiner davon etwas findet, erhältst du einen Fehler, der die beiden Befehle nennt, die das beheben. Die Auflösung lädt nie von selbst herunter – eine Serveranfrage oder ein Cron-Job sollte keine Software als Nebeneffekt installieren.

Using the server

escalator serve   # 127.0.0.1:8000 by default
POST /scrape   {url, markdown?, min_tier?, max_tier?, timeout_ms?}  -> FetchResult
GET  /healthz                                                       -> {status, version}

Authentifiziere dich mit Authorization: Bearer <key>, wobei der Schlüssel einer aus server.api_keys ist. Diese Liste ist die Wahrheit: Entferne einen Schlüssel, und er wird beim nächsten Start widerrufen. Es gibt keinen Endpunkt, um einen zu erstellen.

Eine Wand kommt als 200 OK mit {"status": "challenged"} zurück, nicht als HTTP-Fehler. Das ist beabsichtigt: Ein Agent am anderen Ende kann darauf reagieren. Wiederholen in einer Schleife hilft nicht – escalator löst keine CAPTCHAs, by design.

Mit dem [mcp]-Extra wird dieselbe Leiter unter /mcp als ein Werkzeug bereitgestellt, scrape_url(url, force_browser=False).

Troubleshooting

Beginne hier:

escalator doctor

Es prüft Python, die Konfigurationsdatei, das Datenverzeichnis, die Browser-Auflösung, einen tatsächlichen Headless-Start und – wenn ein Proxy konfiguriert ist – eine echte Anfrage durch ihn, wobei die Egress-IP und das Land mit maskiertem Passwort gemeldet werden. Jedes ❌ wird mit der einen Zeile geliefert, die es behebt, und der Exit-Code ist ungleich Null, wenn etwas fehlgeschlagen ist, sodass Skripte es ebenfalls verwenden können. escalator doctor --json für Maschinen.

symptom

what it usually is

no Chrome-family browser found

escalator browser install

error while loading shared libraries on Linux

doctor nennt das zu installierende Paket

everything returns challenged

du brauchst einen Residential-Proxy: escalator init

/scrape returns 401

kein Schlüssel konfiguriert, oder er wurde aus server.api_keys entfernt

slow first browser fetch

Chrome-Kaltstart; escalator versucht den Start einmal erneut

Wenn es immer noch nicht funktioniert, füge die gesamte escalator doctor-Ausgabe in ein Issue ein – genau das verlangt die letzte Zeile davon, und es ist der schnellste Weg zu einer Antwort.

Development

Siehe CONTRIBUTING.md. Kurz: uv sync, uv run pytest.

License

In die Public Domain entlassen – siehe UNLICENSE. Keine Garantie, keine Namensnennung erforderlich, mach damit, was du willst.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Scrapes webpages and converts them to markdown using AI-powered interaction to automatically handle cookie banners, CAPTCHAs, paywalls, and other blocking elements before extracting clean content.
    15
    48
    Apache 2.0
  • A
    license
    B
    quality
    D
    maintenance
    Enables fetching and converting web content to markdown with built-in prompt injection safeguards that detect and block malicious content attempting to manipulate the LLM.
    1
    2
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables LLM agents to read any website by scraping and crawling into clean Markdown, automatically bypassing bot detection with residential proxies.
    3
    42
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Fetches and renders web pages using a headless Chromium browser, returning clean Markdown or HTML content even for JavaScript-heavy single-page applications.
    207
    MIT

View all related MCP servers

Related MCP Connectors

  • Web scraping for AI agents. Converts URLs to clean, LLM-ready Markdown with anti-bot bypass.

  • Fetch any URL and get clean Markdown. Web scraping for AI agents.

  • Read any web page as clean Markdown for AI agents: fetch, search, metadata, links. SSRF-safe.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ruslanstarikov/escalator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server