Mac MCP

Servidor local de control de macOS de código abierto para agentes de IA: automatización de Safari/Chrome en segundo plano, aplicaciones nativas, archivos, shell y agentes delegados.

Documentación

Mac MCP

Mac MCP 2.1.9

Mac MCP es un servidor de control local para macOS destinado a agentes de IA. Expone tu Mac a través de un endpoint MCP nativo y una superficie REST/OpenAPI, con shell, archivos, automatización de navegador, control de UI de macOS, agentes delegados de OpenCode/Codex, memoria, habilidades de agente, interacción por voz, herramientas de autoactualización y un panel de operaciones local. El endpoint MCP nativo es la superficie de capacidad completa; REST/OpenAPI publica intencionalmente un subconjunto de compatibilidad seleccionado, por lo que algunas capacidades permanecen solo en MCP.

Habla con ChatGPT. Déjalo trabajar en tu Mac.

Mac MCP es agnóstico al modelo y funciona con clientes de IA compatibles con MCP. Pero ChatGPT es una forma especialmente natural de usarlo.

ChatGPT Live puede usar plugins durante conversaciones por voz. Con Mac MCP conectado, la misma conversación de ChatGPT que ya usas puede convertirse en una superficie de control para tu Mac real. Puedes hablar con naturalidad mientras Mac MCP maneja la ejecución: navegar en Safari o Chrome, trabajar con archivos, abrir aplicaciones, ejecutar comandos y coordinar agentes.

En lugar de mover cada tarea a una sesión separada de agente de codificación, puedes mantener la interacción en ChatGPT y simplemente hablar. Desde tu teléfono, puedes pedirle a ChatGPT que trabaje en un Mac accesible en otro lugar. Desde tu escritorio, puedes seguir hablando mientras Mac MCP trabaja en segundo plano sin tomar el control de la computadora.

Por ejemplo:

  • "Revisa mis respuestas de Reddit, responde las importantes y cierra el navegador cuando termines."
  • "Recorre el repositorio, ejecuta las pruebas y dime qué está roto."
  • "Encuentra tres hoteles para el próximo fin de semana, compara las reseñas y guarda la lista corta en mi Mac."

ChatGPT es la conversación. Mac MCP es la capa de ejecución.

El panel de Mac MCP en ChatGPT

Cuando Mac MCP está conectado como plugin de ChatGPT, ChatGPT también muestra Mac MCP como una aplicación que puedes abrir junto a tus conversaciones: desde la barra lateral de ChatGPT en pantalla completa, o como panel lateral dentro de cualquier chat. El panel muestra la actividad de herramientas, agentes delegados y uso de tokens de un vistazo, y te permite elegir el agente predeterminado al que ChatGPT delega. Solo se actualiza cuando presionas actualizar.

El panel se ofrece solo a ChatGPT; otros clientes MCP mantienen su lista de herramientas normal. Todo lo que hace pasa por los mismos perfiles de permisos y aprobaciones que cualquier otra llamada de Mac MCP, y nunca recibe claves API, tokens ni credenciales. Para desactivarlo, establece {"chatgpt_extensions": {"enabled": false}} en ~/.mac-mcp/settings.json. Consulta docs/chatgpt-control-center.md para más detalles.

Esta es una combinación poderosa, no una función de voz exclusiva de Mac MCP. ChatGPT proporciona la interfaz de voz natural y la experiencia de razonamiento; Mac MCP le da una capa de ejecución local en macOS. Los permisos, aprobaciones y límites de uso existentes del plugin de ChatGPT siguen aplicándose, y Mac MCP mantiene sus límites normales de permisos, control en segundo plano, seguridad de resultados y deshacer.

Seguridad: Mac MCP puede ejecutar comandos, leer/escribir archivos y controlar aplicaciones de escritorio. Mantén la autenticación MCP habilitada siempre que el servicio sea accesible fuera de localhost y expónlo solo a clientes de confianza. El panel de operaciones es solo de loopback y requiere un token Bearer de panel separado por usuario; localhost es transporte local de máquina, no un sandbox de mismo usuario.

Valores predeterminados de arranque seguro: la configuración faltante falla de forma cerrada. Sin configuraciones explícitas, la autenticación MCP es obligatoria, la ejecución de shell y las listas de permitidos de hosts HTTP/navegador están deshabilitadas, y el perfil de permisos global predeterminado es standard en lugar de trusted. Una ejecución normal del instalador genera la clave API y escribe las configuraciones previstas explícitamente. El MCP_ALLOW_NO_AUTH=true deliberado se acepta solo en loopback sin endpoint público administrado; el inicio sin autenticación no-loopback o tunelizado se rechaza.

Novedades en 2.1.9

2.1.9 trae Mac MCP a ChatGPT con un panel de plugin nativo, y hace que el trabajo diario del navegador, las aprobaciones, las actualizaciones y los reinicios sean más confiables.

  • Panel de Mac MCP dentro de ChatGPT: ChatGPT ahora muestra Mac MCP como una aplicación de plugin. Ábrelo desde la barra lateral de ChatGPT en pantalla completa o como panel lateral en cualquier conversación. Un panel compacto en blanco y negro, en el mismo estilo que el sitio web de Mac MCP, muestra la actividad de herramientas de hoy, agentes delegados en ejecución y recientes, y uso de tokens de 7 días para Codex, OpenCode y ChatGPT Web. Solo se actualiza cuando presionas actualizar, por lo que nunca consulta tu Mac en segundo plano.
  • Elige tu agente predeterminado desde ChatGPT: la pestaña Configuración del panel te permite elegir el proveedor, modelo y nivel de razonamiento que ChatGPT usa al delegar trabajo. Los modelos provienen de tus propias cuentas de proveedor, y el servidor verifica cada elección antes de guardar. Las notificaciones y detalles de conexión se muestran solo lectura; permisos, proveedores y credenciales siguen viviendo solo en la aplicación Mac.
  • Solo ChatGPT y vinculado a permisos: Claude, Codex, OpenCode y otros clientes nunca ven el panel. Cada acción desde él pasa los mismos perfiles de permisos y aprobaciones que cualquier otra llamada de Mac MCP, y no se envían claves ni tokens.
  • Ve lo que hacen tus agentes: burbujas de actividad opcionales en el Mac muestran para qué sirve cada llamada de herramienta mientras se ejecuta, incluso cuando varias se ejecutan a la vez, y notificaciones opcionales te avisan cuando un agente delegado termina.
  • Aprobaciones de servidor opcionales: una nueva configuración de Aprobación de Servidor (Off, Critical, High Risk) puede pedirte Permitir una vez o Bloquear acciones riesgosas como comandos sin procesar, control de actualizaciones o acciones destructivas de navegador y aplicaciones.
  • Trabajo de navegador más fluido: los agentes pueden completar formularios completos en un solo paso: pueden presionar teclas y Enter sin traer el navegador al frente y esperar botones que aparecen un momento después. Las pestañas de Safari se mantienen rastreadas a través de cambios de sitio y reorganización de pestañas, los clics cuyo efecto aparece en otro lugar de la página cuentan como trabajo, y las imágenes de página ahora funcionan en páginas como Google Sheets.
  • Mejores elecciones entre objetivos similares: Mac MCP ahora prefiere el botón real sobre los recuadros que lo rodean. Una capa opcional de Aceleración de Decisiones (desactivada por defecto, usa tu propia clave de OpenAI) puede resolver empates restantes, guiada por una breve pista del agente.
  • Configuración e historial más fáciles: mac-mcp connect-config imprime configuraciones de conexión listas para pegar para ChatGPT, Codex y OpenCode; el panel agrega una vista segura de historial de transacciones; y la memoria y las habilidades de agente se pueden leer a través de REST.
  • Actualizaciones y reinicios más confiables: las actualizaciones iniciadas desde Mac MCP sobreviven su propio reinicio, mac-mcp restart ya no deja el servidor detenido, los trabajos en segundo plano siguen rastreando los programas que inician, y las operaciones de actualización ya no reemplazan tu identidad Git.
  • Accesibilidad: el Compañero Visual del navegador anuncia actividad a lectores de pantalla y funciona con el teclado.

Automatización de navegador que no secuestra tu Mac

Mac MCP puede inspeccionar e interactuar con pestañas de Safari y Chrome en segundo plano mientras sigues trabajando en otra aplicación o pestaña del navegador. Aquí, segundo plano significa una pestaña normal y visible de Safari/Chrome que Mac MCP controla sin traer el navegador o la pestaña al frente; no es una sesión de navegador oculta o sin cabeza.

  • Las nuevas pestañas del navegador se abren en segundo plano por defecto y devuelven un tab_handle estable.
  • Los identificadores de pestaña estables sobreviven cambios de índice de pestañas, por lo que las tareas de larga duración siguen apuntando a la pestaña prevista de Safari o Chrome incluso cuando otras pestañas se abren, cierran o mueven. Cada paso de AppleScript re-resuelve la pestaña por su identidad nativa, por lo que un cambio en medio de una llamada browser_act no la hace fallar; si la pestaña objetivo se cierra, la llamada devuelve tab_target_closed con las acciones ya completadas y automatic_retry: false en lugar de un error HTTP.
  • browser_observe puede devolver contexto DOM compacto más visuales de viewport, elemento o página completa sin activar el navegador, cambiar pestañas, desplazar la página del usuario o dejar archivos de captura en disco.
  • Las acciones de navegador de alto nivel pueden apuntar directamente a una pestaña específica en segundo plano por identificador, lo que hace prácticos los flujos de investigación paralela y agentes delegados sin robo constante de enfoque.
  • Los respaldos solo de primer plano, como pulsaciones de teclas nativas, clics de coordenadas absolutas, aperturas de URL en primer plano y la ruta nativa del selector de archivos de Safari, están limitados por capacidad. Un modelo no puede otorgarse enfoque enviando allow_foreground=true o background=false.
  • browser_activate_tab se trata como comportamiento visible en primer plano incluso cuando no elevaría la aplicación del navegador, porque cambiar la pestaña actual de Safari o la pestaña activa de Chrome puede interrumpir a un usuario que ya está trabajando allí. La automatización normal debería apuntar a valores estables de tab_handle directamente sin activarlos.
  • El controlador nativo de la barra de menú muestra el trabajo de navegador en vivo en Sesiones y Uso de herramientas reciente con un resumen de navegador/sitio/acción minimizado en privacidad. Las rutas de URL, cadenas de consulta, títulos de página, selectores y contenido de página se omiten intencionalmente de esta vista compacta.
  • Configuración → Uso → Datos y retención controla el historial de uso: desactiva la grabación, conserva 30, 90 o 365 días (predeterminado 365) o borra todo el uso almacenado de herramientas y proveedores. Solo se conservan agregados diarios por herramienta, nunca prompts, argumentos o resultados; un período más corto elimina días anteriores de inmediato.
  • Mostrar pestaña es la acción explícita del usuario local: solo esa ruta de UI confiable recibe una capacidad de primer plano léxica corta y puede traer esa pestaña específica real de Safari/Chrome al frente.

Esto está diseñado para flujos de trabajo donde un agente de IA sigue trabajando en una o más pestañas de navegador en segundo plano mientras el Mac sigue siendo utilizable normalmente.

Decisiones más rápidas en objetivos similares con la API de Decisiones de OpenAI

Las páginas reales están llenas de casi duplicados: un botón Continuar bajo Envío y Facturación, Responder junto a Responder a todos, dos celdas 25 en un selector de fechas de dos meses. Un agente típico se detiene allí, observa la página nuevamente y gasta otro viaje de ida y vuelta del modelo para elegir. Mac MCP puede resolverlo dentro de la misma llamada browser_act.

Cuando la Aceleración de Decisiones está activada, Mac MCP envía los candidatos ya clasificados a la API de Decisiones de OpenAI, el endpoint de respuesta tipada de OpenAI para clasificación y enrutamiento rápido (OpenAI lo describe como aproximadamente 10 veces más rápido que la API de Respuestas). Mac MCP da a cada llamada un presupuesto de 600 ms; una llamada cálida medida en ~330 ms. El agente puede agregar una pista de una línea intent, como "el paso de Facturación", y esa pista decidió nuestros casos de calibración:

