Veilus

Navegador anti-detecção para várias contas em um computador: uma impressão digital e proxy por perfil, e automação que seu assistente de IA escreve e executa via MCP.

Documentação

Estas documentações descrevem o lançamento do Veilus após v0.2.1, que está por vir. Se você tem a v0.2.1, algumas telas e recursos (Datasets, Lixeira, o novo painel de perfil, muitas ferramentas MCP) ainda não estão na sua versão.

MCP (Model Context Protocol) é o padrão pelo qual ferramentas de LLM como Claude Code, Cursor e Claude Desktop se conectam a ferramentas externas — o Veilus fala esse protocolo via stdio, então um LLM pode importar proxies, criar e iniciar perfis, controlar a página de um perfil em execução, escrever e executar scripts Veilus Flow e agendá-los — em seu nome.

Assim como a API REST, isso exige que a API local esteja ativada primeiro, pela página API & MCP na barra lateral do aplicativo — essa página também gera o token que você precisará abaixo.

Conectando

O binário do aplicativo Veilus tem um subcomando mcp que fala MCP via stdio. O cliente precisa do caminho para esse binário e do seu token, passado como variável de ambiente VEILUS_API_TOKEN.

Claude Code

claude mcp add --scope user veilus -e VEILUS_API_TOKEN=<token> -- "<path to Veilus>" mcp

--scope user disponibiliza o Veilus em todas as pastas onde você abrir o Claude Code; sem isso, o Claude Code só vê o Veilus na pasta onde você executou o comando.

Cursor / Claude Desktop

Adicione isto à configuração do servidor MCP do cliente:

{
  "mcpServers": {
    "veilus": {
      "command": "<path to Veilus>",
      "args": ["mcp"],
      "env": {
        "VEILUS_API_TOKEN": "<token>"
      }
    }
  }
}

A página API & MCP preenche o caminho real do binário e o token para você assim que você gerar um — copie o trecho de lá em vez de digitar manualmente.

Ferramentas

Perfis

Proxy

import_proxies

Crie um pool de proxies estático a partir de linhas de proxy (host:porta, host:porta:usuário:senha ou usuário:senha@host:porta). Prefixe uma linha com socks5:// para um proxy SOCKS5; http:// ou sem prefixo significa HTTP; https:// é rejeitado (TLS para o proxy não é suportado). Linhas inválidas são reportadas em rejected\ por número de linha (contando a partir de 1) e não bloqueiam as válidas; se nenhuma linha for válida, nada é criado. Retorna pool_id para create_profiles ou assign_proxy_pool. Senhas são armazenadas, mas nunca retornadas.

ParâmetroTipoObrigatórioDescrição
linesstring[]simUm proxy por elemento
namestringsim
typestringnão

list_proxy_pools

Liste pools de proxies: pool\_id\, name\, kind\ (estático ou rotativo), entry\_count\ e countries\ detectados para seus IPs de saída. Nunca retorna credenciais.

test_proxy

Teste cada proxy de um pool agora: vivo ou morto, latência, IP de saída e seu país e fuso horário. Atualiza a geo em cache do pool, que create_profiles usa. Um proxy morto pode levar até cerca de 10 segundos.

ParâmetroTipoObrigatórioDescrição
pool_idstringsimUUID do pool de proxies

assign_proxy_pool

Atribua um pool de proxies a perfis existentes, um slot para cada. Recusa a chamada inteira (nada é atribuído) se qualquer perfil já tiver um proxy ou pool, listando-os; passe force: true para substituir. NÃO altera o fuso horário dos perfis: se o novo proxy estiver em outro país, launch_profile será bloqueado pela verificação de geo. Novos perfis devem receber seu pool por meio de create_profiles.

ParâmetroTipoObrigatórioDescrição
forcebooleannãoSubstituir um proxy existente. Padrão false
pool_idstringsimUUID do pool de proxies
profile_idsstring[]sim

Controle de página

navigate

Carregue uma URL na aba de um perfil EM EXECUÇÃO e aguarde o evento de carregamento (até 15 s); em caso de timeout, ele CONTINUA MESMO ASSIM e o resultado diz que a página ainda está carregando — então chame wait_for_element para o que você precisar antes de ler a página. O perfil já deve estar aberto — chame launch_profile primeiro; isso nunca o abre.

ParâmetroTipoObrigatórioDescrição
profile_idstringsimUUID de um perfil em execução (launch_profile primeiro)
urlstringsim

snapshot

