O que cli-anything-safari faz?
Uma interface de linha de comando para automação do navegador Safari no macOS. Encapsula
o servidor MCP Node.js safari-mcp
em uma CLI Python Click.
A paridade de recursos é garantida. Cada comando Click é gerado
automaticamente a partir do esquema de ferramentas do safari-mcp (incluído como
resources/tools.json). Todos os 84 recursos são acessíveis com os
nomes e tipos de argumentos exatos que o servidor MCP espera.
Quando usar esta CLI
Cada invocação da CLI inicia um novo subprocesso, portanto há uma
sobrecarga por chamada. Se o seu agente falar MCP nativamente (Claude Code, Cursor,
Cline, etc.), usar o safari-mcp diretamente via MCP stdio será mais rápido.
Use esta CLI quando:
- Seu framework de agente não falar MCP (Codex CLI, GitHub Copilot CLI, scripts personalizados, frameworks de agente mais antigos).
- Você precisar criar scripts de automação do navegador a partir do bash —
cli-anything-safari --json tool snapshot | jq '...'. - Você executar em CI/CD e quiser saída amigável para subprocessos e agendável.
- Você estiver depurando interativamente a partir do Terminal.
Instalação
Pré-requisitos
- macOS — Safari MCP é exclusivo para macOS.
- Safari — já instalado no macOS.
- Node.js 18+ —
brew install nodeou em https://nodejs.org/ - Python 3.10+
- Habilitar Apple Events para o Safari: Safari → Desenvolver → Permitir JavaScript de Apple Events
Instalar a CLI
cd safari/agent-harness
pip install -e .
A primeira chamada ao comando tool baixará o pacote npm safari-mcp (uma vez, alguns MB).
Estrutura de Comandos
A CLI possui 5 comandos de nível superior:
| Comando | Finalidade |
|---|---|
tool | Chamar qualquer um dos 84 recursos do safari-mcp (dinâmico, orientado por esquema) |
tools | Inspecionar o registro de ferramentas incluído (list, describe, count) |
raw | Saída de emergência — chamar um recurso pelo nome completo com argumentos JSON brutos |
session | Estado da sessão em memória (último URL, aba atual) |
repl | REPL interativo (padrão quando nenhum subcomando é fornecido) |
Exemplos de Uso
Descobrir a superfície de ferramentas
# Contagem de ferramentas (verificação de sanidade — deve corresponder às ferramentas registradas do safari-mcp)
cli-anything-safari tools count
# → 84
# Listar cada ferramenta
cli-anything-safari tools list
cli-anything-safari tools list --filter click # filtrar por substring
# Esquema completo para uma ferramenta (formato JSON ou legível)
cli-anything-safari tools describe safari_scroll
cli-anything-safari --json tools describe safari_click
Chamar um recurso (orientado por esquema)
# Navegar
cli-anything-safari tool navigate --url https://example.com
# Tirar um snapshot (preferível a screenshot — texto estruturado com IDs de referência)
cli-anything-safari --json tool snapshot
# Clicar por referência (as referências vêm do snapshot; expiram no próximo snapshot!)
cli-anything-safari tool click --ref 0_5
# Clicar por seletor ou texto visível
cli-anything-safari tool click --selector "#submit"
cli-anything-safari tool click --text "Log in"
# Preencher um campo
cli-anything-safari tool fill --selector "#email" --value "[email protected]"
# Rolar por direção/quantidade (NÃO x/y — observe o esquema!)
cli-anything-safari tool scroll --direction down --amount 500
# Arrastar um elemento sobre outro
cli-anything-safari tool drag \
--source-selector ".card" \
--target-selector ".trash"
# Screenshot — retorna JPEG base64 na saída padrão. Decodifique com:
cli-anything-safari --json tool screenshot --full-page \
| python3 -c "import sys,json,base64; \
d=json.load(sys.stdin); \
open('/tmp/shot.jpg','wb').write(base64.b64decode(d['data']))"
# Salvar como PDF (este escreve diretamente no disco)
cli-anything-safari tool save-pdf --path /tmp/page.pdf
# Avaliar JavaScript (nota: o parâmetro é --script, não --code)
cli-anything-safari tool evaluate --script "document.title"
Navegar e ler em uma única viagem de ida e volta
cli-anything-safari --json tool navigate-and-read --url https://example.com
Preenchimento de formulário (em lote)
safari_fill_form recebe um array de objetos {selector, value}.
Passe-o como uma string JSON:
cli-anything-safari tool fill-form --fields '[
{"selector": "#email", "value": "[email protected]"},
{"selector": "#password", "value": "hunter2"}
]'
Execute cli-anything-safari tools describe safari_fill_form para ver o
esquema exato, incluindo quaisquer novos campos que o safari-mcp adicionar upstream.
Monitoramento de rede
cli-anything-safari tool start-network-capture
cli-anything-safari tool navigate --url https://example.com
cli-anything-safari --json tool network
cli-anything-safari tool performance-metrics
Armazenamento
cli-anything-safari tool get-cookies
cli-anything-safari tool set-cookie --name session --value abc123 --domain example.com
cli-anything-safari tool local-storage --key theme
# export-storage retorna JSON para a saída padrão — sem argumento --path. Pipe para um arquivo:
cli-anything-safari --json tool export-storage > /tmp/storage.json
Saída de emergência com JSON bruto
Quando você precisar passar um objeto aninhado complexo ou quiser usar a CLI a partir de um blob JSON pré-construído:
cli-anything-safari raw safari_evaluate \
--json-args '{"code":"[...document.querySelectorAll(\"a\")].map(a => a.href)"}'
REPL Interativo
cli-anything-safari
O banner do REPL imprime o caminho absoluto para este SKILL.md para que os agentes possam descobrir capacidades por conta própria.
Saída JSON
Todos os comandos suportam --json como uma flag global:
cli-anything-safari --json tool snapshot
cli-anything-safari --json tool list-tabs
cli-anything-safari --json tools list
Gerenciamento de Estado
A CLI mantém uma pequena quantidade de estado em memória apenas para exibição no REPL:
last_url— último URL para o qual a CLI navegou (atualizado após cadatool navigate,tool navigate-and-readoutool new-tabbem-sucedido)current_tab_index— último índice de aba ativa conhecido
Não há nenhuma sessão persistente, nenhum desfazer/refazer, nenhum modelo de documento.
Cada invocação da CLI começa com estado novo. O próprio Safari MCP é sem estado
por chamada: cada comando tool inicia um novo subprocesso npx safari-mcp,
realiza a ação e sai. Esta é uma escolha de design deliberada; veja HARNESS.md e TEST.md para a
lógica por trás do desvio do padrão de desfazer/refazer.
Formatos de Saída
Todos os comandos suportam dois modos de saída:
- Legível por humanos (padrão): texto chave-valor indentado para resultados
dict, listas com marcadores para arrays, texto simples caso contrário - Legível por máquina (flag
--json): JSON estruturado para consumo por agentes
# Saída humana
cli-anything-safari tool snapshot
# Saída JSON para agentes
cli-anything-safari --json tool snapshot
cli-anything-safari --json tools list
cli-anything-safari --json tools describe safari_click
Para Agentes de IA
Ao usar esta CLI programaticamente:
- Sempre use a flag
--jsonpara saída analisável. - Verifique os códigos de retorno — 0 para sucesso, diferente de zero para erros (falhas de validação de URL, falhas de chamada MCP, argumentos JSON inválidos).
- Analise o stderr para mensagens de erro; use stdout para dados.
- Ferramentas de manipulação de arquivos têm nomes de argumentos de caminho inconsistentes — sempre
verifique
tools describe <name>primeiro:tool save-pdf --path /tmp/x.pdftool upload-file --selector ... --file-path /tmp/x.txt(nota:--file-path, não--path)tool export-storage— sem argumento de caminho; pipe a saída JSON para um arquivotool import-storage --path /tmp/x.jsontool screenshot/screenshot-element— retornam base64 na resposta JSON, sem argumento de caminho (decodifique você mesmo)
- Snapshot antes de clicar — as referências de
tool snapshotexpiram no próximo snapshot. Sempre faça snapshot → encontre referência → clique em sucessão próxima. - Descubra ferramentas via
tools list— o registro incluído é a fonte da verdade para o que está disponível. Não codifique nomes de ferramentas que podem mudar upstream. - Use
tools describe <name>para aprender o esquema exato (argumentos obrigatórios, opções de enumeração, argumentos tipados como JSON) antes de construir uma chamada. Nunca presuma nomes de parâmetros a partir da descrição — por exemplo,safari_evaluaterecebe--script(não--code) mesmo que a descrição diga "Código JavaScript para executar".
Orientação Específica para Agentes
Encontrando a ferramenta certa
Use os comandos de introspecção. A CLI garante refletir o servidor MCP 1:1:
# Encontrar todas as ferramentas relacionadas a clique
cli-anything-safari tools list --filter click
# Obter o esquema completo (incluindo cada argumento com tipo, descrição,
# obrigatório/opcional, opções de enumeração, padrões)
cli-anything-safari --json tools describe safari_click
Estratégia de seleção de ferramentas
tool snapshotem vez detool screenshot— texto estruturado com IDs de referência é ordens de magnitude mais barato e carrega as referências necessárias para cliques.tool click --refem vez detool click --selector— referências são estáveis dentro de um único snapshot, seletores podem ser frágeis.tool navigate-and-readem vez denavigate+read-page— economiza uma viagem de ida e volta.tool click-and-readem vez declick+read-page— economiza uma viagem de ida e volta.tool native-clickapenas quando o clique normal falha com 405/403 (bloqueios de WAF, G2, Cloudflare) — ele move fisicamente o cursor.
Referências Expirando
As referências de tool snapshot expiram quando você tira um novo snapshot:
- Primeiro snapshot: referências
0_1,0_2,0_3... - Segundo snapshot: referências
1_1,1_2,1_3...
Sempre faça snapshot → clique em sucessão próxima. Em caso de dúvida, faça outro snapshot.
Segurança de Propriedade de Aba
O Safari MCP rastreia a propriedade de abas por sessão. Ferramentas que modificam uma aba
(navegar, clicar, preencher) são bloqueadas em abas que a sessão não abriu.
Para operar em uma página específica, sempre comece com tool new-tab --url ....
Tratamento de Erros
Erros comuns:
npx not found→ instale Node.js 18+safari-mcp package not found on npm registry→ verifique a redeNot macOS→ o harness é exclusivo para macOSAppleScript denied→ habilite "Allow JavaScript from Apple Events" no Safari → DesenvolverBlocked URL scheme: file→ a validação de URL rejeitou a entrada (por design)
Validação de URL
A CLI valida URLs antes de passá-los para safari_navigate,
safari_navigate_and_read e safari_new_tab. Esquemas bloqueados:
file, javascript, data, vbscript, about, chrome, safari,
webkit, x-apple e outros esquemas internos do navegador. O comando
raw também aplica esta validação para ferramentas de navegação.
Aviso de Multi-Sessão
O Safari MCP impõe uma única sessão ativa eliminando processos Node.js
obsoletos com mais de 10 segundos. Se você executar duas instâncias da CLI ao mesmo tempo,
uma eliminará o backend da outra. Atualmente não há modo daemon
— para fluxos de trabalho sensíveis à latência, use a CLI a partir de um
script Python de longa duração que importe
cli_anything.safari.utils.safari_backend.call() diretamente para evitar
reiniciar o subprocesso a cada invocação.
Links
Considerações de Segurança
Validação de URL
Todas as ferramentas de navegação (tool navigate, tool navigate-and-read, tool new-tab e raw safari_navigate*) passam o argumento url através de
utils/security.py que bloqueia esquemas perigosos e opcionalmente bloqueia
redes privadas (defina CLI_ANYTHING_SAFARI_BLOCK_PRIVATE=1).
Isolamento de Abas
O Safari MCP impõe propriedade de abas por sessão upstream — ferramentas não podem operar em abas que a sessão não abriu.
Isolamento de Perfil
Defina a variável de ambiente SAFARI_PROFILE para usar um perfil Safari separado para
a automação:
export SAFARI_PROFILE="Automation"
cli-anything-safari tool navigate --url https://example.com
Isso mantém cookies/logins/histórico separados da navegação principal do usuário.
Execução de JavaScript
tool evaluate e tool run-script executam JavaScript arbitrário no contexto
da página. Trate entradas não confiáveis com o mesmo cuidado de qualquer caminho
de execução de código dinâmico.
Área de Transferência
tool clipboard-read e tool clipboard-write acessam a área de transferência
do sistema. Tenha cuidado ao executar dentro de uma sessão ativa do usuário —
sobrescrever a área de transferência no meio de uma tarefa é perturbador.
Regenerando o registro de ferramentas
Se você atualizar o safari-mcp, regenere o esquema incluído:
python scripts/extract_tools.py \
"$(npm root -g)/safari-mcp/index.js" \
cli_anything/safari/resources/tools.json
O teste de paridade (test_parity.py) fixa a contagem esperada de ferramentas; atualize-o
quando a lista de ferramentas upstream mudar.
Mais Informações
- Documentação completa:
cli_anything/safari/README.mdno pacote - Cobertura de teste:
cli_anything/safari/tests/TEST.mdno pacote - Análise de arquitetura:
safari/agent-harness/SAFARI.md - Metodologia:
cli-anything-plugin/HARNESS.md - Padrão de backend MCP:
cli-anything-plugin/guides/mcp-backend.md
Versão
1.0.0 — direciona safari-mcp 2.7.8 (84 ferramentas). O registro de ferramentas incluído é
regenerado via scripts/extract_tools.py quando o safari-mcp é atualizado.