Objetivo ambiguoSin pistaCon intent
Continuar de Envío vs Facturación0.16, mantuvo la primera coincidenciaFacturación, 0.83
Responder vs Responder a todosResponderResponder a todos, 0.93
Dos celdas de calendario 25sin respuesta, 0.2825 de noviembre, 0.82

La capa solo puede elegir entre candidatos que Mac MCP ya encontró, nunca elige una acción riesgosa como eliminar, enviar o pagar sobre la coincidencia determinista, y vuelve a la ruta normal ante cualquier tiempo de espera, error o baja confianza. Está desactivada por defecto, usa tu propia clave de OpenAI desde Keychain, y envía solo etiquetas cortas redactadas: sin valores escritos, URLs ni contenido de página. La configuración y los umbrales están en Aceleración de Decisiones Opcional.

Compañero Visual del Navegador (Safari + Chrome)

Mac MCP.app usa una fuente WebExtension compartida para Safari y Chrome para hacer visible el trabajo de navegador activo de Mac MCP dentro de la página exacta que se está automatizando. La extensión es solo de visualización: renderiza un marco de página pulsante sutil, una insignia de actividad pequeña Mac MCP · …, un cursor sintético y retroalimentación de clic para acciones de navegador de alto nivel. Los eventos visuales contienen solo etiquetas de acción limitadas y coordenadas de viewport; texto escrito, selectores, URLs, títulos de página, contenido DOM y secretos no se copian en el evento de la extensión. La superposición es solo retroalimentación de actividad y no debe tratarse como un indicador de seguridad o confianza.

La configuración de Safari depende de cómo esté firmado Mac MCP.app:

Developer ID / compilación firmada por Apple (persistente):

  1. Instala o actualiza Mac MCP normalmente.
  2. Abre Mac MCP.app → Actividad del navegador → Habilitar en Safari…. También puedes usar Safari → Configuración → Extensiones.
  3. Activa Mac MCP Visual Companion y concede acceso al sitio web para los sitios donde quieras comentarios de actividad.

Compilación local de GitHub/fuente (ad-hoc, modo de desarrollo):

  1. Abre Mac MCP.app → Actividad del navegador → Configuración de desarrollador…. Mac MCP revela la carpeta fuente de runtime BrowserVisualCompanion y abre Safari.
  2. En Safari, habilita las funciones de desarrollador web si el menú Desarrollar está oculto.
  3. Elige Desarrollar → Permitir extensiones sin firmar.
  4. Elige Desarrollar → Agregar extensión temporal… y selecciona ~/mac-mcp/menu_app/BrowserVisualCompanion.
  5. Concede acceso al sitio web cuando Safari lo solicite. Safari trata esto como una extensión de desarrollo/temporal; la instalación normal persistente requiere un paquete de aplicación firmado por Apple.

Para Chrome, la creación real de pestañas en segundo plano utiliza la extensión ~/mac-mcp/menu_app/ChromeVisualCompanion exclusiva de Chrome. Abre Mac MCP.app → Actividad del navegador → Configuración de Chrome…, habilita Modo de desarrollador en chrome://extensions, elige Cargar descomprimida y selecciona esa carpeta. El compañero abre nuevas pestañas con la API nativa tabs.create({active:false}) de Chrome, por lo que el trabajo en segundo plano no trae Chrome ni la nueva pestaña al frente. Si el compañero no está disponible, la creación de pestañas en segundo plano falla de forma segura en lugar de recurrir a una apertura de AppleScript que robe el foco. El mismo compañero también lleva a cabo la ejecución de DOM/página a través de la API debugger de Chrome, por lo que las lecturas, clics, escritura y captura visual segura en segundo plano de Mac MCP en Chrome no requieren la alternancia de JavaScript de Apple Events mientras el compañero esté conectado. El compañero de Chrome utiliza una credencial local dedicada solo para el propietario y un WebSocket de bucle local; la credencial no es el MCP_API_KEY global.

El proyecto sigue siendo completamente de código abierto y no necesita la Mac App Store. Para una versión persistente de GitHub, firma/notariza el Mac MCP.app distribuido con Developer ID; menu_app/build_app.sh acepta MAC_MCP_CODESIGN_IDENTITY para esa ruta de versión.

No se requiere un perfil de navegador separado, demonio auxiliar o proyecto Xcode. menu_app/build_app.sh compila el .appex en Mac MCP.app/Contents/PlugIns/ con la cadena de herramientas Swift normal de línea de comandos. Las compilaciones locales usan firma ad-hoc por defecto; los compiladores de versiones pueden configurar MAC_MCP_CODESIGN_IDENTITY para usar una identidad de Developer ID con firma de runtime endurecido/marca de tiempo.

Requisitos

  • macOS 13+
  • Apple Silicon o Mac Intel
  • Python 3.10+
  • Git
  • Herramientas de línea de comandos de Xcode (swiftc)
  • ngrok solo si eliges el modo de endpoint público ngrok integrado
  • cloudflared solo si eliges el modo Cloudflare Tunnel integrado
brew install python git
# Optional public providers:
brew install ngrok       # ngrok mode
brew install cloudflared # Cloudflare Tunnel mode

Ayudantes opcionales:

brew install cliclick brightness

Instalación

Instalador

El instalador interactivo ahora instala solo una versión estable verificada criptográficamente. Clona main, encuentra la confirmación de versión estable firmada más reciente, verifica el verificador de arranque fijado, la firma del manifiesto Ed25519, el inventario completo de SHA-256/modo/tamaño de archivos rastreados, el digesto agregado de la carga útil y el linaje de la versión antes de crear rutas persistentes de fuente/runtime.

Por conveniencia, el arranque transmitido sigue disponible:

curl -fsSL https://raw.githubusercontent.com/bulutarkan/mac-mcp/main/install.sh | bash

Un script transmitido no puede autenticarse criptográficamente antes de comenzar a ejecutarse. Trata ese comando como un arranque de menor garantía. Para una instalación de mayor garantía, obtén install.sh de una confirmación de versión firmada de confianza y compara de forma independiente la huella digital del firmante de la versión documentada en release/README.md antes de ejecutarlo. Una vez que el instalador de confianza esté en ejecución, la carga útil de fuente/runtime clonada es de cierre seguro y verificada criptográficamente.

El instalador:

  • verifica macOS 13+, Apple Silicon o Intel, Git, Python 3.10+, Herramientas de línea de comandos de Xcode y swiftc;
  • verifica la versión estable seleccionada criptográficamente antes de mover cualquier archivo de fuente/runtime a rutas de instalación persistentes;
  • puede ofrecer Homebrew cuando falta una dependencia requerida, manteniendo opcionales los ayudantes como cliclick y brightness;
  • pregunta qué modo de endpoint público quieres (Local only, Cloudflare Tunnel, ngrok o Custom HTTPS) y, cuando se selecciona Cloudflare/ngrok, ofrece instalar el proveedor correspondiente con Homebrew si falta;
  • puede finalizar la configuración de Cloudflare durante la instalación almacenando el nombre de host público en la configuración y aceptando el token de túnel a través de un mensaje de terminal oculto; el token se envía a mac-mcp credential cloudflare save por stdin y nunca se coloca en argumentos de shell, configuración o .env;
  • crea un checkout de fuente Git en ~/Projects/mac-mcp y un runtime separado en ~/mac-mcp sin metadatos de Git;
  • crea y verifica el entorno virtual de Python y las dependencias;
  • genera una clave API MCP fuerte, habilita el acceso autenticado y almacena el .env de runtime con modo 600;
  • instala el CLI mac-mcp en ~/.local/bin/mac-mcp y registra la confirmación implementada para el actualizador integrado;
  • compila y verifica la firma de código del controlador de barra de menú nativo Mac MCP.app en ~/Applications;
  • muestra tanto los formatos de conexión Bearer-token como ?ApiKey= al final;
  • no instala OpenCode, Codex o ChatGPT Web CLI. Si quieres usar Subagentes, instala el proveedor que planeas usar por separado.

Las rutas existentes de fuente/runtime/CLI nunca se sobrescriben silenciosamente. Si Mac MCP ya está instalado, usa el actualizador integrado en lugar de volver a ejecutar el instalador sobre las mismas rutas.

Instalación manual

Si prefieres gestionar el checkout y el entorno de Python tú mismo:

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 fija cada dependencia, incluidos paquetes transitivos y herramientas de compilación, por versión y hash SHA-256; el instalador, el actualizador y CI instalan desde él, y pip rechaza un paquete que no coincida. Después de cambiar dependencias en pyproject.toml, regenéralo con el comando en la parte superior del archivo (uv pip compile ... --generate-hashes).

Configura como 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

Genera un token fuerte:

python3 - <<'PY'
import secrets
print(secrets.token_urlsafe(48))
PY

Cuando la autenticación está habilitada, la credencial preferida del cliente sigue siendo:

Authorization: Bearer <MCP_API_KEY>

Para clientes/conectores MCP que no pueden configurar un encabezado Authorization, Mac MCP también acepta la clave global configurada en la URL del endpoint:

https://your-domain.example/mcp?ApiKey=<MCP_API_KEY>

Generar una configuración de conexión de cliente

Usa el CLI para generar un fragmento de conexión desde el endpoint de Mac MCP y el estado de autenticación realmente configurados en esta Mac:

mac-mcp connect-config --client chatgpt
mac-mcp connect-config --client codex
mac-mcp connect-config --client opencode

El comando nunca imprime el valor de la clave API configurada. Los fragmentos de Codex y OpenCode hacen referencia a una variable de entorno del lado del cliente (MAC_MCP_API_KEY por defecto); configura esa variable en el proceso del cliente con el mismo valor secreto configurado como MCP_API_KEY de Mac MCP. ChatGPT usa la forma de compatibilidad de clave de consulta limitada por encabezado existente e imprime solo ?ApiKey=<API_KEY> como marcador de posición.

--endpoint auto es el predeterminado: usa el endpoint HTTPS público configurado para ChatGPT y bucle local para Codex/OpenCode locales. Usa --endpoint public cuando Codex/OpenCode se ejecuten en otro lugar, o --endpoint local para forzar bucle local donde sea compatible. --name cambia el ID de servidor del lado del cliente, y --auth-env cambia el nombre de la variable de entorno del cliente sin exponer su valor.

Los formatos de configuración del cliente evolucionan. La salida generada etiqueta el formato de destino que asume; prefiere regenerar el fragmento con tu Mac MCP instalado en lugar de copiar un fragmento antiguo del README.

Modos de endpoint público

Mac MCP trata el servidor local y su transporte público como capas separadas. Solo local no expone ningún endpoint público gestionado. ngrok ejecuta un proceso ngrok gestionado y usa NGROK_DOMAIN. Cloudflare Tunnel ejecuta cloudflared directamente en la Mac y conecta el túnel nombrado seleccionado (o un archivo de token controlado por el propietario) a 127.0.0.1:<port>; no se requiere VPS, proxy inverso, reenvío de puertos entrantes o IP pública de Mac. HTTPS personalizado registra un endpoint MCP HTTPS gestionado externamente y no inicia un proveedor de túnel.

La ventana nativa de Configuración proporciona un interruptor de cuatro vías Local only / ngrok / Cloudflare / Custom HTTPS. La selección se persiste bajo server.public_endpoint_mode y server.public_url en ~/.mac-mcp/settings.json; los metadatos opcionales de túnel nombrado pueden usar el campo no secreto server.cloudflare_tunnel. Las instalaciones existentes que solo tienen ngrok_on_start=true continúan comportándose como modo ngrok hasta que se guarde la nueva configuración. Las variables de entorno MAC_MCP_PUBLIC_ENDPOINT_MODE y MAC_MCP_PUBLIC_URL pueden anular los valores persistidos para implementaciones gestionadas/headless.

Cloudflare Tunnel: configuración en 5 minutos

El instalador interactivo puede hacer la configuración del lado de la Mac por ti. Elige Cloudflare Tunnel cuando install.sh pregunte por un endpoint público. Si falta cloudflared, el instalador ofrece brew install cloudflared; rechazarlo no rompe la instalación principal y deja Mac MCP en modo Solo local.