Snapshot de acessibilidade da página atual de um perfil em execução: uma linha por elemento com papel, nome e [id=N]; passe N como node_id para clicar ou digitar. Os IDs mudam quando a página muda — tire um novo snapshot após navegar ou clicar. Lista no máximo 150 elementos e 64 KiB; truncated: true significa que a página tem mais — use wait_for_element com um seletor CSS para alcançar um elemento que não está listado. Elementos dentro de iframes de mesma origem seguem uma linha --- iframe URL ---\ e funcionam com click e type como qualquer outro; um iframe de origem cruzada recebe uma linha (cross-origin …)\ com sua URL, mas seus elementos não são listados — navegue para essa URL para trabalhar dentro dele.

ParâmetroTipoObrigatórioDescrição
profile_idstringsimUUID de um perfil em execução (launch_profile primeiro)

click

Clique em um elemento da página de um perfil em execução por node_id com um mouse real: o ponteiro se move para um ponto dentro do elemento e então pressiona e solta. Falha se a página mudou desde o snapshot (tire um novo), se o elemento não tem caixa visível (oculto ou tamanho zero — clique em seu rótulo visível ou pai), ou se outro elemento o cobre (o erro o nomeia — feche ou role além dele primeiro). Um alerta/confirmação/prompt de JavaScript que a ação abre é respondido imediatamente: dialog\ "dismiss" (padrão, ou seja, Cancelar) ou "accept" (OK), com prompt\_text\ como a resposta digitada para um prompt; o resultado diz qual diálogo abriu e como foi respondido.

ParâmetroTipoObrigatórioDescrição
dialogstringnão
node_idintegersimnode_id do snapshot ([id=N]) ou wait_for_element
profile_idstringsimUUID de um perfil em execução (launch_profile primeiro)
prompt_textstringnão

type

Foque um elemento por node_id e digite texto nele, um evento de tecla por caractere (no máximo 5000 caracteres). Substitui o conteúdo atual do campo: o texto existente é removido antes de digitar. Se o resultado notar que o valor não pôde ser confirmado (campos mascarados, com limite de comprimento ou formatados automaticamente), verifique o campo com snapshot ou evaluate_js.

ParâmetroTipoObrigatórioDescrição
node_idintegersimnode_id do snapshot ([id=N]) ou wait_for_element
profile_idstringsimUUID de um perfil em execução (launch_profile primeiro)
textstringsim

press_key

Pressione uma tecla nomeada na página de um perfil em execução: Enter, Tab, Escape, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Backspace, Delete ou Space. Se nenhuma entrada estiver focada, a ÚLTIMA entrada da página é focada primeiro. Para texto, use type\. Um alerta/confirmação/prompt de JavaScript que a ação abre é respondido imediatamente: dialog\ "dismiss" (padrão, ou seja, Cancelar) ou "accept" (OK), com prompt\_text\ como a resposta digitada para um prompt; o resultado diz qual diálogo abriu e como foi respondido.

ParâmetroTipoObrigatórioDescrição
dialogstringnão
keystringsim
profile_idstringsimUUID de um perfil em execução (launch_profile primeiro)
prompt_textstringnão

scroll

Role a página de um perfil em execução em amount\ pixels (1 a 20000) na direção cima, baixo, esquerda ou direita, com passos de roda do mouse na posição do ponteiro. Como uma roda real, uma área rolável sob o ponteiro rola em vez da página — após um clique dentro de tal área, role lá, ou clique fora dela primeiro. Em um perfil macOS, a distância varia alguns por cento em torno de amount\, como uma roda real; o resultado relata os pixels realmente rolados.

ParâmetroTipoObrigatórioDescrição
amountintegersim
directionstringsim
profile_idstringsimUUID de um perfil em execução (launch_profile primeiro)

wait_for_element

Aguarde até que um seletor CSS corresponda a um elemento na página de um perfil em execução (verifica a cada 200 ms; timeout_ms de 1 a 30000, padrão 5000) e retorne seu node_id para click ou type. Use após navigate ou click para aguardar a próxima página.

ParâmetroTipoObrigatórioDescrição
profile_idstringsimUUID de um perfil em execução (launch_profile primeiro)
selectorstringsimSeletor CSS
timeout_msintegernão

evaluate_js

