Skip to main content
Glama

escalator

Dale una URL, obtén Markdown limpio. Sube por el peldaño más barato que funcione — una petición HTTP simple, la misma petición a través de un proxy residencial, y luego un navegador sigiloso — y se detiene en el primero que devuelva contenido real.

$ 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

Eso es toda la rampa de entrada. init escribe un archivo de configuración, y no hay que editar nada a mano antes de la primera ejecución. Si algo parece mal: escalator doctor.

En un Linux mínimo (un contenedor desnudo, un VPS nuevo) Chrome necesita bibliotecas del sistema que un escritorio ya tiene. escalator no las instala por ti — imprime la línea exacta de apt-get y escalator doctor la repite. Un comando, una vez:

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

Sin baterías, por diseño. escalator viene sin configurar — sin navegador incluido, sin proxies incluidos, sin telemetría, nada escrito fuera de sus propios directorios. init existe para que configurarlo sea una conversación de dos minutos en lugar de una búsqueda del tesoro en el README.

Related MCP server: Safer Fetch MCP Server

Installation

how

command

when

uv (sin instalar)

uvx escalator init

probándolo

uv (persistente)

uv tool install escalator

lo quieres en el PATH

pipx

pipx install escalator

ya usas pipx

pip

pip install escalator

dentro de un venv existente

Docker

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

servidores

Todo lo necesario para el flujo principal está en la instalación predeterminada, incluido el peldaño del navegador — no trae ningún navegador consigo, para eso está escalator browser install. Existe un extra: escalator[mcp] añade la cara MCP, y la imagen Docker lo incluye.

Docker

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

La imagen lleva un navegador fijado y se configura enteramente mediante variables de entorno — consulta docker-compose.example.yml para el cableado del proxy. Se ejecuta como uid 1000, por lo que un ./data montado por bind debe ser escribible por él.

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.

Dos cosas hacen que esto sea más que un bucle for:

200 OK no es éxito. Un peldaño que devuelve HTTP 200 con un intersticial de Cloudflare no ha tenido éxito. core/detect.py clasifica cada respuesta después de la extracción — content, thin o blocked — y solo content cuenta. Sin eso, la escalera nunca escalaría, y la caché aprendería "http funciona" para un dominio que sirve basura para siempre.

La caché olvida. Un peldaño inicial aprendido que solo subiera de nivel haría que cada dominio derivara hacia navegador+proxy e inflaría silenciosamente tu factura de proxy. Las entradas llevan learned_at; pasado ladder.tier_cache_ttl_hours, un dominio reintenta un peldaño más barato.

Consulta DESIGN.md para saber por qué tiene esta forma — y para lo que deliberadamente se niega a hacer.

Configuration

Un archivo, escrito por init, en el directorio de configuración de la plataforma (~/.config/escalator/config.toml en Linux, ~/Library/Application Support/escalator/config.toml en macOS). Sobrescribe la ubicación con --config.

Precedencia, en todas partes:

CLI flag  >  environment  >  config.toml  >  default

Cada clave tiene una variable de entorno, que es como se configura la imagen Docker sin que exista ningún archivo:

clave de configuración

variable de entorno

predeterminado

qué hace

browser.path

ESCALATOR_BROWSER_PATH

Ruta absoluta a un binario de Chrome/Chromium. Vacío = encontrar uno.

browser.headless

ESCALATOR_BROWSER_HEADLESS

true

false necesita una pantalla (o Xvfb), y es más difícil de detectar.

browser.via_proxy

ESCALATOR_BROWSER_VIA_PROXY

true

Enruta los renders también a través del proxy. Cuesta ancho de banda.

browser.max_concurrent

ESCALATOR_BROWSER_MAX_CONCURRENT

4

Chrome es el techo de RAM en una máquina pequeña.

browser.timeout_ms

ESCALATOR_BROWSER_TIMEOUT_MS

30000

Plazo por petición para el peldaño del navegador.

proxy.enabled

ESCALATOR_PROXY_ENABLED

false

El interruptor. Todo lo demás se ignora mientras esto sea false.

proxy.url

ESCALATOR_PROXY_URL

http://user:pass@host:port, o socks5://...

proxy.list

ESCALATOR_PROXY_LIST

Varias salidas, usadas en round-robin. Combinado con url.

http.timeout_ms

ESCALATOR_HTTP_TIMEOUT_MS

10000

Plazo por petición para los dos peldaños http.