Para la configuración del lado de Cloudflare:

  1. Tu dominio debe estar activo en Cloudflare. En el panel de Cloudflare, ve a Red → Túneles, elige Crear túnel y dale cualquier nombre que identifique esta Mac.
  2. Abre la pestaña Rutas del túnel, elige Agregar ruta → Aplicación publicada, selecciona el nombre de host que quieras (por ejemplo mac.example.com) y apunta el servicio a http://localhost:8000 para una instalación predeterminada. Si cambiaste el puerto del servidor de Mac MCP, usa ese puerto en su lugar.
  3. Cloudflare muestra un comando de configuración/instalación cloudflared para el conector. No ejecutes el comando de instalación del servicio cuando Mac MCP esté gestionando el túnel. Copia solo el token del túnel de ese comando. Para un túnel existente, Agregar una réplica también expone un comando de conector que contiene el token.
  4. De vuelta en el instalador de Mac MCP, ingresa el nombre de host público como https://mac.example.com y pega el token en el mensaje oculto. Si omites cualquiera de los valores, el instalador deja de forma segura el modo público como Solo local; termina más tarde en Mac MCP.app → Configuración → Avanzado → Cloudflare.
  5. Inicia Mac MCP. mac-mcp start crea/habilita un trabajo launchd por usuario con KeepAlive; no es necesario que una ventana de Terminal permanezca abierta. Verifica con mac-mcp status y mac-mcp doctor.

La documentación actual de Cloudflare llama a esto un túnel gestionado remotamente y una ruta de Aplicación publicada. Consulta Configurar Cloudflare Tunnel, Agregar rutas y Tokens de túnel. Un token de túnel es una credencial: cualquiera que lo tenga puede ejecutar un conector para ese túnel, así que gíralo en Cloudflare si alguna vez se expone.

Para la configuración más simple de Cloudflare, crea el túnel y el nombre de host en Cloudflare, luego pega el token del túnel una vez en Configuración → Avanzado → Cloudflare. Mac MCP lo escribe atómicamente en ~/.mac-mcp/cloudflare-tunnel-token como un archivo 0600 solo para el propietario, nunca escribe el token en settings.json o .env, nunca lo vuelve a mostrar, e inicia cloudflared con --token-file para que el secreto no se exponga en los argumentos del proceso. CLOUDFLARE_TUNNEL_TOKEN_FILE puede anular la ruta del archivo de credenciales sin poner el valor del token en el entorno. Las credenciales de túnel nombrado siguen disponibles como alternativa avanzada. El túnel conecta Cloudflare directamente a http://127.0.0.1:<port> en la Mac: no se requiere VPS, IP pública, reenvío de puertos del enrutador o apertura de firewall entrante. El modo personalizado es para operadores que ya proporcionan su propio enrutamiento HTTPS externo. Todas las URL públicas deben ser HTTPS y no pueden contener cadenas de consulta, fragmentos o userinfo de URL. mac-mcp status muestra la URL del conector seleccionado y mac-mcp doctor verifica el proveedor seleccionado, la seguridad del archivo de credenciales y la ruta pública /health sin enviar la clave API MCP. Cambiar de proveedor detiene cualquier proceso gestionado de ngrok/cloudflared que ya no esté seleccionado. En modo Cloudflare, mac-mcp start (y la acción Iniciar de la aplicación nativa) instala/habilita un LaunchAgent de usuario con KeepAlive, por lo que el túnel permanece independiente de Terminal y se reinicia automáticamente si cloudflared sale; mac-mcp stop expulsa y deshabilita ese trabajo. Authorization sigue siendo la fuente autoritativa cuando se proporcionan ambas formas. Las credenciales de consulta ApiKey vacías, duplicadas o inválidas son rechazadas mientras la autenticación esté habilitada. El servidor elimina ApiKey de su URL local de registro de acceso antes de registrar, pero los proxies/túneles ascendentes aún pueden observar las cadenas de consulta, por lo que se deben preferir los encabezados Bearer siempre que el cliente los admita.

Terminología de producto y seguridad

Mac MCP utiliza un pequeño glosario canónico para que la interfaz de usuario y la documentación no impliquen un aislamiento o invisibilidad más fuertes de lo que el producto realmente proporciona. Consulte docs/TERMINOLOGY.md para las definiciones completas.

  • Automatización de navegador en segundo plano: automatización visible de Safari/Chrome que no roba el foco; no oculta ni sin cabeza.
  • Capacidad: si la política del servidor Mac MCP permite una herramienta/clase de riesgo.
  • Aprobación: un mecanismo de confirmación humana y su fuente; separado de la aplicación de capacidades.
  • Localhost / loopback: transporte local de la máquina, no aislamiento de mismo usuario ni sandbox.
  • Sesión lógica de Mac MCP: una identidad de dirección local con hash que mantiene coherente un flujo de agente/conversación; no es la identidad cruda del proveedor.
  • Usuario dedicado: contención/endurecimiento que reduce el radio de explosión; no es un sandbox completo.

Para un despliegue avanzado de dos cuentas, consulte Despliegue endurecido con un usuario macOS dedicado no administrador. Cubre autenticación de loopback, un directorio compartido explícito con ACL, límites de TCC/sesión de GUI, comportamiento de herramientas, reversión y una matriz de validación de dos usuarios.

Perfiles de permisos y semántica de aprobación

Mac MCP trata la aplicación de capacidades y la aprobación humana como conceptos de seguridad separados. Que una capacidad esté permitida significa solo que la política del servidor Mac MCP permite esa herramienta/clase de riesgo. No significa que aparecerá un segundo mensaje de confirmación antes de que se ejecute la acción.

PerfilComportamiento de capacidad aplicado por el servidorFuente de aprobación con Aprobación de servidor OffAviso automático de riesgo
trustedTodas las capacidades registradas; las familias destructivas no están restringidas adicionalmente por el perfil.noneNo
standardBloquea raw_execution y update_control; las operaciones destructivas se limitan a las familias de navegador/accesibilidad; el límite del modo de acceso es de solo lectura.noneNo
read_onlyPermite solo capacidades de lectura/red/navegador/accesibilidad nativa y deniega llamadas destructivas.noneNo

Aprobación de servidor es una superposición de aprobación opcional, separada de estos perfiles de capacidad. Su valor predeterminado es Off. Critical requiere confirmación de Mac MCP Permitir una vez / Bloquear para ejecución cruda, control de actualización y llamadas destructivas de control de procesos. High Risk agrega acciones destructivas externas/navegador/nativas. La superposición se evalúa solo después de la aplicación de capacidades, utiliza concesiones de una sola acción exacta, deniega cuando se requiere una aprobación pero el proveedor de aprobación local no está disponible o agota el tiempo, y se puede cambiar desde Configuración → Permisos y seguridad sin reiniciar el servidor. Mac MCP no acepta una afirmación de "ya aprobado" proporcionada por el cliente como prueba para omitir esta puerta del servidor; la aprobación del cliente/externa aún puede aplicarse de forma independiente.

ask_confirmation sigue siendo una herramienta de interacción explícita y no es un envoltorio de confirmación general alrededor de llamadas de herramientas normales. Por separado, Mac MCP tiene puertas de seguridad obligatorias y estrechas del lado del servidor para cruces riesgosos de límites de confianza. Bajo standard y perfiles delegados con alcance, un contexto web no confiable → acción de host privilegiado puede requerir una decisión de Permitir una vez / Bloquear consciente de la fuente. El perfil global trusted omite intencionalmente esa confirmación rutinaria web→host para que los flujos de trabajo interactivos de confianza no se interrumpan en cada salto de shell/archivo/UI a menos que la superposición opcional de Aprobación de servidor coincida independientemente con la acción. La fuga detectada de credenciales/secretos a un origen no confiable sigue siendo consciente de la fuente y sujeta a aprobación incluso bajo trusted. Las concesiones de acción exacta permanecen vinculadas al origen y son de un solo uso.

Los trabajadores delegados de Codex actualmente se ejecutan con Codex approval_policy="never"; su sandbox/modo de acceso está separado de la aprobación humana. El comportamiento de permisos de OpenCode también es del lado del proveedor y no debe tratarse como una garantía de confirmación del servidor Mac MCP.

Establezca el perfil de capacidad del servidor con MAC_MCP_PERMISSION_PROFILE=trusted|standard|read_only. La aplicación nativa de la barra de menú lee /dashboard/api/security/semantics y muestra Capacidades permitidas, Comportamiento de aprobación y el perfil de riesgo opcional de Aprobación de servidor por separado. Los cambios de perfil de permisos persisten en mcp_server/.env; la Aprobación de servidor persiste como security.server_approval_profile en ~/.mac-mcp/settings.json solo para el propietario. Ambos se aplican a nuevas solicitudes inmediatamente sin reiniciar el servidor. Los agentes delegados existentes mantienen el perfil de capacidad con alcance emitido cuando se iniciaron; la superposición de aprobación de riesgo del lado del servidor sigue siendo una puerta de ejecución del servidor.

Las protecciones de resiliencia del navegador son configurables con MAC_MCP_NO_PROGRESS_THRESHOLD (predeterminado 4, rango 2–10) y MAC_MCP_TAB_LEASE_TTL_S (predeterminado 300 segundos, rango 30–3600). El interruptor de no progreso detiene solo acciones repetidas y significativas del navegador que no logran cambiar la revisión del DOM, la URL o el título; los flujos de espera/desplazamiento/extracción no consumen ese presupuesto. La propiedad de pestaña del agente delegado es lógica y limitada en el tiempo: completar/cancelar/fallar un agente libera la propiedad sin cerrar la pestaña del usuario, y el siguiente agente debe hacer un browser_observe fresco antes de actuar sobre un identificador previamente propiedad.

Límite de URL saliente / SSRF

http_request y browser_open_url tratan las listas de permitidos de nombres de host públicos y el acceso a redes privadas como permisos separados. Un HTTP_ALLOWLIST=* o BROWSER_ALLOWLIST=* comodín permite nombres de host públicos; no permite loopback, RFC1918/ULA, enlace local/metadatos, NAT de grado portador, multidifusión, no especificado, reservado u otro espacio de direcciones no global. Los nombres de host que se resuelven a cualquier dirección bloqueada fallan de forma cerrada. La información de usuario de URL y los esquemas que no son HTTP(S) también se rechazan.

Para http_request, cada salto de redirección se vuelve a validar antes de la siguiente solicitud. El transporte HTTP además se resuelve nuevamente en el momento de la conexión TCP, rechaza una respuesta DNS que ha cambiado a espacio de direcciones bloqueado y se conecta a la IP ya validada mientras conserva el nombre de host original para la identidad HTTP/TLS. Las variables de proxy de entorno no se heredan deliberadamente en esta ruta de acceso al host. La salida de redirección está limitada a los orígenes de destino en lugar de copiar rutas de redirección completas o cadenas de consulta.

Los motores de navegador poseen su propia pila de red, por lo que Mac MCP no afirma fijación de IP a nivel de transporte para Safari o Chrome. En cambio, la navegación del navegador valida DNS antes de la navegación y luego vuelve a validar la URL de destino observada por el navegador después de la navegación; un cambio de DNS del mismo host se resuelve nuevamente en ese límite. Si se observa una pestaña recién creada en un destino bloqueado, se cierra con el mejor esfuerzo y la llamada falla como browser_redirect_blocked; para una pestaña existente, Mac MCP restaura con el mejor esfuerzo la URL segura observada previamente.

El acceso de desarrollo local/privado es opcional por nombre de host a través de HTTP_PRIVATE_ALLOWLIST y BROWSER_PRIVATE_ALLOWLIST (nombres/sufijos separados por comas, por ejemplo localhost). Estas excepciones son independientes de las listas de permitidos públicas normales; * se ignora intencionalmente en las listas de permitidos privadas para que el acceso a redes privadas no pueda habilitarse accidentalmente.

