stealth-chrome-devtools-mcp
Servidor MCP de automação de navegador indetectável, construído sobre o nodriver (baseado em CDP), com evasão anti-bot, sessões de login persistentes e gerenciamento de cookies.
Documentação
Stealth Chrome DevTools MCP
Automação de navegador indetectável para agentes de IA via Model Context Protocol.
Um servidor MCP Stealth Chrome DevTools autocontido com gerenciamento inteligente de perfis, filtragem de argumentos furtivos anti-detecção e tratamento robusto do ciclo de vida de processos. Construído sobre nodriver (baseado em CDP) para evasão anti-bot completa.
Demonstrações
Bypass do Cloudflare Turnstile
https://github.com/user-attachments/assets/c4de61ae-6878-4fff-9bfd-65cdd4fadc2f
Sessões de login persistentes
https://github.com/user-attachments/assets/f81fc0c2-9233-48cd-8a9d-2577b1d33d57
Principais recursos
- Indetectável por sistemas anti-bot — Cloudflare, DataDome, PerimeterX, etc.
- Gerenciamento inteligente de perfis — estratégia mestre/snapshot/clone preserva logins entre sessões
- Filtragem de argumentos furtivos — remove automaticamente mais de 30 flags detectáveis do Chrome (assinaturas de Puppeteer/Playwright, marcadores de automação)
- Suporte a múltiplas instâncias — inicie e gerencie vários navegadores simultaneamente
- Um backend compartilhado entre sessões — cada sessão de cliente faz proxy para um processo backend compartilhado, em vez de iniciar um próprio, um por desktop para que uma inicialização com janela chegue a uma tela real; o cold start simultâneo é testado em escala com 40 sessões concorrentes, todas utilizáveis em segundos contra um único backend
- Sufixo automático para perfis ocupados —
github-sessionautomaticamente viragithub-session-2quando ocupado - Recuperação de órfãos — limpa com segurança processos de navegador vazados sem matar os ativos
- Persistência de sessão — perfis clonados carregam cookies, logins e Web Data do mestre
- Zero timeout de inatividade — navegadores permanecem vivos até serem fechados explicitamente
- Acesso completo ao CDP — manipulação de DOM, interceptação de rede, execução de JavaScript, capturas de tela
Início rápido
Adicione à sua configuração MCP (claude_desktop_config.json, .claude/settings.json, etc.):
{
"mcpServers": {
"stealth-chrome-devtools-mcp": {
"command": "uvx",
"args": ["stealth-chrome-devtools-mcp==2.0.6"]
}
}
}
Ou instale via pip:
pip install stealth-chrome-devtools-mcp==2.0.6
Falhas são relatadas aos mantenedores por padrão, com seu nome de usuário e nome da máquina removidos. Consulte Relatório de erros para saber o que um relatório contém e como desativá-lo.
Desenvolvimento local
{
"mcpServers": {
"stealth-chrome-devtools-mcp": {
"command": "uv",
"args": [
"--directory", "/path/to/stealth-chrome-devtools-mcp",
"run", "stealth-chrome-devtools-mcp"
]
}
}
}
Como funciona
Estratégia de perfil do navegador
C:\stealth-mcp-browser-sessions\
master/ # Your primary Chrome profile (logins, cookies, extensions)
master-snapshot/ # Safe copy refreshed while master is closed
sessions/ # Cloned profiles for concurrent use
github-session/
github-session-2/ # Auto-suffixed when github-session is busy
spawn_browser()usa o perfil mestre quando disponível- Antes de abrir o mestre, o servidor atualiza
master-snapshot - Quando o mestre está ocupado, um clone é criado a partir do snapshot
- Clones carregam todos os cookies, logins e dados de sessão
- Snapshots desatualizados são atualizados automaticamente quando os arquivos de autenticação mudam
Os clones excluem caches do Chrome regeneráveis, então cada um tem alguns MB em vez de vários GB. Clones automáticos descartáveis são excluídos ao fechar, e um limite de armazenamento (STEALTH_MCP_CLONE_STORAGE_CAP_GB, padrão 10 GB) recupera os clones ociosos mais antigos caso algum vaze — para que sessions/ permaneça limitado. A remoção por limite é recuperável: um clone removido é movido para sessions/.trash/ e só é purgado após uma janela de retenção (STEALTH_MCP_CLONE_TRASH_RETENTION_HOURS, padrão 24 h), permitindo restaurar uma remoção equivocada em vez de perdê-la.
Perfis nomeados que você cria explicitamente (por exemplo, github-session) persistem e nunca são excluídos. Mas até um perfil "persistente" é ~98% regenerável (caches mais o modelo de IA on-device de vários GB do Chrome). Então, quando sessions/ exceder STEALTH_MCP_BROWSER_SESSION_STORAGE_CAP_GB (padrão 20 GB), os maiores perfis nomeados ociosos têm diretórios regeneráveis podados, enquanto todo login é preservado — o Chrome os reconstrói na próxima inicialização. Perfis em uso nunca são tocados.
Nota para máquinas compartilhadas: a raiz da sessão do navegador usa por padrão
C:\stealth-mcp-browser-sessions(raiz da unidade), que contém seus cookies e dados de sessão logados. Em uma máquina de usuário único, tudo bem. Em uma máquina Windows compartilhada multi-usuário, outros usuários locais podem conseguir ler — aponteSTEALTH_MCP_BROWSER_SESSION_ROOTpara um local dentro do seu perfil de usuário (por exemplo,%LOCALAPPDATA%\stealth-mcp) para que as ACLs do usuário do SO o protejam.
Filtragem de argumentos furtivos
O servidor remove automaticamente flags do Chrome que comprometeriam a furtividade:
| Categoria | Exemplos | Por que remove |
|---|---|---|
| Sinais de automação | --enable-automation, --test-type | Define navigator.webdriver=true |
| Vazamentos de impressão digital | --disable-gpu, --disable-webgl | Detectável via sondas WebGL/canvas |
| Padrões do Puppeteer | --disable-backgrounding-occluded-windows | Assinatura de bot |
| Padrões do Playwright | --password-store=basic, --use-mock-keychain | Assinatura de bot |
Argumentos removidos são reportados em spawn_diagnostics.stealth_args_stripped.
Recuperação de órfãos
Na reinicialização do servidor, o sistema de limpeza de processos:
- Recolhe apenas navegadores cujo backend proprietário está morto — cada navegador rastreado registra qual backend o iniciou, então dois backends rodando lado a lado nunca recolhem navegadores um do outro
- Mantém o rastreamento de
create_timecomo segunda rede de segurança: nunca mata um processo que iniciou depois do início da sessão atual do servidor - Lida com segurança com
psutil.AccessDeniedem processos elevados do Windows
Navegação com janela e onde ela abre
Um navegador com janela aparece no desktop do processo que o iniciou, não da sessão que pediu. Como as sessões compartilham um backend, um backend iniciado primeiro a partir de um login SSH ou de uma sessão de serviço do Windows não pode mostrar uma janela para ninguém — inclusive para as sessões rodando no desktop físico.
Portanto, o backend é vinculado ao contexto de exibição: um por desktop, mais um para o contexto headless. A descoberta prefere um backend que possa mostrar uma janela, ou seja, um spawn_browser(headless=False) acionado por SSH usa automaticamente o backend do desktop e sua janela abre na tela real. Quando tal backend não existe, o spawn levanta em vez de entregar um navegador invisível; execute stealth-chrome-devtools doctor para ver quais contextos têm um backend. Spawns headless funcionam a partir de qualquer lugar.
Exemplos de uso
# Spawn with default master profile
spawn_browser()
# Named session with login persistence
spawn_browser(user_data_dir="github-session")
# Same name while first is open → auto-suffixes to github-session-2
spawn_browser(user_data_dir="github-session")
# Headless with stealth (bad args auto-stripped)
spawn_browser(headless=True, browser_args=["--enable-automation"])
# → stealth_args_stripped: ["--enable-automation stripped: sets navigator.webdriver=true"]
Ferramentas MCP
| Ferramenta | Descrição |
|---|---|
spawn_browser | Iniciar uma nova instância de navegador furtivo |
navigate | Navegar para uma URL |
take_screenshot | Capturar screenshot da página |
execute_script | Executar JavaScript no contexto da página |
query_elements | Encontrar elementos DOM por seletor CSS |
click_element | Clicar em um elemento |
type_text | Digitar texto em um campo de entrada |
get_page_content | Obter conteúdo HTML da página |
list_instances | Listar todas as instâncias de navegador ativas |
close_instance | Fechar um navegador específico |
list_network_requests | Visualizar tráfego de rede interceptado |
get_cookies / set_cookie | Gerenciar cookies do navegador |
94 ferramentas em 11 seções — a contagem é derivada do registro de ferramentas ao vivo, nunca mantida manualmente. Veja o mapa de navegação completo →.
Isso é o que o servidor serve, que não é o mesmo que o gate de release prova. No SHA do release no ledger de evidências, 3 dessas 94 são qualificadas para release: verificadas ponta a ponta sobre o transporte stdio real que um cliente realmente fala. As demais são dirigidas contra Chrome real pela suíte E2E, mas através de uma costura in-process, então são served-unqualified no fio — testadas, não provadas lá. RELEASE_CONTRACT.md lista o estado de cada ferramenta e é a única fonte para esses números.
Testes
# Unit tests only (no Chrome needed)
uv run pytest -m "not integration"
# All tests (needs Chrome installed)
uv run pytest
# Verbose with short tracebacks
uv run pytest -v --tb=short
Se o seu caminho de checkout contiver espaços ou um
&,uv run pytestfalhará comFailed to canonicalize script path— use o Python do venv diretamente:.venv\Scripts\python.exe -m pytest -m "not integration". Veja CONTRIBUTING.md para o fluxo completo de teste/gate.
Uma suíte abrangente cobre filtragem de argumentos furtivos, resolução de perfil, recuperação de órfãos, varreduras de limite de armazenamento, o CLI de ops e integração completa com navegador.
Variáveis de ambiente
Todas opcionais. Os padrões funcionam para uso normal. Defina-as no seu shell, ou em
~/.stealth-mcp/.env — cada chave está documentada em .env.example.
Um .env no diretório do seu projeto é deliberadamente ignorado. O backend é um processo compartilhado iniciado com a pasta que seu cliente MCP tinha aberta, então ler o .env do projeto significaria ler a configuração de aplicativo de outra pessoa — o que travava o servidor imediatamente em um DATABASE_URL comum e adotava silenciosamente o PORT, DEBUG e SENTRY_DSN desse aplicativo como se fossem do servidor.
| Variável | Padrão | Propósito |
|---|---|---|
STEALTH_MCP_BROWSER_SESSION_ROOT | C:\stealth-mcp-browser-sessions (Win) / ~/.stealth-mcp-browser-sessions (Unix) | Pasta base para perfis |
BROWSER_MASTER_USER_DATA_DIR | <root>/master | Caminho do perfil mestre do Chrome |
BROWSER_MASTER_SNAPSHOT_DIR | <root>/master-snapshot | Fonte do snapshot para clones |
BROWSER_PROFILE_CLONE_ROOT | <root>/sessions | Pasta para cópias de perfil |
BROWSER_PROFILE_REFRESH_DAYS | 7 | Atualizar cópias após N dias (0 = desativar) |
STEALTH_MCP_CLONE_STORAGE_CAP_GB | 10 | Limite total de armazenamento de clones automáticos; os clones ociosos mais antigos são recuperados quando excedido (0 = desativar). Perfis nomeados e clones em uso nunca são tocados. |
STEALTH_MCP_BROWSER_SESSION_STORAGE_CAP_GB | 20 | Limite total de armazenamento de sessions/; quando excedido, os maiores perfis nomeados ociosos são podados de diretórios de cache/modelo regeneráveis — logins mantidos (0 = desativar). (Renomeado de STEALTH_MCP_SESSION_STORAGE_CAP_GB; atualize sua config — o nome antigo não é mais lido.) |
STEALTH_MCP_CLONE_TRASH_RETENTION_HOURS | 24 | Por quanto tempo um clone removido por limite permanece recuperável em sessions/.trash/ antes da purga (0 = purgar na próxima varredura). |
STEALTH_MCP_CLONE_OUTPUT_DIR | ~/.stealth-mcp/element_clones | Onde screenshots, derramamentos de grandes respostas e arquivos de clone de elementos são escritos. Mantidos em um diretório por usuário (nunca dentro do pacote instalado) para que um site-packages somente leitura não quebre as capturas. |
BROWSER_IDLE_TIMEOUT | 0 | Timeout de limpeza de inatividade (0 = desativado) |
STEALTH_CHROME_PROFILE_KEY | não definido | Forçar uma chave de clone estável |
STEALTH_MCP_CLIENT_ROOTS_TIMEOUT_SECONDS | 5 | Prazo para a solicitação roots/list que o caminho de clone automático envia ao cliente MCP para nomear um clone. O MCP roots é opcional, então um cliente pode nunca responder; no vencimento, o nome do clone cai para CODEX_WORKSPACE/CLAUDE_PROJECT_DIR/PWD/cwd (0 = nunca perguntar). |
STEALTH_BROWSER_DEBUG | false | Habilitar log de depuração |
STEALTH_MCP_NO_ERROR_REPORTING | false | Defina como true para desativar o relatório de erros |
CLI
Instala um comando de ops stealth-chrome-devtools para gerenciar o servidor e seu uso de disco. (Isso é para ops — para dirigir um navegador, use o servidor MCP ou seu backend HTTP.)
Estes quatro apenas leem e pré-visualizam — não mudam nada, e a suíte de testes os executa em cada commit, então são conhecidos por funcionar:
stealth-chrome-devtools status
stealth-chrome-devtools profiles
stealth-chrome-devtools cleanup
stealth-chrome-devtools cleanup --browser-session-cap-gb 12
status informa se o backend está ativo, além da raiz da sessão do navegador e ambos os limites; profiles lista perfis com tamanho / papel / uso; cleanup pré-visualiza o disco recuperável (dry run), e --browser-session-cap-gb pré-visualiza com um limite mais restrito.
Estes não são executados automaticamente — --apply exclui, serve não retorna, e doctor exige Chrome instalado:
stealth-chrome-devtools cleanup --apply # actually reclaim
stealth-chrome-devtools doctor # check Chrome / environment
stealth-chrome-devtools serve --http --port 19222 # start the server
cleanup exclui clones automáticos ociosos acima do limite de clones e poda perfis nomeados ociosos até o estado de sessão — logins mantidos — acima do limite de session do navegador. É um dry run, a menos que você passe --apply, nunca toca em perfis em uso, e usa os mesmos seletores da varredura automática, então a pré-visualização corresponde a --apply.
Preparando o perfil mestre
- Inicie o servidor MCP
- Chame
spawn_browser()semuser_data_dir - Entre nas suas contas no navegador que abrir
- Feche-o — sessões futuras usam este perfil ou clonam a partir dele
Requisitos
- Python 3.11+
- Chrome, Chromium ou Microsoft Edge
- uv (recomendado) ou pip
- Uma sessão de desktop para navegação com janela (headless funciona a partir de SSH, CI e serviços)
Relatório de erros
Crashes e erros são reportados ao Sentry por padrão, para que uma falha que você encontrar seja uma falha que possamos ver e corrigir. Não há nada para instalar nem nada para configurar: o SDK já vem com o pacote e o destino já está embutido.
O que um relatório contém. O tipo e a mensagem da exceção, o stack trace, a versão do pacote e a plataforma. Três coisas ficam de fora:
- o seu nome da máquina (o
server_namedo Sentry) é descartado por completo; - o seu nome de usuário é removido de todos os caminhos, então um frame do stack trace aparece como
C:\Users\~\...,/home/~/...ou/Users/~/...em vez do seu diretório pessoal; - variáveis locais não são capturadas de forma alguma. O SDK do Sentry as envia por padrão; nós desativamos isso, porque uma variável local nesta ferramenta pode conter uma senha de proxy, um cabeçalho
AuthorizationouCookie, ou um script que você pediu para executar — segredos que nenhuma regra de caminho conseguiria resgatar.
Isso é universal — acontece em todas as instalações, incluindo a nossa, e não há como optar por voltar a enviar esses campos. O que deliberadamente permanece é a parte que torna um relatório útil: o tipo do erro, o caminho do módulo após o segmento do diretório pessoal, a linha do código-fonte que falhou e a versão da qual veio.
Uma mensagem de erro ainda cita aquilo com que a chamada que falhou estava trabalhando — uma URL que você acessou, um arquivo que você pediu. Se não é uma troca que você queira fazer, desative o relatório.
Para desativar, defina uma variável no seu shell ou no ~/.stealth-mcp/.env:
STEALTH_MCP_NO_ERROR_REPORTING=true
Versões anteriores liam o SENTRY_DSN do ambiente. Elas não leem mais — essa variável pertence à sua aplicação, e um backend compartilhado iniciado a partir da pasta do seu projeto estava capturando-a. Veja Environment Variables para entender por que esta ferramenta ignora completamente o .env do seu projeto.
Configuração de desenvolvimento
git clone https://github.com/DevinoSolutions/stealth-chrome-devtools-mcp
cd stealth-chrome-devtools-mcp
uv sync --extra dev --extra test # install linters + test deps
npm install # arm husky pre-commit/pre-push hooks
Os seis portões de qualidade são executados automaticamente em cada commit: ruff format, ruff check, ty check, vulture, suppression-owner check, file-budget check. Testes de unidade são executados antes do push.
Documentação
- CLAUDE.md — mapa de navegação da árvore de fontes + glossário + convenções
- DESIGN.md — invariantes de arquitetura e o porquê por trás deles
- RUNBOOK.md — operação do backend: verbos, logs, recuperação, caminho de fumaça MCP
- CONTRIBUTING.md — clone → instalação → teste, o portão de qualidade, convenções
Licença
Veja LICENSE.
Construído por Devino Solutions