Execute uma expressão JavaScript na página de um perfil em execução e retorne seu valor como text\, codificado em JSON (strings voltam entre aspas); promises são aguardadas. undefined\ volta como o texto (undefined)\, não JSON null\. Um erro lançado volta como texto começando com [JS Error] — este é um resultado normal de chamada, não uma falha de ferramenta. Resultados acima de 64 KiB são cortados e sinalizados com truncated: true. Um loop síncrono é interrompido PELA PRÓPRIA PÁGINA após cerca de 9 s; seu resultado também volta como texto comum [JS Error]. Uma promise que nunca resolve faz a chamada em si falhar após 10 s com um erro de timeout. Isso NÃO é uma sandbox: executa com todos os direitos da página conectada (lê cookies, envia requisições como o usuário). Um alerta/confirmação/prompt de JavaScript que a ação abre é respondido imediatamente: dialog\ "dismiss" (padrão, ou seja, Cancelar) ou "accept" (OK), com prompt\_text\ como a resposta digitada para um prompt; o resultado diz qual diálogo abriu e como foi respondido.

ParâmetroTipoObrigatórioDescrição
dialogstringnão
expressionstringsim
profile_idstringsimUUID de um perfil em execução (launch_profile primeiro)
prompt_textstringnão

set_file

Anexe um arquivo a uma entrada de arquivo (, geralmente mostrada como um botão "Escolher Arquivo") da página de um perfil em execução por node_id, em vez de clicar nela — um clique abre o seletor de arquivos do sistema, que não pode ser controlado. Apenas arquivos dentro da pasta de uploads do aplicativo (~/.veilus/data/uploads) são permitidos: passe o nome do arquivo, ou um caminho absoluto dentro dessa pasta; qualquer outra coisa é recusada. Peça ao usuário para copiar o arquivo para lá primeiro.

ParâmetroTipoObrigatórioDescrição
node_idintegersimnode_id do snapshot ([id=N]) ou wait_for_element
pathstringsimnome do arquivo dentro de ~/.veilus/data/uploads
profile_idstringsimUUID de um perfil em execução (launch_profile primeiro)

Script

list_scripts

Liste todos os scripts, do mais recente para o mais antigo, sem o código-fonte: scriptId\, name\, description\, version\, mode\ (raw\ ou dsl\), origin\ (mcp\ se um agente o escreveu, app\ se o usuário o fez), approved\ e updatedAt\. Verifique aqui antes de save_script para atualizar um script existente em vez de salvar uma duplicata.