La procedencia web no confiable es pegajosa a nivel de sesión lógica. Una vez que una sesión consume contenido de navegador de terceros, escribir ese contenido en un archivo temporal local, leerlo de vuelta, cerrar la pestaña o pasar por herramientas de solo lectura no relacionadas no borra esa procedencia. Los flujos de trabajo con alcance/no confiables continúan a través de la puerta de seguridad web→host hasta que el trabajo se mueve a una sesión de sala limpia independiente. El perfil global trusted mantiene la procedencia pegajosa para auditoría y verificaciones de fuga de secretos, pero no muestra un diálogo rutinario de Permitir una vez para cada salto de host privilegiado normal. Los hijos delegados generados desde una sesión contaminada heredan los metadatos de contaminación (origen, razón y huellas de credenciales) sin copiar DOM crudo o secretos en el registro de seguridad; la delegación anidada preserva la cadena de herencia. Una sesión MCP genuinamente independiente sin carga útil transferida comienza limpia bajo la política normal.

Instalar la aplicación de la barra de menú

./menu_app/install_app.sh

Ubicación predeterminada:

~/Applications/Mac MCP.app

La aplicación es independiente del servidor:

  • salir de la aplicación no detiene MCP;
  • detener MCP no cierra la aplicación;
  • mac-mcp start abre la aplicación automáticamente cuando está instalada;
  • los controles del servidor permanecen disponibles incluso mientras la sección de Voz está contraída.

La aplicación utiliza las API del panel de control de localhost con una credencial Bearer de panel separada almacenada en ~/.mac-mcp/dashboard-token (modo 0600). La aplicación de menú lee ese archivo solo para el propietario localmente y nunca necesita el MCP_API_KEY global:

/dashboard/api/summary
/dashboard/api/security/semantics
/dashboard/api/events
/dashboard/api/agents
/dashboard/api/steering

Dirección en vivo de la barra de menú

Mac MCP mantiene una sesión lógica de Mac MCP visible entre llamadas de herramientas en lugar de mostrarla solo durante los pocos milisegundos mientras una herramienta se está ejecutando. Prefiere metadatos de conversación estables proporcionados por el cliente MCP (por ejemplo, los metadatos openai/session con alcance de conversación de OpenAI), luego _meta.client_id genérico y finalmente un transporte Streamable HTTP con estado reutilizado como respaldo. Los valores de identidad crudos se someten a hash antes de ingresar al estado de dirección y nunca se exponen en el panel de control. Esto es importante para hosts que crean una sesión de transporte fresca para cada llamada de herramienta: las llamadas repetidas de la misma conversación aún se colapsan en una tarjeta de agente Trabajando / Inactivo.

Los mensajes de dirección se mantienen solo en memoria y están vinculados al agente lógico seleccionado, nunca a una cola global de "siguiente llamador". Si el agente seleccionado actualmente tiene una herramienta en ejecución, el mensaje se agrega a la respuesta en vivo de esa herramienta como contenido estructurado _mac_mcp_steering. Si el agente está inactivo, el mensaje permanece en cola para esa sesión lógica y su próxima herramienta solicitada es anticipada antes de la ejecución con un error de herramienta mac_mcp_steering_preempted, para que el agente vea la nueva dirección del usuario antes de hacer más trabajo. Una conversación/sesión diferente no puede consumir ese mensaje. Las sesiones de dirección lógica expiran después de 10 minutos de inactividad de forma predeterminada. La divulgación de Sesiones de la barra de menú le permite ingresar cualquier número positivo de minutos y persiste ese valor en ~/.mac-mcp/settings.json; los transportes de protocolo con estado están limitados por separado para que los transportes de cliente de corta duración no se acumulen indefinidamente. El texto de dirección crudo no se escribe en el SQLite de telemetría, y las llamadas de respaldo anidadas como tool_invoke no crean sesiones visibles duplicadas.

La aceptación de POST de dirección es idempotente para clientes que envían client_instruction_id. La aplicación de menú genera un UUID para cada acción de Enviar y reutiliza ese mismo UUID para un reintento limitado cuando el resultado HTTP es ambiguo. Reenviar la misma sesión + ID de cliente + texto devuelve el mensaje canónico original st_* en lugar de poner en cola un duplicado; reutilizar un ID de cliente con texto diferente u otra sesión activa devuelve 409 idempotency_conflict. Las filas de ciclo de vida recientes incluyen el ID de correlación del cliente para que la aplicación de menú pueda recuperar un mensaje aceptado después de una respuesta perdida. El índice de deduplicación activo está limitado; las claves desalojadas se mueven a una ventana de tumba limitada para que un reintento tardío de la misma generación devuelva 409 idempotency_expired en lugar de crear silenciosamente una segunda instrucción. Cada ciclo de vida del daemon también publica un generation_id aleatorio. La aplicación de menú nativa vincula cada nuevo envío de instrucciones y reintento ambiguo a esa generación. Si el daemon se reinicia antes de que se pueda recuperar una respuesta incierta, un reintento de generación anterior se rechaza como 409 stale_generation con outcome=unknown; nunca se reproduce automáticamente en el nuevo daemon. El usuario puede entonces reenviar intencionalmente, lo que crea un ID de cliente nuevo contra la generación actual. El marcador de generación evita la reproducción duplicada a través de los límites de reinicio; no pretende recuperar el resultado en memoria perdido del daemon anterior. Los clientes heredados que omiten generation_id siguen siendo compatibles, pero no reciben esta garantía más sólida de límite de reinicio.

Si la aplicación de menú nativa se relanza mientras el daemon sigue ejecutándose, las sesiones lógicas propiedad del daemon permanecen disponibles y la nueva instancia de la aplicación las redescubre desde /dashboard/api/steering. Un envío de instrucciones cuyo resultado HTTP seguía siendo ambiguo al salir de la aplicación conserva solo un registro de correlación de corta duración exclusivo del propietario en ~/.mac-mcp/pending-steering.json (ID de cliente, ID de sesión lógica, SHA-256 del mensaje, ID de generación del daemon, marca de tiempo; nunca el mensaje sin procesar). Al relanzar, la aplicación concilia ese registro contra el estado recent del daemon; volver a introducir el mismo mensaje reutiliza la clave de idempotencia original solo mientras la generación del daemon siga coincidiendo.

Por ejemplo, si un agente está investigando con automatización de navegador visible que no roba el foco en una pestaña de Safari y escribes stop using Airbnb and check Booking.com instead en la Sesión de ese agente, Mac MCP enruta la instrucción solo a ese agente lógico. Una herramienta en ejecución puede devolver la instrucción inmediatamente; un agente inactivo se interrumpe antes de su siguiente llamada a herramienta para que pueda cambiar de rumbo primero.

Eficiencia de actualización de estado de SwiftUI

El controlador nativo permanece @MainActor y mantiene la misma cadencia de sondeo, pero publica valores de panel decodificados solo cuando realmente cambian. Las instantáneas de sesión se comparan por session_id estable antes de reemplazar la matriz observable, preservando la identidad de fila de SwiftUI y evitando la invalidación de jerarquía para sondeos idénticos. Las actualizaciones de duración volátiles se combinan solo mientras su etiqueta renderizada permanezca sin cambios. Esta es una optimización de eficiencia de renderizado/estado, no un modo de actualización más lenta.

Arquitectura de información de sesiones

La barra de menú deriva tres secciones deterministas de la instantánea de ciclo de vida versionada: Necesita atención (failed, no resuelto/desconocido, o eventos de sesión recientes desconectados/expirados), Activo (trabajando, en cola, entregado, pendiente o en espera de confirmación) y Reciente (sesiones ready/acknowledged inactivas retenidas). Las filas de terminal históricas son informativas, no dirigibles. El icono de estado de la barra de menú lleva solo una señal agregada de atención/activo. Mac MCP no muestra controles de Reintentar/Cancelar de sesión porque no existen tales acciones de backend; el Reintento de conexión sigue siendo una acción separada de accesibilidad del panel.

Ciclo de vida de sesión versionado

La API de instrucciones expone schema_version: 1 y separa la actividad del ciclo de vida de instrucciones. Los campos heredados state=working|idle y queued permanecen por compatibilidad; los nuevos clientes deberían preferir activity_state, lifecycle_state, pending_instruction_count, last_transition_at y last_error.

El ciclo de vida de instrucciones es intencionalmente pequeño: ready → queued → delivered → acknowledged. Si la herramienta subyacente falla antes de que se pueda entregar la instrucción en cola, la sesión entra en failed mientras mantiene la instrucción pendiente para la siguiente llamada a herramienta. Las sesiones respaldadas por transporte emiten disconnected cuando su transporte MCP desaparece, y las sesiones inactivas emiten expired cuando su TTL de retención expira. Las transiciones de ciclo de vida ilegales se rechazan internamente en lugar de producir silenciosamente un estado ambiguo.

acknowledged se infiere cuando el mismo agente lógico hace su siguiente solicitud de herramienta de nivel superior después de recibir instrucciones; significa que el agente continuó después del límite de entrega, no que el modelo envió un paquete de confirmación separado. La accesibilidad del daemon/API es una preocupación de conexión diferente y se maneja por separado mediante la UX de conexión de la aplicación de menú.

Resiliencia de conexión de la barra de menú

El controlador nativo no trata una solicitud de panel fallida como datos vacíos válidos. Una respuesta /dashboard/api/steering vacía exitosa limpia la lista de sesiones normalmente; un error HTTP, tiempo de espera o rechazo de conexión conserva la última instantánea exitosa y la marca como obsoleta. Si la aplicación nunca ha recibido una instantánea de sesión válida, muestra Datos de sesión no disponibles en lugar de Aún no hay sesiones de agente.

Una falla de transporte como tiempo de espera o rechazo de conexión entra en disconnected; un error HTTP o respuesta inválida de un servidor accesible entra en degraded, incluyendo fallas del endpoint de resumen principal. Los fallos de estado HTTP, tiempos de espera y errores de conexión rechazada se muestran por separado. El sondeo automático retrocede de 1 segundo a un límite de 30 segundos y vuelve a la cadencia normal de 2,5 segundos después de la siguiente actualización completa exitosa.

Comandos del 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

La bandera heredada --ngrok sigue siendo compatible como alias de --public-mode ngrok. Cuando no se proporciona una anulación de CLI, start/restart usan el modo de endpoint público guardado por la ventana de Configuración nativa (o las anulaciones de entorno MAC_MCP_PUBLIC_*).

mac-mcp doctor realiza comprobaciones de solo lectura para el runtime local, Python/versión, espacio en disco, validez de estado/configuración, permisos de macOS, ayudantes requeridos/opcionales, salud del servidor local, salud/configuración del endpoint público seleccionado, metadatos del archivo de credenciales del panel y estado del acompañante de Safari/Chrome. Usa --json para automatización; el JSON informa local_ok, public_endpoint y health (healthy, degraded, failed) por separado. Un endpoint público seleccionado que no se puede alcanzar hace que doctor salga con 1 y mac-mcp status salga con 2 (1 significa que el servidor local está caído); pasa --local-only a cualquiera de los comandos para juzgar solo el runtime local. --support-bundle [PATH] escribe un informe de soporte estructurado exclusivo del propietario (0600); excluye intencionalmente .env sin procesar, valores de configuración, registros, credenciales, cookies, mensajes y contenido de chat.

Los permisos se leen del servidor en ejecución, porque macOS registra el consentimiento para el proceso que lo solicita: doctor informa Accesibilidad, Grabación de pantalla y Automatización por aplicación (Eventos del sistema, Safari, Chrome, Calendario, Recordatorios, Notas, Correo) como permitido, no permitido, aún no preguntado o no verificado, con las funciones que cada uno habilita y la ruta exacta de Configuración del sistema y el nombre de la aplicación para permitir. Estas son consultas de solo lectura que nunca muestran un aviso de permiso. El acceso al micrófono pertenece al Ayudante de Voz separado de Mac MCP, por lo que se describe en lugar de verificarse. Cuando el servidor no está en ejecución, doctor lo indica y describe su propio proceso en su lugar. Los conflictos de puerto nombran el programa que usa el puerto (Mac MCP nunca detiene un programa que no inició) y señalan a Configuración → Avanzado → Puerto del servidor; los problemas de túnel indican si el binario del túnel falta, la credencial no es segura, el proceso del túnel se detuvo o la ruta pública no responde.