ladder.min_content_chars

ESCALATOR_LADDER_MIN_CONTENT_CHARS

200

Por debajo de esta cantidad de caracteres extraídos, una página es 'thin' y la escalera sube.

ladder.tier_cache_ttl_hours

ESCALATOR_LADDER_TIER_CACHE_TTL_HOURS

72

Cuánto tiempo sobrevive un peldaño aprendido antes de degradarse un paso más barato.

politeness.respect_robots

ESCALATOR_POLITENESS_RESPECT_ROBOTS

true

Tu máquina, tu decisión.

politeness.rate_limit_rps

ESCALATOR_POLITENESS_RATE_LIMIT_RPS

1.0

Por dominio. 0 desactiva el intervalo por completo.

politeness.user_agent

ESCALATOR_POLITENESS_USER_AGENT

un UA de Chrome

Se usa para el emparejamiento con robots.txt.

server.api_keys

ESCALATOR_SERVER_API_KEYS

Claves Bearer para escalator serve. Esta lista ES la verdad: eliminar una la revoca.

server.host

ESCALATOR_SERVER_HOST

127.0.0.1

127.0.0.1 lo mantiene fuera de la red local. Los contenedores quieren 0.0.0.0.

server.port

ESCALATOR_SERVER_PORT

8000

Puerto para escalator serve.

storage.data_dir

ESCALATOR_STORAGE_DATA_DIR

Base de datos y navegadores gestionados. Vacío = el predeterminado de la plataforma a continuación.

storage.request_log_limit

ESCALATOR_STORAGE_REQUEST_LOG_LIMIT

5000

Filas mantenidas en request_log; recortadas al insertar.

Los datos — la base de datos SQLite y cualquier navegador descargado — viven en el directorio de datos de la plataforma, que se puede sobrescribir con ESCALATOR_STORAGE_DATA_DIR. Nunca se escribe nada fuera de él.

Where the browser comes from

escalator browser list muestra la búsqueda, en orden:

  1. una ruta explícita — --browser-path, luego ESCALATOR_BROWSER_PATH, luego browser.path. Si está configurada y es incorrecta, es un error que nombra la ruta, nunca una caída silenciosa.

  2. navegadores instalados en esta máquina: Google Chrome real primero, luego Chromium, luego Edge y Brave.

  3. un navegador que escalator browser install descargó anteriormente.

Si ninguno de esos encuentra algo, obtienes un error que nombra los dos comandos que lo arreglan. La resolución nunca descarga por sí sola — una petición de servidor o un trabajo cron no debería instalar software como efecto secundario.

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}

Autentica con Authorization: Bearer <key>, donde la clave es una de server.api_keys. Esa lista es la verdad: elimina una clave y se revoca en el próximo inicio. No hay endpoint para acuñar una.

Un muro devuelve 200 OK con {"status": "challenged"}, no como un error HTTP. Eso es deliberado: un agente al otro lado puede reaccionar. Reintentar en bucle no ayudará — escalator no resuelve CAPTCHAs, por diseño.

Con el extra [mcp], la misma escalera se expone en /mcp como una herramienta, scrape_url(url, force_browser=False).

Troubleshooting

Empieza aquí:

escalator doctor

Comprueba Python, el archivo de configuración, el directorio de datos, la resolución del navegador, un lanzamiento headless real y — si hay un proxy configurado — una petición real a través de él, informando la IP de salida y el país con la contraseña enmascarada. Cada ❌ viene con la línea que lo arregla, y el código de salida es distinto de cero si algo falla, para que los scripts también puedan usarlo. escalator doctor --json para máquinas.

síntoma

lo que suele ser

no Chrome-family browser found

escalator browser install

error while loading shared libraries en Linux

doctor nombra el paquete a instalar

todo devuelve challenged

necesitas un proxy residencial: escalator init

/scrape devuelve 401

no hay clave configurada, o se eliminó de server.api_keys

primera petición de navegador lenta

arranque en frío de Chrome; escalator reintenta el lanzamiento una vez

Si aún no funciona, pega la salida completa de escalator doctor en un issue — eso es lo que pide su última línea, y es la ruta más rápida a una respuesta.

Development

Consulta CONTRIBUTING.md. En resumen: uv sync, uv run pytest.

License

Publicado en el dominio público — consulta UNLICENSE. Sin garantía, sin atribución requerida, haz lo que quieras con él.

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