save_script Salve um script Playwright (TypeScript) no Veilus Flow. Sem script_id: cria um novo script; com script_id: substitui o código-fonte. Contrato - violações são rejeitadas com números de linha: (1) conectar com chromium.connectOverCDP(http://127.0.0.1:${process.env.VEILUS\_DEBUG\_PORT}\); (2) sem chromium.launch/launchPersistentContext; (3) usar browser.contexts()[0], não newContext(); (4) sem setUserAgent/setViewportSize - a identidade pertence ao perfil; (5) erros devem sair com código não zero: main().catch((e) => { console.error(e); process.exit(1); }); (6) importar apenas playwright e módulos nativos do Node; (7) terminar main() com await browser.close()\ - ele apenas desconecta do navegador do perfil e permite que o script saia; sem ele, a execução trava. Leia variáveis via process.env.VEILUS_VAR_<NAME> (nomes em UPPER_SNAKE_CASE); imprima o que precisar ver com console.log para stdout. Um script recém-salvo não é aprovado: run_script pode executá-lo (em no máximo 3 perfis), agendamentos aguardam até o usuário aprová-lo no aplicativo. name\ é usado apenas na criação; atualizar (com script_id) não renomeia, e apenas scripts salvos por um agente podem ser atualizados. Retorna scriptId\ (o id deste script — passe como script_id para get_script ou para save_script novamente), version\ e approved\.

ParâmetroTipoObrigatórioDescrição
descriptionstringnão
namestringsim
script_idstringnãoUUID do script cujo código-fonte será substituído; omita para criar um novo script
sourcestringsimO código-fonte TypeScript completo

get_script

Leia o código-fonte e o estado de aprovação de um script Raw, para corrigi-lo e salvá-lo novamente com save_script. Retorna scriptId\, name\, description\, version\, source\, approved\ e origin\.

ParâmetroTipoObrigatórioDescrição
script_idstringsim

run_script

Execute um script nos perfis fornecidos. Retorna a execução IMEDIATAMENTE, sem aguardar a conclusão; seu id\ é o run_id para get_run_result.

ParâmetroTipoObrigatórioDescrição
headlessbooleannãoInicia os perfis da execução em modo headless, sem janela — a mesma inicialização do launch_profile com headless\ (veja lá): a impressão digital do perfil permanece inalterada. Padrão false.
profile_idsstring[]simUUIDs dos perfis nos quais executar
script_idstringsimUUID do script
variablesobjectnãoVariáveis para o script, lidas no script como process.env.VEILUS_VAR_<NAME>

compile_script

Compile um script DSL de arrastar e soltar em código executável. Não o executa. Agentes que escrevem scripts devem usar save_script em vez disso.

ParâmetroTipoObrigatórioDescrição
dslobjectsimCorpo do script DSL
targetstringnãoAlvo da compilação

Lote

run_batch

Execute um script APROVADO em muitos perfis de verdade. Retorna a execução IMEDIATAMENTE; seu id\ é o run_id para get_run_result. Diferente de run_script (um teste em no máximo 3 perfis, sem necessidade de aprovação), o script deve ter sido aprovado pelo usuário em Veilus → Flow, caso contrário a chamada é recusada. Um id de perfil que não existe é contado como um perfil com falha da execução, não rejeitado (diferente de create_schedule, que recusa ids desconhecidos com 404). concurrency (padrão 3, 1-16, limitado pelo max\ de get_capacity) é quantos perfis executam ao mesmo tempo; stagger_ms (padrão 1500, 0-600000, ou seja, 10 minutos) é a pausa entre inicializações; use get_capacity para escolher.

ParâmetroTipoObrigatórioDescrição
concurrencyintegernão
profile_idsstring[]sim
script_idstringsimUUID de um script aprovado
stagger_msintegernão
variablesobjectnãoVariáveis para esta execução, lidas como process.env.VEILUS_VAR_<NAME>

get_capacity

Quantos navegadores estão abertos (ativos), aguardando uma vaga (na fila) e permitidos ao mesmo tempo (máximo) nesta máquina. Use para escolher a concorrência do run_batch.

Agendamentos

create_schedule

Crie um agendamento que executa um script APROVADO nos perfis fornecidos em horários definidos. O script já deve ter sido aprovado pelo usuário em Veilus → Flow: um script não aprovado é recusado agora, não ignorado depois. schedule_type: interval (interval_minutes, com interval_unit em minutos ou segundos, pelo menos 5 segundos), daily (daily_hour e daily_minute, horário local do computador), weekly (daily_hour, daily_minute e weekly_day, 0 = domingo), cron (cron_expr, 5 campos) ou once (run_at, um horário futuro RFC 3339 com offset; o agendamento executa uma vez e depois se desativa). concurrency (padrão 1, 1-16) e stagger_ms (padrão 0, 0-600000, ou seja, 10 minutos) se aplicam a cada execução. Retorna o agendamento, incluindo nextRunAt.

ParâmetroTipoObrigatórioDescrição
concurrencyintegernão
cron_exprstringnão
daily_hourintegernão
daily_minuteintegernão
enabledbooleannão
headlessbooleannãoInicia os perfis da execução em modo headless, sem janela — a mesma inicialização do launch_profile com headless\ (veja lá): a impressão digital do perfil permanece inalterada. Padrão false.
interval_minutesintegernão
interval_unitstringnão
namestringsim
profile_idsstring[]sim
run_atstringnãoRFC 3339 com offset, ex.: 2026-10-04T09:00:00+07:00; obrigatório para once
schedule_typestringsim
script_idstringsimUUID de um script aprovado
stagger_msintegernão
weekly_dayintegernão

list_schedules

Liste todos os agendamentos: seu script, perfis alvo, horário, flag de ativação e horários da próxima e última execução.

set_schedule_enabled

Ative ou desative um agendamento. Ativá-lo recalcula a próxima execução a partir de agora e exige que seu script ainda esteja aprovado; desativá-lo mantém o agendamento e seu histórico de execuções.

ParâmetroTipoObrigatórioDescrição
enabledbooleansim
schedule_idstringsimUUID do agendamento

run_schedule_now

Execute um agendamento uma vez agora, sem aguardar o temporizador. Retorna a execução IMEDIATAMENTE; seu id\ é o run_id para get_run_result. Recusado enquanto o agendamento já tiver uma execução em andamento, ou se seu script não estiver aprovado.

ParâmetroTipoObrigatórioDescrição
schedule_idstringsimUUID do agendamento

Monitoramento

list_runs

Liste as execuções mais recentes, das mais novas para as mais antigas: status e contagens de perfis, sem detalhes por perfil (get_run_result tem isso). Sem schedule_id, lista execuções de todos os agendamentos e de run_script e run_batch. limit tem padrão 20, no máximo 100.

ParâmetroTipoObrigatórioDescrição
limitintegernão
schedule_idstringnãoApenas execuções deste agendamento

get_run_result

Resultado de uma execução por run\_id\ — use após chamar run_script.

ParâmetroTipoObrigatórioDescrição
run_idstringsimUUID retornado por run_script

Conjuntos de dados

create_dataset

Crie um conjunto de dados: uma tabela armazenada no Veilus que scripts aprovados leem por perfil. Modo fixed\: cada perfil recebe UMA linha para contas boas; suas colunas chegam como process.env.VEILUS_VAR_<COLUMN>. Modo consume\: cada execução pega rows\_per\_run\ (1-50, padrão 1) linhas não utilizadas; uma execução com falha as devolve, uma execução bem-sucedida as marca como usadas; elas chegam como VEILUS_VAR_ROWS (array JSON de {COLUNA: valor}) e, quando rows_per_run é 1, também uma variável por coluna. VEILUS_VAR_ROW_INDEX é o número da linha. Colunas são UPPER_SNAKE_CASE; ROWS, ROW_INDEX, PROFILE_ID, RUN_ID e DEBUG_PORT são reservadas. Marque uma coluna como secret: true\ para senhas: ela é armazenada e fornecida a scripts aprovados, mas nenhuma ferramenta a retorna. Linhas ruins são relatadas em rejected\ por número de linha (a partir de 1). Retorna datasetId\.

ParâmetroTipoObrigatórioDescrição
columnsobject[]sim
modestringsim
namestringsim
rowsobject[]nãoUm objeto por linha, com chave pelo nome da coluna; todo valor deve ser uma string — converta números e datas em texto antes de enviar
rows_per_runintegernão

append_dataset_rows

Adicione linhas a um conjunto de dados, no mesmo formato do rows\ de create_dataset. Linhas ruins são relatadas em rejected\ por número de linha e não bloqueiam as boas.

ParâmetroTipoObrigatórioDescrição
dataset_idstringsimUUID do conjunto de dados
rowsobject[]simUm objeto por linha, com chave pelo nome da coluna; todo valor deve ser uma string — converta números e datas em texto antes de enviar

list_datasets

Liste conjuntos de dados: id, nome, modo, colunas com sua flag de segredo, rowsPerRun, contagens de linhas (total e atribuídas para fixo; disponíveis, reservadas e usadas para consumo) e quantos perfis usam cada um. Nunca retorna valores de linhas.

get_dataset_rows

Leia as linhas de um conjunto de dados em ordem: limit\ linhas (padrão 100, no máximo 500) a partir de offset\. Cada linha tem seu índice, seus valores e, para um conjunto fixo, o perfil ao qual está atribuída; para um conjunto de consumo, seu estado. Colunas secretas são sempre omitidas de values\.

ParâmetroTipoObrigatórioDescrição
dataset_idstringsimUUID do conjunto de dados
limitintegernão
offsetintegernão

assign_dataset

Atribua um conjunto de dados a perfis existentes. Um conjunto fixo vai para o slot de Identidade de cada perfil e dá a ele uma linha não atribuída (menor índice primeiro); perfis sem linha são nomeados em withoutRow\ e não recebem nada — nunca compartilhe uma conta entre perfis. Um conjunto de consumo vai para o slot de Conteúdo. Recusa a chamada inteira se um perfil já tiver um conjunto de dados diferente nesse slot, a menos que force: true; recusa nomes de colunas que também existam no conjunto de dados no outro slot do perfil. Toda execução posterior de um script APROVADO nesses perfis carrega os dados; agendamentos e run_batch não precisam de novo campo.

ParâmetroTipoObrigatórioDescrição
dataset_idstringsimUUID do conjunto de dados
forcebooleannãoSubstitui um conjunto de dados já no slot. Padrão false
profile_idsstring[]sim

unassign_dataset

Remova um conjunto de dados dos perfis. Para um conjunto fixo, suas linhas voltam a ficar não atribuídas. Ids de perfis que não existem mais são aceitos, para que linhas mantidas por perfis excluídos possam ser liberadas.

ParâmetroTipoObrigatórioDescrição
dataset_idstringsimUUID do conjunto de dados
profile_idsstring[]sim

reset_dataset_rows

Para um conjunto de consumo: coloque toda linha usada de volta como disponível, para que execuções as peguem novamente. Retorna quantas linhas foram alteradas.

ParâmetroTipoObrigatórioDescrição
dataset_idstringsimUUID do conjunto de dados