Las mismas comprobaciones están en la aplicación bajo Configuración → Ayuda y diagnóstico: ejecutar o volver a verificar diagnósticos, usar el botón de reparación junto a cada problema (reiniciar, abrir la configuración correcta o el panel de Configuración del sistema, ver el registro redactado), exportar un informe de soporte después de ver su contenido, ver el registro del servidor o del túnel, copiar información de versión y abrir la documentación, el formulario de problemas o la política de seguridad privada. Nada se envía automáticamente a ningún lugar.

mac-mcp status --json imprime un objeto para scripts: ok, state, exit_code, server (running, pid, identity, port, health de la ruta local /health), public_endpoint (mode, url, tunnel_running, route — si el /health público responde — y error), stray_processes, supervisor y remediation. state distingue los casos: healthy, stopped, port_conflict, ownership_unverified, unresponsive (proceso vivo pero /health no responde), degraded (túnel seleccionado no en ejecución, o en ejecución mientras su ruta pública no responde) y config_error (configuración de endpoint público inválida). doctor --json lleva el mismo campo exit_code.

Los códigos de salida de CLI son un contrato estable:

Comando0123
statussaludableservidor detenido, no verificado, puerto ocupado o no responde /healthendpoint público no disponible o mal configurado (0 con --local-only)—
doctortodas las comprobaciones pasanuna comprobación falló——
startiniciadono pudo iniciar (por ejemplo, conflicto de puerto)configuración inválida o error de arranque de seguridadngrok iniciado pero su /health público aún no responde
stop / restarthechoun componente no se detuvo o volvió saludable——
restart --waitreiniciado y saludablereinicio falló, o solo el endpoint público falló (degradado)—sin resultado informado a tiempo
update --checkverificadocomprobación fallócambios locales bloquean la actualización—
updateactualizado o ya actualactualización falló o fue bloqueada——
recipe runcompletadofallónecesita aprobaciónservidor no en ejecución
recipe listlistadosolicitud falló—servidor no en ejecución

En resumen: 0 es éxito, 1 es una falla operativa, 2 significa que una persona debe actuar (configuración, aprobación, un conector degradado o uso de línea de comandos inválido) y 3 significa que el servidor no se pudo alcanzar.

mac-mcp logs [server|cloudflared|ngrok|audit|update] [-n LINES] imprime las últimas líneas de un registro con tokens, claves y valores de credenciales redactados; mac-mcp logs --list muestra el tamaño de cada registro y los límites. Los registros del servidor, cloudflared y ngrok rotan a 10 MB y conservan tres archivos anteriores (MAC_MCP_LOG_MAX_BYTES, MAC_MCP_LOG_BACKUPS); la rotación copia y trunca, por lo que el proceso en ejecución sigue escribiendo. El registro de auditoría (solo herramienta, resultado y duración, 0600) rota a 5 MB con tres archivos anteriores, y solo se conservan los 20 registros de actualización más recientes (MAC_MCP_UPDATE_LOGS_KEPT).

Supervisión de fallos. mac-mcp start registra que el servidor debería ejecutarse y carga un pequeño trabajo de launchd (com.macmcp.supervisor, cada 30 segundos; su plist permanece en ~/.mac-mcp, por lo que nada nuevo se inicia al iniciar sesión). Si el proceso del servidor desaparece, o deja de responder a /health durante cuatro comprobaciones consecutivas, se inicia de nuevo a través del mac-mcp start normal; un túnel ngrok que salió se reinicia de la misma manera mientras el servidor sigue ejecutándose. mac-mcp stop registra la detención primero, por lo que el supervisor nunca la deshace, y el supervisor se aparta durante actualizaciones y reinicios. Después de tres recuperaciones fallidas en 15 minutos, retrocede. mac-mcp status y doctor (también Configuración → Ayuda y diagnóstico) muestran la última recuperación y por qué; MAC_MCP_SUPERVISOR=0 desactiva la supervisión.

Reinicios. mac-mcp restart verifica la configuración, el binario del túnel y el Python del runtime antes de detener cualquier cosa, y deja un servidor en funcionamiento solo si una comprobación falla. Si el nuevo servidor no se inicia, reintenta una vez; el estado final (succeeded, degraded cuando solo el endpoint público falló, o failed con un comando de reparación) se escribe en ~/.mac-mcp/restart-status.json. restart --wait espera ese resultado, que es lo que informa el botón Reiniciar de la aplicación. Actualizaciones. Solo se ejecuta una actualización a la vez; una segunda solicitud informa el ID y el estado de la actualización en curso. Se conservan las 10 copias de seguridad de runtime más recientes (MAC_MCP_UPDATE_BACKUPS_KEPT), más la que necesita la recuperación, y cada actualización elimina las carpetas temporales y los worktrees que dejó un actualizador que fue eliminado. Los worktrees de agentes finalizados sin nada pendiente de revisión se eliminan después de 7 días (MAC_MCP_AGENT_WORKTREE_RETENTION_DAYS, 0 los conserva); doctor muestra el uso de disco de las copias de seguridad y los worktrees.

Si el Python del runtime desaparece. Cuando una actualización de Homebrew o macOS elimina el Python con el que se construyó el venv del runtime, mac-mcp lo indica e imprime el comando de reparación en lugar de fallar con "bad interpreter":

python3 ~/mac-mcp/mcp_server/venv_repair.py check
python3 ~/mac-mcp/mcp_server/venv_repair.py repair

repair construye y verifica un nuevo venv junto al anterior con el Python de Homebrew más reciente compatible, lo intercambia, conserva el anterior como .venv.previous-<timestamp> y lo restaura si el nuevo falla en sus comprobaciones. doctor advierte con antelación cuando el venv apunta a una ruta versionada de Homebrew que la próxima actualización eliminará.

mac-mcp conformance ejecuta el laboratorio de regresión determinista de Computer Use. Su suite predeterminada es segura para CI y verifica contratos como el comportamiento del navegador en segundo plano, los respaldos explícitos de primer plano, la identidad estable de las pestañas, el rechazo de handles obsoletos, la preparación de render/elementos, los lotes de acciones acotados y el manejo de clics sin efecto. --live añade comprobaciones de solo lectura contra este Mac sin hacer clic ni escribir en las aplicaciones del usuario.

Planes de Computer Use de bucle cerrado

computer_plan usa por defecto el esquema de plan v2 para flujos de trabajo acotados de varios pasos en navegador/nativo. Además de los pasos de herramienta ordinarios y la reutilización de resultados de $ref, un plan puede usar wait_until, branch condicional, retry acotado y un único fallback seguro. Los fallos recuperables de pre-mutación por estado obsoleto/preparación pueden desencadenar una observación nueva y un reenlace semántico del objetivo dentro de la misma llamada de herramienta del modelo: los objetivos del navegador usan browser_find semántico, mientras que los objetivos nativos prefieren AXIdentifier y, de lo contrario, requieren una huella única de rol/título/descripción. Las coincidencias ambiguas fallan de forma cerrada en lugar de adivinar.

La recuperación tiene presupuestos independientes de conteo/tiempo además de los límites existentes de plan/acciones totales. El trabajo mutador nunca se reproduce automáticamente después de ACTION_NO_EFFECT, incertidumbre de verificación, denegación de política, outcome_unknown, una excepción que cruza un límite de herramienta mutadora o un lote de acciones parcialmente exitoso. Los resources opcionales del plan usan el mismo estado de propiedad global que la admisión de agentes delegados, por lo que un recurso conflictivo de pestaña/nativo/espacio de trabajo puede fallar en la verificación previa antes de que se ejecute cualquier paso del plan. Cada acción anidada sigue pasando por la política normal de Mac MCP, el alcance, los arrendamientos de navegador/nativo, la telemetría y la verificación de efectos.

Aceleración de decisiones opcional (experimental)

Configuración → Avanzado → Aceleración de decisiones tiene un resolutor de Decisions de OpenAI opcional. Está desactivado por defecto. La clave de API de OpenAI se almacena en Keychain (com.bulutarkan.mac-mcp / openai-decisions-api-key) y nunca en settings.json; Probar envía una pequeña solicitud de verificación.

Cuando el interruptor está desactivado, la clave falta o OpenAI rechazó la clave, el comportamiento no cambia y no se realiza ninguna llamada saliente. Cuando está habilitado con una clave que funciona:

  • browser_act pregunta a Decisions solo cuando la clasificación determinista encuentra dos o más objetivos casi iguales (puntuaciones superiores ≥ 0.60 y dentro de 0.10). Los objetivos únicos nunca activan una llamada.
  • La recuperación de computer_plan pregunta a Decisions solo por un reenlace ambiguo de navegador/nativo que de otro modo fallaría de forma cerrada con RECOVERY_AMBIGUOUS_TARGET.
  • Las acciones de browser_act aceptan una cadena intent opcional (por ejemplo, "el paso de Facturación") que se añade a la entrada de Decisions solo cuando la clasificación es ambigua. Está limitada a 120 caracteres y los secretos se redactan; sin ella, la solicitud no cambia.
  • Decisions solo puede elegir uno de los IDs de candidatos ya clasificados. Una elección se acepta con confianza ≥ 0.80, o ≥ 0.65 cuando coincide con la coincidencia determinista superior. Una respuesta de none, por ejemplo en un empate real, mantiene la elección determinista.
  • Una alternativa arriesgada (eliminar, enviar, pagar, …) nunca se elige sobre la coincidencia determinista.
  • Los tiempos de espera (600 ms por defecto), errores, límites de velocidad, claves inválidas y baja confianza recurren a la ruta determinista existente.
  • La política, las aprobaciones, los arrendamientos, las comprobaciones de toma de control y la preparación siguen ejecutándose después de la elección y siguen siendo autoritativos.
  • Solo se envían etiquetas de candidatos cortas y redactadas, roles y el texto de destino solicitado. Los valores escritos, las URL y el contenido de la página no se envían.

settings.json → decision_acceleration también acepta scope (browser, native, both, off), timeout_ms, accept_threshold, agree_threshold y max_candidates; un valor inválido desactiva la función.

Endpoint local predeterminado:

http://127.0.0.1:8000/mcp

Se puede proporcionar un puerto personalizado a través de MAC_MCP_PORT o banderas de CLI.

Voz

ChatGPT Voice como interfaz

Cuando Mac MCP está conectado como un plugin de ChatGPT, las experiencias compatibles de ChatGPT Voice pueden usarlo durante una conversación en vivo. Eso te permite hablar con ChatGPT de forma natural mientras Mac MCP realiza el trabajo compatible en el Mac.

Mac MCP no reemplaza ni modifica ChatGPT Voice. Proporciona la capa de ejecución detrás de la conversación.

Interacción de voz local

ask_user_voice es una capacidad separada de Mac MCP. Permite que el agente hable un mensaje corto a través del Mac, grabe la respuesta local, la transcriba con Groq Whisper y continúe la tarea con la transcripción devuelta.

La voz está desactivada hasta que la actives, porque envía datos a terceros: el texto de la pregunta va al servicio de texto a voz en línea de Microsoft (edge_tts) y la respuesta grabada va a Groq para su transcripción, donde se aplica la retención propia de Groq. Antes de cada grabación, Mac MCP muestra un diálogo para Grabar, Permitir siempre o rechazar; no se graba ni envía nada antes de esa elección, y un diálogo rechazado o sin respuesta devuelve skipped con fallback_tool: ask_user. Permitir siempre se puede revocar en Configuración → Voz → Preguntar antes de cada grabación. La grabación se elimina del Mac después, la transcripción se reemplaza con [voice transcript not stored] en el historial de actividad, y cada decisión se registra como un evento de seguridad voice_egress con solo proveedor, modelo, consentimiento y resultado.

La aplicación de menú gestiona:

  • interruptor experimental de habilitar/deshabilitar;
  • clave de API de Groq en el Keychain de macOS;
  • micrófono de entrada;
  • dispositivo de salida;
  • idioma;
  • tiempo de espera;
  • voz y velocidad de TTS.

La configuración no secreta se almacena en:

~/.mac-mcp/settings.json

