Mac MCP
Servidor local de controle macOS de código aberto para agentes de IA: automação em segundo plano do Safari/Chrome, apps nativos, arquivos, shell e agentes delegados.
Documentação
Mac MCP 2.1.9
O Mac MCP é um servidor de controle local para macOS, voltado a agentes de IA. Ele expõe seu Mac por meio de um endpoint MCP nativo e uma superfície REST/OpenAPI, com shell, arquivos, automação de navegador, controle de UI do macOS, agentes delegados OpenCode/Codex, memória, Agent Skills, interação por voz, ferramentas de auto-atualização e um painel de operações local. O endpoint MCP nativo é a superfície completa de capacidades; o REST/OpenAPI publica intencionalmente um subconjunto de compatibilidade selecionado, então algumas capacidades permanecem exclusivas do MCP.
Fale com o ChatGPT. Deixe-o trabalhar no seu Mac.
O Mac MCP é agnóstico de modelo e funciona com clientes de IA compatíveis com MCP. Mas o ChatGPT é uma forma especialmente natural de usá-lo.
O ChatGPT Live pode usar plugins durante conversas por voz. Com o Mac MCP conectado, a mesma conversa do ChatGPT que você já usa pode se tornar uma superfície de controle para o seu Mac real. Você pode falar naturalmente enquanto o Mac MCP cuida da execução: navegando no Safari ou Chrome, trabalhando com arquivos, abrindo apps, executando comandos e coordenando agentes.
Em vez de mover cada tarefa para uma sessão separada de agente de codificação, você pode manter a interação no ChatGPT e simplesmente falar. Do seu celular, você pode pedir ao ChatGPT para trabalhar em um Mac acessível em outro lugar. Do seu desktop, você pode continuar falando enquanto o Mac MCP trabalha em segundo plano, sem assumir o controle do computador.
Por exemplo:
- "Verifique minhas respostas no Reddit, responda às importantes e feche o navegador quando terminar."
- "Percorra o repositório, execute os testes e me diga o que está quebrado."
- "Encontre três hotéis para o próximo fim de semana, compare as avaliações e salve a lista final no meu Mac."
O ChatGPT é a conversa. O Mac MCP é a camada de execução.
O painel do Mac MCP no ChatGPT
Quando o Mac MCP está conectado como um plugin do ChatGPT, o ChatGPT também mostra o Mac MCP como um app que você pode abrir ao lado das suas conversas: pela barra lateral do ChatGPT em tela cheia, ou como um painel lateral dentro de qualquer chat. O painel mostra a atividade das ferramentas, agentes delegados e uso de tokens de relance, e permite escolher o agente padrão para o qual o ChatGPT delega. Ele só atualiza quando você pressiona atualizar.
O painel é oferecido apenas ao ChatGPT; outros clientes MCP mantêm sua lista normal de ferramentas. Tudo o que ele faz passa pelos mesmos perfis de permissão e aprovações que qualquer outra chamada do Mac MCP, e ele nunca recebe chaves de API, tokens ou credenciais. Para desativá-lo, defina {"chatgpt_extensions": {"enabled": false}} em ~/.mac-mcp/settings.json. Veja docs/chatgpt-control-center.md para detalhes.
Esta é uma combinação poderosa, não um recurso de voz exclusivo do Mac MCP. O ChatGPT fornece a interface de voz natural e a experiência de raciocínio; o Mac MCP dá a ele uma camada de execução local no macOS. As permissões, aprovações e limites de uso existentes do plugin do ChatGPT ainda se aplicam, e o Mac MCP mantém seus limites normais de permissão, controle em segundo plano, segurança de resultados e desfazer.
Segurança: O Mac MCP pode executar comandos, ler/escrever arquivos e controlar apps de desktop. Mantenha a autenticação MCP habilitada sempre que o serviço estiver acessível fora do localhost e exponha-o apenas a clientes em que você confia. O painel de operações é somente loopback e exige um token Bearer separado por usuário; localhost é transporte local da máquina, não uma sandbox do mesmo usuário.
Padrões seguros de inicialização: configuração ausente falha de forma fechada. Sem configurações explícitas, a autenticação MCP é obrigatória, a execução de shell e as listas de permissão de host HTTP/navegador são desativadas, e o perfil de permissão global assume o padrão standard em vez de trusted. Uma execução normal do instalador gera a chave de API e escreve as configurações pretendidas explicitamente. MCP_ALLOW_NO_AUTH=true deliberado é aceito apenas em loopback, sem endpoint público gerenciado; inicialização sem autenticação em não-loopback ou túnel é recusada.
O que há de novo na 2.1.9
A 2.1.9 traz o Mac MCP para dentro do próprio ChatGPT com um painel de plugin nativo, e torna o trabalho diário no navegador, aprovações, atualizações e reinicializações mais confiáveis.
- Painel do Mac MCP dentro do ChatGPT: O ChatGPT agora mostra o Mac MCP como um app de plugin. Abra-o pela barra lateral do ChatGPT em tela cheia ou como um painel lateral em qualquer conversa. Um painel compacto em preto e branco, no mesmo estilo do site do Mac MCP, mostra a atividade de ferramentas de hoje, agentes delegados em execução e recentes, e uso de tokens de 7 dias para Codex, OpenCode e ChatGPT Web. Ele só atualiza quando você pressiona atualizar, então nunca consulta seu Mac em segundo plano.
- Escolha seu agente padrão pelo ChatGPT: a aba Configurações do painel permite escolher o provedor, o modelo e o nível de raciocínio que o ChatGPT usa ao delegar trabalho. Os modelos vêm das suas próprias contas de provedor, e o servidor verifica cada escolha antes de salvar. Notificações e detalhes de conexão são mostrados somente leitura; permissões, provedores e credenciais ainda vivem apenas no app Mac.
- Exclusivo do ChatGPT e vinculado a permissões: Claude, Codex, OpenCode e outros clientes nunca veem o painel. Cada ação dele passa pelos mesmos perfis de permissão e aprovações que qualquer outra chamada do Mac MCP, e nenhuma chave ou token é enviado a ele.
- Veja o que seus agentes estão fazendo: bolhas de atividade opcionais no Mac mostram para que serve cada chamada de ferramenta enquanto ela roda, mesmo quando várias rodam ao mesmo tempo, e notificações opcionais avisam quando um agente delegado termina.
- Aprovações opcionais do servidor: uma nova configuração de Aprovação do Servidor (
Off,Critical,High Risk) pode pedir que você Permita uma vez ou Bloqueie ações arriscadas, como comandos brutos, controle de atualização ou ações destrutivas de navegador e app. - Trabalho mais suave no navegador: agentes podem concluir formulários inteiros em uma única etapa: podem pressionar teclas e Enter sem trazer o navegador para a frente e esperar por botões que aparecem um momento depois. As abas do Safari permanecem rastreadas em mudanças de site e reorganização de abas, cliques cujo efeito aparece em outro lugar da página contam como funcionais, e imagens de página agora funcionam em páginas como o Google Sheets.
- Melhores escolhas entre alvos semelhantes: o Mac MCP agora prefere o botão real em vez das caixas ao redor dele. Uma camada opcional de Aceleração de Decisão (desativada por padrão, usa sua própria chave OpenAI) pode quebrar empates restantes, guiada por uma dica curta do agente.
- Configuração e histórico mais fáceis:
mac-mcp connect-configimprime configurações de conexão prontas para colar no ChatGPT, Codex e OpenCode; o painel adiciona uma visão segura do histórico de transações; e memória e Agent Skills podem ser lidas via REST. - Atualizações e reinicializações mais confiáveis: atualizações iniciadas de dentro do Mac MCP sobrevivem à própria reinicialização,
mac-mcp restartnão deixa mais o servidor parado, trabalhos em segundo plano continuam rastreando os programas que iniciam, e operações de atualização não substituem mais sua identidade Git. - Acessibilidade: o Visual Companion do navegador anuncia atividade a leitores de tela e funciona com o teclado.
Automação de navegador que não sequestra seu Mac
O Mac MCP pode inspecionar e interagir com abas do Safari e Chrome em segundo plano enquanto você continua trabalhando em outro app ou aba do navegador. Aqui, segundo plano significa uma aba normal e visível do Safari/Chrome que o Mac MCP controla sem trazer o navegador ou a aba para a frente; não é uma sessão de navegador oculta/headless.
- Novas abas do navegador abrem em segundo plano por padrão e retornam um
tab_handleestável. - Identificadores de aba estáveis sobrevivem a mudanças de índice de aba, então tarefas de longa duração continuam mirando a aba pretendida do Safari ou Chrome mesmo quando outras abas abrem, fecham ou se movem. Cada etapa do AppleScript re-resolve a aba pela identidade nativa, então uma mudança no meio de uma chamada
browser_actnão a faz falhar; se a aba alvo em si fechar, a chamada retornatab_target_closedcom as ações já concluídas eautomatic_retry: falseem vez de um erro HTTP. browser_observepode retornar contexto DOM compacto mais visuais de viewport, elemento ou página inteira sem ativar o navegador, trocar de aba, rolar a página do usuário ou deixar arquivos de screenshot no disco.- Ações de alto nível do navegador podem mirar diretamente uma aba específica em segundo plano pelo identificador, o que torna fluxos de pesquisa paralela e agentes delegados práticos sem roubo constante de foco.
- Fallbacks somente em primeiro plano, como pressionamentos de tecla nativos, cliques por coordenadas absolutas, aberturas de URL em primeiro plano e o caminho nativo do seletor de arquivos do Safari, são limitados por capacidade. Um modelo não pode conceder a si mesmo foco enviando
allow_foreground=trueoubackground=false. browser_activate_tabé tratado como comportamento visível em primeiro plano, mesmo quando não elevaria o app do navegador, porque mudar a aba atual do Safari ou a aba ativa do Chrome pode interromper um usuário que já trabalha lá. Automação normal deve mirar valores estáveis detab_handlediretamente, sem ativá-los.- O controlador nativo da barra de menus mostra o trabalho ativo do navegador em Sessões e Uso Mais Recente de Ferramentas com um resumo de navegador/site/ação com privacidade minimizada. Caminhos de URL, strings de consulta, títulos de página, seletores e conteúdo de página são intencionalmente omitidos desta visão compacta.
- Configurações → Uso → Dados e Retenção controla o histórico de uso: desative a gravação, mantenha 30, 90 ou 365 dias (padrão 365) ou limpe todo o uso armazenado de ferramentas e provedores. Apenas agregados diários por ferramenta são mantidos, nunca prompts, argumentos ou resultados; um período mais curto remove dias mais antigos imediatamente.
- Mostrar Aba é a ação explícita do usuário local: apenas esse caminho de UI confiável recebe uma capacidade lexical curta de primeiro plano e pode trazer aquela aba específica e real do Safari/Chrome para a frente.
Isso é projetado para fluxos de trabalho em que um agente de IA continua trabalhando em uma ou mais abas de navegador em segundo plano enquanto o Mac permanece utilizável normalmente.
Decisões mais rápidas em alvos semelhantes com a API de Decisões da OpenAI
Páginas reais estão cheias de quase duplicatas: um botão Continuar sob Envio e Cobrança, Responder ao lado de Responder a todos, duas células 25 em um seletor de data de dois meses. Um agente típico para ali, observa a página novamente e gasta outra ida e volta de modelo escolhendo. O Mac MCP pode resolver isso dentro da mesma chamada browser_act.
Quando a Aceleração de Decisão está ativada, o Mac MCP envia os candidatos já classificados para a API de Decisões da OpenAI, o endpoint de resposta tipada da OpenAI para classificação e roteamento rápidos (a OpenAI o descreve como cerca de 10x mais rápido que a API de Respostas). O Mac MCP dá a cada chamada um orçamento de 600 ms; uma chamada quente mediu cerca de ~330 ms. O agente pode adicionar uma dica de uma linha intent, como "a etapa de Cobrança", e essa dica decidiu nossos casos de calibração:
| Alvo ambíguo | Sem dica | Com intent |
|---|---|---|
| Continuar de Envio vs Cobrança | 0,16, manteve a primeira correspondência | Cobrança, 0,83 |
| Responder vs Responder a todos | Responder | Responder a todos, 0,93 |
| Duas células de calendário 25 | sem resposta, 0,28 | 25 de novembro, 0,82 |
A camada só pode escolher entre candidatos que o Mac MCP já encontrou, nunca escolhe uma ação arriscada como excluir, enviar ou pagar em vez da correspondência determinística, e volta ao caminho normal em qualquer timeout, erro ou baixa confiança. Ela está desativada por padrão, usa sua própria chave OpenAI do Keychain e envia apenas rótulos curtos e redigidos: sem valores digitados, URLs ou conteúdo de página. Configuração e limites estão em Aceleração de Decisão Opcional.
Visual Companion do navegador (Safari + Chrome)
Mac MCP.app usa uma fonte WebExtension compartilhada para Safari e Chrome para tornar o trabalho ativo do Mac MCP no navegador visível dentro da página exata que está sendo automatizada. A extensão é somente exibição: renderiza um sutil quadro pulsante na página, um pequeno selo de atividade Mac MCP · …, um cursor sintético e feedback de clique para ações de alto nível do navegador. Eventos visuais contêm apenas rótulos de ação limitados e coordenadas de viewport; texto digitado, seletores, URLs, títulos de página, conteúdo DOM e segredos não são copiados para o evento da extensão. A sobreposição é apenas feedback de atividade e não deve ser tratada como um indicador de segurança ou confiança.
A configuração do Safari depende de como Mac MCP.app é assinado:
Developer ID / build assinado pela Apple (persistente):
- Instale ou atualize o Mac MCP normalmente.
- Abra Mac MCP.app → Atividade do Navegador → Ativar no Safari…. Você também pode usar Safari → Ajustes → Extensões.
- Ative o Mac MCP Visual Companion e conceda acesso ao site para os sites onde você deseja feedback de atividade.
Build local do GitHub/fonte (ad-hoc, modo de desenvolvimento):
- Abra Mac MCP.app → Atividade do Navegador → Configuração do Desenvolvedor…. O Mac MCP revela a pasta de origem do runtime
BrowserVisualCompanione abre o Safari. - No Safari, ative os recursos de desenvolvedor web se o menu Desenvolver estiver oculto.
- Escolha Desenvolver → Permitir Extensões Não Assinadas.
- Escolha Desenvolver → Adicionar Extensão Temporária… e selecione
~/mac-mcp/menu_app/BrowserVisualCompanion. - Conceda acesso ao site quando o Safari solicitar. O Safari trata isso como uma extensão de desenvolvimento/temporária; a instalação normal persistente requer um pacote de aplicativo assinado pela Apple.
Para o Chrome, a criação real de abas em segundo plano usa a extensão ~/mac-mcp/menu_app/ChromeVisualCompanion exclusiva do Chrome. Abra Mac MCP.app → Atividade do Navegador → Configuração do Chrome…, ative o Modo do desenvolvedor em chrome://extensions, escolha Carregar sem compactação e selecione essa pasta. O companion abre novas abas com a API nativa tabs.create({active:false}) do Chrome, portanto, o trabalho em segundo plano não traz o Chrome ou a nova aba para a frente. Se o companion não estiver disponível, a criação de abas em segundo plano falha de forma segura, em vez de recorrer a um AppleScript que rouba o foco. O mesmo companion também executa a execução de DOM/página por meio da API debugger do Chrome, portanto, leituras, cliques, digitação e captura visual segura em segundo plano do Mac MCP no Chrome não exigem a alternância de JavaScript do Apple Events enquanto o companion estiver conectado. O companion do Chrome usa uma credencial local dedicada somente do proprietário e um WebSocket de loopback; a credencial não é o MCP_API_KEY global.
O projeto permanece totalmente open source e não precisa da Mac App Store. Para uma versão persistente do GitHub, assine/notarize o Mac MCP.app distribuído com o Developer ID; menu_app/build_app.sh aceita MAC_MCP_CODESIGN_IDENTITY para esse caminho de versão.
Nenhum perfil de navegador separado, daemon auxiliar ou projeto Xcode é necessário. menu_app/build_app.sh compila o .appex em Mac MCP.app/Contents/PlugIns/ com o toolchain normal de linha de comando do Swift. Builds locais usam assinatura ad-hoc por padrão; os criadores de versões podem definir MAC_MCP_CODESIGN_IDENTITY para usar uma identidade de Developer ID com assinatura de runtime/timestamp endurecida.
Requisitos
- macOS 13+
- Apple Silicon ou Mac Intel
- Python 3.10+
- Git
- Xcode Command Line Tools (
swiftc) - ngrok somente se você escolher o modo de endpoint público ngrok integrado
- cloudflared somente se você escolher o modo Cloudflare Tunnel integrado
brew install python git
# Optional public providers:
brew install ngrok # ngrok mode
brew install cloudflared # Cloudflare Tunnel mode
Auxiliares opcionais:
brew install cliclick brightness
Instalação
Instalador
O instalador interativo agora instala apenas uma versão estável criptograficamente verificada. Ele clona main, encontra o commit de versão estável assinado mais recente, verifica o verificador de bootstrap fixado, a assinatura do manifesto Ed25519, o inventário completo de SHA-256/modo/tamanho dos arquivos rastreados, o digest agregado do payload e a linhagem da versão antes de criar caminhos persistentes de origem/runtime.
Por conveniência, o bootstrap transmitido ainda está disponível:
curl -fsSL https://raw.githubusercontent.com/bulutarkan/mac-mcp/main/install.sh | bash
Um script transmitido não pode se autenticar criptograficamente antes de começar a executar. Trate esse comando como um bootstrap de menor garantia. Para instalação de maior garantia, obtenha install.sh de um commit de versão assinado confiável e compare de forma independente a impressão digital do assinante da versão documentada em release/README.md antes de executá-lo. Quando o instalador confiável estiver em execução, o payload de origem/runtime clonado será fail-closed e verificado criptograficamente.
O instalador:
- verifica macOS 13+, Apple Silicon ou Intel, Git, Python 3.10+, Xcode Command Line Tools e
swiftc; - verifica criptograficamente a versão estável selecionada antes de mover qualquer arquivo de origem/runtime para caminhos de instalação persistentes;
- pode oferecer o Homebrew quando uma dependência necessária estiver ausente, mantendo auxiliares opcionais como
cliclickebrightnessopcionais; - pergunta qual modo de endpoint público você deseja (
Local only,Cloudflare Tunnel,ngrokouCustom HTTPS) e, quando Cloudflare/ngrok é selecionado, oferece a instalação do provedor correspondente com o Homebrew se estiver ausente; - pode concluir a configuração do Cloudflare durante a instalação armazenando o hostname público nas configurações e aceitando o token do túnel por meio de um prompt de terminal oculto; o token é enviado para
mac-mcp credential cloudflare savevia stdin e nunca é colocado em argumentos de shell, configurações ou.env; - cria um checkout de origem Git em
~/Projects/mac-mcpe um runtime separado em~/mac-mcpsem metadados Git; - cria e verifica o ambiente virtual Python e as dependências;
- gera uma chave de API MCP forte, ativa o acesso autenticado e armazena o
.envdo runtime com modo600; - instala o CLI
mac-mcpem~/.local/bin/mac-mcpe registra o commit implantado para o atualizador integrado; - compila e verifica a assinatura de código do controlador nativo da barra de menus
Mac MCP.appem~/Applications; - mostra os formatos de conexão Bearer-token e
?ApiKey=no final; - não instala OpenCode, Codex ou ChatGPT Web CLI. Se você quiser usar Subagents, instale o provedor que planeja usar separadamente.
Caminhos existentes de origem/runtime/CLI nunca são sobrescritos silenciosamente. Se o Mac MCP já estiver instalado, use o atualizador integrado em vez de executar novamente o instalador sobre os mesmos caminhos.
Instalação manual
Se você preferir gerenciar o checkout e o ambiente Python você mesmo:
git clone https://github.com/bulutarkan/mac-mcp.git
cd mac-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install --require-hashes -r requirements.lock
pip install --no-deps --no-build-isolation -e .
cp mcp_server/.env.example mcp_server/.env
requirements.lock fixa cada dependência, incluindo pacotes transitivos e ferramentas de build, por versão e hash SHA-256; o instalador, o atualizador e o CI instalam a partir dele, e o pip recusa um pacote que não corresponda. Após alterar dependências em pyproject.toml, regenere-o com o comando no topo do arquivo (uv pip compile ... --generate-hashes).
Configure no mínimo:
MCP_API_KEY=replace-with-a-long-random-token
MCP_ALLOW_NO_AUTH=false
MCP_ALLOW_SHELL=true
RATE_LIMIT_PER_MINUTE=120
# Optional built-in ngrok provider
NGROK_DOMAIN=your-domain.ngrok-free.dev
# Optional environment overrides for public endpoint selection.
# Normally these are managed from Mac MCP Settings instead.
# MAC_MCP_PUBLIC_ENDPOINT_MODE=cloudflare
# MAC_MCP_PUBLIC_URL=https://mac.example.com/mcp
Gere um token forte:
python3 - <<'PY'
import secrets
print(secrets.token_urlsafe(48))
PY
Quando a autenticação está habilitada, a credencial preferida do cliente ainda é:
Authorization: Bearer <MCP_API_KEY>
Para clientes/conectores MCP que não podem definir um cabeçalho Authorization, o Mac MCP também aceita a chave global configurada na URL do endpoint:
https://your-domain.example/mcp?ApiKey=<MCP_API_KEY>
Gerar uma configuração de conexão do cliente
Use o CLI para gerar um snippet de conexão a partir do endpoint do Mac MCP e do estado de autenticação realmente configurados neste Mac:
mac-mcp connect-config --client chatgpt
mac-mcp connect-config --client codex
mac-mcp connect-config --client opencode
O comando nunca imprime o valor da chave de API configurada. Os snippets do Codex e do OpenCode referenciam uma variável de ambiente do lado do cliente (MAC_MCP_API_KEY por padrão); defina essa variável no processo do cliente com o mesmo valor secreto configurado como MCP_API_KEY do Mac MCP. O ChatGPT usa o formulário de compatibilidade de chave de consulta limitada por cabeçalho existente e imprime apenas ?ApiKey=<API_KEY> como um placeholder.
--endpoint auto é o padrão: ele usa o endpoint HTTPS público configurado para ChatGPT e loopback para Codex/OpenCode locais. Use --endpoint public quando Codex/OpenCode forem executados em outro lugar, ou --endpoint local para forçar loopback onde houver suporte. --name altera o ID do servidor do lado do cliente, e --auth-env altera o nome da variável de ambiente do cliente sem expor seu valor.
Os formatos de configuração do cliente evoluem. A saída gerada rotula o formato de destino que assume; prefira regenerar o snippet com seu Mac MCP instalado em vez de copiar um fragmento antigo do README.
Modos de endpoint público
O Mac MCP trata o servidor local e seu transporte público como camadas separadas. Somente local não expõe nenhum endpoint público gerenciado. ngrok executa um processo ngrok gerenciado e usa NGROK_DOMAIN. Cloudflare Tunnel executa cloudflared diretamente no Mac e conecta o túnel nomeado selecionado (ou um arquivo de token controlado pelo proprietário) a 127.0.0.1:<port>; nenhum VPS, proxy reverso, encaminhamento de porta de entrada ou IP público do Mac é necessário. HTTPS personalizado registra um endpoint MCP HTTPS gerenciado externamente e não inicia um provedor de túnel.
A janela nativa de Configurações fornece um switch de quatro vias Local only / ngrok / Cloudflare / Custom HTTPS. A seleção é persistida em server.public_endpoint_mode e server.public_url em ~/.mac-mcp/settings.json; metadados opcionais de túnel nomeado podem usar o campo não secreto server.cloudflare_tunnel. Instalações existentes que têm apenas ngrok_on_start=true continuam se comportando como modo ngrok até que a nova configuração seja salva. As variáveis de ambiente MAC_MCP_PUBLIC_ENDPOINT_MODE e MAC_MCP_PUBLIC_URL podem substituir valores persistidos para implantações gerenciadas/headless.
Cloudflare Tunnel: configuração em 5 minutos
O instalador interativo pode fazer a configuração do lado do Mac para você. Escolha Cloudflare Tunnel quando install.sh perguntar sobre um endpoint público. Se cloudflared estiver ausente, o instalador oferece brew install cloudflared; recusá-lo não quebra a instalação principal e deixa o Mac MCP no modo Somente local.
Para a configuração do lado do Cloudflare:
- Seu domínio deve estar ativo no Cloudflare. No painel do Cloudflare, vá para Networking → Tunnels, escolha Create tunnel e dê a ele qualquer nome que identifique este Mac.
- Abra a guia Routes do túnel, escolha Add route → Published application, selecione o hostname que você deseja (por exemplo,
mac.example.com) e aponte o serviço parahttp://localhost:8000para uma instalação padrão. Se você alterou a porta do servidor do Mac MCP, use essa porta. - O Cloudflare mostra um comando de configuração/instalação
cloudflaredpara o conector. Não execute o comando de instalação do serviço quando o Mac MCP estiver gerenciando o túnel. Copie apenas o token do túnel desse comando. Para um túnel existente, Add a replica também expõe um comando de conector contendo o token. - De volta ao instalador do Mac MCP, insira o hostname público, como
https://mac.example.com, e cole o token no prompt oculto. Se você pular qualquer um dos valores, o instalador deixa com segurança o modo público como Somente local; termine mais tarde em Mac MCP.app → Configurações → Avançado → Cloudflare. - Inicie o Mac MCP.
mac-mcp startcria/habilita um joblaunchdpor usuário comKeepAlive; nenhuma janela do Terminal precisa permanecer aberta. Verifique commac-mcp statusemac-mcp doctor.
A documentação atual do Cloudflare chama isso de túnel gerenciado remotamente e uma rota de Published application. Consulte Set up Cloudflare Tunnel, Add routes e Tunnel tokens. Um token de túnel é uma credencial: qualquer pessoa que o tenha pode executar um conector para esse túnel, então gire-o no Cloudflare se ele for exposto.
Para a configuração mais simples do Cloudflare, crie o túnel e o hostname no Cloudflare e cole o token do túnel uma vez em Configurações → Avançado → Cloudflare. O Mac MCP o escreve atomicamente em ~/.mac-mcp/cloudflare-tunnel-token como um arquivo 0600 somente do proprietário, nunca escreve o token em settings.json ou .env, nunca o reexibe e inicia cloudflared com --token-file para que o segredo não seja exposto em argumentos de processo. CLOUDFLARE_TUNNEL_TOKEN_FILE pode substituir o caminho do arquivo de credencial sem colocar o valor do token no ambiente. As credenciais de túnel nomeado permanecem disponíveis como uma alternativa avançada. O túnel conecta o Cloudflare diretamente a http://127.0.0.1:<port> no Mac: nenhum VPS, IP público, encaminhamento de porta do roteador ou abertura de firewall de entrada é necessário. O modo personalizado é para operadores que já fornecem seu próprio roteamento HTTPS externo. Todas as URLs públicas devem ser HTTPS e não podem conter strings de consulta, fragmentos ou userinfo de URL. mac-mcp status mostra a URL do conector selecionado e mac-mcp doctor verifica o provedor selecionado, a segurança do arquivo de credencial e a rota pública /health sem enviar a chave de API MCP. Alternar provedores interrompe qualquer processo ngrok/cloudflared gerenciado que não esteja mais selecionado. No modo Cloudflare, mac-mcp start (e a ação Iniciar do aplicativo nativo) instala/habilita um LaunchAgent de usuário com KeepAlive, para que o túnel permaneça independente do Terminal e seja reiniciado automaticamente se cloudflared sair; mac-mcp stop encerra e desabilita esse job.
Authorization permanece autoritativo quando ambas as formas são fornecidas. Credenciais de consulta ApiKey vazias, duplicadas ou inválidas são rejeitadas enquanto a autenticação estiver habilitada. O servidor remove ApiKey de sua URL local de log de acesso antes de registrar, mas proxies/túneis upstream ainda podem observar strings de consulta, portanto, cabeçalhos Bearer devem ser preferidos sempre que o cliente os suportar.
Terminologia de produto e segurança
O Mac MCP usa um pequeno glossário canônico para que a interface e a documentação não impliquem isolamento ou invisibilidade mais fortes do que o produto realmente oferece. Consulte docs/TERMINOLOGY.md para as definições completas.
- Automação de navegador em segundo plano: automação visível do Safari/Chrome que não rouba o foco; não é oculta ou headless.
- Capacidade: se a política do servidor Mac MCP permite uma classe de ferramenta/risco.
- Aprovação: um mecanismo de confirmação humana e sua fonte; separado da aplicação de capacidade.
- Localhost / loopback: transporte local da máquina, não isolamento entre usuários ou sandbox.
- Sessão lógica do Mac MCP: uma identidade de direcionamento local com hash que mantém um fluxo de agente/conversa coerente; não é a identidade bruta do provedor.
- Usuário dedicado: contenção/endurecimento que reduz o raio de explosão; não é um sandbox completo.
Para uma implantação avançada com duas contas, consulte Implantação endurecida com um usuário macOS dedicado sem privilégios de administrador. Ela cobre autenticação loopback, um diretório compartilhado explícito via ACL, limites de TCC/sessão GUI, comportamento de ferramentas, reversão e uma matriz de validação com dois usuários.
Perfis de permissão e semântica de aprovação
O Mac MCP trata aplicação de capacidade e aprovação humana como conceitos de segurança separados. Uma capacidade permitida significa apenas que a política do servidor Mac MCP permite aquela classe de ferramenta/risco. Isso não significa que um segundo prompt de confirmação aparecerá antes da ação ser executada.
| Perfil | Comportamento de capacidade aplicado pelo servidor | Fonte de aprovação com Aprovação do Servidor Off | Prompt automático de risco |
|---|---|---|---|
trusted | Todas as capacidades registradas; famílias destrutivas não são adicionalmente restritas pelo perfil. | none | Não |
standard | Bloqueia raw_execution e update_control; operações destrutivas são limitadas às famílias de navegador/acessibilidade; o teto do modo de acesso é somente leitura. | none | Não |
read_only | Permite apenas capacidades de leitura/rede/navegador/acessibilidade nativa e nega chamadas destrutivas. | none | Não |
Aprovação do Servidor é uma camada opcional de aprovação, separada desses perfis de capacidade. O padrão é Off. Critical exige confirmação Permitir Uma Vez / Bloquear do Mac MCP para execução bruta, controle de atualização e chamadas destrutivas de controle de processo. High Risk adiciona ações destrutivas externas/navegador/nativas. A camada é avaliada somente após a aplicação de capacidade, usa concessões de ação exata de uso único, nega quando uma aprovação é necessária, mas o provedor local de aprovação está indisponível ou expira, e pode ser alterada em Configurações → Permissões e Segurança sem reiniciar o servidor. O Mac MCP não aceita uma alegação de "já aprovado" fornecida pelo cliente como prova para contornar esta barreira do servidor; a aprovação do cliente/externa pode ainda ser aplicada de forma independente.
ask_confirmation permanece uma ferramenta de interação explícita e não é um invólucro genérico de confirmação em torno de chamadas normais de ferramentas. Separadamente, o Mac MCP tem barreiras de segurança obrigatórias e estreitas no lado do servidor para cruzamentos arriscados de limites de confiança. Sob standard e perfis delegados com escopo, um contexto web não confiável → ação privilegiada do host pode exigir uma decisão Permitir Uma Vez / Bloquear ciente da origem. O perfil global trusted intencionalmente pula essa confirmação rotineira web→host para que fluxos de trabalho interativos confiáveis não sejam interrompidos a cada salto de shell/arquivo/UI, a menos que a camada opcional de Aprovação do Servidor corresponda independentemente à ação. Egresso detectado de credenciais/segredos para uma origem não confiável permanece ciente da origem e sujeito a aprovação mesmo sob trusted. Concessões de ação exata permanecem vinculadas à origem e de uso único.
Trabalhadores delegados do Codex atualmente executam com approval_policy="never" do Codex; seu sandbox/modo de acesso é separado da aprovação humana. O comportamento de permissão do OpenCode também é do lado do provedor e não deve ser tratado como uma garantia de confirmação do servidor Mac MCP.
Defina o perfil de capacidade do servidor com MAC_MCP_PERMISSION_PROFILE=trusted|standard|read_only. O aplicativo nativo da barra de menus lê /dashboard/api/security/semantics e mostra Capacidades Permitidas, Comportamento de Aprovação e o perfil de risco opcional Aprovação do Servidor separadamente. Alterações no perfil de permissão persistem em mcp_server/.env; a Aprovação do Servidor persiste como security.server_approval_profile em ~/.mac-mcp/settings.json somente do proprietário. Ambos se aplicam a novas solicitações imediatamente, sem reiniciar o servidor. Agentes delegados existentes mantêm o perfil de capacidade com escopo emitido quando foram iniciados; a camada de aprovação de risco do lado do servidor permanece uma barreira de execução do servidor.
As proteções de resiliência do navegador são configuráveis com MAC_MCP_NO_PROGRESS_THRESHOLD (padrão 4, intervalo 2–10) e MAC_MCP_TAB_LEASE_TTL_S (padrão 300 segundos, intervalo 30–3600). O disjuntor de sem progresso interrompe apenas ações repetidas e significativas do navegador que não conseguem alterar a revisão do DOM, a URL ou o título; fluxos de espera/rolagem/extração não consomem esse orçamento. A propriedade da aba do agente delegado é lógica e limitada no tempo: concluir/cancelar/falhar um agente libera a propriedade sem fechar a aba do usuário, e o próximo agente deve fazer um novo browser_observe antes de agir em um identificador anteriormente possuído.
Limite de URL de saída / SSRF
http_request e browser_open_url tratam listas de permissão de hostname público e acesso a rede privada como permissões separadas. Um HTTP_ALLOWLIST=* ou BROWSER_ALLOWLIST=* curinga permite hostnames públicos; isso não permite loopback, RFC1918/ULA, link-local/metadata, NAT de operadora, multicast, não especificado, reservado ou outro espaço de endereço não global. Hostnames que resolvem para qualquer endereço bloqueado falham de forma fechada. Userinfo de URL e esquemas não HTTP(S) também são rejeitados.
Para http_request, cada salto de redirecionamento é revalidado antes da próxima solicitação. O transporte HTTP adicionalmente resolve novamente no momento da conexão TCP, rejeita uma resposta DNS que mudou para espaço de endereço bloqueado e conecta ao IP já validado, mantendo o hostname original para identidade HTTP/TLS. Variáveis de proxy de ambiente são deliberadamente não herdadas por este caminho de acesso ao host. A saída de redirecionamento é limitada às origens de destino, em vez de copiar caminhos completos de redirecionamento ou strings de consulta.
Os mecanismos de navegador possuem sua própria pilha de rede, então o Mac MCP não afirma fixação de IP em nível de transporte para Safari ou Chrome. Em vez disso, a navegação do navegador valida o DNS antes da navegação e depois revalida a URL de destino observada pelo navegador após a navegação; uma mudança de DNS no mesmo host é resolvida novamente nesse limite. Se uma nova aba criada for observada em um destino bloqueado, ela é fechada na melhor das hipóteses e a chamada falha como browser_redirect_blocked; para uma aba existente, o Mac MCP restaura na melhor das hipóteses a URL segura observada anteriormente.
O acesso de desenvolvimento local/privado é opcional por hostname através de HTTP_PRIVATE_ALLOWLIST e BROWSER_PRIVATE_ALLOWLIST (nomes/sufixos separados por vírgula, por exemplo localhost). Essas exceções são independentes das listas de permissão públicas normais; * é intencionalmente ignorado nas listas de permissão privadas para que o acesso à rede privada não possa ser habilitado acidentalmente.
A proveniência web não confiável é persistente no nível da sessão lógica. Uma vez que uma sessão consome conteúdo de navegador de terceiros, escrever esse conteúdo em um arquivo local temporário, lê-lo de volta, fechar a aba ou passar por ferramentas somente leitura não relacionadas não apaga essa proveniência. Fluxos de trabalho com escopo/não confiáveis continuam através da barreira de segurança web→host até que o trabalho se mova para uma sessão independente de sala limpa. O perfil global trusted mantém a proveniência persistente para auditoria e verificações de egresso de segredos, mas não mostra um diálogo rotineiro de Permitir Uma Vez para cada salto privilegiado normal do host. Filhos delegados gerados de uma sessão contaminada herdam os metadados de contaminação (origem, motivo e impressões digitais de credenciais) sem copiar DOM bruto ou segredos para o log de segurança; delegação aninhada preserva a cadeia de herança. Uma sessão MCP genuinamente independente, sem payload transferido, começa limpa sob a política normal.
Instalar o aplicativo da barra de menus
./menu_app/install_app.sh
Local padrão:
~/Applications/Mac MCP.app
O aplicativo é independente do servidor:
- sair do aplicativo não interrompe o MCP;
- interromper o MCP não sai do aplicativo;
mac-mcp startabre o aplicativo automaticamente quando ele é instalado;- os controles do servidor permanecem disponíveis mesmo enquanto a seção Voice estiver recolhida.
O aplicativo usa as APIs do painel localhost com uma credencial Bearer separada do painel armazenada em ~/.mac-mcp/dashboard-token (modo 0600). O aplicativo de menu lê esse arquivo somente do proprietário localmente e nunca precisa do MCP_API_KEY global:
/dashboard/api/summary
/dashboard/api/security/semantics
/dashboard/api/events
/dashboard/api/agents
/dashboard/api/steering
Direcionamento ao vivo na barra de menus
O Mac MCP mantém uma sessão lógica do Mac MCP visível entre chamadas de ferramentas, em vez de mostrá-la apenas pelos poucos milissegundos enquanto uma ferramenta está em execução. Ele prefere metadados estáveis de conversa fornecidos pelo cliente MCP (por exemplo, os metadados openai/session com escopo de conversa da OpenAI), depois _meta.client_id genérico e, finalmente, um transporte Streamable HTTP reutilizável com estado como fallback. Valores de identidade bruta são submetidos a hash antes de entrar no estado de direcionamento e nunca são expostos no painel. Isso importa para hosts que criam uma nova sessão de transporte para cada chamada de ferramenta: chamadas repetidas da mesma conversa ainda se agrupam em um único cartão de agente Trabalhando / Ocioso.
As mensagens de direcionamento são mantidas apenas em memória e estão vinculadas ao agente lógico selecionado, nunca a uma fila global de "próximo chamador". Se o agente selecionado atualmente tem uma ferramenta em execução, o prompt é anexado à resposta ao vivo dessa ferramenta como conteúdo estruturado _mac_mcp_steering. Se o agente está ocioso, o prompt permanece na fila para aquela sessão lógica e sua próxima ferramenta solicitada é antecipada antes da execução com um erro de ferramenta mac_mcp_steering_preempted, para que o agente veja a nova direção do usuário antes de fazer mais trabalho. Uma conversa/sessão diferente não pode consumir esse prompt. Sessões lógicas de direcionamento expiram após 10 minutos de inatividade por padrão. A divulgação Sessões da barra de menus permite inserir qualquer número positivo de minutos e persiste esse valor em ~/.mac-mcp/settings.json; transportes de protocolo com estado são separadamente limitados para que transportes de cliente de curta duração não se acumulem indefinidamente. Texto bruto de direcionamento não é gravado no SQLite de telemetria, e chamadas aninhadas de fallback como tool_invoke não criam sessões visíveis duplicadas.
A aceitação de POST de direcionamento é idempotente para clientes que enviam client_instruction_id. O aplicativo de menu gera um UUID para cada ação Enviar e reutiliza o mesmo UUID para uma nova tentativa limitada quando o resultado HTTP é ambíguo. Reproduzir a mesma sessão + ID do cliente + texto retorna a mensagem canônica original st_* em vez de enfileirar uma duplicata; reutilizar um ID de cliente com texto diferente ou outra sessão ativa retorna 409 idempotency_conflict. Linhas recentes do ciclo de vida incluem o ID de correlação do cliente para que o aplicativo de menu possa recuperar uma mensagem aceita após uma resposta perdida. O índice ativo de deduplicação é limitado; chaves removidas movem-se para uma janela limitada de tombstone para que uma nova tentativa tardia da mesma geração retorne 409 idempotency_expired em vez de criar silenciosamente uma segunda instrução.
Cada daemon em execução também publica um generation_id aleatório. O app de menu nativo vincula cada nova submissão de direcionamento e nova tentativa ambígua a essa geração. Se o daemon reiniciar antes que uma resposta incerta possa ser recuperada, uma nova tentativa de geração antiga é rejeitada como 409 stale_generation com outcome=unknown; ela nunca é reproduzida automaticamente no novo daemon. O usuário pode então reenviar intencionalmente, o que cria um novo ID de cliente contra a geração atual. O marcador de geração evita reprodução duplicada entre limites de reinicialização; ele não finge recuperar o resultado perdido na memória do daemon antigo. Clientes legados que omitem generation_id permanecem compatíveis, mas não recebem essa garantia mais forte de limite de reinicialização.
Se o app de menu nativo for relançado enquanto o daemon continua em execução, as sessões lógicas de propriedade do daemon permanecem disponíveis e a nova instância do app as redescobre a partir de /dashboard/api/steering. Uma submissão de direcionamento cujo resultado HTTP ainda estava ambíguo na saída do app mantém apenas um registro de correlação de curta duração, exclusivo do proprietário, em ~/.mac-mcp/pending-steering.json (ID do cliente, ID da sessão lógica, SHA-256 do prompt, ID da geração do daemon, timestamp; nunca o prompt bruto). No relançamento, o app reconcilia esse registro com o estado recent do daemon; reentrar no mesmo prompt reutiliza a chave de idempotência original somente enquanto a geração do daemon ainda corresponder.
Por exemplo, se um agente está pesquisando com automação de navegador visível e sem roubo de foco em uma aba do Safari e você digita stop using Airbnb and check Booking.com instead na Sessão desse agente, o Mac MCP roteia a instrução apenas para esse agente lógico. Uma ferramenta em execução pode retornar o direcionamento imediatamente; um agente ocioso é interrompido antes de sua próxima chamada de ferramenta para que possa mudar de curso primeiro.
Eficiência de atualização de estado do SwiftUI
O controlador nativo permanece @MainActor e mantém a mesma cadência de polling, mas publica valores de painel decodificados somente quando eles realmente mudam. Snapshots de sessão são comparados por session_id estável antes de substituir o array observável, preservando a identidade das linhas do SwiftUI e evitando invalidação de hierarquia para polls idênticos. Atualizações voláteis de duração são coalescidas apenas enquanto seu rótulo renderizado permaneceria inalterado. Esta é uma otimização de eficiência de renderização/estado, não um modo de atualização mais lenta.
Arquitetura de informações das sessões
A barra de menus deriva três seções determinísticas do snapshot de ciclo de vida versionado: Needs Attention (failed, não resolvido/desconhecido, ou eventos recentes de sessão desconectada/expirada), Active (trabalhando, na fila, entregue, pendente ou aguardando confirmação) e Recent (sessões ready/acknowledged ociosas retidas). Linhas terminais históricas são informativas, não direcionáveis. O ícone de status da barra de menus carrega apenas um sinal agregado de atenção/ativo. O Mac MCP não mostra controles de Retry/Cancel de sessão porque não existem tais ações de backend; Retry de conexão permanece uma ação separada de acessibilidade do painel.
Ciclo de vida de sessão versionado
A API de direcionamento expõe schema_version: 1 e separa atividade de ciclo de vida de instrução. Os campos legados state=working|idle e queued permanecem para compatibilidade; novos clientes devem preferir activity_state, lifecycle_state, pending_instruction_count, last_transition_at e last_error.
O ciclo de vida da instrução é intencionalmente pequeno: ready → queued → delivered → acknowledged. Se a ferramenta subjacente falhar antes que o direcionamento enfileirado possa ser entregue, a sessão entra em failed enquanto mantém a instrução pendente para a próxima chamada de ferramenta. Sessões com transporte emitem disconnected quando seu transporte MCP desaparece, e sessões ociosas emitem expired quando seu TTL de retenção expira. Transições ilegais de ciclo de vida são rejeitadas internamente em vez de produzir silenciosamente estado ambíguo.
acknowledged é inferido quando o mesmo agente lógico faz sua próxima solicitação de ferramenta de nível superior após receber direcionamento; significa que o agente continuou após o limite de entrega, não que o modelo enviou um pacote de confirmação separado. A acessibilidade do daemon/API é uma preocupação de conexão diferente e é tratada separadamente pela UX de conexão do app de menu.
Resiliência de conexão da barra de menus
O controlador nativo não trata uma solicitação de painel com falha como dados vazios válidos. Uma resposta /dashboard/api/steering vazia bem-sucedida limpa a lista de sessões normalmente; um erro HTTP, timeout ou recusa de conexão preserva o último snapshot bem-sucedido e o marca como obsoleto. Se o app nunca recebeu um snapshot de sessão válido, ele mostra Session data unavailable em vez de No agent sessions yet.
Uma falha de transporte, como timeout ou recusa de conexão, entra em disconnected; um erro HTTP ou resposta inválida de um servidor acessível entra em degraded, incluindo falhas do endpoint de resumo primário. Falhas de status HTTP, timeouts e erros de conexão recusada são exibidos separadamente. O polling automático recua de 1 segundo para um limite de 30 segundos e retorna à cadência normal de 2,5 segundos após a próxima atualização bem-sucedida completa.
Comandos do servidor
mac-mcp start
mac-mcp start --public-mode ngrok
# Save the Cloudflare token once in Mac MCP Settings → Advanced.
mac-mcp start --public-mode cloudflare --public-url https://mac.example.com/mcp
mac-mcp start --public-mode custom --public-url https://mac.example.com/mcp
mac-mcp start --public-mode none
mac-mcp status
mac-mcp status --json
mac-mcp restart
mac-mcp stop
mac-mcp dashboard
mac-mcp doctor
mac-mcp conformance
O sinalizador legado --ngrok permanece suportado como um alias para --public-mode ngrok. Quando nenhuma substituição de CLI é fornecida, start/restart usam o modo de endpoint público salvo pela janela nativa de Settings (ou as substituições de ambiente MAC_MCP_PUBLIC_*).
mac-mcp doctor executa verificações somente leitura para o runtime local, Python/versão, espaço em disco, validade de estado/configurações, permissões do macOS, helpers necessários/opcionais, saúde do servidor local, saúde/configuração do endpoint público selecionado, metadados do arquivo de credenciais do painel e estado do companheiro Safari/Chrome. Use --json para automação; o JSON relata local_ok, public_endpoint e health (healthy, degraded, failed) separadamente. Um endpoint público selecionado que não pode ser alcançado faz doctor sair com 1 e mac-mcp status sair com 2 (1 significa que o servidor local está fora do ar); passe --local-only para qualquer comando para julgar apenas o runtime local. --support-bundle [PATH] escreve um relatório de suporte estruturado somente do proprietário (0600); ele exclui intencionalmente .env bruto, valores de configurações, logs, credenciais, cookies, prompts e conteúdo de chat.
As permissões são lidas do servidor em execução, porque o macOS registra consentimento para o processo que pergunta: doctor relata Accessibility, Screen Recording e automação por app (System Events, Safari, Chrome, Calendar, Reminders, Notes, Mail) como permitido, não permitido, ainda não perguntado ou não verificado, com os recursos que cada um habilita e o caminho exato de System Settings e nome do app para permitir. Estas são consultas somente leitura que nunca mostram um prompt de permissão. O acesso ao microfone pertence ao Mac MCP Voice Helper separado, então é descrito em vez de verificado. Quando o servidor não está em execução, doctor diz isso e descreve seu próprio processo. Conflitos de porta nomeiam o programa usando a porta (o Mac MCP nunca para um programa que não iniciou) e apontam para Settings → Advanced → Server Port; problemas de túnel dizem se o binário do túnel está ausente, a credencial é insegura, o processo do túnel parou ou a rota pública não responde.
As mesmas verificações estão no app em Settings → Help & Diagnostics: execute ou reexecute diagnósticos, use o botão de correção ao lado de cada problema (reiniciar, abrir a configuração certa ou o painel de System Settings, ver o log redigido), exporte um relatório de suporte depois de ver o que ele contém, veja o log do servidor ou túnel, copie informações de versão e abra a documentação, formulário de problema ou política de segurança privada. Nada é enviado automaticamente para lugar nenhum.
mac-mcp status --json imprime um objeto para scripts: ok, state, exit_code, server (running, pid, identity, port, health da rota local /health), public_endpoint (mode, url, tunnel_running, route — se o /health público responde — e error), stray_processes, supervisor e remediation. state distingue os casos: healthy, stopped, port_conflict, ownership_unverified, unresponsive (processo vivo, mas /health não responde), degraded (túnel selecionado não em execução, ou em execução enquanto sua rota pública não responde) e config_error (configurações de endpoint público inválidas). doctor --json carrega o mesmo campo exit_code.
Os códigos de saída da CLI são um contrato estável:
| Comando | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
status | saudável | servidor parado, não verificado, porta ocupada ou não respondendo /health | endpoint público indisponível ou mal configurado (0 com --local-only) | — |
doctor | todas as verificações passam | uma verificação falhou | — | — |
start | iniciado | não pôde iniciar (por exemplo, conflito de porta) | configuração inválida ou erro de bootstrap de segurança | ngrok iniciado, mas seu /health público ainda não responde |
stop / restart | concluído | um componente não parou ou voltou saudável | — | — |
restart --wait | reiniciado e saudável | reinicialização falhou, ou apenas o endpoint público falhou (degradado) | — | nenhum resultado relatado a tempo |
update --check | verificado | verificação falhou | mudanças locais bloqueiam a atualização | — |
update | atualizado ou já atual | atualização falhou ou foi bloqueada | — | — |
recipe run | concluído | falhou | precisa de aprovação | servidor não em execução |
recipe list | listado | solicitação falhou | — | servidor não em execução |
Em resumo: 0 é sucesso, 1 é uma falha operacional, 2 significa que uma pessoa precisa agir (configuração, aprovação, um conector degradado ou uso inválido de linha de comando) e 3 significa que o servidor não pôde ser alcançado.
mac-mcp logs [server|cloudflared|ngrok|audit|update] [-n LINES] imprime as últimas linhas de um log com tokens, chaves e valores de credenciais redigidos; mac-mcp logs --list mostra o tamanho de cada log e os limites. Logs do servidor, cloudflared e ngrok rotacionam em 10 MB e mantêm três arquivos mais antigos (MAC_MCP_LOG_MAX_BYTES, MAC_MCP_LOG_BACKUPS); a rotação copia e trunca, então o processo em execução continua escrevendo. O log de auditoria (ferramenta, resultado e duração apenas, 0600) rotaciona em 5 MB com três arquivos mais antigos, e apenas os 20 logs de atualização mais recentes são mantidos (MAC_MCP_UPDATE_LOGS_KEPT).
Supervisão de crash. mac-mcp start registra que o servidor deve ser executado e carrega um pequeno job launchd (com.macmcp.supervisor, a cada 30 segundos; seu plist permanece em ~/.mac-mcp, então nada novo inicia no login). Se o processo do servidor desaparecer, ou parar de responder /health por quatro verificações consecutivas, ele é iniciado novamente através do mac-mcp start normal; um túnel ngrok encerrado é reiniciado da mesma forma enquanto o servidor continua em execução. mac-mcp stop registra a parada primeiro, então o supervisor nunca a desfaz, e o supervisor se afasta durante atualizações e reinicializações. Após três recuperações falhas em 15 minutos, ele recua. mac-mcp status e doctor (também Settings → Help & Diagnostics) mostram a última recuperação e o motivo; MAC_MCP_SUPERVISOR=0 desativa a supervisão.
Reinicializações. mac-mcp restart verifica a configuração, o binário do túnel e o Python do runtime antes de parar qualquer coisa, e deixa um servidor em funcionamento sozinho se uma verificação falhar. Se o novo servidor não subir, ele tenta uma vez; o estado final (succeeded, degraded quando apenas o endpoint público falhou, ou failed com um comando de reparo) é escrito em ~/.mac-mcp/restart-status.json. restart --wait espera por esse resultado, que é o que o botão Restart do app relata.
Atualizações. Apenas uma atualização é executada por vez; uma segunda solicitação informa o ID e o status da atualização em andamento. Os 10 backups de runtime mais recentes são mantidos (MAC_MCP_UPDATE_BACKUPS_KEPT), além daquele necessário para recuperação, e cada atualização remove pastas temporárias e worktrees deixados por um atualizador que foi interrompido. Worktrees de agentes concluídos sem nada restante para revisão são removidos após 7 dias (MAC_MCP_AGENT_WORKTREE_RETENTION_DAYS, 0 os mantém); doctor mostra o uso de disco de backups e worktrees.
Se o Python do runtime desaparecer. Quando uma atualização do Homebrew ou do macOS remove o Python a partir do qual o venv do runtime foi criado, mac-mcp informa isso e imprime o comando de reparo em vez de falhar com "bad interpreter":
python3 ~/mac-mcp/mcp_server/venv_repair.py check
python3 ~/mac-mcp/mcp_server/venv_repair.py repair
repair cria e verifica um novo venv ao lado do antigo com o Python do Homebrew mais recente suportado, faz a troca, mantém o antigo como .venv.previous-<timestamp> e o restaura se o novo falhar nas verificações. doctor avisa antecipadamente quando o venv aponta para um caminho versionado do Homebrew que a próxima atualização removerá.
mac-mcp conformance executa o laboratório de regressão determinística de Computer Use. Sua suíte padrão é segura para CI e verifica contratos como comportamento de navegador em segundo plano, fallbacks explícitos de primeiro plano, identidade estável de abas, rejeição de handles obsoletos, prontidão de render/elemento, lotes de ações limitados e tratamento de cliques sem efeito. --live adiciona verificações somente leitura neste Mac sem clicar ou digitar nos aplicativos do usuário.
Planos de Computer Use em malha fechada
computer_plan usa por padrão o schema v2 de planos para fluxos de trabalho limitados de múltiplas etapas em navegador/nativo. Além de etapas de ferramentas comuns e reutilização de resultados $ref, um plano pode usar wait_until, branch condicional, retry limitado e um único fallback seguro. Falhas recuperáveis de stale/prontidão pré-mutação podem acionar uma nova observação e re-vinculação semântica de alvo dentro da mesma chamada de ferramenta do modelo: alvos de navegador usam browser_find semântico, enquanto alvos nativos preferem AXIdentifier e, caso contrário, exigem uma impressão digital única de role/título/descrição. Correspondências ambíguas falham de forma fechada em vez de adivinhar.
A recuperação tem orçamentos independentes de contagem/tempo, além dos limites existentes de total de plano/unidades de ação. Trabalho de mutação nunca é reproduzido automaticamente após ACTION_NO_EFFECT, incerteza de verificação, negação de política, outcome_unknown, uma exceção cruzando um limite de ferramenta de mutação ou um lote de ações parcialmente bem-sucedido. resources opcionais do plano usam o mesmo estado global de propriedade que a admissão de agentes delegados, de modo que um recurso conflitante de aba/nativo/workspace pode falhar no preflight antes de qualquer etapa do plano ser executada. Cada ação aninhada ainda passa pela política normal do Mac MCP, escopo, leases de navegador/nativo, telemetria e verificação de efeitos.
Aceleração de Decisão Opcional (experimental)
Configurações → Avançado → Aceleração de Decisão tem um resolvedor OpenAI Decisions opcional. Ele está desativado por padrão. A chave da API OpenAI é armazenada no Keychain (com.bulutarkan.mac-mcp / openai-decisions-api-key) e nunca em settings.json; Testar envia uma pequena solicitação de verificação.
Quando o interruptor está desligado, a chave está ausente ou a OpenAI rejeitou a chave, o comportamento permanece inalterado e nenhuma chamada externa é feita. Quando ativado com uma chave funcional:
browser_actconsulta Decisions apenas quando a classificação determinística encontra dois ou mais alvos quase iguais (pontuações principais ≥ 0,60 e dentro de 0,10). Alvos únicos nunca acionam uma chamada.- A recuperação
computer_planconsulta Decisions apenas para uma re-vinculação ambígua de navegador/nativo que, caso contrário, falharia de forma fechada comRECOVERY_AMBIGUOUS_TARGET. - Ações
browser_actaceitam uma stringintentopcional (por exemplo, "a etapa de Faturamento") que é adicionada à entrada de Decisions apenas quando a classificação é ambígua. Ela é limitada a 120 caracteres e segredos são redigidos; sem ela, a solicitação permanece inalterada. - Decisions só pode escolher um dos IDs de candidatos já classificados. Uma escolha é aceita com confiança ≥ 0,80, ou ≥ 0,65 quando concorda com a correspondência determinística principal. Uma resposta
none, por exemplo em um empate verdadeiro, mantém a escolha determinística. - Uma alternativa arriscada (excluir, enviar, pagar, …) nunca é escolhida em vez da correspondência determinística.
- Timeouts (600 ms padrão), erros, limites de taxa, chaves inválidas e baixa confiança todos caem no caminho determinístico existente.
- Política, aprovações, leases, verificações de takeover e prontidão ainda são executados após a escolha e permanecem autoritativos.
- Apenas rótulos curtos e redigidos de candidatos, roles e o texto de alvo solicitado são enviados. Valores digitados, URLs e conteúdo de página não são enviados.
settings.json → decision_acceleration também aceita scope (browser, native, both, off), timeout_ms, accept_threshold, agree_threshold e max_candidates; um valor inválido desativa o recurso.
Endpoint local padrão:
http://127.0.0.1:8000/mcp
Uma porta personalizada pode ser fornecida por meio de MAC_MCP_PORT ou flags de CLI.
Voz
ChatGPT Voice como interface
Quando o Mac MCP está conectado como um plugin do ChatGPT, experiências suportadas do ChatGPT Voice podem usá-lo durante uma conversa ao vivo. Isso permite que você fale com o ChatGPT naturalmente enquanto o Mac MCP executa trabalhos suportados no Mac.
O Mac MCP não substitui nem modifica o ChatGPT Voice. Ele fornece a camada de execução por trás da conversa.
Interação de voz local
ask_user_voice é uma capacidade separada do Mac MCP. Ela permite que o agente fale um prompt curto pelo Mac, grave a resposta local, transcreva-a com Groq Whisper e continue a tarefa com a transcrição retornada.
A voz está desativada até você ativá-la, porque ela envia dados a terceiros: o texto da pergunta vai para o serviço de texto-para-fala online da Microsoft (edge_tts) e a resposta gravada vai para a Groq para transcrição, onde a retenção própria da Groq se aplica. Antes de cada gravação, o Mac MCP mostra um diálogo para Gravar, Sempre Permitir ou recusar; nada é gravado ou enviado antes dessa escolha, e um diálogo recusado ou sem resposta retorna skipped com fallback_tool: ask_user. Sempre Permitir pode ser revogado em Configurações → Voz → Perguntar antes de cada gravação. A gravação é excluída do Mac depois, a transcrição é substituída por [voice transcript not stored] no histórico de atividades, e cada decisão é registrada como um evento de segurança voice_egress com apenas provedor, modelo, consentimento e resultado.
O aplicativo de menu gerencia:
- alternância experimental de ativar/desativar;
- chave da API Groq no Keychain do macOS;
- microfone de entrada;
- dispositivo de saída;
- idioma;
- timeout;
- voz e taxa do TTS.
Configurações não secretas são armazenadas em:
~/.mac-mcp/settings.json
Variáveis de ambiente permanecem suportadas como fallbacks, incluindo MAC_MCP_VOICE_GROQ_API_KEY, GROQ_API_KEY, MAC_MCP_VOICE_LANGUAGE, MAC_MCP_VOICE_INPUT_DEVICE, MAC_MCP_VOICE_OUTPUT_DEVICE e MAC_MCP_VOICE_TTS_RATE.
Alterações transacionais no sistema de arquivos e desfazer
O Mac MCP registra em diário suas operações primárias destrutivas de arquivo antes de alterar o sistema de arquivos. write_file, edit_file, move_file e delete_path agora retornam um transaction_id aleatório, além de undoable, undo_expires_at e qualquer irreversible_reason explícito. write_files_batch(..., atomic=true) prepara todas as pré-imagens antes da primeira gravação e restaura todo o lote se qualquer gravação posterior falhar. file_transaction_batch estende o mesmo limite de tudo-ou-nada a uma sequência mista de até 50 ações write, move e delete. Transações reversíveis recentes podem ser restauradas com file_transaction_undo; por padrão, o desfazer se recusa a sobrescrever arquivos alterados após o commit original, enquanto force=true é uma substituição explícita de conflito.
O diário vive sob ~/.mac-mcp/transactions/ por padrão. O diretório e as pastas de transação são somente do proprietário (0700); manifestos e arquivos de snapshot são 0600. Manifestos contêm apenas os caminhos/estado necessários para restauração, hashes/impressões digitais, tamanhos, timestamps e metadados de transação — nunca o novo conteúdo de arquivo ou texto de edição. Pré-imagens reversíveis necessariamente contêm os bytes originais, então são mantidas apenas em arquivos de snapshot somente do proprietário com retenção limitada. Os padrões são uma janela de desfazer/expiração de 7 dias, 64 transações, 1 GiB de armazenamento total do diário e 256 MiB de dados de pré-imagem por transação; entradas expiradas são removidas na inicialização do daemon e na atividade do diário, enquanto limites de contagem/bytes são aplicados em cada transação. As variáveis de ambiente MAC_MCP_FILE_JOURNAL_* correspondentes podem restringir esses limites.
Se uma única pré-imagem de gravação/movimentação/exclusão exceder o limite de snapshot, a operação preserva a compatibilidade retroativa, mas retorna undoable=false com irreversible_reason=snapshot_limit_exceeded. Operações atômicas em lote são mais estritas: se um snapshot completo de rollback não puder ser preparado, o lote é recusado antes da primeira mutação. Uma falha de processo após a preparação, mas antes do commit, deixa uma entrada de diário prepared; o desfazer normal trata esse resultado como desconhecido, enquanto um force=true explícito pode restaurar o pré-estado registrado. O desfazer de agente delegado também re-verifica cada caminho de transação contra o escopo de recursos atual do agente, de modo que um ID de transação não pode contornar o confinamento do workspace. copy_file e create_directory não fazem parte deste limite inicial de diário de transações.
Escopos de arquivo delegados seguros contra symlinks
Chamadas delegadas com path_roots explícito usam um segundo limite de sistema de arquivos em tempo de operação, além da verificação normal de política do servidor. Leituras, gravações, edições, movimentações, cópias, exclusões, travessia de diretórios, busca de nome/conteúdo, snapshots de transação e desfazer/rollback com escopo percorrem componentes de caminho com descritores de arquivo de diretório, além de O_NOFOLLOW, em vez de confiar em uma string de caminho verificada anteriormente. Uma troca de symlink entre a validação de política e a operação real do sistema de arquivos, portanto, falha de forma fechada em vez de seguir a substituição para fora do workspace. Operações recursivas de find/search/tree relatam ou pulam entradas de symlink sem atravessá-las, e o acesso direto a um symlink que resolve fora das raízes permitidas é negado.
Essa travessia mais estrita é aplicada apenas quando um escopo de recursos delegado tem path_roots explícito; o comportamento local comum de arquivos sem escopo permanece compatível. Movimentações entre dispositivos com escopo são rejeitadas em vez de cair em uma sequência de cópia/exclusão que enfraqueceria o limite de descritores. Falhas de corrida retornam erros estruturados scoped_path_unsafe e não expõem conteúdos de arquivos fora do workspace.
Garantia de segurança
O Mac MCP publica uma Matriz de Garantia de Segurança apoiada por regressão que mapeia classes de risco estáveis para seus controles, testes automatizados exatos e histórico de versões. scripts/verify_security_assurance.py valida esses links no CI, de modo que testes renomeados, controles ausentes, tags de garantia órfãs, falta de vinculação ao CHANGELOG e material semelhante a segredo/caminho privado na matriz pública falham no gate em vez de ficarem silenciosamente desatualizados.
O acesso ao plano de controle de agentes delegados é limitado por linhagem. Um agente com escopo pode inspecionar e gerenciar a si mesmo e descendentes que possui, mas metadados, resultados, logs, esperas e ações de ciclo de vida de irmãos, ancestrais e agentes/equipes não relacionados falham de forma fechada. O plano de controle autenticado/raiz local mantém sua visão administrativa existente. A linhagem de proprietário/raiz/pai é persistida nos metadados de agente/equipe, e eventos de negação são registrados sem abrir uma intenção de efeito colateral mutante.
Retomada durável de fluxo de trabalho delegado
Agentes delegados agora obtêm um checkpoint de fluxo de trabalho durável e independente de provedor sob ~/.mac-mcp/workflows/. O checkpoint armazena o hash de entrada da tarefa original, linhagem de provedor/sessão, geração de retomada, um cursor de marco do provedor sanitizado e uma cadeia limitada de recibos de efeitos colaterais verificados do Mac MCP. As linhas de recibos contêm metadados de ferramenta/família, além de hashes de argumentos/resultados; prompts brutos, comandos, conteúdos de arquivos, valores tipados, credenciais e cargas de ferramentas não são copiados para o armazenamento de checkpoints. Os arquivos de fluxo de trabalho e de mapa de agentes são somente do proprietário (0600) dentro de um diretório somente do proprietário (0700) e carregam um hash de integridade, de modo que estado corrompido ou incompatível falhe de forma segura.
Uma agent_action(action="retry") normal só é permitida enquanto a reprodução do prompt original ainda for segura. Uma vez que um efeito colateral verificado tenha ocorrido, uma geração de retomada já exista ou o resultado se torne incerto, uma nova reprodução retorna 409 retry_replay_unsafe. Para um agente interrompido com um checkpoint verificado, agent_action(action="resume") continua a mesma sessão de provedor com uma geração incrementada e um resumo compacto de recibos que instrui explicitamente o provedor a não repetir efeitos colaterais concluídos. Se a sessão do provedor não puder ser recuperada, o hash de entrada/sessão não corresponder, o checkpoint estiver corrompido ou uma mutação direta nativa do provedor tornar o estado de commit não verificável, o Mac MCP retorna um conflito de resultado desconhecido em vez de adivinhar.
O Mac MCP pode emitir recibos fortes apenas para efeitos colaterais roteados por meio de seu próprio limite de ferramentas. Antes de uma ferramenta mutável do Mac MCP ser executada, ela grava de forma durável uma intenção de efeito colateral pendente com hash; apenas um resultado retornado com sucesso pode converter essa intenção em um recibo verificado. Se o processo morrer no meio, a intenção pendente sobrevive e o fluxo de trabalho se torna de resultado desconhecido em vez de reproduzível. Mutações diretas de shell ou arquivo do Codex/OpenCode são, portanto, tratadas de forma conservadora em um limite de falha; atividade opaca de ferramenta CLI do ChatGPT Web também é marcada como incerta. Isso é intencional: a retomada durável prefere recusar uma reprodução ambígua a afirmar que uma ação destrutiva é segura para repetir. Os metadados de agente/dashboard expõem workflow_id, resume_generation, estado/segurança do checkpoint, contagens de efeitos colaterais pendentes/verificados, o cursor sanitizado, o último horário de checkpoint durável e se um agente interrompido pode ser retomado com segurança.
O cancelamento do cliente segue o mesmo modelo de segurança. Os corpos de ferramentas MCP síncronos recebem um contexto de cancelamento cooperativo compartilhado, mesmo quando executados em uma thread de trabalho. O Mac MCP encerra grupos de processos que possui, interrompe trabalhos criados por uma chamada de comando paralelo cancelada, interrompe a sondagem nativa do navegador, libera leases de abas do navegador por meio da limpeza normal de contexto e executa restauração de foco nativa limitada antes de propagar o cancelamento. A telemetria registra cancelled separadamente de falhas comuns. Se uma operação mutável for opaca ou não puder ser comprovadamente interrompida antes de seu efeito, sua intenção durável é encerrada como client_cancelled_outcome_unknown, telemetria/controle expõem outcome_unknown e a nova tentativa/retomada automática é bloqueada em vez de arriscar um efeito colateral duplicado.
Worktrees Git isolados para agentes de escrita
Agentes delegados com access_mode="workspace_write" usam git_isolation="auto" por padrão. Quando cwd está dentro de um repositório Git e o escopo de escrita pode ser atenuado com segurança, o Mac MCP cria uma branch/worktree efêmera sob uma raiz de workspace já autorizada, remapeia o cwd/escopo de caminho do filho para esse checkout e registra o commit base, além de metadados de arquivos alterados/diff. git_isolation="required" falha de forma segura quando essa garantia não pode ser aplicada; off mantém o checkout original. Agentes somente leitura não precisam de worktree, enquanto acesso full irrestrito nunca é apresentado como confinado a worktree. Workspaces não-Git mantêm graciosamente o comportamento existente no modo auto.
Tarefas irmãs paralelas recebem worktrees separados. Uma equipe fixa um commit base Git, tarefas downstream de DAG/revisores integram patches de dependências concluídos em um checkout isolado novo, e revisões/retomadas limitadas de codificadores continuam o mesmo worktree em vez de perder edições em andamento. Cancelamento/falha deixa o checkout isolado recuperável. get_agent/wait_agents expõem o caminho do worktree, base, arquivos alterados, estatística de diff e estado de aplicação.
Retornar alterações ao checkout de origem do usuário é explícito: agent_action(action="apply") é somente plano de controle local/raiz. Ele recusa caminhos tocados que estão sujos, detecta alterações de caminhos tocados desde a base do agente, pré-valida o patch contra o HEAD atual em um worktree de integração temporário, reverifica impressões digitais por caminho imediatamente antes da mutação e reverte pré-imagens já copiadas se uma etapa de aplicação interna falhar. Ele nunca executa git reset --hard, git clean ou um cherry-pick/merge automático da árvore de origem. Alterações não relacionadas do usuário são deixadas intactas. Conflitos retornam os caminhos afetados e nenhuma mutação intencional da árvore de origem. despawn recusa alterações isoladas não aplicadas até que sejam aplicadas com segurança ou descartadas explicitamente; worktrees de retomada/revisão compartilhados permanecem ativos até que sua última referência de agente desapareça.
Admissão global de agentes entre equipes
Equipes delegadas independentes compartilham uma fila de admissão persistida antes do início dos processos do provedor. O agendador aplica um teto global de agentes ativos, além de tetos específicos por provedor entre equipes, de modo que várias equipes não possam consumir cada uma seu próprio orçamento max_parallel e sobrecarregar coletivamente o mesmo provedor. Os padrões são 8 globais e 8 por provedor; operadores podem ajustar MAC_MCP_AGENT_GLOBAL_ACTIVE_LIMIT, MAC_MCP_AGENT_PROVIDER_LIMIT e substituições de provedor, como MAC_MCP_AGENT_PROVIDER_LIMIT_OPENCODE, _CODEX ou _CHATGPT. As leases de admissão são estado local somente do proprietário, com heartbeat dos trabalhadores em execução e reivindicadas após MAC_MCP_AGENT_ADMISSION_TTL_S se um trabalhador desaparecer. MAC_MCP_AGENT_ADMISSION_QUEUE_LIMIT limita o trabalho persistente em espera.
A fila é ciente de FIFO sem transformar um recurso bloqueado não relacionado em um gargalo global de cabeça de linha. Trabalho executável mais antigo mantém prioridade para slots escassos de provedor/global e recursos conflitantes, enquanto uma tarefa bloqueada no workspace A não impede uma tarefa mais jovem de usar o workspace independente B. O estado de tarefa/equipe expõe queued, posição/motivo/detalhes da fila, reivindicações de recursos e contagens ativas globais/provedor. O dashboard de Operações mostra o global ativo/limite e a contagem enfileirada em tempo real. O cancelamento da equipe remove suas solicitações enfileiradas imediatamente; leases ativas permanecem mantidas até que seu provedor/trabalhador seja realmente interrompido. A conclusão normal desperta outras equipes enfileiradas automaticamente, e leases de falha expiradas são podadas de forma segura na próxima admissão/snapshot. O estado de throttle existente do ChatGPT alimenta a mesma decisão de admissão: cooldown ativo impede nova admissão, e a janela de concorrência reduzida pós-throttle temporariamente reduz o limite efetivo do agendador global do ChatGPT para um, enquanto o gate de espaçamento de início existente controla o horário exato de lançamento seguro.
Tarefas spawn_agents podem opcionalmente declarar reivindicações resources=[...]. Os tipos suportados são workspace, path, file, browser_tab, native_app, native_window, process e clipboard; os modos são read ou write. Reivindicações de leitura/leitura podem coexistir, enquanto qualquer escrita sobreposta é serializada. IDs de caminho/arquivo/workspace são resolvidos dentro do escopo de caminho delegado da tarefa, reivindicações de abas do navegador devem caber no escopo do navegador da tarefa, e leases de abas em tempo de ação do navegador existentes permanecem como guarda final de propriedade em vez de serem substituídas. Escopos de caminho somente leitura são automaticamente reivindicados como leituras compartilhadas. Escritas em workspaces não-Git são automaticamente reivindicadas como escritas exclusivas; worktrees Git isolados #50 evitam intencionalmente uma reivindicação de escrita grosseira do repositório de origem para que worktrees irmãos independentes ainda possam ser executados concorrentemente.
read_file também retorna um revision aditivo usando a mesma impressão digital das verificações de conflito de transação do sistema de arquivos. Uma tarefa pode anexar esse valor como expected_revision em uma reivindicação kind="file". O Mac MCP o reverifica antes da admissão/início do provedor; uma incompatibilidade retorna file_revision_conflict e o provedor nunca começa, fornecendo uma guarda estilo CAS para corridas de mutação de arquivos.
Notificações nativas de conclusão de agentes
O aplicativo de menu do macOS pode opcionalmente notificá-lo quando o trabalho delegado terminar enquanto o Mac MCP estiver em segundo plano. O recurso está desativado por padrão e a permissão de notificação do macOS é solicitada somente quando você ativa explicitamente Notificações de Agentes nas Configurações Gerais.
Agentes autônomos geram uma notificação de terminal para estados de conclusão ou necessidade de atenção. Equipes multiagentes são coalescidas em uma notificação de terminal de nível de equipe em vez de uma notificação por filho. O conteúdo da notificação é intencionalmente mínimo: apenas um rótulo sanitizado de agente/equipe é mostrado, nunca prompts brutos, resultados, URLs, caminhos de arquivos ou segredos. Clicar em um alerta abre o dashboard autenticado local de Operações focado no agente ou equipe relevante. O tempo de entrega, Não Perturbe, modos de Foco e apresentação permanecem sob controle do macOS.
Orçamentos de equipe de agentes e nova tentativa adaptativa
Resultado de equipe ciente de falhas e quórum
wait_agents separa conclusão de sucesso. mode="all" mantém seu significado de conclusão existente (condition_met=true uma vez que todo trabalho relevante é terminal), enquanto campos aditivos success, outcome e partial_failure indicam se o trabalho concluído realmente teve sucesso. mode="any" e mode="majority" contam apenas trabalho completed bem-sucedido; trabalho com falha, tempo esgotado, travado, cancelado, ignorado, orçamento esgotado e com falha de qualidade não pode satisfazer um quórum de sucesso. Para equipes DAG, o quórum é calculado sobre resultados de tarefas em vez de tentativas históricas de agentes, de modo que novas tentativas/revisões não distorcem o denominador.
Resultados de trabalho normalizados são running, completed, partial_failure, failed ou cancelled. timed_out é deliberadamente separado e significa apenas que o prazo da chamada de espera expirou enquanto sua condição ainda era possível; um agente cujo próprio status é timeout é relatado como trabalho com falha, não como timeout de espera. As respostas também incluem contagens de sucesso/falha/pendente, totais/limiares de quórum, quorum_possible e razões estruturadas de falha de tarefa/agente. Campos existentes de equipe status, count, terminal_count, linhas de agentes e campos aninhados team permanecem disponíveis para compatibilidade.
spawn_agents aplica limiares de admissão de equipe compartilhados além do timeout de cada agente filho. max_parallel permanece o teto de concorrência; team_timeout_s limita por quanto tempo o agendador pode admitir novos nós DAG. admission_tool_call_budget e admission_token_budget opcionais param novos nós DAG e novas tentativas uma vez que o uso observado da equipe atinge o limiar configurado. Eles são intencionalmente não limites rígidos de tempo de execução: agentes que já estavam em execução podem terminar e empurrar o uso observado além do limiar em vez de serem mortos em um limite inseguro de efeito colateral. Os resumos de equipe expõem o contrato, valores usados/restantes, excesso e se o trabalho ainda está ativo no limiar. Os nomes mais antigos max_total_tool_calls e max_total_tokens permanecem aliases obsoletos para compatibilidade e têm a mesma semântica somente de admissão.
max_team_retries é um orçamento de repetição compartilhado separado. Repetições automáticas são classificadas antes da reprodução: limites de taxa, timeouts/paradas, sobrecarga do provedor e falhas transitórias de transporte podem ser repetidas; autenticação, permissão, cota, modelo/solicitação inválidos e falhas desconhecidas do provedor falham rapidamente. A segurança durável de efeitos colaterais/checkpoint tem precedência sobre a classificação de erros, e cada slot de repetição de equipe é reservado atomicamente com espaçamento inicial limitado, para que falhas concorrentes não possam criar uma tempestade de repetições. admission_token_budget é aceito apenas para provedores que expõem uso confiável; o ChatGPT Web atualmente rejeita essa opção em vez de fingir que o uso não relatado é zero.
Superfície da API de Memória e Habilidades de Agente
O endpoint MCP nativo permanece como a superfície completa de Memória e Habilidades de Agente. REST/OpenAPI expõe intencionalmente apenas o subconjunto de compatibilidade somente leitura: memory_search, memory_get, skill_list, skill_search e skill_get baseado em nome. Essas rotas usam a mesma autenticação de servidor, perfil de permissão, autorização de família de ferramentas com escopo e gate de contexto de segurança que o restante da superfície REST publicada.
As memórias são armazenadas como arquivos de dia em Markdown sob ~/.mac-mcp/memory (ou MAC_MCP_MEMORY_DIR) mais um índice de busca SQLite local; a pasta, os arquivos e o índice são mantidos somente para o proprietário, mesmo para um local personalizado. Excluir uma memória a remove do arquivo Markdown (e do próprio arquivo, uma vez que um dia não tenha mais memórias) e do índice, suas linhas de texto completo e vetor, com exclusão segura do SQLite e um checkpoint WAL para que o texto não permaneça no banco de dados; isso não é uma limpeza forense de disco. Configurações → Uso → Memória mostra quantas memórias existem, exporta todas como JSON, exclui todas após mostrar quantas serão excluídas e define um período de retenção opcional (até exclusão por padrão; 90 dias a 2 anos), que mantém memórias altas e críticas, a menos que você desative isso.
Mutação de memória (memory_add, memory_update, memory_delete) e registro/índice de mutação de Habilidades de Agente (skill_register, skill_update_index) permanecem somente MCP. REST skill_get aceita um nome de habilidade exato, mas deliberadamente não aceita um caminho SKILL.md porque a busca de caminho MCP pode registrar uma habilidade externa. Respostas REST públicas também omitem metadados locais de sistema de arquivos/índice, como caminhos de arquivos de memória, raízes/diretórios/caminhos de recursos absolutos de habilidades e diagnósticos de sincronização de índice.
Aprendizado de papéis para agentes delegados
O Mac MCP mantém lições de fluxo de trabalho separadas da memória factual genérica. Agentes delegados podem optar por um papel com role="coder", role="reviewer" ou role="orchestrator". No momento da criação, apenas um pequeno conjunto top-k de lições aprovadas e relevantes para esse papel é injetado; as instruções atuais da tarefa sempre têm prioridade. Tarefas não relacionadas não recebem contexto de lição.
Um trabalhador pode emitir um candidato compacto e estruturado de lição no final de uma execução, mas os candidatos são colocados em quarentena e nunca ativados automaticamente. lesson_search permite que o pai revise os candidatos e lesson_feedback registra resultados de approve, success, failure, disable ou enable. Falhas repetidas reduzem a confiança e podem desabilitar uma lição; lições obsoletas de baixa confiança podem ser desabilitadas durante lesson_consolidate. Duplicatas exatas são mescladas dentro do mesmo domínio de confiança, enquanto ações preferenciais contraditórias são relatadas para revisão em vez de escolher silenciosamente um vencedor. Criação manual de candidatos e consolidação permanecem disponíveis por meio da descoberta de ferramentas, para que a superfície compacta de ferramentas permaneça pequena. lesson_export retorna todas as lições armazenadas para revisão, e lesson_delete remove uma lição, as lições de um papel ou todas as lições após confirm=true (o texto excluído é sobrescrito no disco). Lições não atualizadas ou usadas por privacy.lesson_retention_days (padrão 365, 0 as mantém até a exclusão) são removidas automaticamente e nunca chegam a um prompt de trabalhador.
As lições de papel são armazenadas como campos estruturados e referências de evidência limitadas em ~/.mac-mcp/role-learning/role-lessons.sqlite3; transcrições brutas de agentes não são armazenadas no banco de dados de lições. A proveniência fixa é aplicada: uma sessão contaminada pela web não pode escrever ou aprovar lições confiáveis, filhos contaminados não recebem contexto de lição confiável e candidatos não confiáveis são mantidos em um namespace de quarentena separado, para que não possam envenenar uma lição confiável existente.
Resiliência de subagentes ChatGPT
Quando o ChatGPT Web CLI é usado como provedor de agente delegado, o Mac MCP mantém longas alternâncias web limitadas sem tratar o orçamento como um timeout rígido de tarefa. O orçamento padrão de alternância suave é de 15 minutos; se uma ferramenta ainda estiver ativa, o Mac MCP espera por ela, com um teto rígido de ferramenta de 20 minutos, e então solicita um interrupt controlado do ChatGPT que continua a mesma tarefa em uma nova alternância. A continuação evita explicitamente repetir trabalho concluído ou efeitos colaterais externos. Subagentes ChatGPT usam raciocínio Alto por padrão; extra-high permanece opcional.
Se o ChatGPT relatar limitação de solicitações, o Mac MCP registra o motivo/hora, aplica um resfriamento exponencial limitado, recupera a sessão existente do ChatGPT para repetição quando possível e escalona outros inícios de trabalhadores ChatGPT durante a janela de recuperação em vez de lançar uma tempestade de repetições. Linhas de agentes no painel e na barra de menu expõem o tempo decorrido da alternância, além de contagens de checkpoint/limitação. Esses valores podem ser ajustados com CHATGPT_PROVIDER_TURN_BUDGET_S, CHATGPT_PROVIDER_HARD_TOOL_BUDGET_S, CHATGPT_PROVIDER_RATE_LIMIT_BACKOFF_S e CHATGPT_PROVIDER_RATE_LIMIT_BACKOFF_CAP_S.
Painel de operações
Abra-o com o lançador local autenticado:
mac-mcp dashboard
O shell estático do painel é somente loopback. Cada solicitação sensível /dashboard/api/* e o fluxo ao vivo /dashboard/events adicionalmente exigem um token Bearer separado do painel armazenado em ~/.mac-mcp/dashboard-token com modo 0600; o diretório de estado é mantido somente para o proprietário (0700). O app CLI/menu passa a credencial do navegador em um fragmento de URL, que não é enviado na solicitação HTTP, e o JavaScript do painel imediatamente o move para sessionStorage, remove-o da barra de endereço e usa um cabeçalho Authorization para solicitações API/SSE. O conector global MCP_API_KEY não é exposto ao navegador.
O painel registra atividade de ferramentas MCP/REST sanitizada, status, latência, estado recente de agentes delegados, chamadas ativas e frequência de ferramentas. Campos de identidade do provedor, como sessão/assunto/organização/localização do OpenAI, são descartados da telemetria; a migração de segurança também limpa linhas persistidas legadas no primeiro início. A telemetria persiste localmente sob:
~/.mac-mcp/dashboard/telemetry.sqlite3
Loopback significa local à máquina, não privado ao usuário. O token do painel impede que processos locais não autenticados não relacionados e solicitações de origem de navegador usem endpoints sensíveis, mas um processo malicioso já em execução como o mesmo usuário macOS geralmente pode ler os arquivos desse usuário e está dentro desse limite de confiança. Sockets de domínio Unix foram avaliados para tráfego app de menu ↔ daemon; eles podem fornecer permissões de proprietário do sistema de arquivos, mas não resolvem o isolamento de mesmo UID e não podem ser consumidos diretamente pelo painel do navegador, então HTTP loopback autenticado permanece como o único transporte. Veja docs/LOCAL_API_SECURITY.md para o modelo de ameaça e decisão.
Cobertura de ferramentas
O Mac MCP 2.1 anuncia uma superfície central compacta por padrão, apoiada por um catálogo de capacidades MCP central registrado maior. O catálogo visível exato é consciente do perfil de permissão e do escopo delegado: list_tools e tool_discover usam a mesma política de disponibilidade, enquanto tool_invoke preserva o status de sucesso/falha da ferramenta aninhada.
Defina MAC_MCP_TOOL_PROFILE=full para anunciar todas as ferramentas permitidas pelo perfil de permissão ativo diretamente ao cliente. Você também pode adicionar ferramentas selecionadas à superfície compacta com MAC_MCP_CORE_EXTRA_TOOLS=name1,name2. Contagens exatas do catálogo são intencionalmente derivadas em tempo de execução em vez de codificadas aqui, para que a documentação não possa divergir conforme ferramentas são adicionadas ou removidas.
O conjunto de capacidades cobre:
- terminal/sistema e trabalhos em segundo plano (cada fluxo de saída mantém até 16 MB,
get_job_outputlê apenas a fatia solicitada, trabalhos concluídos expiram após 7 dias, 200 trabalhos ou 1 GB, edelete_jobremove um; substitua comMAC_MCP_JOB_STREAM_MAX_BYTES,MAC_MCP_JOB_RETENTION_DAYS,MAC_MCP_JOB_RETENTION_COUNT,MAC_MCP_JOB_RETENTION_BYTES); - agentes delegados OpenCode/Codex;
- gerenciamento de arquivos;
- automação macOS e controle de UI de Acessibilidade;
- receitas salvas:
computer_plan(save_as_recipe="name")mantém um plano bem-sucedido como rascunho em~/.mac-mcp/recipes(somente proprietário);recipe(action="update", parameterize=[{"literal": "October", "param": "month"}])transforma valores fixos em parâmetros tipados,recipe(action="activate", confirm=true)o torna executável após revisão (valores semelhantes a segredos são recusados), erecipe(action="run", values={...})valida os valores e executa as etapas por meio decomputer_plancom a política e verificação usuais; receitas podem ser listadas, inspecionadas, pausadas, retomadas e excluídas; - lançadores de receitas fora de um chat:
mac-mcp recipe listemac-mcp recipe run rcp_… --param month=November(saída 0 concluído, 1 falhou, 2 precisa de aprovação, 3 servidor não está em execução) para comandos de script Raycast ou uma ação "Executar Script de Shell" do Shortcuts, e linksmacmcp://recipe/run?id=rcp_…&month=Novemberpara uma ação "Abrir URL" do Shortcuts. Um link sempre pede confirmação no Mac MCP antes de executar e o resultado chega como uma notificação; lançadores só podem executar receitas ativadas e passar valores simples, nunca nomes de ferramentas ou comandos; - adaptadores tipados
mac_apppara Finder, Notas, Mail, Calendário, Lembretes, Pré-visualização e Ajustes do Sistema, incluindo Calendáriocreate_event/update_event, Lembreteslist_reminders/complete_reminder, Notascreate_notee Mailcreate_draft(salvo apenas em Rascunhos, nunca enviado; com várias contas de Mail, o remetente deve ser nomeado): cada um retorna o id estável do item com uma verificação de leitura de volta, uma criação repetida retorna o item existente em vez de um gêmeo, e um resultado incerto é relatado comooutcome_unknownem vez de repetido; - automação de navegador Safari/Chrome com identificadores de aba estáveis e observação visual em segundo plano;
browser_checkpointentrega uma etapa de login, 2FA, passkey ou captcha a você (uma notificação, então o agente espera até 5 minutos ou verifica novamente) e retoma quando essa aba não mostra mais o desafio, sem ler ou armazenar senhas ou códigos; com o complemento Chrome, agentes também trabalham dentro de quadros de origem cruzada (frame=), veem diálogos nativos de alerta/confirmar/prompt e respondem apenas em uma decisão explícita, usam eventos reais de passar o mouse, arrastar e teclas, e clicam em apps canvas por coordenadas de viewport; - HTTP e busca;
- entrada humana de texto/escolha/confirmação/voz;
- memória persistente;
- Habilidades de Agente;
- auto-atualização segura.
Use a descoberta de ferramentas MCP para o esquema ao vivo autoritativo. tool_discover classifica ferramentas contra uma consulta em palavras simples, diz por que cada uma correspondeu e pagina resultados longos com next_cursor.
Listagens e leituras de múltiplos arquivos relatam quando param cedo: list_directory, find_files e list_jobs retornam page.has_more/page.next_cursor, read_multiple_files gasta um orçamento total de caracteres e lista arquivos não lidos em not_read, e read_file fornece next_offset para a próxima linha.
Falhas carregam um contrato legível por máquina em cada transporte: um erro MCP termina com uma linha error_contract={...} e um corpo de erro REST tem um objeto error ao lado de detail, ambos com code, stage, outcome (not_executed, completed ou unknown) e retry (fix_arguments, safe_retry, observe_again, wait_for_user ou never_retry). Um resultado unknown nunca diz safe_retry; observe o estado atual antes de agir novamente. Uma ferramenta que executou e relatou falha (por exemplo, uma saída de shell não zero) é um resultado normal com ok: false, não um erro.
Ferramentas MCP que alteram estado aceitam um idempotency_key opcional (8-128 caracteres). Repetir uma chamada concluída com a mesma chave e argumentos retorna o primeiro resultado marcado como idempotent_replay em vez de executá-la novamente; a mesma chave com argumentos diferentes é idempotency_key_conflict; uma repetição enquanto a primeira chamada ainda está em execução ou terminou com resultado desconhecido é recusada, nunca reexecutada. As chaves são limitadas ao chamador (agente ou ator autenticado, para que um cliente reconectado ainda encontre sua chamada) e mantidas por 24 horas em um ~/.mac-mcp/idempotency.sqlite3 exclusivo do proprietário; resultados que parecem segredos ou excedem 256 KB não são armazenados. Isso é deduplicação, não execução exatamente uma vez.
REST tem uma superfície versionada gerada a partir do contrato da ferramenta MCP: POST /api/v2/<tool> usa o próprio esquema de entrada da ferramenta MCP e passa pelas mesmas políticas, aprovações, telemetria, idempotency_key e contrato de erro. Uma chamada concluída retorna o resultado da ferramenta com HTTP 200 (mesmo quando relata ok: false); uma falha retorna {"error": {...}} com o status do contrato. O esquema é publicado em openapi/mac-mcp-v2.json (versão da API 2.0.0, versão do produto em x-product-version), regenerado com python -m mcp_server.rest_v2 --write e verificado quanto a desvios nos testes. As rotas não versionadas /api e openapi/custom-gpt-actions.json continuam funcionando inalteradas.
Atualização
Pelo aplicativo: clique no ícone da barra de menus do Mac MCP, abra Configurações (ícone de engrenagem) → Geral → Atualizações. O cartão verifica o canal de lançamento verificado quando você o abre e mostra sua versão atual ao lado do lançamento verificado mais recente. Verificar atualização verifica novamente, e Atualizar agora instala enquanto o cartão lista cada etapa em execução, desde Preparar e Backup até Reiniciar e a verificação final de Saúde. Se uma atualização for interrompida, o mesmo botão muda para Retomar recuperação ou Tentar recuperação novamente. "Bloqueado por alterações locais" significa que o checkout da fonte tem arquivos não confirmados ou não rastreados (git status no checkout da fonte os lista): confirme, guarde ou mova-os e verifique novamente. Se algo ainda parecer errado, mac-mcp doctor relata o estado da atualização e da recuperação.
Pelo Terminal, para automação ou se preferir a CLI:
mac-mcp update --check
mac-mcp update
Ambos os caminhos executam o mesmo atualizador com as mesmas verificações de assinatura, linhagem e repositório sujo.
O atualizador examina o histórico do primeiro pai de origin/main e instala o checkpoint de lançamento estável verificado criptograficamente mais recente, não o HEAD arbitrário do repositório. Commits de desenvolvimento ou não verificados além desse checkpoint não são oferecidos como atualizações normais. Ele também bloqueia repositórios sujos, preserva sobreposições de runtime e arquivos privados, cria um backup de runtime, reinicia o serviço gerenciado, realiza uma verificação de saúde e reverte arquivos de runtime gerenciados se a verificação falhar.
Na versão 2.0, menu_app/ faz parte do runtime gerenciado. Se Mac MCP.app já estiver instalado, uma atualização bem-sucedida o reconstrói e atualiza automaticamente.
Permissões do macOS
Conceda apenas as permissões exigidas pelas ferramentas que você usa:
- Acessibilidade para
mac_observe,mac_act, Eventos do Sistema e automação de desktop; - Gravação de tela para captura de tela protegida;
- Automação quando o macOS pedir permissão para controlar Safari, Chrome, Eventos do Sistema, Lembretes ou outros aplicativos;
- Microfone para
ask_user_voice.
Contribuição e segurança
Contribuições são bem-vindas. Veja CONTRIBUTING.md para o fluxo de trabalho de desenvolvimento e pull requests. Use os formulários de issue do GitHub para bugs e solicitações de recursos, siga SECURITY.md para relato privado de vulnerabilidades e veja CODE_OF_CONDUCT.md para expectativas da comunidade.
Desenvolvimento
Execute os testes:
python -m unittest discover -s tests -v
Compile o aplicativo de menu nativo sem instalá-lo:
./menu_app/build_app.sh /tmp/mac-mcp-build
Estrutura do projeto:
mcp_server/ Python MCP server and dashboard
menu_app/ Native SwiftUI menu bar controller
tests/ Regression tests
openapi/ REST/OpenAPI schema assets
Licença
MIT