SlimAtlas
Um servidor MCP que fornece capacidades de automação de navegador extremamente leves usando o navegador Lightpanda. Este servidor permite que LLMs interajam com páginas da web por meio de automação de navegador.
Documentação
SlimAtlas AI
Um servidor MCP standalone extremamente leve para automação de navegador eficiente em tokens para agentes de IA, projetado para rodar em servidores.
~5x menos memória que Chromium. ~25x snapshots menores que HTML bruto.
Funciona com Linux e macOS.
Construído com Bun, Puppeteer e Lightpanda.
Recursos
- Automação de Navegador: Navegue, clique, digite, preencha formulários e avalie JavaScript
- Leve por Padrão: ~5x menos memória que Chromium, ~25x snapshots menores que HTML bruto
- Snapshots de Página: Obtenha snapshots compactos de árvore de acessibilidade em YAML com IDs de nó únicos para direcionamento preciso de elementos
- Contexto Otimizado para LLM: Snapshots são reduzidos ao essencial semântico, mantendo o uso de contexto mínimo para que você possa caber mais páginas e sessões mais longas na mesma janela
- Navegador de Fallback Configurável: Modelo de dois níveis — navegador leve primeiro, depois escala para Chrome com interface, Browserless ou Browserbase na nuvem apenas quando o padrão é detectado como bot, falha ou expira.
- Limitação de Taxa: Fique abaixo do radar. Imponha um atraso mínimo configurável entre requisições a domínios específicos com padrões curinga (
*,*.reddit.com) além de jitter opcional, para que seu agente se ajuste ao ritmo em vez de bombardear um site e acionar suas defesas anti-bot. - Suporte a Proxy: Roteie cada requisição através de um proxy HTTP com uma única configuração
PROXY_SERVER— aplicada automaticamente a ambas as camadas de navegador, para que seu IP real nunca toque o alvo. Suporta autenticação básica inline (http://user:pass@host:port). - Gerenciamento Robusto de Sessões: Serialização por sessão, limite opcional de sessões (
MAX_SESSIONS), recuperação de falhas no meio da sessão com replay de histórico e desligamento gracioso. - Gerenciamento de Sessões: Reutilize sessões em múltiplas operações com IDs de sessão únicos
- Multiplataforma: Funciona em Linux e macOS, com fallback configurável para navegador real quando necessário
Benchmark
SlimAtlas foi avaliado contra Playwright MCP (Chromium headless e com interface) usando slim-atlas-bench — 25 sites reais em 5 categorias, 3 execuções cada (225 no total), todos rodando em Docker no localhost.
Configuração: Cada serviço roda como um servidor MCP em seu próprio contêiner Docker. O harness de benchmark mede a latência por chamada de ferramenta (navegar + snapshot) via langchain-mcp-adapters, e captura a RAM do contêiner via API de estatísticas do Docker. Snapshots são estimados em tokens a ~4 caracteres/token (mesma metodologia da linha de base de HTML bruto).
| Métrica (mediana) | SlimAtlas | Playwright Headless | Playwright Headful |
|---|---|---|---|
| Navegar + Snapshot (ms) | 1.383 | 1.116 | 687 |
| RAM do Contêiner (MB) | 124 | 635 | 815 |
| Tokens do Snapshot | 414 | 940 | 1.843 |
SlimAtlas troca velocidade de navegação por uso drasticamente menor de recursos. Chromium é mais rápido no carregamento de páginas, mas usa 5–6x mais RAM e produz 2–4x mais tokens por snapshot — os dois custos que dominam em escala em fluxos de trabalho de agentes.
Resultados
Tokens do Snapshot![]() | Uso de Memória![]() |
Instalação
Requer Bun ≥1.1.
# Install dependencies
bun install
O binário do navegador é baixado automaticamente na primeira execução.
Navegador de fallback: Nível 1 é sempre o navegador leve. Nível 2 é FALLBACK_BROWSER — um de headful (Chrome com interface), browserbase (nuvem), browserless (nuvem), ou none (padrão, sem fallback). Quando o padrão falha, expira ou é detectado como bot, a sessão alterna uma vez para o fallback configurado. Chrome é empacotado pelo Puppeteer; Browserbase/Browserless exigem credenciais de API (veja abaixo).
Uso
Executar o Servidor MCP
# Standalone HTTP server (default)
bun run src/index.ts --port=8080
# Remote, authenticated
MCP_AUTH_TOKEN=s3cret bun run src/index.ts --host=0.0.0.0 --port=8080
SlimAtlas expõe um único endpoint MCP /mcp Streamable HTTP. Cada cliente recebe sua própria sessão via cabeçalho mcp-session-id; MAX_SESSIONS limita a concorrência. Aponte seu cliente MCP para ele:
{
"mcpServers": {
"slimatlas": {
"url": "http://localhost:8080/mcp",
"transport": "http"
}
}
}
Com autenticação:
{
"mcpServers": {
"slimatlas": {
"url": "http://your-host:8080/mcp",
"transport": "http",
"headers": { "Authorization": "Bearer s3cret" }
}
}
}
Dica: Use --host=0.0.0.0 para expor remotamente, mas sempre defina MCP_AUTH_TOKEN ao fazer isso. O servidor fala apenas HTTP simples — termine TLS na frente (Caddy/nginx) ou o token Bearer viaja pela rede em texto claro.
Docker
A imagem inclui o binário Lightpanda no momento da construção, então o contêiner inicia autocontido e nunca baixa novamente:
docker build -t slimatlas .
docker run -p 8080:8080 -e MCP_AUTH_TOKEN=s3cret slimatlas
# -> http://localhost:8080/mcp
Fixei uma versão do Lightpanda para builds reproduzíveis (qualquer tag lightpanda-io/browser — padrão nightly):
docker build --build-arg LIGHTPANDA_VERSION=0.3.3 -t slimatlas:0.3.3 .
Multi-arquitetura é tratada automaticamente — o build detecta a arquitetura do contêiner via uname -m (x86_64 → lightpanda-x86_64-linux, aarch64 → lightpanda-aarch64-linux), então o binário sempre corresponde à plataforma em construção.
Apple Silicon (Macs M-series): passe
--platform linux/arm64para construir/executar nativamente. Sem isso, o Docker Desktop pode usaramd64por padrão e executar o contêiner sob Rosetta, o que falha ao iniciar o binário Lightpanda (rosetta error: failed to open elf …).docker build --platform linux/arm64 --build-arg FALLBACK_BROWSER=headful -t slimatlas . docker run --platform linux/arm64 --name slimatlas -p 8080:8080 -e MCP_AUTH_TOKEN=s3cret -e PLUGINS=document-export -e LIGHTPANDA_POOL_SIZE=20 -e CHROME_POOL_SIZE=10 -e SKIP_LIGHTPANDA_DOMAINS=reddit.com -e RATE_LIMIT_DOMAINS=reddit.com -e RATE_LIMIT_MIN_DELAY_MS=10000 slimatlasNota sobre sites com verificação anti-bot (Reddit, sites atrás de Cloudflare): em
linux/arm64a imagem usa Debian Chromium como fallback, que as barreiras anti-bot atuais (ex: "Prove sua humanidade" do Reddit, "Só um momento..." do Cloudflare) servem um desafio interativo independentemente das configurações de stealth. Verificado contra Reddit: o mesmo contêiner emlinux/amd64— que fixa Chrome-for-Testing (padrão131.0.6778.204; builds estáveis atuais são bloqueados) — renderiza threads normalmente. Prefira a imagem amd64 para alvos com verificação anti-bot (em Macs M-series ela roda sob Rosetta; Lightpanda funciona lá pois o binário x86_64 é incluído no momento da construção).Escolha do mecanismo / proxy: AMBAS as camadas de navegador roteiam através de
PROXY_SERVER(mesmas credenciais; Lightpanda via auth inline--http-proxy, Chrome via--proxy-server+page.authenticate). Reddit renderiza através de Lightpanda com proxy diretamente; quando uma sessão encontra um desafio, a camada de detecção de bot a escala para o fallback Chrome 131. Adicione-e SKIP_LIGHTPANDA_DOMAINS=reddit.compara forçar threads diretamente para Chrome.Notas sobre proxy:
PROXY_SERVERaceitahttp://user:pass@host:portou o formato do dashboardhost:port:user:pass(normalizado internamente). Sessões persistentes (formatogate.<provider>:port:user-sessid-xxx:pass) funcionam através da mesma variável de ambiente.-e PROXY_BYPASS_DOMAINS=a.com,b.comroteia domínios listados DIRETO no Chrome (para sites cujo Cloudflare desaprova mais suas saídas de proxy do que seu próprio IP).Exemplo completo de produção — configuração verificada contra Reddit e uma rajada paralela de páginas de estatísticas:
docker build --platform linux/amd64 --build-arg FALLBACK_BROWSER=headful -t slimatlas . docker rm -f slimatlas docker run -d --name slimatlas -p 8080:8080 \ -e MCP_AUTH_TOKEN=s3cret \ -e PLUGINS=document-export \ -e CHROME_POOL_SIZE=6 \ -e RATE_LIMIT_DOMAINS=reddit.com \ -e RATE_LIMIT_MIN_DELAY_MS=10000 \ -e TZ=America/New_York \ -e PROXY_SERVER="http://user:pass@proxy-host:port" \ -e PROXY_BYPASS_DOMAINS=cloudflare-heavy-site.com \ slimatlasOmita
PROXY_SERVER,PROXY_BYPASS_DOMAINSeTZse você não usa proxy.CHROME_POOL_SIZEimporta: o padrão de 1 serializa toda sessão escalada por desafio e causa timeouts no cliente quando uma sessão vaza. A versão fixada do Chrome é substituível no momento da construção com--build-arg CHROME_CFT_VERSION=<version>se a barreira de um site começar a sinalizá-lo.
Variante com fallback com interface. A imagem padrão executa apenas Lightpanda (FALLBACK_BROWSER=none). Para habilitar o fallback Chrome com interface (necessário apenas se você definir FALLBACK_BROWSER=headful em tempo de execução), construa a variante com interface — ela adiciona as bibliotecas de runtime do Chrome + Xvfb (~150MB) e predefine FALLBACK_BROWSER=headful:
docker build --build-arg LIGHTPANDA_VERSION=0.3.3 FALLBACK_BROWSER=headful -t slimatlas:headful .
docker run -p 8080:8080 -e MCP_AUTH_TOKEN=s3cret -e PLUGINS=document-export slimatlas:headful
Xvfb é iniciado lentamente dentro do contêiner na primeira sessão que escala para Chrome com interface — sem entrypoint ou xvfb-run manual necessário.
Plugin de exportação de documentos (PDF/PPTX). browser_print_pdf e browser_export_pptx vêm no plugin document-export e estão desabilitados por padrão — habilite com -e PLUGINS=document-export (ou a flag --plugins=document-export). Ambas as ferramentas forçam o fallback para Chrome real, então precisam de uma imagem que realmente tenha um: use a variante com interface acima. Na imagem padrão apenas com Lightpanda, as ferramentas aparecem na lista mas toda chamada falha (No fallback browser configured). Guia de criação de plugins: docs/plugins.md.
Modo Stdio
Para clientes MCP que iniciam o servidor como subprocesso (local, cliente único), use transporte stdio:
bun run src/index.ts
{
"mcpServers": {
"slimatlas": {
"command": "bun",
"args": ["run", "path/to/mcp/src/index.ts"]
}
}
}
Configuração
Adicione à configuração do seu cliente MCP:
{
"mcpServers": {
"slimatlas": {
"command": "bun",
"args": ["run", "path/to/mcp/src/index.ts"]
}
}
}
Dica: Defina FALLBACK_BROWSER=none para usar apenas o navegador leve e propagar erros honestamente. Use headful ou browserbase para habilitar um fallback de navegador real.
Veja docs/configs.md para todas as variáveis de ambiente e flags de CLI.
Navegador de fallback
FALLBACK_BROWSER | Navegador Nível 2 | Notas |
|---|---|---|
none (padrão) | — | Apenas navegador leve; erros propagam honestamente |
headful | Chrome com interface | Janela real no macOS; precisa de xvfb em Linux headless |
browserbase | Browserbase na nuvem | Requer BROWSERBASE_API_KEY + BROWSERBASE_PROJECT_ID |
Pule o navegador padrão para domínios conhecidamente difíceis com SKIP_LIGHTPANDA_DOMAINS (separados por vírgula, ciente de subdomínios). Hosts correspondentes iniciam diretamente no navegador de fallback. Requer FALLBACK_BROWSER != none (caso contrário, a lista é ignorada com um aviso).
Limitação de taxa
Ritmo educado e anti-detecção para seu agente. RateLimiter impõe um atraso mínimo em todo o servidor entre chamadas browser_navigate aos domínios que você lista, com jitter aleatório opcional para que o ritmo não seja um intervalo fixo e identificável. Buckets são chaveados por host em todas as sessões (porque o site alvo vê seu IP, não suas sessões), e padrões suportam curingas:
| Padrão | Correspondências | Bucket |
|---|---|---|
* | Todo host | Cada host limitado independentemente |
*.reddit.com | Apenas subdomínios (www.reddit.com, old.reddit.com) — não reddit.com | Todos os subdomínios correspondentes compartilham um bucket |
g2.com | g2.com + seus subdomínios | Apex + subdomínios compartilham um bucket |
Desabilitado por padrão. Habilite com uma lista de domínios não vazia e um atraso não zero:
# Via CLI flags
bun run src/index.ts --rate-limit-domains=*.reddit.com,g2.com --rate-limit-min-delay-ms=2000 --rate-limit-jitter-ms=1500
# Or via environment / .env
RATE_LIMIT_DOMAINS=*.reddit.com,g2.com
RATE_LIMIT_MIN_DELAY_MS=2000
RATE_LIMIT_JITTER_MS=1500
Proxy
Mantenha seu IP real longe do alvo. Defina um único PROXY_SERVER e SlimAtlas roteia todo o tráfego HTTP de ambas as camadas de navegador através dele — sem necessidade de configuração por navegador:
- Navegador leve (nível 1) — encaminhado via sua flag nativa
--http-proxy. - Fallback Chrome (nível 2) — aplicado via
--proxy-serverna inicialização.
# Via CLI flag
bun run src/index.ts --proxy-server=http://host:8080
# Or via environment / .env
PROXY_SERVER=http://user:pass@host:8080
Autenticação básica inline (http://user:pass@host:port) é suportada na camada do navegador leve. Para proxies com allowlist de IP (sem credenciais), funciona em ambas as camadas. (Autenticação Chrome por página via page.authenticate está no roadmap.)
Flags de CLI
Toda variável de ambiente também pode ser passada como uma flag de CLI em minúsculas no formato --flag=value. Flags de CLI sobrescrevem variáveis de ambiente. Flags desconhecidas fazem o servidor encerrar na inicialização. Consulte docs/configs.md para a lista completa.
bun run src/index.ts --fallback-browser=headful --lightpanda-pool-size=3 --skip-lightpanda-domains=g2.com --navigate-timeout=60000
Para usar flags a partir de um cliente MCP, adicione-as ao array args:
{
"mcpServers": {
"slimatlas": {
"command": "bun",
"args": [
"run",
"path/to/mcp/src/index.ts",
"--fallback-browser=headful",
"--skip-lightpanda-domains=g2.com,linkedin.com",
"--chrome-pool-size=3"
]
}
}
}
Fluxo de Uso
# Example: Navigate, snapshot, and interact with a page
# 1. Navigate to a URL (creates a new session automatically)
result = mcp.call("browser_navigate", {"url": "https://example.com"})
# Returns: session_id: abc1, result: Navigated to https://example.com. Title: Example Domain
# 2. Take a snapshot to see the page structure
snapshot = mcp.call("browser_snapshot", {"session_id": "abc1"})
# Returns YAML with node IDs like: 0: {type: div, children: ...}
# 3. Click a node by ID (from the snapshot)
mcp.call("browser_click", {"session_id": "abc1", "nodeId": 2})
# 4. Type into a search box
mcp.call("browser_type", {"session_id": "abc1", "nodeId": 5, "text": "search query"})
# 5. Close the session when done
mcp.call("browser_close", {"session_id": "abc1"})
Ferramentas Disponíveis
As ferramentas principais do browser_* abaixo estão sempre disponíveis. Duas ferramentas adicionais de pipeline — browser_print_pdf e browser_export_pptx — acompanham o plugin document-export e estão desabilitadas por padrão (-e PLUGINS=document-export / --plugins=document-export); consulte docs/plugins.md.
| Ferramenta | Descrição | Valor |
|---|---|---|
browser_navigate | Navegar para uma URL com estratégia de espera configurável | Ponto de entrada para todas as interações web. Suporta load, domcontentloaded, networkidle0, networkidle2 |
browser_snapshot | Obter árvore de acessibilidade YAML com IDs de nó únicos | Representação estruturada da página ideal para compreensão por LLM. IDs de nó permitem direcionamento preciso para cliques/digitação |
browser_view_node | Visualizar conteúdo específico de nó por ID (texto ou imagem) | Inspecionar elementos individuais sem reler a página inteira. Retorna imagens como base64 para verificação visual |
browser_click | Clicar em elemento por ID de nó ou seletor CSS | ID de nó (do snapshot) é recomendado em vez de seletores CSS por confiabilidade e simplicidade |
browser_type | Digitar texto em um elemento com atraso opcional de teclas | Simula digitação humana. Use para caixas de busca, formulários e entradas de texto |
browser_fill | Preencher um elemento de entrada com um valor instantaneamente | Mais rápido que browser_type para campos de formulário. Limpa o valor existente antes de digitar |
browser_go_back | Navegar para trás no histórico do navegador | Essencial para fluxos de múltiplas etapas e correção de erros de navegação |
browser_go_forward | Navegar para frente no histórico do navegador | Complementa browser_go_back para navegação bidirecional |
browser_reload | Recarregar a página atual | Atualizar conteúdo dinâmico ou recuperar de estado obsoleto da página |
browser_get_page_info | Obter URL e título da página atual | Maneira rápida de verificar sucesso de navegação e contexto atual |
browser_close | Fechar sessão do navegador e liberar recursos | Importante para limpeza. Sessões fecham automaticamente por timeout, mas fechamento explícito é recomendado |
Ferramentas de plugin (somente com PLUGINS=document-export):
| Ferramenta | Descrição | Valor |
|---|---|---|
browser_print_pdf | Imprimir página atual ou documento HTML fornecido em PDF base64 | Apenas para pipelines de geração de documentos/relatórios — NÃO para pesquisa/navegação de agentes. Força o fallback de Chrome real (FALLBACK_BROWSER); aceita um session_id fornecido pelo chamador (criar → imprimir → browser_close) |
browser_export_pptx | Converter página atual ou documento HTML fornecido em .pptx base64 via dom-to-pptx | Apenas para pipelines de geração de apresentações. Slides são os elementos que correspondem a selector (padrão .slide) no tamanho final de pixel (ex.: 1920x1080); with_previews=true também retorna PNGs por slide. Força o fallback de Chrome real; o chamador fecha a sessão com browser_close |
Executando Testes
# Run all tests
bun test
# Run tests in watch mode
bun test --watch
Requisitos
- Bun ≥1.1
- Linux ou macOS (baixa automaticamente) ou Chrome/Chromium (fallback)
Licença
MIT