Las variables de entorno siguen siendo compatibles como respaldo, incluyendo MAC_MCP_VOICE_GROQ_API_KEY, GROQ_API_KEY, MAC_MCP_VOICE_LANGUAGE, MAC_MCP_VOICE_INPUT_DEVICE, MAC_MCP_VOICE_OUTPUT_DEVICE y MAC_MCP_VOICE_TTS_RATE.

Cambios transaccionales del sistema de archivos y deshacer

Mac MCP registra sus operaciones destructivas primarias de archivos antes de cambiar el sistema de archivos. write_file, edit_file, move_file y delete_path ahora devuelven un transaction_id aleatorio más undoable, undo_expires_at y cualquier irreversible_reason explícito. write_files_batch(..., atomic=true) prepara todas las preimágenes antes de la primera escritura y restaura todo el lote si falla cualquier escritura posterior. file_transaction_batch extiende el mismo límite de todo o nada a una secuencia mixta de hasta 50 acciones de write, move y delete. Las transacciones reversibles recientes se pueden restaurar con file_transaction_undo; por defecto, deshacer se niega a sobrescribir archivos modificados después de la confirmación original, mientras que force=true es una anulación explícita de conflictos.

El diario vive bajo ~/.mac-mcp/transactions/ por defecto. El directorio y las carpetas de transacción son solo del propietario (0700); los manifiestos y los archivos de instantáneas son 0600. Los manifiestos contienen solo las rutas/estado necesarios para la restauración, hashes/huellas, tamaños, marcas de tiempo y metadatos de transacción — nunca el contenido nuevo del archivo ni el texto de edición. Las preimágenes reversibles contienen necesariamente los bytes originales, por lo que se conservan solo en archivos de instantáneas solo del propietario con retención acotada. Los valores predeterminados son una ventana de deshacer/caducidad de 7 días, 64 transacciones, 1 GiB de almacenamiento total del diario y 256 MiB de datos de preimagen por transacción; las entradas caducadas se eliminan al inicio del daemon y en la actividad del diario, mientras que los límites de conteo/bytes se aplican en cada transacción. Las variables de entorno MAC_MCP_FILE_JOURNAL_* correspondientes pueden ajustar esos límites.

Si una preimagen de escritura/movimiento/eliminación individual excede el límite de instantánea, la operación conserva la compatibilidad hacia atrás pero devuelve undoable=false con irreversible_reason=snapshot_limit_exceeded. Las operaciones atómicas por lotes son más estrictas: si no se puede preparar una instantánea de reversión completa, el lote se rechaza antes de la primera mutación. Un bloqueo del proceso después de la preparación pero antes de la confirmación deja una entrada de diario prepared; el deshacer normal trata ese resultado como desconocido, mientras que un force=true explícito puede restaurar el estado previo registrado. El deshacer de agentes delegados también vuelve a verificar cada ruta de transacción contra el alcance de recursos actual del agente, por lo que un ID de transacción no puede eludir el confinamiento del espacio de trabajo. copy_file y create_directory no forman parte de este límite inicial del diario de transacciones.

Alcances de archivos delegados seguros contra symlinks

Las llamadas delegadas con path_roots explícito usan un segundo límite del sistema de archivos en tiempo de operación además de la verificación normal de política del servidor. Las lecturas, escrituras, ediciones, movimientos, copias, eliminaciones, recorridos de directorios, búsquedas de nombre/contenido, instantáneas de transacciones y deshacer/reversión con alcance recorren los componentes de ruta con descriptores de archivo de directorio más O_NOFOLLOW en lugar de confiar en una cadena de ruta verificada anteriormente. Un intercambio de symlink entre la validación de política y la operación real del sistema de archivos falla de forma cerrada en lugar de seguir el reemplazo fuera del espacio de trabajo. Las operaciones recursivas de búsqueda/búsqueda/árbol informan u omiten entradas de symlink sin atravesarlas, y el acceso directo a un symlink que se resuelve fuera de las raíces permitidas se deniega.

Este recorrido más estricto se aplica solo cuando un alcance de recursos delegado tiene path_roots explícito; el comportamiento local/ordinario sin alcance de archivos sigue siendo compatible. Los movimientos entre dispositivos con alcance se rechazan en lugar de recurrir a una secuencia de copia/eliminación que debilitaría el límite de descriptores. Los fallos de carrera devuelven errores estructurados scoped_path_unsafe y no exponen contenidos de archivos fuera del espacio de trabajo.

Garantía de seguridad

Mac MCP publica una Matriz de Garantía de Seguridad respaldada por regresiones que mapea clases de riesgo estables a sus controles, pruebas automatizadas exactas e historial de versiones. scripts/verify_security_assurance.py valida esos enlaces en CI para que las pruebas renombradas, los controles faltantes, las etiquetas de garantía huérfanas, la falta de vinculación con CHANGELOG y el material similar a secretos/rutas privadas en la matriz pública fallen la compuerta en lugar de quedar obsoletos silenciosamente.

El acceso al plano de control de agentes delegados está limitado por linaje. Un agente con alcance puede inspeccionar y gestionar a sí mismo y a los descendientes que posee, pero los metadatos, resultados, registros, esperas y acciones de ciclo de vida de hermanos, ancestros y agentes/equipos no relacionados fallan de forma cerrada. El plano de control local autenticado/raíz conserva su vista administrativa existente. El linaje de propietario/raíz/padre se persiste en los metadatos de agentes/equipos y los eventos de denegación se registran sin abrir una intención de efecto secundario mutador.

Reanudación duradera de flujos de trabajo delegados

Los agentes delegados ahora obtienen un punto de control de flujo de trabajo duradero independiente del proveedor bajo ~/.mac-mcp/workflows/. El punto de control almacena el hash de entrada de la tarea original, el linaje de proveedor/sesión, la generación de reanudación, un cursor de hito de proveedor saneado y una cadena acotada de recibos de efectos secundarios verificados de Mac MCP. Las filas de recibos contienen metadatos de herramienta/familia más hashes de argumentos/resultados; los prompts sin procesar, comandos, contenidos de archivos, valores tipados, credenciales y cargas útiles de herramientas no se copian en el almacén de puntos de control. Los archivos de flujo de trabajo y mapa de agentes son solo del propietario (0600) dentro de un directorio solo del propietario (0700) y llevan un hash de integridad para que el estado corrupto o no coincidente falle de forma segura.

Una agent_action(action="retry") normal solo se permite mientras sea seguro reproducir el prompt original. Una vez que ha ocurrido un efecto secundario verificado, ya existe una generación de reanudación o el resultado se vuelve incierto, la reproducción fresca devuelve 409 retry_replay_unsafe. Para un agente interrumpido con un punto de control verificado, agent_action(action="resume") continúa la misma sesión de proveedor con una generación incrementada y un resumen de recibos compacto que instruye explícitamente al proveedor a no repetir efectos secundarios completados. Si la sesión del proveedor no se puede recuperar, el hash de entrada/sesión no coincide, el punto de control está corrupto o una mutación directa nativa del proveedor hizo que el estado de confirmación no sea verificable, Mac MCP devuelve un conflicto de resultado desconocido en lugar de adivinar.

Mac MCP puede emitir recibos sólidos solo para efectos secundarios enrutados a través de su propio límite de herramientas. Antes de que una herramienta mutante de Mac MCP se ejecute, escribe de forma duradera una intención de efecto secundario pendiente con hash; solo un resultado devuelto con éxito puede convertir esa intención en un recibo verificado. Si el proceso muere en el medio, la intención pendiente sobrevive y el flujo de trabajo se vuelve de resultado desconocido en lugar de reproducible. Las mutaciones directas de shell o archivos de Codex/OpenCode se tratan de forma conservadora a través de un límite de bloqueo; la actividad opaca de la herramienta CLI de ChatGPT Web también se marca como incierta. Esto es intencional: la reanudación duradera prefiere rechazar una reproducción ambigua sobre afirmar que una acción destructiva es segura de repetir. Los metadatos de agente/dashboard exponen workflow_id, resume_generation, estado/seguridad del punto de control, conteos de efectos secundarios pendientes/verificados, el cursor saneado, la última hora de punto de control duradero y si un agente interrumpido es reanudable de forma segura.

La cancelación del cliente sigue el mismo modelo de seguridad. Los cuerpos de herramientas MCP síncronas reciben un contexto de cancelación cooperativa compartido incluso cuando se ejecutan en un hilo de trabajo. Mac MCP termina los grupos de procesos que posee, detiene los trabajos creados por una llamada de comando paralelo cancelada, interrumpe el sondeo nativo del navegador, libera las concesiones de pestañas del navegador a través de la limpieza normal del contexto y ejecuta la restauración de enfoque nativa acotada antes de propagar la cancelación. La telemetría registra cancelled por separado de los fallos ordinarios. Si una operación mutante es opaca o no se puede demostrar que se detuvo antes de su efecto, su intención duradera se cierra como client_cancelled_outcome_unknown, la telemetría/control exponen outcome_unknown y el reintento/reanudación automáticos se bloquean en lugar de arriesgar un efecto secundario duplicado.

Árboles de trabajo Git aislados para agentes de escritura

Los agentes delegados con access_mode="workspace_write" usan git_isolation="auto" por defecto. Cuando cwd está dentro de un repositorio Git y el alcance de escritura se puede atenuar de forma segura, Mac MCP crea una rama/árbol de trabajo efímero bajo una raíz de espacio de trabajo ya autorizada, reasigna el cwd/alcance de ruta del hijo a ese checkout y registra el commit base más los metadatos de archivos modificados/diff. git_isolation="required" falla de forma segura cuando esa garantía no se puede aplicar; off mantiene el checkout original. Los agentes de solo lectura no necesitan un árbol de trabajo, mientras que el acceso sin restricciones a full nunca se presenta como confinado a un árbol de trabajo. Los espacios de trabajo que no son Git mantienen de forma elegante el comportamiento existente en el modo auto.

Las tareas hermanas paralelas reciben árboles de trabajo separados. Un equipo fija un commit base de Git, las tareas posteriores de DAG/revisor integran los parches de dependencias completados en un checkout aislado fresco, y las revisiones/reanudaciones de codificador acotadas continúan el mismo árbol de trabajo en lugar de perder ediciones en curso. La cancelación/bloqueo deja el checkout aislado recuperable. get_agent/wait_agents exponen la ruta del árbol de trabajo, la base, los archivos modificados, el stat de diff y el estado de aplicación.

Devolver los cambios al checkout fuente del usuario es explícito: agent_action(action="apply") es solo del plano de control local/raíz. Rechaza rutas tocadas que están sucias, detecta cambios en rutas tocadas desde la base del agente, precomprueba el parche contra el HEAD actual en un árbol de trabajo de integración temporal, vuelve a verificar las huellas dactilares por ruta inmediatamente antes de la mutación y revierte las preimágenes ya copiadas si un paso de aplicación interno falla. Nunca ejecuta git reset --hard, git clean o un cherry-pick/merge automático del árbol fuente. Los cambios de usuario no relacionados se dejan intactos. Los conflictos devuelven las rutas afectadas y ninguna mutación intencional del árbol fuente. despawn rechaza cambios aislados no aplicados hasta que se apliquen de forma segura o se descarten explícitamente; los árboles de trabajo de reanudación/revisión compartidos permanecen vivos hasta que su última referencia de agente desaparezca.

Admisión global de agentes entre equipos

Los equipos delegados independientes comparten una cola de admisión persistente antes de que comiencen los procesos del proveedor. El programador aplica un límite global de agentes activos más límites específicos del proveedor entre equipos, de modo que varios equipos no puedan consumir cada uno su propio presupuesto de max_parallel y sobrecargar colectivamente al mismo proveedor. Los valores predeterminados son 8 globales y 8 por proveedor; los operadores pueden ajustar MAC_MCP_AGENT_GLOBAL_ACTIVE_LIMIT, MAC_MCP_AGENT_PROVIDER_LIMIT y anulaciones de proveedor como MAC_MCP_AGENT_PROVIDER_LIMIT_OPENCODE, _CODEX o _CHATGPT. Las concesiones de admisión son estado local solo del propietario, con latido de los trabajadores en ejecución y reclamadas después de MAC_MCP_AGENT_ADMISSION_TTL_S si un trabajador desaparece. MAC_MCP_AGENT_ADMISSION_QUEUE_LIMIT limita el trabajo persistente en espera.

