Safari MCP
Automação nativa do navegador Safari para agentes de IA — 80 ferramentas via AppleScript, zero sobrecarga do Chrome, mantém logins. Apenas macOS.
Documentação
🦁 Safari MCP
O navegador para o seu agente de codificação.
Seu Safari real, com login feito — sem Chrome, sem aquecimento, sem headless.
Instalar no VS Code · VS Code Insiders · Instalar no Cursor
98 ferramentas · Sem necessidade de Chrome/Puppeteer/Playwright · ~5ms por comando · 60% menos CPU que o Chrome
Início Rápido · Todas as 98 Ferramentas · Exemplos · Por que Safari MCP? · Arquitetura · Changelog

❌ Sem Safari MCP
Seu agente de IA precisa navegar. Então ele:
- Inicia Chromium via Playwright — sem logins, sem cookies, sem sessões
- Usa Chrome DevTools MCP — e derrete o ventilador do seu computador rodando um segundo navegador
- Depende de scrapers headless — bloqueados por Cloudflare, reCAPTCHA e detecção de bots
✅ Com Safari MCP
Sua IA controla o Safari no qual você já está logado — Gmail, GitHub, Ahrefs, Slack, banco.
WebKit nativo. ~60% menos CPU. Operação em segundo plano. 98 ferramentas. Um único comando npx. Apenas macOS.
📰 Destaque no freeCodeCamp: Como Conectar Seu Agente de Codificação de IA a um Navegador no macOS · HackerNoon: Reverse-Engineering React, Shadow DOM e CSP
🍎 A Apple lança um Safari MCP oficial —
safaridriver --mcp, primeiro no Safari Technology Preview 247 (julho de 2026) e no Safari estável desde a versão 27.0. Ele controla uma sessão de automação isolada para depuração. O safari-mcp controla o Safari real no qual você já está logado — seus cookies e sessões, em segundo plano, com 98 ferramentas. Veja a comparação completa abaixo.
Destaques
- 98 ferramentas — navegação, cliques, formulários, capturas de tela, rede, armazenamento, acessibilidade e muito mais
- Zero aquecimento — WebKit nativo em Apple Silicon, ~60% menos CPU que o Chrome
- Seu navegador real — mantém todos os logins, cookies e sessões (Gmail, GitHub, Ahrefs, etc.)
- Operação em segundo plano — o Safari permanece em segundo plano, sem roubar a janela
- Sem dependências de navegador — sem Puppeteer, sem Playwright, sem WebDriver, sem Chrome
- Processo persistente — reutiliza um único processo osascript (~5ms por comando vs ~80ms)
- Compatível com frameworks — preenchimento de formulários em React, Vue, Angular, Svelte via setters nativos
Nas palavras dos usuários
Depoimentos não solicitados — citações retiradas do rastreador de issues público, cada uma com link para o tópico de origem.
"Eu executo múltiplas sessões de Pi/subagentes contra meu perfil normal do Safari em paralelo. Compartilhar seus cookies e logins é intencional." — @maxim, sobre executar agentes concorrentes contra um navegador real
"O servidor tem um modelo deliberado de propriedade de abas … o código é cuidadoso com isso, e para o caso padrão essa é a postura de segurança correta." — @turner-moore, sobre por que as proteções se recusam a tocar nas suas abas
"Validação local direta do pacote: Safari MCP doctor 6/6." — @jrepp, que encontrou e corrigiu um bug de alinhamento de fila no helper de foco
Início Rápido
Pré-requisitos
- macOS (qualquer versão com Safari)
- Node.js 20+
- Safari → Ajustes → Avançado → Mostrar recursos para desenvolvedores web ✓
- Safari → Ajustes → Desenvolvedor → Permitir JavaScript de Apple Events ✓
Instalar (um comando)
npx safari-mcp
É isso — sem necessidade de instalação global. Ou instale permanentemente:
npm install -g safari-mcp
Configurar seu cliente MCP
Todos os clientes executam o Safari MCP da mesma forma — npx safari-mcp. Escolha seu editor:
Claude Code
claude mcp add safari -- npx safari-mcp
Ou edite ~/.mcp.json:
{
"mcpServers": {
"safari": {
"command": "npx",
"args": ["safari-mcp"]
}
}
}
Claude Desktop
Edite ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"safari": {
"command": "npx",
"args": ["safari-mcp"]
}
}
}
Reinicie o Claude Desktop após salvar.
Cursor
Com um clique: Instalar no Cursor
Ou edite .cursor/mcp.json no seu projeto:
{
"mcpServers": {
"safari": {
"command": "npx",
"args": ["safari-mcp"]
}
}
}
VS Code / VS Code Insiders
Com um clique: Instalar no VS Code
Ou edite .vscode/mcp.json:
{
"servers": {
"safari": {
"type": "stdio",
"command": "npx",
"args": ["safari-mcp"]
}
}
}
Windsurf
Edite .windsurf/mcp.json no seu projeto (ou ~/.codeium/windsurf/mcp_config.json globalmente):
{
"mcpServers": {
"safari": {
"command": "npx",
"args": ["safari-mcp"]
}
}
}
Cline
Abra o Cline no VS Code → clique no ícone MCP → Editar Configurações MCP → adicione:
{
"mcpServers": {
"safari": {
"command": "npx",
"args": ["safari-mcp"]
}
}
}
Continue
Edite ~/.continue/config.yaml (ou .continue/config.yaml no workspace):
mcpServers:
- name: safari
command: npx
args:
- safari-mcp
Goose
Edite ~/.config/goose/config.yaml:
extensions:
safari:
name: safari
type: stdio
cmd: npx
args:
- safari-mcp
enabled: true
LM Studio
Abra o LM Studio → Configurações → Servidores MCP → Adicionar Servidor:
- Nome:
safari - Comando:
npx - Args:
safari-mcp
Zed
Abra o Zed → Configurações → pesquise por "Context Servers" e adicione:
{
"context_servers": {
"safari": {
"command": {
"path": "npx",
"args": ["safari-mcp"]
}
}
}
}
Alternativa: Homebrew
brew install achiya-automation/tap/safari-mcp
Alternativa: a partir do código-fonte
git clone https://github.com/achiya-automation/safari-mcp.git
cd safari-mcp && npm install
Fluxo de Trabalho de Uso
O padrão recomendado para agentes de IA usando Safari MCP:
1. safari_snapshot → Get page state (accessibility tree)
2. safari_click/fill/... → Interact with elements by ref
3. safari_snapshot → Verify the result
Segmentação de elementos — as ferramentas aceitam múltiplas estratégias de segmentação:
| Estratégia | Exemplo | Melhor para |
|---|---|---|
| Seletor CSS | #login-btn, .submit | Elementos únicos |
| Texto visível | "Sign In", "Submit" | Botões, links |
| Coordenadas | x: 100, y: 200 | Canvas, widgets personalizados |
| Ref do snapshot | ref: "e42" | Qualquer elemento da árvore de acessibilidade |
Dica: Comece com
safari_snapshotpara obter refs de elementos e depois use refs para segmentação precisa. Isso é mais rápido e confiável do que seletores CSS.
Executando vários agentes ao mesmo tempo
Vários agentes ou subagentes controlando um único Safari ao mesmo tempo vão disputar a aba ativa — a menos que você os execute contra um daemon HTTP compartilhado em vez de um processo por cliente:
SAFARI_MCP_HTTP=1 SAFARI_MCP_HTTP_PORT=9225 npx safari-mcp
Depois aponte cada cliente para ele:
{ "mcpServers": { "safari-mcp": { "type": "http", "url": "http://127.0.0.1:9225/mcp" } } }
Um daemon, muitas sessões — e cada sessão tem seu próprio estado de aba. O servidor vincula activeTabIndex, o sinalizador de propriedade e um marcador de aba exclusivo ao ID da sessão MCP, então a sessão A fisicamente não consegue ler ou direcionar a aba da sessão B.
Duas propriedades tornam isso seguro em vez de apenas organizado:
-
A identidade da aba é um marcador, não um índice. Cada sessão grava um ID exclusivo na página que abre, então a propriedade sobrevive à navegação e sobrevive ao usuário reordenar ou fechar outras abas. Um índice sozinho deslizaria silenciosamente para a aba errada.
-
Falha de forma segura. Se a aba marcada de uma sessão não puder ser encontrada novamente, todas as ferramentas se recusam em vez de recorrer a qualquer aba que esteja na frente — porque essa aba geralmente é sua:
Tab tracking lost — refusing to fall back to "current tab of window" (would target the user's active tab). Call safari_new_tab to reopen.
Isso também reduz drasticamente o número de processos: ~17 processos node para 17 sessões concorrentes vira 1.
SAFARI_PROFILE continua opcional — deixe sem definir e as sessões se vinculam às suas janelas normais do Safari, com cookies e logins intactos. Detalhes em docs/http-transport-design.md.
Prefere stdio (um processo por agente) em vez de um daemon persistente? Isso também funciona — o isolamento então vem do próprio limite do processo. Uma ressalva: se seu cliente multiplexa agentes via mcporter, o mcporter armazena em cache um único cliente MCP para todos eles — independentemente do transporte escolhido — então o servidor nunca vê sessões distintas e o isolamento por sessão não pode ser ativado. mcporter-lanes (uma extensão pi por @maxim, nascida da #76) corrige isso upstream: cada sessão de agente recebe seu próprio diretório de daemon — e, portanto, seu próprio safari-mcp — com um timeout de inatividade para que os processos não se acumulem.
Agindo em uma aba que você já tem aberta
Por padrão, o servidor toca apenas nas abas que ele mesmo abriu. Aponte-o para uma das suas e ele se recusa:
Tab safety: refusing "click" — current tab (https://mail.example.com/inbox) was not
opened by this MCP session. Use safari_new_tab or safari_switch_tab to target your own tab.
Esse padrão existe porque versões antigas realmente clicavam e fechavam as abas das pessoas. Mas "ler o artigo que estou vendo" e "preencher o formulário na minha tela" são casos reais, e reabrir a página perde o estado da sessão que tornou sua aba útil. Defina SAFARI_MCP_ALLOW_USER_TABS=1 e um safari_switch_tab explícito adota a aba em vez de recusá-la; a partir daí, a sessão trabalha nela como se fosse uma das suas, e informa isso:
{ "tabIndex": 3, "safeUrl": "https://mail.example.com/inbox", "note": "(user tab, opted-in)" }
O que o sinalizador deliberadamente não faz:
- Ele libera a adoção, não as proteções. Apenas
safari_switch_tabadota, e apenas a aba que você nomeou. Um clique ou navegação comum nunca cai em qualquer aba que esteja na frente — o servidor age na aba para a qual você o apontou, não naquela para a qual você navegou. safari_close_tabainda se recusa. Fechar é a única ação cujo custo você não pode desfazer, então uma aba adotada é gravável, nunca descartável. Feche-a você mesmo.- A adoção é local à sessão. Nada é gravado no arquivo de propriedade compartilhado, então ela termina com a sessão em vez de vazar para o próximo processo na máquina.
safari_doctor imprime o estado do sinalizador, e toda operação em uma aba adotada registra (user tab, opted-in) — então "por que tocou na minha aba" tem uma resposta em vez de ser um mistério. Desativado por padrão; defina-o apenas para agentes com os quais você quer trabalhar dentro da sua própria sessão de navegação. Projetado em #92.
Variáveis de ambiente
| Variável | Padrão | O que faz |
|---|---|---|
SAFARI_MCP_HTTP | desligado | Executa um daemon HTTP compartilhado em vez de um processo por cliente (veja acima). |
SAFARI_MCP_HTTP_PORT | 9225 | Porta para esse daemon. |
SAFARI_PROFILE | não definido | Vincula sessões a um perfil Safari nomeado. Não definido = suas janelas normais. |
SAFARI_MCP_ALLOW_USER_TABS | desligado | Permite que safari_switch_tab adote uma aba que você já tinha aberta, em vez de recusá-la (veja abaixo). |
MCP_MAX_TABS | 6 | Abas que uma sessão pode manter abertas. Abrir mais uma fecha a aba mais antiga da sessão, e safari_new_tab a nomeia em evictedTab (seu recibo). |
SAFARI_MCP_RAISE_ON_NAVIGATE | desligado | Permite que a navegação traga o Safari para a frente e impede que a proteção de foco coloque seu aplicativo anterior de volta. |
SAFARI_MCP_SCREENSHOT_MAX_WIDTH | não definido | Reduz cada safari_screenshot para esta largura em pixels (capturas Retina são 2× a viewport). maxWidth por chamada o substitui. |
SAFARI_MCP_KEEPALIVE_TAB | desligado | Mantém uma página servida pelo daemon aberta na janela do perfil para que o Safari nunca estacione o worker da extensão entre comandos. |
SAFARI_MCP_OPEN_WINDOW_CMD | não definido | Comando executado com o nome do perfil quando a janela do perfil está ausente (por exemplo, após uma reinicialização). Deve abrir a janela sem focar o Safari. |
SAFARI_MCP_RAISE_ON_NAVIGATE=1 é para agentes cujo objetivo principal é mostrar uma página — um assistente de voz respondendo "abrir YouTube", um driver de demonstração. Todo o resto deve deixá-lo desligado: por padrão, o Safari MCP trabalha em segundo plano e devolve o foco para o aplicativo que você estava usando, então um agente pode controlar uma página enquanto você continua digitando em outro lugar.
Ferramentas (98)
Clique para expandir a lista completa de ferramentas — organizada por categoria
Navegação (4)
| Ferramenta | Descrição |
|---|---|
safari_navigate | Navegar para URL (HTTPS automático, aguarda carregamento) |
safari_go_back | Voltar no histórico |
safari_go_forward | Avançar no histórico |
safari_reload | Recarregar página (recarga forçada opcional) |
Leitura de Página (3)
| Ferramenta | Descrição |
|---|---|
safari_read_page | Obter título, URL e conteúdo de texto |
safari_get_source | Obter código-fonte HTML completo |
safari_navigate_and_read | Navegar + ler em uma única chamada |
Clique e Interação (6)
| Ferramenta | Descrição |
|---|---|
safari_click | Clicar por seletor CSS, texto visível ou coordenadas |
safari_double_click | Duplo clique (selecionar palavra, etc.) |
safari_right_click | Clique direito (menu de contexto) |
safari_hover | Passar o cursor sobre o elemento |
safari_click_and_wait | Clicar + aguardar navegação |
safari_click_and_read | Clicar e retornar a página atualizada — economiza uma ida e volta (React Router + carregamentos completos) |
Entrada de Formulário (11)
| Ferramenta | Descrição |
|---|---|
safari_fill | Preencher campo de entrada (compatível com React/Vue/Angular) |
safari_clear_field | Limpar campo de entrada |
safari_select_option | Selecionar opção de menu suspenso |
safari_fill_form | Preencher vários campos em lote |
safari_fill_and_submit | Preencher formulário + enviar em uma única chamada |
safari_type_text | Digitar teclas reais (baseado em JS, sem Eventos do Sistema) |
safari_press_key | Pressionar tecla com modificadores |
safari_react_select_set | Definir valor react-select v5 via React fiber — ignora a interface do menu |
safari_react_select_list_options | Listar opções de um menu suspenso react-select v5 sem abri-lo |
safari_replace_editor | Substituir todo o conteúdo em um editor de código (Monaco, CodeMirror, Ace, ProseMirror) |
safari_verify_state | Verificar se o estado do editor no nível do framework corresponde ao esperado — detecta DOM desatualizado antes do Envio |
Capturas de Tela e PDF (3)
| Ferramenta | Descrição |
|---|---|
safari_screenshot | Captura de tela como PNG (viewport ou página inteira) |
safari_screenshot_element | Captura de tela de um elemento específico |
safari_save_pdf | Exportar página como PDF |
Rolagem (3)
| Ferramenta | Descrição |
|---|---|
safari_scroll | Rolar para cima/baixo por pixels |
safari_scroll_to | Rolar para posição exata |
safari_scroll_to_element | Rolagem suave até o elemento |
Gerenciamento de Abas (5)
| Ferramenta | Descrição |
|---|---|
safari_list_tabs | Listar todas as abas (índice, título, URL) |
safari_new_tab | Abrir nova aba (em segundo plano, sem roubar o foco) |
safari_close_tab | Fechar aba |
safari_switch_tab | Alternar para aba por índice |
safari_wait_for_new_tab | Aguardar nova aba (ex.: popup OAuth) e alternar automaticamente para ela |
Aguardar (2)
| Ferramenta | Descrição |
|---|---|
safari_wait_for | Aguardar elemento, texto ou mudança de URL |
safari_wait | Aguardar milissegundos especificados |
JavaScript (3)
| Ferramenta | Descrição |
|---|---|
safari_evaluate | Executar JavaScript arbitrário, retornar resultado |
safari_eval_file | Executar JavaScript lido de um caminho de arquivo (evita scripts inline enormes) |
safari_list_frames | Listar todos os documentos na aba (página principal + cada iframe) com frameId, URL e tamanho do texto — passe um frameId para safari_evaluate's frame para executar dentro de um iframe de origem cruzada |
Inspeção de Elementos (4)
| Ferramenta | Descrição |
|---|---|
safari_get_element | Detalhes do elemento (tag, retângulo, atributos, visibilidade) |
safari_query_all | Encontrar todos os elementos correspondentes |
safari_get_computed_style | Estilos CSS calculados |
safari_detect_forms | Detectar automaticamente todos os formulários com seletores de campo |
Acessibilidade (2)
| Ferramenta | Descrição |
|---|---|
safari_accessibility_snapshot | Árvore de acessibilidade completa: papéis, ARIA, elementos focáveis |
safari_snapshot | Árvore de acessibilidade com IDs de referência para cada elemento interativo — forma preferida de ver o estado da página |
Arrastar e Soltar (1)
| Ferramenta | Descrição |
|---|---|
safari_drag | Arrastar entre elementos ou coordenadas |
Operações de Arquivo (2)
| Ferramenta | Descrição |
|---|---|
safari_upload_file | Enviar arquivo via JS DataTransfer (sem diálogo de arquivo!) |
safari_paste_image | Colar imagem no editor (sem tocar na área de transferência!) |
Diálogo e Janela (2)
| Ferramenta | Descrição |
|---|---|
safari_handle_dialog | Lidar com alerta/confirmação/prompt |
safari_resize | Redimensionar janela do navegador |
Emulação de Dispositivo (2)
| Ferramenta | Descrição |
|---|---|
safari_emulate | Emular dispositivo (iPhone, iPad, Pixel, Galaxy) |
safari_reset_emulation | Redefinir para desktop |
Cookies e Armazenamento (11)
| Ferramenta | Descrição |
|---|---|
safari_get_cookies | Obter todos os cookies |
safari_set_cookie | Definir cookie com todas as opções |
safari_delete_cookies | Excluir um ou todos os cookies |
safari_local_storage | Ler localStorage |
safari_set_local_storage | Escrever localStorage |
safari_delete_local_storage | Excluir/limpar localStorage |
safari_session_storage | Ler sessionStorage |
safari_set_session_storage | Escrever sessionStorage |
safari_delete_session_storage | Excluir/limpar sessionStorage |
safari_export_storage | Exportar todo o armazenamento como JSON (backup/restauração de sessões) |
safari_import_storage | Importar estado de armazenamento de JSON |
Área de Transferência (2)
| Ferramenta | Descrição |
|---|---|
safari_clipboard_read | Ler texto da área de transferência |
safari_clipboard_write | Escrever texto na área de transferência |
Rede (6)
| Ferramenta | Descrição |
|---|---|
safari_network | Requisições de rede rápidas via API de Performance |
safari_start_network_capture | Iniciar captura detalhada (fetch + XHR) |
safari_network_details | Obter requisições capturadas com cabeçalhos/temporização |
safari_clear_network | Limpar requisições capturadas |
safari_mock_route | Simular respostas de rede (interceptar fetch/XHR) |
safari_clear_mocks | Remover todas as simulações de rede |
Console (4)
| Ferramenta | Descrição |
|---|---|
safari_start_console | Iniciar captura de mensagens do console |
safari_get_console | Obter todas as mensagens capturadas |
safari_clear_console | Limpar mensagens capturadas |
safari_console_filter | Filtrar por nível (log/aviso/erro) |
Desempenho (2)
| Ferramenta | Descrição |
|---|---|
safari_performance_metrics | Temporização de navegação, Web Vitals, memória |
safari_throttle_network | Simular slow-3g/fast-3g/4g/offline |
Extração de Dados (4)
| Ferramenta | Descrição |
|---|---|
safari_extract_tables | Tabelas como JSON estruturado |
safari_extract_meta | Tudo sobre meta: OG, Twitter, JSON-LD, canônico |
safari_extract_images | Imagens com dimensões e informações de carregamento |
safari_extract_links | Links com detecção de rel, externo/nofollow |
Avançado (7)
| Ferramenta | Descrição |
|---|---|
safari_override_geolocation | Substituir geolocalização do navegador |
safari_list_indexed_dbs | Listar bancos de dados IndexedDB |
safari_get_indexed_db | Ler registros IndexedDB |
safari_css_coverage | Encontrar regras CSS não utilizadas |
safari_analyze_page | Análise completa da página em uma única chamada |
safari_doctor | Diagnosticar a cadeia de permissões + daemon do macOS (Apple Events, Acessibilidade, Gravação de Tela, codesign) com correções por falha |
safari_reload_extension | Recarregar a extensão Safari MCP Bridge sem alternância manual |
Automação (1)
| Ferramenta | Descrição |
|---|---|
safari_run_script | Executar várias ações em uma única chamada (lote) |
Entrada Nativa — CGEvent (4)
| Ferramenta | Descrição |
|---|---|
safari_native_click | Clique de mouse no nível do SO (CGEvent, isTrusted: true) — ignora detecção de WAF/bot quando safari_click está bloqueado (405/403) |
safari_native_hover | Passar cursor no nível do SO — aciona :hover/mouseenter reais para dicas de ferramenta e UIs ofuscadas |
safari_native_type | Inserir texto via pipeline real de colar — ProseMirror/Slate/Draft.js processam nativamente, então o Envio envia dados reais |
safari_native_keyboard | Pressionamento de tecla no nível do SO + modificadores para o Safari, sem roubar o foco — alcança manipuladores protegidos por confiança do React (envio Discord/Slack) |
Validação iOS e WebKit (4)
| Ferramenta | Descrição |
|---|---|
safari_inspect_viewport | Validar a tag <meta name=viewport> para iOS Safari (device-width, zoom/WCAG, viewport-fit) |
safari_safe_area_insets | Ler valores ao vivo de safe-area-inset + uso de viewport-fit / env() (notch / Dynamic Island) |
safari_check_pwa | Auditar prontidão para "Adicionar à Tela Inicial" / PWA do iOS (apple-touch-icon, manifest, theme-color, splash) |
safari_webkit_compat | Verificar CSS da página contra este Safari via CSS.supports() — propriedades não suportadas, prefixos -webkit- ausentes, peculiaridades conhecidas |
Segurança
O Safari MCP roda localmente no seu Mac com superfície de ataque mínima:
| Aspecto | Detalhe |
|---|---|
| Rede | Sem conexões remotas — toda comunicação é local (stdio + localhost) |
| Permissões | Permissões do sistema macOS necessárias (Gravação de Tela para capturas de tela) |
| Dados | Sem telemetria, sem análises, sem envio de dados para qualquer lugar |
| Extensão | Comunica-se apenas com as pontes de perfil locais (localhost:9224/9228/9232/9236), validadas pelo Safari |
| Código | Totalmente código aberto (MIT) — audite cada linha |
Safari MCP vs Alternativas
| Recurso | Safari MCP | Chrome DevTools MCP | Playwright MCP |
|---|---|---|---|
| CPU/Calor | 🟢 Mínimo | 🔴 Alto | 🟡 Médio |
| Seus logins | ✅ Sim | ✅ Sim | ❌ Não |
| Nativo do macOS | ✅ WebKit | ❌ Chromium | ❌ Chromium/WebKit |
| Dependências do navegador | Nenhuma | Chrome + porta de depuração | Runtime Playwright |
| Ferramentas | 98 | ~30 | ~25 |
| Envio de arquivo | JS (sem diálogo) | CDP | API Playwright |
| Colar imagem | JS (sem área de transferência) | CDP | API Playwright |
| Roubo de foco | ❌ Em segundo plano | ❌ Em segundo plano | ❌ Headless |
| Simulação de rede | ✅ | ❌ | ✅ |
| Lighthouse | ❌ | ✅ | ❌ |
| Rastreamento de desempenho | ❌ | ✅ | ❌ |
Dica: Use o Safari MCP para tarefas diárias de navegação (95% do trabalho) e o Chrome DevTools MCP apenas para auditorias de Lighthouse/Desempenho.
vs Safari MCP Oficial da Apple (safaridriver)
Em julho de 2026, a Apple lançou um servidor oficial Safari MCP construído sobre safaridriver — primeiro no Safari Technology Preview 247, e no Safari estável desde 27.0. Isso é uma ótima validação para a categoria — e ele é construído para um trabalho diferente. O servidor da Apple conduz uma sessão de automação WebDriver isolada para depuração; o safari-mcp conduz o Safari real no qual você já está logado.
No macOS 27.0 com Safari 27.0, safaridriver --help lista --mcp e seu tools/list responde com 17 entradas (verificado em 2026-09-15); o Safari 26.5.2 não tinha --mcp (verificado em 2026-07-23). Verifique sua própria máquina com safaridriver --help | grep mcp.
Executando ambos? O guia de configuração da Apple registra seu servidor sob o nome
safari-mcp(claude mcp add safari-mcp -- /usr/bin/safaridriver --mcp) — o mesmo nome deste pacote. Dê a um deles um nome diferente, ex.:claude mcp add safari-webdriver -- /usr/bin/safaridriver --mcp, para que seu cliente não sobrescreva um com o outro ou deixe você adivinhando qual servidor respondeu.
| 🦁 safari-mcp (este repositório) | Apple safaridriver --mcp | |
|---|---|---|
| Seus logins / cookies reais | ✅ Seu Safari real | ⚠️ Sessão de automação isolada — sem acesso ao AutoFill ou atividade de navegação |
| Roda em | ✅ Safari estável, todo Mac | ⚠️ Safari 27 ou posterior, ou Safari Technology Preview 247+ |
| Em segundo plano (sem roubo de foco) | ✅ Sim | ❌ Janela dedicada com banner "controlado por automação" |
Página vê navigator.webdriver | ✅ false — uma aba comum | ⚠️ true — exigido de toda sessão WebDriver |
| Ferramentas | 98 | 17 |
| Armazenamento (cookies, localStorage, IndexedDB) | ✅ 10 ferramentas | ❌ |
| Simulação de rede + limitação | ✅ Sim | ❌ Inspeção de rede somente leitura |
| Emulação de dispositivo (iPhone, iPad) | ✅ Sim | ⚠️ Apenas viewport + tipo de mídia |
| Configuração | npx safari-mcp | Ative "Permitir automação remota e agentes externos" nas configurações de Desenvolvedor do Safari e aponte seu cliente para safaridriver --mcp |
| Suporte oficial da Apple | ❌ Comunidade (MIT) | ✅ Apple, padrão WebDriver |
Sobre a linha
navigator.webdriver: o padrão WebDriver exige que toda sessão controlada remotamente relatetrue, então o servidor da Apple faz isso. O safari-mcp avalia JavaScript em uma aba comum, então ele lêfalse(verificado no Safari 27.0, 2026-09-17). Essa é a diferença se um site recusar tráfego WebDriver. Não é um recurso anti-detecção — nada mais sobre o navegador é disfarçado, e seus logins reais estão em uso, então trate cada página como se ela soubesse exatamente quem você é.
Quando o servidor da Apple é a escolha certa: você quer especificamente uma sessão limpa, padrão WebDriver, para depuração de compatibilidade no Safari 27 ou posterior. Para todo o resto — automação diária no navegador em que você já está conectado, em segundo plano — o safari-mcp foi construído exatamente para isso.
Por que Safari MCP e não os outros projetos Safari MCP?
Existem vários projetos "safari-mcp" por aí. Veja como eles se comparam:
| Recurso | 🦁 safari-mcp (este repositório) | lxman/safari-mcp-server | Epistates/MCPSafari | HayoDev/safari-devtools-mcp |
|---|---|---|---|---|
| Ferramentas | 98 | ~10 | 23 | ~15 |
| Instalação | npx safari-mcp | Manual | Binário | npx |
| Mecanismo | Duplo (Extensão + AppleScript) | WebDriver | Somente extensão | Protocolo DevTools |
| Mantém seus logins reais do Safari | ✅ Sim | ⚠️ Limitado | ✅ Sim | ❌ Sessão de depuração |
| Segundo plano (sem roubo de foco) | ✅ Sim | ❌ Não | ⚠️ Às vezes | ✅ Sim |
| Ferramentas de armazenamento (cookies, localStorage, IndexedDB) | 10 | 0 | 0 | 2 |
| Extração de dados (tabelas, meta, imagens, links) | 4 | 0 | 0 | 0 |
| Simulação de rede | ✅ Sim | ❌ Não | ❌ Não | ❌ Não |
| Emulação de dispositivo (iPhone, iPad, Pixel) | ✅ Sim | ❌ Não | ❌ Não | ❌ Não |
| Upload de arquivo (sem diálogo) | ✅ JS DataTransfer | ❌ Não | ❌ Não | ❌ Não |
| Colar imagem (sem tocar na área de transferência) | ✅ Sim | ❌ Não | ❌ Não | ❌ Não |
| Exportação PDF | ✅ Sim | ❌ Não | ❌ Não | ❌ Não |
| Captura de console | 4 ferramentas | 0 | 1 | 1 |
| Métricas de desempenho + Web Vitals | ✅ Sim | ❌ Não | ❌ Não | ⚠️ Parcial |
| Manutenção ativa | ✅ Várias versões/semana | 🟡 Esporádica | 🟡 Lenta | 🟡 Lenta |
| Licença | MIT | MIT | Nenhuma especificada | MIT |
| No Registro MCP | ✅ | ❌ | ❌ | ✅ |
| No Awesome MCP | ✅ | ❌ | ❌ | ❌ |
TL;DR — se você quer o Safari MCP mais completo, com a instalação mais suave, mais ferramentas e manutenção ativa, este é o escolhido.
Arquitetura
O Safari MCP usa uma arquitetura de mecanismo duplo — a Extensão é preferida por velocidade e capacidades avançadas, com AppleScript como fallback sempre disponível:
Claude/Cursor/AI Agent
↓ MCP Protocol (stdio)
Safari MCP Server (Node.js)
↓ ↓
Extension (HTTP) AppleScript + Swift daemon
(~5-20ms/cmd) (~5ms/cmd, always available)
↓ ↓
Content Script do JavaScript in tab N
↓ ↓
Page DOM ←←←←←←←←←← Page DOM
Principais decisões de design:
- Mecanismo duplo com fallback automático — a Extensão é preferida; se não estiver conectada, o AppleScript cuida de tudo perfeitamente
- Auxiliar Swift persistente — um processo de longa duração em vez de gerar por comando (16x mais rápido)
- Operações indexadas por aba — todo JS roda em uma aba específica por índice, nunca rouba o foco visual
- Abordagem JS-first — digitar, clicar, upload de arquivo usam eventos JavaScript (sem conflitos de teclado do System Events)
- Sem
activate— o Safari nunca é trazido para o primeiro plano
Extensão do Safari (Opcional)
A Extensão do Safari MCP é opcional, mas recomendada. Sem ela, ~80% da funcionalidade funciona apenas com AppleScript. A extensão adiciona capacidades que o AppleScript não pode fornecer:
O que a Extensão Adiciona
| Capacidade | Com Extensão | Somente AppleScript |
|---|---|---|
| Shadow DOM fechado (Reddit, Web Components) | ✅ Acesso total | ❌ Invisível |
| Sites com CSP estrito | ✅ Ignora via mundo MAIN | ❌ Frequentemente bloqueado |
| Manipulação de estado React/Vue/Angular | ✅ Profunda (Fiber, ProseMirror) | ⚠️ Básica |
| Detecção de estado de carregamento (spinners, skeletons) | ✅ Detecção inteligente | ❌ Não |
| Tratamento de diálogos (alert/confirm) | ❌ | ✅ Somente AppleScript |
| Clique nativo no nível do SO (CGEvent) | ❌ | ✅ Somente AppleScript |
| Exportação PDF | ❌ | ✅ Somente AppleScript |
Quando você precisa da extensão? Se você está automatizando SPAs modernos com shadow DOM fechado (ex.: Reddit), sites com Política de Segurança de Conteúdo estrita, ou editores com muitos frameworks (Draft.js, ProseMirror, Slate).
Instalando a Extensão
A extensão requer uma compilação única com Xcode (gratuito, incluído no macOS).
Nota para usuários npm: O diretório
xcode/não está incluído no pacote npm. Clone o repositório GitHub para compilar a partir do código-fonte.
Pré-requisitos: Xcode (instale pela App Store — gratuito)
# 1. Clone the repo (the npm package does not include the Xcode project)
git clone https://github.com/achiya-automation/safari-mcp.git
cd safari-mcp
# 2. Build a clean, Apple Development-signed app
# If needed, first choose your Team in Xcode → Signing & Capabilities.
xcodebuild -project "xcode/Safari MCP/Safari MCP.xcodeproj" \
-scheme "Safari MCP (macOS)" -configuration Release \
-allowProvisioningUpdates clean build
# 3. Locate the signed app
APP_PATH=$(find ~/Library/Developer/Xcode/DerivedData/Safari_MCP-*/Build/Products/Release -name "Safari MCP.app" -maxdepth 2 | head -1)
# 4. Re-sign safari-helper with the Apple Events entitlement
# (helps macOS surface the TCC Automation prompt reliably)
codesign --sign - --force --entitlements safari-helper.entitlements safari-helper
# 5. Open the app (needed once so Safari registers the extension)
open "$APP_PATH"
Não re-assine ad-hoc
Safari MCP.appcomcodesign --deep --sign -. Isso substitui a identidade de Desenvolvimento Apple no wrapper e na extensão incorporada; o Safari atual pode silenciosamente desativar ou marcar a extensão como removida. Se uma compilação anterior foi assinada ad-hoc, execute o comandoclean buildacima novamente.
Alternativamente, abra xcode/Safari MCP/Safari MCP.xcodeproj diretamente no Xcode, selecione seu Apple ID em Assinatura e Capacidades, e clique em Executar. Uma conta pessoal gratuita de Desenvolvedor Apple é suficiente para uso local.
Depois, no Safari:
- Safari → Ajustes → Avançado → ative Mostrar recursos para desenvolvedores web
- Safari → Ajustes → Desenvolvedor → Permitir extensões não assinadas (necessário a cada reinício do Safari)
- Safari → Ajustes → Extensões → ative Safari MCP Bridge
A extensão conecta automaticamente ao primeiro bridge local cujo perfil Safari declarado corresponde ao seu. As portas padrão do bridge são 9224, 9228, 9232 e 9236; uma configuração de perfil único normalmente usa 9224.
Nota: "Permitir extensões não assinadas" é redefinido toda vez que o Safari reinicia. Você precisará reativá-lo em Safari → Ajustes → Desenvolvedor após cada reinício. A extensão em si permanece instalada.
Status do ícone da barra de ferramentas:
- LIGADO — conectado ao servidor MCP
- DESLIGADO — desativado manualmente via popup
- (sem selo) — servidor não está rodando, reconectará automaticamente
Permissões do macOS
O Safari MCP precisa destas permissões únicas:
| Permissão | Onde | Por quê |
|---|---|---|
| JavaScript de Eventos Apple | Safari → Ajustes → Desenvolvedor | Necessário para do JavaScript |
| Automação → Safari | Ajustes do Sistema → Privacidade e Segurança → Automação | Necessário para todas as ferramentas baseadas em AppleScript |
| Gravação de Tela | Ajustes do Sistema → Privacidade e Segurança → Gravação de Tela e Áudio do Sistema | Necessário para safari_screenshot sem a extensão, e para safari_save_pdf |
| Acessibilidade (safari-helper) | Ajustes do Sistema → Privacidade e Segurança → Acessibilidade (chamado Controle de Dispositivos e Acesso a Dados no macOS 27) | Necessário para safari_native_click, safari_native_keyboard, safari_native_hover e safari_save_pdf |
Concedendo Acessibilidade ao safari-helper (necessário para safari_native_*)
As ferramentas safari_native_click, safari_native_keyboard e safari_native_hover injetam eventos CGEvent no nível do SO no Safari sem roubar o foco. O macOS exige que o binário auxiliar subjacente seja aprovado em Acessibilidade antes que esses eventos possam alcançar uma janela não em primeiro plano.
- Abra Ajustes do Sistema → Privacidade e Segurança → Acessibilidade (no macOS 27 o painel é chamado Controle de Dispositivos e Acesso a Dados).
- Clique em
+(desbloqueie com sua senha se necessário). - Navegue até o binário auxiliar e adicione-o:
- Instalação global npm:
$(npm root -g)/safari-mcp/safari-helper - Instalação npx / projeto:
./node_modules/safari-mcp/safari-helper - Clone do código-fonte:
/path/to/safari-mcp/safari-helper
- Instalação global npm:
- Certifique-se de que o interruptor ao lado dele está LIGADO.
O script pós-instalação re-assina o auxiliar com um identificador estável (com.achiya-automation.safari-mcp) para que esta permissão sobreviva a futuras atualizações — sem esse passo, cada npm update revogaria silenciosamente a aprovação porque o identificador assinado ad-hoc do binário muda a cada compilação.
Se safari_native_click relatar sucesso mas a página não reagir (nenhum evento de clique isTrusted: true dispara), o auxiliar provavelmente está sem esta aprovação. As ferramentas safari_* (não-native_) não precisam dela.
Concedendo Automação → Safari (importante para usuários de IDE)
O TCC do macOS concede a permissão de Automação ao processo pai que inicia o servidor MCP, não ao safari-mcp em si. Então você precisa conceder Automação → Safari ao aplicativo que executa Claude Code / Cursor / Windsurf — tipicamente Visual Studio Code ou Terminal.
Se o diálogo de permissão nunca aparecer automaticamente, execute este comando uma vez a partir de um Terminal que já tenha permissão de Automação:
osascript -e 'tell application "Safari" to get URL of current tab of window 1'
Essa chamada registra o aplicativo Terminal no banco de dados de Automação e então aciona o prompt para o Safari. Depois que você aprovar, chamadas MCP subsequentes de qualquer cadeia de processos filhos funcionarão.
Solução de Problemas
| Problema | Correção |
|---|---|
| "Erro AppleScript" | Ative "Permitir JavaScript de Eventos Apple" em Safari → Ajustes → Desenvolvedor |
| "Não autorizado a enviar eventos Apple para o Safari" | Conceda Automação → Safari ao seu IDE (veja acima) |
"Não autorizado" após npm update | Atualizações mudam o cdhash do binário — o macOS revoga silenciosamente a permissão de Automação. Execute novamente o one-liner osascript acima para re-conceder |
safari_native_click relata sucesso mas a página não reage | Adicione safari-helper em Ajustes do Sistema → Privacidade e Segurança → Acessibilidade (veja Concedendo Acessibilidade acima). Confirme anexando um listener click com {capture:true} no console da página — sem a concessão, nenhum evento isTrusted: true dispara |
| Capturas de tela vazias | Conceda Gravação de Tela e Áudio do Sistema ao Terminal/VS Code — ou, quando o safari-mcp roda como um LaunchAgent, ao próprio binário node (uma atualização do node via Homebrew muda seu caminho, então re-conceda após atualizar). safari_doctor nomeia o binário exato |
| Extensão ausente após ativar "Permitir extensões não assinadas" (macOS 27) | Problema conhecido do macOS 27.0 (183044008): com a configuração ativada, recompile o aplicativo da extensão (veja Instalando a Extensão) e ela aparecerá |
| Aba não encontrada | Chame safari_list_tabs para atualizar os índices das abas |
| Problemas com teclado hebraico | Toda digitação usa eventos JS — imune ao layout do teclado |
| HTTPS bloqueado | safari_navigate tenta HTTPS automaticamente primeiro, com fallback para HTTP |
| Safari rouba o foco | Certifique-se de estar na versão mais recente — newTab restaura sua aba ativa |
FAQ
Funciona com o Safari Technology Preview?
Não. Todo caminho AppleScript tem como alvo application "Safari" e o auxiliar nativo procura o bundle id com.apple.Safari, então o STP (com.apple.SafariTechnologyPreview) é um aplicativo diferente que o safari-mcp nunca aborda. Execute-o contra o Safari estável.
Note que o servidor safaridriver --mcp próprio da Apple é o que precisa do STP 247+ (ou Safari 27+) — veja Safari MCP vs Alternativas. Os dois não estão relacionados.
Ele lida com abas privadas/anonimato?
Não como um modo suportado, e não é testado. Nenhuma ferramenta abre uma janela privada, e o Safari desativa extensões na Navegação Privada a menos que você ative cada uma explicitamente, então o bridge da extensão — e tudo na coluna "Com Extensão" de Extensão do Safari (Opcional) — está desligado lá por padrão.
Se você quer uma identidade isolada, use um perfil separado do Safari: janelas de perfil são um conceito de primeira classe aqui (veja Executando vários agentes ao mesmo tempo).
Funciona com várias janelas do Safari?
Sim. As buscas por abas percorrem every window em vez de assumir a janela 1, e uma aba é fixada pelo par (index, tabCount) da sua janela, porque um índice por si só é ambíguo quando duas janelas estão abertas. As janelas de perfil são reconhecidas pela nomenclatura de janelas ProfileName — Tab Title do Safari.
O identificador confiável continua sendo o recibo que safari_new_tab retorna: passe-o para cada chamada posterior e a aba será endereçada diretamente, não importa quantas janelas se movam ao redor dela.
Quais versões do macOS são suportadas?
Qualquer macOS com Safari — o pacote declara "os": ["darwin"] e não há versão mínima do SO, e não há bloqueio de versão no código. Node.js 20+ é o requisito obrigatório ("engines": { "node": ">=20" }).
Dois lugares onde o SO realmente importa na prática:
- No macOS 27, o painel de Acessibilidade é renomeado para Controle de Dispositivos e Acesso a Dados — mesma permissão, novo nome (veja Permissões do macOS).
- Safari 26 e 27 mudaram vários comportamentos de plataforma web que ferramentas específicas consideram; esses casos são tratados, não bloqueados.
Posso executar várias instâncias simultaneamente?
Sim — é isso que Executando vários agentes ao mesmo tempo aborda. Cada sessão possui suas próprias abas, e a propriedade é rastreada por sessão, em vez de por índice de aba, então um agente não pode agir (ou fechar) uma aba que outro agente possui.
Um processo vincula a porta da ponte de extensão; os outros fazem proxy através dela e assumem a porta se esse processo sair.
Preciso manter o Safari em primeiro plano?
Não. safari_new_tab abre uma aba em segundo plano e nunca rouba o foco, e os poucos comandos que o macOS força a ativação implícita restauram seu aplicativo anterior em primeiro plano depois — com uma proteção que deixa o foco intacto se você estava digitando no Safari um momento antes.
As duas exceções são as ferramentas deliberadamente nativas — safari_native_click, safari_native_keyboard, safari_native_hover — que enviam eventos reais do SO e, portanto, chegam onde a janela em primeiro plano estiver. Não use essas enquanto estiver trabalhando em outra aba do Safari.
Como ele interage com as extensões do Safari?
Suas extensões existentes continuam funcionando normalmente; o safari-mcp controla o mesmo Safari que você usa, então bloqueadores de conteúdo e gerenciadores de senhas se comportam exatamente como fazem para você.
O safari-mcp também inclui sua própria extensão opcional. Sem ela, cerca de 80% das ferramentas ainda funcionam apenas via AppleScript; com ela, você também obtém shadow DOM fechado, sites com CSP estrito, estado profundo de frameworks e detecção de estado de carregamento. Manipulação de diálogos, cliques nativos e exportação de PDF seguem o outro caminho — esses são apenas AppleScript. A divisão completa está em Extensão do Safari (Opcional).
O que acontece se "Permitir JavaScript de Apple Events" não estiver habilitado?
Qualquer coisa que avalie JavaScript falha — safari_evaluate, safari_read_page, preenchimento de formulários, extração — enquanto ações puramente AppleScript, como abrir ou alternar abas, ainda funcionam. Essa é a causa usual de "abre a aba, mas não lê nada".
Ative em Safari → Ajustes → Avançado → Mostrar recursos para desenvolvedores web e depois Safari → Ajustes → Desenvolvedor → Permitir JavaScript de Apple Events. Ambos estão listados em Pré-requisitos. safari_doctor percorre o restante da cadeia (Automação, helper nativo, Acessibilidade, Gravação de Tela) e nomeia essa configuração na dica de correção — mas a verificação de Apple Events dele conta apenas janelas, o que a permissão de Automação sozinha satisfaz, então não falhará nesse ponto para você.
Funciona Com
O Safari MCP funciona com qualquer cliente compatível com MCP:
| Cliente | Status |
|---|---|
| Claude Code | ✅ Testado diariamente |
| Claude Desktop | ✅ Testado |
| Cursor | ✅ Testado |
| Windsurf | ✅ Compatível |
| VS Code + Continue | ✅ Compatível |
Contribuindo
PRs são bem-vindos! Veja CONTRIBUTING.md para instruções de configuração.
O código-fonte tem dois arquivos:
safari.js— camada de automação do Safari (AppleScript + JavaScript)index.js— servidor MCP com definições de ferramentas
Patrocinadores
O Safari MCP é gratuito e de código aberto. Se ele economiza seu tempo ou ciclos de CPU, considere apoiar seu desenvolvimento:
Seu apoio financia:
- 🧪 Testes em várias versões do macOS e lançamentos do Safari
- 🛠️ Novas ferramentas e recursos
- 📖 Documentação e exemplos
Suporte Comercial
Precisa integrar o Safari MCP ao seu produto ou stack de agentes? A Achiya Automation oferece:
- Correções de bugs prioritárias e desenvolvimento de ferramentas personalizadas para seu caso de uso
- Consultoria de integração — conectando o Safari MCP a sistemas de agentes de produção (Claude, Cursor, n8n, personalizados)
- Suporte a implantação privada — Safari MCP multiusuário, ambientes macOS não padronizados, CI/CD
- Workshops de treinamento para equipes de engenharia que adotam automação baseada em MCP
Criado pelo autor do Safari MCP. Inicie uma conversa →
O que os agentes desbloqueiam com o Safari MCP
Quando um agente de IA controla o Safari MCP, ele obtém coisas que um navegador headless não consegue:
- Sessões autenticadas reais — Gmail, GitHub, Ahrefs, Slack, painéis bancários já estão todos logados
- Preenchimento de formulários ciente de frameworks —
safari_fill_and_submitchama setters do React/Vue/Angular nativamente, sem adivinhar se os eventosinputdispararam - Operação em segundo plano — o agente trabalha em paralelo enquanto você continua usando seu Mac
- Uma chamada MCP por fluxo de trabalho —
safari_run_scriptagrupa navegação + cliques + extração em uma única ida e volta
O padrão se mantém entre modelos: dirija o navegador em que o humano já confia — você herda logins, cookies, extensões e o ambiente exato do usuário em uma única etapa.
Comunidade
Mais de 6.000 downloads mensais de npm — desenvolvedores estão criando agentes de IA no macOS com o Safari MCP.
- Discussões no GitHub — faça perguntas, compartilhe casos de uso
- Issues — relatórios de bugs e solicitações de recursos
— comece a contribuir
Ecossistema
Outros servidores MCP para macOS que complementam o Safari MCP:
| Projeto | O que faz | Quando usar |
|---|---|---|
| mcp-server-macos-use | Automação de macOS em nível de SO (acessibilidade, controle de tela) | Interações em todo o sistema além do Safari |
| chrome-devtools-mcp | Protocolo DevTools do Chrome | Auditorias Lighthouse, rastreamentos específicos do Chrome |
Usando o Safari MCP junto com o Chrome DevTools MCP? O Safari lida com 95% da navegação diária (zero overhead), o Chrome lida com os 5% que precisam de Lighthouse ou rastreamentos específicos do Chrome.
Listado Em
Licença
MIT — use como quiser.
Criado pela Achiya Automation — automação e agentes de IA para negócios.