La cola es consciente de FIFO sin convertir un recurso bloqueado no relacionado en un atasco global de cabeza de línea. El trabajo ejecutable más antiguo mantiene prioridad para ranuras escasas de proveedor/global y recursos conflictivos, mientras que una tarea bloqueada en el espacio de trabajo A no impide que una tarea más joven use el espacio de trabajo B independiente. El estado de tarea/equipo expone queued, posición/motivo/detalles de la cola, reclamos de recursos y conteos activos globales/proveedor. El dashboard de Operaciones muestra el activo/límite global en vivo y el conteo en cola. La cancelación del equipo elimina sus solicitudes en cola inmediatamente; las concesiones activas permanecen retenidas hasta que su proveedor/trabajador se detenga realmente. La finalización normal despierta automáticamente a otros equipos en cola, y las concesiones de bloqueo caducadas se podan de forma segura en la próxima admisión/snapshot. El estado de limitación de ChatGPT existente alimenta la misma decisión de admisión: el enfriamiento activo impide nueva admisión, y la ventana de concurrencia reducida posterior a la limitación baja temporalmente el límite efectivo del programador global del proveedor de ChatGPT a uno mientras la puerta de espaciado de inicio existente controla el tiempo de lanzamiento seguro exacto.

Las tareas de spawn_agents pueden declarar opcionalmente reclamos de resources=[...]. Los tipos admitidos son workspace, path, file, browser_tab, native_app, native_window, process y clipboard; los modos son read o write. Los reclamos de lectura/lectura pueden coexistir, mientras que cualquier escritura superpuesta se serializa. Los IDs de ruta/archivo/espacio de trabajo se resuelven dentro del alcance de ruta delegado de la tarea, los reclamos de pestañas del navegador deben ajustarse al alcance del navegador de la tarea, y las concesiones de pestañas existentes en tiempo de acción del navegador siguen siendo la guardia de propiedad final en lugar de ser reemplazadas. Los alcances de ruta de solo lectura se reclaman automáticamente como lecturas compartidas. Las escrituras de espacios de trabajo que no son Git se reclaman automáticamente como escrituras exclusivas; los árboles de trabajo Git aislados #50 evitan intencionalmente un reclamo de escritura grueso del repositorio fuente para que los árboles de trabajo hermanos independientes puedan ejecutarse concurrentemente.

read_file también devuelve un revision aditivo usando la misma huella dactilar que las comprobaciones de conflicto de transacciones del sistema de archivos. Una tarea puede adjuntar ese valor como expected_revision en un reclamo de kind="file". Mac MCP lo vuelve a verificar antes de la admisión/inicio del proveedor; una discrepancia devuelve file_revision_conflict y el proveedor nunca comienza, proporcionando una guardia de estilo CAS para carreras de mutación de archivos.

Notificaciones nativas de finalización de agentes

La aplicación de menú de macOS puede notificarte opcionalmente cuando el trabajo delegado termina mientras Mac MCP está en segundo plano. La función está desactivada por defecto y el permiso de notificación de macOS se solicita solo cuando habilitas explícitamente Notificaciones de Agentes en Configuración General.

Los agentes independientes generan una notificación de terminal para estados de finalización o necesita-atención. Los equipos multiagente se combinan en una notificación de terminal a nivel de equipo en lugar de una notificación por hijo. El contenido de la notificación es intencionalmente mínimo: solo se muestra una etiqueta de agente/equipo saneada, nunca prompts sin procesar, resultados, URLs, rutas de archivos o secretos. Hacer clic en una alerta abre el dashboard de Operaciones autenticado local enfocado en el agente o equipo relevante. El tiempo de entrega, No Molestar, modos de Enfoque y presentación permanecen bajo el control de macOS.

Presupuestos de equipos de agentes y reintento adaptativo

Resultado de equipo consciente de fallos y quórum

wait_agents separa finalización de éxito. mode="all" mantiene su significado de finalización existente (condition_met=true una vez que todo el trabajo relevante es terminal), mientras que los campos aditivos success, outcome y partial_failure indican si el trabajo terminado realmente tuvo éxito. mode="any" y mode="majority" cuentan solo el trabajo exitoso de completed; el trabajo fallido, con tiempo agotado, estancado, cancelado, omitido, con presupuesto agotado y con fallo de calidad no puede satisfacer un quórum de éxito. Para equipos DAG, el quórum se calcula sobre los resultados de las tareas en lugar de los intentos históricos de agentes, de modo que los reintentos/revisiones no distorsionen el denominador.

Los resultados de trabajo normalizados son running, completed, partial_failure, failed o cancelled. timed_out está deliberadamente separado y significa solo que el plazo de la llamada de espera expiró mientras su condición aún era posible; un agente cuyo propio estado es timeout se informa como trabajo fallido, no como un tiempo de espera de espera. Las respuestas también incluyen conteos de éxito/fallo/pendiente, totales/umbrales de quórum, quorum_possible y razones estructuradas de fallo de tarea/agente. Los campos existentes de equipo status, count, terminal_count, filas de agentes y campos anidados team permanecen disponibles para compatibilidad.

spawn_agents aplica umbrales de admisión de equipo compartidos además del tiempo de espera de cada agente hijo. max_parallel sigue siendo el límite de concurrencia; team_timeout_s limita cuánto tiempo puede admitir el programador nuevos nodos DAG. Los opcionales admission_tool_call_budget y admission_token_budget detienen nuevos nodos DAG y reintentos una vez que el uso observado del equipo alcanza el umbral configurado. Intencionalmente no son límites duros de tiempo de ejecución: los agentes que ya estaban ejecutándose pueden terminar y empujar el uso observado más allá del umbral en lugar de ser eliminados en un límite de efecto secundario inseguro. Los resúmenes de equipo exponen el contrato, los valores usados/restantes, el exceso y si el trabajo sigue activo en el umbral. Los nombres más antiguos max_total_tool_calls y max_total_tokens siguen siendo alias obsoletos para compatibilidad y tienen la misma semántica solo de admisión. max_team_retries es un presupuesto de reintentos compartido separado. Los reintentos automáticos se clasifican antes de la reproducción: los límites de tasa, los tiempos de espera/estancamientos, la sobrecarga del proveedor y las fallas transitorias de transporte pueden reintentarse; las fallas de autenticación, permisos, cuotas, modelo/solicitud no válidos y proveedor desconocido fallan rápidamente. La seguridad duradera de los efectos secundarios/puntos de control tiene prioridad sobre la clasificación de errores, y cada espacio de reintento del equipo se reserva atómicamente con un espaciado de inicio acotado para que las fallas concurrentes no puedan crear una tormenta de reintentos. admission_token_budget se acepta solo para proveedores que exponen un uso confiable; ChatGPT Web actualmente rechaza esa opción en lugar de fingir que el uso no informado es cero.

Superficie de API de Memoria y Habilidades de Agente

El endpoint MCP nativo sigue siendo la superficie completa de Memoria y Habilidades de Agente. REST/OpenAPI expone intencionalmente solo el subconjunto de compatibilidad orientado a lectura: memory_search, memory_get, skill_list, skill_search y skill_get basado en nombres. Estas rutas utilizan la misma autenticación de servidor, perfil de permisos, autorización de familia de herramientas con alcance y puerta de contexto de seguridad que el resto de la superficie REST publicada.

Las memorias se almacenan como archivos de día en Markdown bajo ~/.mac-mcp/memory (o MAC_MCP_MEMORY_DIR) más un índice de búsqueda SQLite local; la carpeta, los archivos y el índice se mantienen solo para el propietario incluso para una ubicación personalizada. Eliminar una memoria la elimina del archivo Markdown (y del archivo en sí una vez que un día no tiene memorias restantes) y del índice, sus filas de texto completo y vectoriales, con borrado seguro de SQLite y un punto de control WAL para que el texto no permanezca en la base de datos; esto no es un borrado forense del disco. Configuración → Uso → Memoria muestra cuántas memorias existen, las exporta todas como JSON, las elimina todas después de mostrar cuántas se eliminarán y establece un período de retención opcional (hasta que se eliminen por defecto; de 90 días a 2 años), que conserva las memorias altas y críticas a menos que lo desactives.

La mutación de memoria (memory_add, memory_update, memory_delete) y el registro/índice de mutación de Habilidades de Agente (skill_register, skill_update_index) siguen siendo solo MCP. REST skill_get acepta un nombre de habilidad exacto pero deliberadamente no acepta una ruta SKILL.md porque la búsqueda de ruta MCP puede registrar una habilidad externa. Las respuestas REST públicas también omiten metadatos locales de archivos/índice, como rutas de archivos de memoria, raíces/directorios/rutas de recursos absolutos de habilidades y diagnósticos de sincronización de índices.

Aprendizaje de roles para agentes delegados

Mac MCP mantiene lecciones de flujo de trabajo separadas de la memoria fáctica genérica. Los agentes delegados pueden optar por un rol con role="coder", role="reviewer" o role="orchestrator". En el momento de la generación, solo se inyecta un pequeño conjunto top-k de lecciones aprobadas y relevantes para ese rol; las instrucciones de la tarea actual siempre tienen prioridad. Las tareas no relacionadas no reciben contexto de lecciones.

Un trabajador puede emitir un candidato de lección estructurado compacto al final de una ejecución, pero los candidatos se ponen en cuarentena y nunca se activan automáticamente. lesson_search permite que el padre revise los candidatos y lesson_feedback registra resultados de approve, success, failure, disable o enable. Las fallas repetidas reducen la confianza y pueden deshabilitar una lección; las lecciones obsoletas de baja confianza pueden deshabilitarse durante lesson_consolidate. Los duplicados exactos se fusionan dentro del mismo dominio de confianza, mientras que las acciones preferidas contradictorias se informan para revisión en lugar de elegir silenciosamente un ganador. La creación manual de candidatos y la consolidación siguen disponibles a través del descubrimiento de herramientas para que la superficie de herramientas central compacta siga siendo pequeña. lesson_export devuelve cada lección almacenada para revisión, y lesson_delete elimina una lección, las lecciones de un rol o todas las lecciones después de confirm=true (el texto eliminado se sobrescribe en el disco). Las lecciones no actualizadas o utilizadas durante privacy.lesson_retention_days (por defecto 365, 0 las conserva hasta que se eliminen) se eliminan automáticamente y nunca llegan a un mensaje de trabajador.

Las lecciones de rol se almacenan como campos estructurados y referencias de evidencia acotadas en ~/.mac-mcp/role-learning/role-lessons.sqlite3; las transcripciones crudas de agentes no se almacenan en la base de datos de lecciones. Se aplica una procedencia estricta: una sesión contaminada por la web no puede escribir ni aprobar lecciones de confianza, los hijos contaminados no reciben contexto de lecciones de confianza y los candidatos no confiables se mantienen en un espacio de nombres de cuarentena separado para que no puedan envenenar una lección de confianza existente.

Resiliencia de subagentes de ChatGPT

Cuando ChatGPT Web CLI se usa como proveedor de agentes delegados, Mac MCP mantiene los turnos web largos acotados sin tratar el presupuesto como un tiempo de espera duro de tarea. El presupuesto de turno suave por defecto es de 15 minutos; si una herramienta sigue activa, Mac MCP espera por ella, con un techo duro de herramienta de 20 minutos, luego solicita un interrupt controlado de ChatGPT que continúa la misma tarea en un turno nuevo. La continuación evita explícitamente repetir trabajo completado o efectos secundarios externos. Los subagentes de ChatGPT usan por defecto razonamiento Alto; extra-high sigue siendo opcional.

Si ChatGPT informa limitación de solicitudes, Mac MCP registra el motivo/hora, aplica un enfriamiento exponencial acotado, recupera la sesión existente de ChatGPT para reintentar cuando sea posible y escalona otros inicios de trabajadores de ChatGPT durante la ventana de recuperación en lugar de lanzar una tormenta de reintentos. Las filas de agentes del panel y la barra de menú exponen el tiempo transcurrido del turno más los recuentos de puntos de control/limitación. Estos valores se pueden ajustar con CHATGPT_PROVIDER_TURN_BUDGET_S, CHATGPT_PROVIDER_HARD_TOOL_BUDGET_S, CHATGPT_PROVIDER_RATE_LIMIT_BACKOFF_S y CHATGPT_PROVIDER_RATE_LIMIT_BACKOFF_CAP_S.

Panel de operaciones

Ábrelo con el lanzador local autenticado:

mac-mcp dashboard

El shell estático del panel es solo de bucle local. Cada solicitud sensible de /dashboard/api/* y el flujo en vivo de /dashboard/events requieren adicionalmente un token Bearer separado del panel almacenado en ~/.mac-mcp/dashboard-token con modo 0600; el directorio de estado se mantiene solo para el propietario (0700). La CLI/aplicación de menú pasa la credencial del navegador en un fragmento de URL, que no se envía en la solicitud HTTP, y el JavaScript del panel lo mueve inmediatamente a sessionStorage, lo elimina de la barra de direcciones y usa un encabezado Authorization para solicitudes API/SSE. El conector global MCP_API_KEY no se expone al navegador.

El panel registra actividad de herramientas MCP/REST saneada, estado, latencia, estado reciente de agentes delegados, llamadas activas y frecuencia de herramientas. Los campos de identidad del proveedor, como sesión/asunto/organización/ubicación de OpenAI, se eliminan de la telemetría; la migración de seguridad también limpia filas persistentes heredadas en el primer inicio. La telemetría persiste localmente bajo:

~/.mac-mcp/dashboard/telemetry.sqlite3

Bucle local significa solo máquina local, no privado de usuario. El token del panel evita que procesos locales no autenticados no relacionados y solicitudes de origen de navegador usen endpoints sensibles, pero un proceso malicioso que ya se ejecuta como el mismo usuario de macOS generalmente puede leer los archivos de ese usuario y está dentro de este límite de confianza. Se evaluaron sockets de dominio Unix para el tráfico de aplicación de menú ↔ demonio; pueden proporcionar permisos de propietario del sistema de archivos pero no resuelven el aislamiento del mismo UID y no pueden ser consumidos directamente por el panel del navegador, por lo que HTTP de bucle local autenticado sigue siendo el transporte único. Consulta docs/LOCAL_API_SECURITY.md para el modelo de amenazas y la decisión.

Cobertura de herramientas

Mac MCP 2.1 anuncia una superficie central compacta por defecto, respaldada por un catálogo de capacidades MCP más grande registrado centralmente. El catálogo visible exacto es consciente del perfil de permisos y del alcance delegado: list_tools y tool_discover usan la misma política de disponibilidad, mientras que tool_invoke preserva el estado de éxito/fallo de la herramienta anidada.

Establece MAC_MCP_TOOL_PROFILE=full para anunciar cada herramienta permitida por el perfil de permisos activo directamente al cliente. También puedes agregar herramientas seleccionadas a la superficie compacta con MAC_MCP_CORE_EXTRA_TOOLS=name1,name2. Los recuentos exactos del catálogo se derivan intencionalmente en tiempo de ejecución en lugar de estar codificados aquí para que la documentación no pueda desviarse a medida que se agregan o eliminan herramientas.

El conjunto de capacidades cubre:

  • terminal/sistema y trabajos en segundo plano (cada flujo de salida conserva hasta 16 MB, get_job_output lee solo el segmento solicitado, los trabajos terminados expiran después de 7 días, 200 trabajos o 1 GB, y delete_job elimina uno; anula con MAC_MCP_JOB_STREAM_MAX_BYTES, MAC_MCP_JOB_RETENTION_DAYS, MAC_MCP_JOB_RETENTION_COUNT, MAC_MCP_JOB_RETENTION_BYTES);
  • agentes delegados de OpenCode/Codex;
  • gestión de archivos;
  • automatización de macOS y control de UI de Accesibilidad;
  • recetas guardadas: computer_plan(save_as_recipe="name") conserva un plan exitoso como borrador en ~/.mac-mcp/recipes (solo propietario); recipe(action="update", parameterize=[{"literal": "October", "param": "month"}]) convierte valores fijos en parámetros tipados, recipe(action="activate", confirm=true) lo hace ejecutable después de la revisión (se rechazan valores similares a secretos), y recipe(action="run", values={...}) valida los valores y ejecuta los pasos a través de computer_plan con la política y verificación habituales; las recetas se pueden listar, inspeccionar, pausar, reanudar y eliminar;
  • lanzadores de recetas fuera de un chat: mac-mcp recipe list y mac-mcp recipe run rcp_… --param month=November (salida 0 hecho, 1 fallido, 2 necesita aprobación, 3 servidor no ejecutándose) para comandos de script de Raycast o una acción de "Ejecutar script de shell" de Atajos, y enlaces macmcp://recipe/run?id=rcp_…&month=November para una acción de "Abrir URL" de Atajos. Un enlace siempre pide confirmación en Mac MCP antes de ejecutarse y el resultado llega como notificación; los lanzadores solo pueden ejecutar recetas activadas y pasar valores simples, nunca nombres de herramientas o comandos;
  • adaptadores tipados de mac_app para Finder, Notas, Correo, Calendario, Recordatorios, Vista Previa y Configuración del Sistema, incluidos Calendario create_event/update_event, Recordatorios list_reminders/complete_reminder, Notas create_note y Correo create_draft (guardado solo en Borradores, nunca enviado; con varias cuentas de correo el remitente debe nombrarse): cada uno devuelve el id estable del elemento con una verificación de lectura posterior, una creación repetida devuelve el elemento existente en lugar de un gemelo, y un resultado incierto se informa como outcome_unknown en lugar de reintentarse;
  • automatización de navegador Safari/Chrome con identificadores de pestaña estables y observación visual en segundo plano; browser_checkpoint te entrega un paso de inicio de sesión, 2FA, passkey o captcha (una notificación, luego el agente espera hasta 5 minutos o vuelve a verificar) y se reanuda una vez que esa pestaña ya no muestra el desafío, sin leer ni almacenar contraseñas o códigos; con el complemento de Chrome, los agentes también trabajan dentro de marcos de origen cruzado (frame=), ven diálogos nativos de alerta/confirmar/prompt y los responden solo con una decisión explícita, usan eventos reales de hover, arrastre y teclado, y hacen clic en aplicaciones de lienzo por coordenadas de viewport;
  • HTTP y búsqueda;
  • entrada humana de texto/elección/confirmación/voz;
  • memoria persistente;
  • Habilidades de Agente;
  • autoactualización segura.

Usa el descubrimiento de herramientas MCP para el esquema en vivo autoritativo. tool_discover clasifica herramientas contra una consulta en palabras simples, dice por qué coincidió cada una y pagina resultados largos con next_cursor.

Los listados y lecturas de múltiples archivos informan cuando se detienen temprano: list_directory, find_files y list_jobs devuelven page.has_more/page.next_cursor, read_multiple_files gasta un presupuesto total de caracteres y lista archivos no leídos en not_read, y read_file da next_offset para la siguiente línea.

Las fallas llevan un contrato legible por máquina en cada transporte: un error MCP termina con una línea error_contract={...} y un cuerpo de error REST tiene un objeto error junto a detail, ambos con code, stage, outcome (not_executed, completed o unknown) y retry (fix_arguments, safe_retry, observe_again, wait_for_user o never_retry). Un resultado de unknown nunca dice safe_retry; observa el estado actual antes de actuar nuevamente. Una herramienta que se ejecutó e informó una falla (por ejemplo, una salida de shell no cero) es un resultado normal con ok: false, no un error. Las herramientas MCP que cambian estado aceptan un idempotency_key opcional (8-128 caracteres). Repetir una llamada completada con la misma clave y argumentos devuelve el primer resultado marcado como idempotent_replay en lugar de ejecutarla de nuevo; la misma clave con argumentos diferentes es idempotency_key_conflict; una repetición mientras la primera llamada aún está en curso o terminó con un resultado desconocido se rechaza, nunca se vuelve a ejecutar. Las claves están limitadas al llamante (agente o actor autenticado, por lo que un cliente reconectado aún encuentra su llamada) y se conservan durante 24 horas en un ~/.mac-mcp/idempotency.sqlite3 solo del propietario; los resultados que parecen secretos o superan los 256 KB no se almacenan. Esto es deduplicación, no ejecución exactamente una vez.

REST tiene una superficie versionada generada a partir del contrato de herramientas MCP: POST /api/v2/<tool> toma el esquema de entrada propio de la herramienta MCP y pasa por la misma política, aprobaciones, telemetría, idempotency_key y contrato de errores. Una llamada completada devuelve el resultado de la herramienta con HTTP 200 (incluso cuando informa ok: false); un fallo devuelve {"error": {...}} con el estado del contrato. El esquema se publica en openapi/mac-mcp-v2.json (versión de API 2.0.0, versión de producto en x-product-version), se regenera con python -m mcp_server.rest_v2 --write y se verifica su desviación en las pruebas. Las rutas sin versión /api y openapi/custom-gpt-actions.json siguen funcionando sin cambios.

Actualización

Desde la aplicación: haz clic en el icono de la barra de menú de Mac MCP, abre Configuración (icono de engranaje) → General → Actualizaciones. La tarjeta verifica el canal de lanzamiento verificado cuando la abres y muestra tu versión actual junto a la versión verificada más reciente. Buscar actualización vuelve a comprobar, y Actualizar ahora la instala mientras la tarjeta enumera cada paso a medida que se ejecuta, desde Preparar y Copia de seguridad hasta Reiniciar y la verificación de salud final. Si una actualización se interrumpe, el mismo botón cambia a Reanudar recuperación o Reintentar recuperación. "Bloqueado por cambios locales" significa que el checkout de origen tiene archivos sin confirmar o sin seguimiento (git status en el checkout de origen los enumera): confirma, guarda o muévelos, luego verifica de nuevo. Si algo aún parece incorrecto, mac-mcp doctor informa el estado de actualización y recuperación.

Desde Terminal, para automatización o si prefieres la CLI:

mac-mcp update --check
mac-mcp update

Ambas rutas ejecutan el mismo actualizador con las mismas comprobaciones de firma, linaje y repositorio sucio.

El actualizador escanea el historial de primer padre de origin/main e instala el punto de control de lanzamiento estable verificado criptográficamente más reciente, no el HEAD arbitrario del repositorio. Los commits de desarrollo o no verificados que estén por delante de ese punto de control no se ofrecen como actualizaciones normales. También bloquea repositorios sucios, conserva superposiciones de tiempo de ejecución y archivos privados, crea una copia de seguridad en tiempo de ejecución, reinicia el servicio administrado, realiza una verificación de salud y revierte los archivos de tiempo de ejecución administrados si la verificación falla.

En 2.0, menu_app/ es parte del tiempo de ejecución administrado. Si Mac MCP.app ya está instalado, una actualización exitosa lo reconstruye y refresca automáticamente.

Permisos de macOS

Otorga solo los permisos requeridos por las herramientas que uses:

  • Accesibilidad para mac_observe, mac_act, Eventos del Sistema y automatización de escritorio;
  • Grabación de pantalla para captura de pantalla protegida;
  • Automatización cuando macOS pida permiso para controlar Safari, Chrome, Eventos del Sistema, Recordatorios u otras aplicaciones;
  • Micrófono para ask_user_voice.

Contribución y seguridad

Las contribuciones son bienvenidas. Consulta CONTRIBUTING.md para el flujo de trabajo de desarrollo y solicitudes de extracción. Usa los formularios de problemas de GitHub para errores y solicitudes de funciones, sigue SECURITY.md para informar vulnerabilidades de forma privada y consulta CODE_OF_CONDUCT.md para las expectativas de la comunidad.

Desarrollo

Ejecuta las pruebas:

python -m unittest discover -s tests -v

Compila la aplicación de menú nativa sin instalarla:

./menu_app/build_app.sh /tmp/mac-mcp-build

Estructura del proyecto:

mcp_server/   Python MCP server and dashboard
menu_app/     Native SwiftUI menu bar controller
tests/        Regression tests
openapi/      REST/OpenAPI schema assets

Licencia

MIT