dot-mcp

MCP autohospedado para Linux/Termux: shell, archivos, memoria, tareas, navegador y una bóveda local experimental. Acceso remoto protegido con OAuth; se ejecuta en tu propia máquina.

Documentación

dot-mcp

Agente MCP personal para ChatGPT, Claude y Gemini: shell, archivos, memoria, objetivos, tareas, bandeja de entrada, programador y OAuth autoalojado — ejecutándose en tu propia máquina.

⚠️ El servidor otorga acceso completo al shell a quien tenga una credencial. Exponlo solo mientras lo uses y luego detenlo (dot-mcp stop).

Instalación

pip install dot-mcp

Requiere Python 3.10+ y OpenSSH (ssh, ssh-keygen) para el túnel.

Uso

dot-mcp start    # server + public URL (runs in background)
dot-mcp status   # check if it is running
dot-mcp stop     # stop server + tunnel

dot-mcp start imprime todo lo que necesita el conector:

Public URL            https://xxxx.tunnl.gg/mcp/
Owner secret          <stored on your machine>
OAuth Client ID       dots-xxxxxxxx
OAuth Client secret   <stored on your machine>

Agrega la URL pública como conector MCP personalizado (auth = OAuth). Aprueba una vez con el secreto del propietario cuando se solicite. La URL del túnel permanece igual al reiniciar; el túnel gratuito caduca después de 24 h o 2 h de inactividad.

Linux/Termux es el entorno compatible para la gestión de procesos. Detener solo afecta a los procesos iniciados con los nuevos registros de propiedad. Si actualizas desde una versión anterior, detén su servidor/túnel antes de iniciar esta versión; los archivos PID heredados sin formato no se confían deliberadamente.

DOT_MCP_STATE_DIR anula el directorio completo de credenciales/claves SSH (predeterminado ~/.config/dot-mcp), no su directorio padre. Esto es independiente de --data-dir.

Las rutas de archivo son relativas a $HOME a menos que sean absolutas. Las rutas absolutas conservan su ubicación y deben estar dentro de $HOME, $TMPDIR o almacenamiento compartido disponible; otras rutas se rechazan, no se colocan silenciosamente en HOME. En Android, cuando $TMPDIR está fuera de /tmp, /tmp y /tmp/... se asignan a $TMPDIR. Las herramientas de archivos devuelven el path efectivo. El texto de los comandos de shell nunca se reasigna, así que usa esa ruta efectiva en los comandos de shell cuando se aplique esta asignación.

Las raíces de archivos son salvaguardas, no una zona de pruebas de shell. Una credencial de shell aún otorga acceso completo como el usuario del sistema operativo del servidor. Usa un usuario/contenedor de sistema operativo separado para cargas de trabajo no confiables.

Opciones: --port (predeterminado 33041), --data-dir (predeterminado ~/.dot-mcp), --json (salida apta para scripts).

Túnel de desarrollo (solo pruebas)

dots start --dev usa un túnel rápido de Cloudflare en lugar del flujo predeterminado de tunnl.gg con clave estable. Necesita cloudflared en PATH, no OpenSSH. La falta de cloudflared se informa como not installed: cloudflared; no se instala nada.

DEV / INESTABLE: los nombres de host del túnel rápido cambian en cada reinicio y no tienen garantía de disponibilidad. Pueden ocurrir errores 1033/caídas. Los túneles rápidos de Cloudflare no admiten SSE, por lo que algunas combinaciones de cliente/transporte MCP pueden fallar incluso si la inicialización de arranque pasa. No uses este modo para conectores de producción.

La protección de host/origen permanece habilitada. El host descubierto de trycloudflare.com se pasa al servidor antes de su único arranque, con verificación pública autenticada de inicialización. Una verificación fallida detiene el servidor y el túnel propietarios. dots stop detiene cualquier proveedor; --json incluye modo, proveedor y campos inestables. Una configuración explícita vacía de Cloudflare evita reutilizar un túnel nombrado guardado.

Esto es un cambio de proveedor, NO una zona de pruebas de seguridad: usa un contenedor/usuario de sistema operativo separado con credenciales desechables. El modo de desarrollo no cambia las rutas de datos o credenciales predeterminadas y aún puede usar una bóveda local existente opcional. En una zona de pruebas aislada, usa rutas DOT_MCP_DATA y DOT_MCP_STATE_DIR separadas y un HOME desechable; no montes archivos personales. Los paquetes opcionales de navegador/bóveda no son necesarios para una prueba básica de MCP/OAuth. --dev --vault usa el mismo proveedor de desarrollo pero requiere el desbloqueo normal de la bóveda local.

Documentación de Cloudflare: https://developers.cloudflare.com/tunnel/get-started/quick-tunnels/

Qué puede hacer (51 herramientas en esta revisión de desarrollo)

  • Shell: run_command (sesiones en segundo plano + tiempo de espera) + read_output
  • Archivos: list_dir, read_file (paginado + sha256), write_file (atómico + salvaguardas), append_file, edit_file
  • Memoria: remember, recall, forget — persiste entre chats
  • Objetivos/Tareas: set_goal, add_update, get_state, add_task, complete_task
  • Bandeja de entrada: notify_user, poll_inbox, ack_inbox — mensajes entre chats
  • Programador: add_schedule, list_schedules, remove_schedule — trabajos en segundo plano que se ejecutan entre chats
  • Navegador: browser_open/navigate/snapshot/click/type/scroll/key/screenshot/close
    • browser_hover/select/wait/back/reload — las capturas informan estado deshabilitado, marcado y de opción seleccionada; wait maneja páginas dinámicas
  • En vivo: /live se reconecta automáticamente (capacidad de sessionStorage), muestra el dominio actual, vista de pantalla completa; el control aún requiere el token del propietario
  • UI: open_workspace — panel integrado (tareas, memoria, sesiones)

Trabajo duradero (revisión de desarrollo)

Los nombres/firmas de herramientas existentes permanecen disponibles. Nuevas herramientas de trabajo:

  • create_work_task, get_work_task, list_work_tasks, update_work_task
  • start_command, get_session_status, cancel_command
  • register_artifact, bootstrap_context, ack_work_result, purge_session_output

Flujo sugerido para ChatGPT/Claude:

  1. Llama a bootstrap_context al inicio de un nuevo chat.
  2. Crea una tarea de trabajo, luego start_command con su task_id.
  3. Consulta read_output / get_session_status. La salida es legible mientras se ejecuta.
  4. Verifica el resultado, registra los archivos de salida y establece la tarea a done con un resultado, o blocked con una pregunta. Salir con cero solo nunca finaliza una tarea.
  5. En un nuevo chat, carga el contexto e inspecciona get_work_task para reanudar.

start_command regresa inmediatamente. Una idempotency_key reutilizada devuelve la misma sesión para una solicitud idéntica; una solicitud cambiada con esa clave se rechaza. Esto evita lanzamientos duplicados, no efectos externos exactamente una vez. set_goal cambia el objetivo actual sin eliminar el historial de add_update.

El run_command original sigue siendo la API síncrona heredada. Usa las nuevas herramientas de inicio/estado para trabajo asíncrono duradero; read_output y get_session_status manejan ambas. El estado heredado es solo en memoria y no sobrevive al reinicio. purge_session_output limpia la salida heredada finalizada mientras conserva sus metadatos; la salida activa no se puede purgar. La salida duradera aún requiere ack_work_result antes de purgar.

Límites de comandos predeterminados: 4 sesiones activas, 1 hora de tiempo de ejecución máximo, 4 MiB de salida combinada por sesión y 64 MiB de salida guardada antes de que se rechace nuevo trabajo. La salida no se elimina silenciosamente: reconoce un resultado finalizado y purga explícitamente su salida. Los metadatos de tareas/eventos/sesiones permanecen en work.sqlite3 (archivo privado).

En el primer uso, las tareas heredadas se copian de state.json una vez, con una copia de seguridad privada. Las herramientas JSON antiguas aún usan sus archivos antiguos, y bootstrap_context muestra las tareas/bandeja de entrada heredadas actuales por separado. La memoria/objetivos/programadores/OAuth no se migran ni reescriben. Usa las nuevas herramientas de tareas de trabajo de manera consistente; la lista de tareas heredadas y la lista de trabajo duradero están separadas después de la importación inicial.

Un servidor posee la ejecución por directorio de datos. Después de un bloqueo/reinicio del servidor, los comandos en ejecución no verificados se detienen si su identidad de proceso guardada aún coincide, y se marcan como interrupted. Nunca se reinician automáticamente. Esto es recuperación de registros veraces, no supervivencia transparente de procesos.

Los artefactos son rutas de archivo locales más SHA-256, no enlaces de descarga alojados. Esta revisión no tiene navegador, notificaciones push ni trabajador LLM autónomo, y no necesita una nueva clave de API de modelo para el flujo de trabajo de chat activo. Un host puede necesitar actualizar sus herramientas después de una actualización. La integración en vivo de ChatGPT/Claude sigue pendiente de prueba por el propietario.

Modelo de seguridad

  • /mcp/ requiere Authorization: Bearer (JWT OAuth o secreto del propietario) — cualquier otra cosa recibe 401, incluso desde localhost
  • OAuth 2.1 está autoalojado: registro dinámico, PKCE, JWT de 1 h + tokens de actualización rotativos de 30 días, ID de cliente/secreto manual para conectores estilo Claude
  • Límites de velocidad por IP (300/min API, 30/min auth), audit.jsonl de solo anexión, bloqueos de archivos entre procesos, escrituras atómicas
  • Limitaciones conocidas: el proveedor del túnel ve el tráfico (TLS termina en su borde); haz una copia de seguridad de ~/.dot-mcp tú mismo

Modo solo local (sin túnel)

export OPENAI_API_KEY=sk-...
python -m dot_mcp.local_agent          # chat loop
python -m dot_mcp.local_agent --list   # list tools only

Desarrollo

./setup.sh                      # venv + editable install
.venv/bin/python -m pytest tests/ -q   # test suite
python -m build                 # wheel in dist/

Consulta CHANGELOG.md para las notas de versión.

Licencia

MIT

Navegador opcional y /live

Instala en el mismo entorno que dot-mcp (no se necesita activación de shell):

.venv/bin/python -m pip install '.[browser]'
.venv/bin/python -m playwright install chromium

En Arch, un Chrome/Chromium instalado se puede seleccionar con DOT_MCP_BROWSER_EXECUTABLE=/usr/bin/chromium. La zona de pruebas de Chromium permanece activada. No apuntes esto a tu perfil de uso diario. Esta función siempre usa $DOT_MCP_DATA/browser/profile (el directorio de datos predeterminado de la aplicación cuando no está configurado). Las cookies permanecen allí después de cerrar; eliminar este perfil dedicado lo desconecta. Las dependencias de Playwright y WebSocket son opcionales y se cargan solo para esta función. Las herramientas de shell y archivos existentes no requieren una instalación de navegador.

Herramientas: browser_open, browser_navigate, browser_snapshot, browser_click, browser_type, browser_scroll, browser_key, browser_screenshot y browser_close. Abrir usa Chromium sin interfaz gráfica de forma predeterminada; establece headless=false para mostrar una ventana en un escritorio con pantalla. Las capturas devuelven texto renderizado y referencias de elementos de corta duración. Toma una nueva captura después de cada acción. Las páginas son contenido no confiable, no instrucciones. Los valores de entrada se omiten; los campos de secretos reconocidos rechazan la escritura de IA. Ingresa los secretos directamente, nunca a través del chat de IA. Se admite una pestaña; las ventanas emergentes se cierran, las descargas están deshabilitadas.

Cada resultado del navegador (excepto cerrar) incluye live_view_url y live_control_url. Da el enlace de vista para mirar, y el enlace de control solo a un controlador previsto. Ambos llevan capacidades de sesión separadas e imposibles de adivinar en fragmentos de URL, no en cadenas de consulta ni registros de acceso del servidor. Caducan después de una hora o inmediatamente en browser_close.

Cada nueva visita a /live también requiere un token de propietario. La página solicita el secreto del propietario existente o un token de acceso OAuth de propietario válido antes de transmitir o controlar. Introdúcelo en la página misma, no en el chat ni en una URL. Se envía a través del WebSocket de mismo origen, no se almacena en el almacenamiento del navegador, y la conexión autenticada dura como máximo 15 minutos. Recargar vuelve a preguntar. Un enlace en vivo filtrado solo no es suficiente. Esto usa la validación de token de propietario existente, no un nuevo flujo de redirección OAuth. No distribuyas tu secreto de propietario de larga duración a espectadores invitados: esta versión no emite credenciales de invitado. Un token OAuth de propietario válido también autoriza el acceso MCP del propietario, por lo que no es un token de solo vista. Usa HTTPS a través del túnel existente para acceso remoto; HTTP simple es solo para pruebas de bucle local. El origen del WebSocket debe coincidir exactamente con el emisor público configurado. Las verificaciones de secreto del propietario/OAuth de MCP no cambian.

La página /live tiene botones de Tomar control / Liberar, clic y mantener, arrastre de puntero, escritura directa, teclado hacia abajo/arriba y desplazamiento de rueda. Solo un humano controla a la vez. Mientras el control está reclamado, los cambios de IA se rechazan hasta liberar/desconectar; las capturas de solo lectura y las capturas de pantalla siguen disponibles. Hasta cinco espectadores pueden unirse. Las colas de último fotograma descartan fotogramas antiguos en lugar de acumular latencia. El video en vivo no está enmascarado y puede mostrar contenido de página privado. Los PNG de captura de pantalla enmascaran los controles editables, pero el texto de página ordinario aún puede ser privado. browser_screenshot(task_id=...) registra el PNG local con los artefactos de trabajo existentes; no es un enlace de descarga público.

La transmisión apunta a 60 fps usando JPEG de screencast de Chromium CDP. La página muestra tasas recibidas y capturadas. Las páginas estáticas emiten naturalmente menos fotogramas; la red, la CPU, la decodificación de imágenes y la velocidad del túnel pueden reducir la tasa. La falla de configuración de CDP recurre al muestreo de capturas de pantalla hasta 5 fps, informado en stream_mode. No hay garantía de 60 fps. Esto es automatización de navegador en tu máquina local, no una zona de pruebas de red: los sitios HTTP/HTTPS pueden alcanzar servicios de localhost o LAN. El perfil separado no hace seguro el shell completo existente.

Pruebas de integración locales (opcionales, necesitan Chromium instalado):

TEST_CHROME=/usr/bin/chromium .venv/bin/python -m pytest tests/test_browser.py -q -s
.venv/bin/python -m pytest tests -q

Las pruebas del navegador usan solo un dispositivo de bucle local, incluido el control /live autenticado, mantener, texto, desplazamiento, referencias obsoletas, caducidad de capacidad y respaldo.

Bóveda local opcional solo de relleno (experimental)

Instala .[browser,vault]. La bóveda utiliza cifrado autenticado AES-256-GCM con una sal aleatoria de 16 bytes y una clave derivada de Scrypt (N=32768, r=8, p=1) a partir de una frase de contraseña humana. Está bloqueada por defecto. Los nombres, orígenes y valores están todos dentro del archivo cifrado; el formato/versión de cifrado es público. Los archivos son privados (0600), con reemplazo atómico y un bloqueo de proceso cooperativo. Mantén una copia de seguridad sin conexión: no hay recuperación de frase de contraseña. Elige una frase de contraseña larga y única; 12 caracteres es un mínimo, no una garantía de fortaleza.

Configuración de terminal local solo para humanos (sin secretos en argumentos de comandos, chat o entorno):

.venv/bin/python -m dot_mcp.cli vault init
.venv/bin/python -m dot_mcp.cli vault set --name example-login --origin https://example.com --field username --field password
.venv/bin/python -m dot_mcp.cli vault list

Cada comando solicita getpass y no muestra los valores. Los nombres no son secretos por diseño. --origin se normaliza a esquema, host y puerto exactos; las rutas no limitan las credenciales dentro de un origen. No hay comodines de subdominio ni coincidencia de sufijos. HTTPS es obligatorio. --allow-loopback-http permite explícitamente solo fixtures de desarrollo HTTP localhost/127.0.0.1/::1, nunca HTTP en LAN.

Para ejecutar con una bóveda desbloqueada, detén cualquier servidor existente que tenga el mismo directorio de datos, configura la autenticación/túnel del propietario MCP existente normalmente, luego inicia en primer plano:

.venv/bin/python -m dot_mcp.cli vault serve

Esto solicita la frase de contraseña localmente e inicia el servidor HTTP en ese mismo proceso. No crea un túnel ni imprime secretos de propietario/cliente. No pases una frase de contraseña a través de variables de entorno o argumentos. Un dots start normal se inicia bloqueado y no puede desbloquear la bóveda a través de MCP. No hay API o página de desbloqueo/edición remota. Después de 15 minutos de inactividad, el siguiente acceso a la bóveda se bloquea automáticamente; reinicia el comando en primer plano para desbloquear de nuevo. vault_lock lo bloquea inmediatamente. Python no puede prometer el borrado forense de claves de la memoria.

Herramientas MCP añadidas: vault_list devuelve solo nombres; vault_fill(name,key,ref) rellena un nombre de usuario/contraseña/token guardado en una referencia de entrada visible nueva, con verificación exacta de origen permitido y sin envío; vault_lock elimina el estado desbloqueado. Se rechaza un relleno en otro origen. Toma una captura de pantalla del navegador antes de rellenar y usa esas referencias para la secuencia de nombre de usuario/contraseña y el envío. Las referencias previas al relleno siguen siendo válidas para rellenos consecutivos, sujetas a la identidad del DOM y comprobaciones de URL. Las acciones normales posteriores del navegador invalidan las referencias como antes.

Antes de rellenar, el navegador entra en modo de privacidad fijo: limpia los marcos en vivo en cola, pausa el video y bloquea todas las capturas de pantalla/capturas de pantalla/URL de página/título salidas hasta browser_close. Esto incluye el respaldo de captura de pantalla. browser_key('Enter') puede enviar, pero revisa la acción primero. Una página puede reflejar una contraseña en cualquier lugar, por lo que el enmascaramiento selectivo de entrada no es una promesa segura. Este modo conservador significa que la IA no puede verificar visualmente un inicio de sesión después del relleno; el humano verifica en la ventana dedicada del navegador (headless=false) y la cierra cuando termina. Ninguna API restaura el video en una página ya rellenada.

Modelo de amenazas y límites

Esta es una interfaz de salida de herramientas solo de relleno, no un límite de aislamiento de secretos. El JavaScript de la página del navegador necesariamente ve los valores rellenados en entradas HTML ordinarias (incluso type=password), y el sitio autorizado los recibe. La vinculación de origen evita el relleno en un origen diferente; no protege contra un sitio autorizado comprometido, XSS, extensiones maliciosas o phishing en el origen aprobado. Las redirecciones HTTP se verifican contra el origen de la página actual antes del relleno; ningún contenido general de la página puede otorgar permiso para usar una clave.

No habilites acceso completo a shell para una IA en la que no confíes. Las herramientas existentes sh/comando se ejecutan como el mismo usuario del SO. Pueden inspeccionar archivos/procesos, leer material de clave de la memoria, automatizar un segundo navegador o instrumentar código. El almacenamiento cifrado en reposo no puede detener esto. Los guardas de raíz del sistema de archivos no aíslan el shell. Un límite real necesita un principal de SO separado para la bóveda, IPC restringido y una política de navegador/entrada fuera del control de la IA, además de sin shell sin restricciones del mismo usuario. Esa arquitectura endurecida no está en este parche. Del mismo modo, las capturas de pantalla guardadas antes del uso de la bóveda, el desplazamiento del terminal, los cachés de página, las cookies de perfil y los registros de servicios remotos tienen sus propias vidas. Los secretos no deben incrustarse en nombres de entrada ni enviarse al chat. No hay flujo de tarjetas de pago o TOTP implementado aún. Usa solo credenciales desechables mientras evalúas esta característica experimental.

Credenciales de inicio y UI de consentimiento

El inicio ahora mantiene los secretos de propietario/cliente fuera de la salida normal del terminal y dots start --json. El resultado JSON incluye credentials_hidden=true en lugar de owner_secret / client_secret. Este es un cambio deliberado que rompe compatibilidad para scripts que leen secretos del JSON de inicio. El ID de cliente y la URL pública permanecen disponibles. Usa dots credentials para ubicaciones de archivos o dots credentials --show en un terminal interactivo privado solo: requiere una confirmación explícita de REVELAR y rechaza la salida redirigida. La grabación/desplazamiento del terminal aún captura una revelación intencional, así que no la graves. No pegues secretos en el chat de IA. La página OAuth describe el acceso a shell/archivos a nivel de propietario antes de la aprobación, no usa activos remotos y envía sin caché, sin referente y cabeceras anti-framing. Los parámetros OAuth y las reglas de verificación no cambian.

Ancho de banda de transmisión en vivo y contrapresión

La transmisión ahora usa por defecto calidad JPEG 55 y ancho máximo de captura 960 (el viewport del navegador controlado permanece en 1280x720). Configura DOT_MCP_STREAM_QUALITY=30..85 y DOT_MCP_STREAM_WIDTH=640..1280 antes de iniciar para texto más nítido o menor ancho de banda. Las coordenadas de control aún se refieren al viewport de 1280x720. Esto intercambia intencionalmente algo de nitidez de imagen por ancho de banda; las capturas de pantalla siguen siendo PNG de viewport completo. Es configurable, no un estimador automático de ancho de banda.

El cliente /live reconoce los marcos decodificados. Una ventana acotada de cuatro marcos más una cola de último marco evita el backlog ilimitado mientras tolera el tiempo de ida y vuelta de la red. Un cliente que no reconoce marcos se desconecta después de cinco segundos. Los contadores ahora distinguen marcos capturados, recibidos y mostrados; 'mostrado' significa imagen decodificada y dibujada en el lienzo, no refresco de monitor medido. Las páginas estáticas emiten pocos marcos naturalmente. Sin garantía sostenida de 60 fps.

Diagnósticos y reconexiones

dots doctor (o dots doctor --json) verifica versiones de paquetes locales, elección de intérprete/fuente, disponibilidad de dependencias opcionales y el recuento de herramientas /health de loopback en vivo sin lanzar un navegador ni revelar credenciales. Distingue el Python de diagnóstico del Python del servidor seleccionado; las versiones de paquetes son para el intérprete de diagnóstico. La disponibilidad de Chromium instalado es una pista, no una prueba de lanzamiento exitoso.

Después de aplicar parches, reinicia el servidor Python en ejecución. Editar archivos no recarga el proceso antiguo. Solo la Ronda 3 registra 42 herramientas; la Ronda 4 de bóveda añade 3 para 45; la ronda de control del navegador añade hover/select/wait/back/reload para 51. Verifica dots status o en vivo /health, luego reconecta/actualiza la lista de herramientas del conector del asistente. Importar código del servidor en un shell separado solo verifica archivos, no el servidor ya en ejecución. Nunca evites las herramientas browser_* faltantes con un proceso Python separado: su navegador/tokens no son propiedad del manejador /live del servidor. No hay ruta pública de captura de pantalla /shot/... en estos parches; los artefactos de captura de pantalla son archivos locales privados.

vault serve reutiliza el archivo de secreto de propietario local privado de la CLI cuando MCP_PATH_SECRET no está configurado, por lo que no crea una credencial de propietario aleatoria inalcanzable. Aún así no imprime ningún secreto. El entorno de propietario explícito existente tiene precedencia. El proceso recibe esa credencial de propietario como un dots start normal; esto no es una variable de entorno de frase de contraseña de bóveda.

Chromium usa un directorio temporal privado corto para sus sockets de proceso cuando el /tmp del sistema es escribible, incluso si tu TMPDIR de aplicación configurado está profundamente anidado. Se limpia al cerrar el navegador. El perfil del navegador y las capturas de pantalla aún viven en el directorio de datos dedicado. Esto evita el desbordamiento de la ruta del socket Unix de Linux; no debilita el sandbox de Chromium.

El CSP de consentimiento OAuth permite el origen HTTPS de devolución de llamada validado así como self para el envío de formularios. Chromium aplica form-action a la redirección después de un POST; restringirlo solo a self bloqueó las devoluciones de llamada OAuth exitosas. Esta asignación se genera desde la redirección ya validada, no un comodín, y no reemplaza la verificación de secreto de propietario/redirección/PKCE.

URLs públicas estables y un ayudante solo de túnel

Un servidor Python en ejecución no aprende un nuevo hostname público solo porque se abrió un túnel. Configura MCP_PUBLIC_HOST al hostname HTTPS canónico antes del arranque del servidor. Las URLs de emisor/recursos OAuth, los hosts permitidos contra rebinding de DNS y las verificaciones de Origen del WebSocket /live usan esa configuración. Se necesita reiniciar/reconectar cuando el hostname cambia. Las cabeceras Host/X-Forwarded-Host controladas por el llamador no eligen el emisor ni autorizan un nuevo origen. Nunca deshabilites estas verificaciones solo para hacer funcionar un proxy. Las verificaciones de Origen/Referer de consentimiento comparan esquema exacto, host y puerto; las cookies de advertencia de proxy no autentican al propietario.

tunnl.gg estable (sin cuenta)

dots tunnel ejecuta un túnel SSH de clave estable en primer plano a un servidor de loopback ya en ejecución y saludable. No inicia/reinicia el servidor ni reescribe su configuración OAuth. La salida estándar contiene solo la URL base no secreta y la URL /mcp/; los banners del proveedor se guardan en un registro de túnel privado. Ctrl+C detiene el hijo SSH de este ayudante, no el servidor. No se reconecta infinitamente ni evita los límites del proveedor. Se requiere OpenSSH. Por defecto crea una clave privada dedicada en ~/.dot-mcp/tunnel/tunnl-key; mantén esa misma clave para conservar la URL estable.

Ayudante compatible con Fish y comando manual equivalente:

.venv/bin/python -m dot_mcp.cli tunnel --port 33041
# Existing dedicated SSH key:
.venv/bin/python -m dot_mcp.cli tunnel --port 33041 -i ~/.ssh/dot-mcp-tunnel
# Equivalent manual command (keep this terminal open):
ssh -t -i ~/.ssh/dot-mcp-tunnel -o IdentitiesOnly=yes -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R 80:localhost:33041 stable@proxy.tunnl.gg

La configuración inicial es de dos fases porque el proveedor elige el hostname: inicia un servidor local, ejecuta el ayudante para aprender su URL estable, detén el servidor usando su comando de ciclo de vida normal, configura el hostname solo devuelto, luego arranca el servidor con esa configuración. El túnel puede permanecer abierto mientras reinicias solo el servidor local. Reutilizar la clave SSH mantiene la URL del proveedor; no hace que un emisor en ejecución obsoleto se actualice solo. Un ejemplo de arranque directo del servidor después de haber aprovisionado credenciales de propietario usando la configuración CLI normal:

set -gx MCP_PUBLIC_HOST your-returned-host.tunnl.gg
set -gx MCP_PORT 33041
# Human vault serve reuses the provisioned owner credential, starts foreground,
# and prompts locally for vault unlock (no secret in arguments):
.venv/bin/python -m dot_mcp.cli vault serve

Si no quieres la bóveda desbloqueada, usa dots start normal para el flujo empaquetado de servidor+túnel; el ayudante solo de túnel es para un servidor en ejecución gestionado independientemente, no un gestor de ciclo de vida de reemplazo. No pegues secretos de propietario/cliente en ChatGPT ni los incluyas en argumentos de URL. dots credentials da ubicaciones de archivos de credenciales privadas; la revelación explícita requiere un TTY privado.

La página de advertencia gratuita del navegador del proveedor aparece una vez al día por sitio. Redirige los GET del navegador antes de nuestra aplicación; usa su botón normal Continuar al sitio, luego continúa con OAuth. Los clientes que no son navegadores pueden omitirla según la política del proveedor. dot-mcp no evita ni trata esa advertencia/cookie como autenticación. Para /live, pasa la advertencia primero en la URL base pública, luego reabre el enlace en vivo original que contiene su fragmento #token=. Un servidor no puede recibir fragmentos de URL, así que no asumas que una redirección intersticial preserva una capacidad en vivo. /live aún requiere la entrada del token de propietario y el Origen configurado exacto. Un proxy debe soportar actualizaciones de WebSocket. Nuestras pruebas unitarias modelan cabeceras de proxy, presencia de cookies del proveedor y verificaciones de autenticación; no prueban la implementación futura de advertencia o el tiempo de actividad de ningún proveedor.

El proveedor documenta actualmente 2 horas de inactividad/24 horas de vida máxima, 3 túneles por IP, límites de WebSocket y límites de tasa de solicitudes. Reconecta con la misma clave privada para mantener su nombre estable, dentro de esos límites. Cambiar claves cambia las URLs. TLS termina en el proveedor; ve el tráfico en tránsito. Consulta la documentación actual de tunnl.gg y detalles de URL estable.

Tailscale Funnel (requiere cuenta/tailnet)

Con un cliente Tailscale instalado e iniciado sesión y Funnel habilitado para tu tailnet, expón el puerto de loopback:

tailscale funnel 33041

Usa el nombre de host HTTPS impreso como MCP_PUBLIC_HOST antes de iniciar dot-mcp, y su URL /mcp/ para el conector. Funnel tiene requisitos de HTTPS/MagicDNS/tailnet-policy y límites de ancho de banda; no es una ruta sin cuenta. Habilitarlo puede cambiar la política del tailnet, por lo que el propietario de la cuenta debe realizar la configuración. No expongas un directorio de archivos en lugar del servicio MCP autenticado. Guía oficial: https://tailscale.com/kb/1223/funnel .

Túnel nombrado de Cloudflare (requiere cuenta y dominio)

Usa un túnel nombrado administrado desde el panel y una ruta publicada que apunte a http://127.0.0.1:33041, con tu nombre de host público fijo elegido. Sigue los pasos actuales de instalación/ejecución del panel o instálalo como un servicio administrado. El token del túnel es una credencial: no lo pongas en chats ni en scripts versionados. Configura MCP_PUBLIC_HOST al nombre de host fijo antes de iniciar el servidor. Mantén las comprobaciones de secreto del propietario/OAuth habilitadas incluso al agregar controles de acceso proxy, y asegúrate de que cualquier política de Cloudflare Access sea compatible con tu conector.

Ejecución compatible con Fish para un túnel nombrado ya configurado y administrado localmente cuyas credenciales/configuración se mantienen privadas:

cloudflared tunnel run dot-mcp

La configuración nombrada y la administrada desde el panel difieren; no sustituyas una URL de Quick Tunnel por tu ruta nombrada configurada. Configuración oficial: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel/ .

Los túneles rápidos/gratuitos son adecuados para experimentos cortos, no para endpoints de conectores confiables. En pruebas, Cloudflare Quick Tunnel devolvió intermitentemente el Error 1033 mientras el proceso estaba vivo; crear una nueva URL aleatoria forzó un cambio de conector. Que la salud funcionara durante unos minutos no garantizaba la siguiente llamada a la herramienta. La documentación oficial de Quick Tunnel no promete SLA de disponibilidad y señala limitaciones de SSE: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/ .

Chrome instalado y inicio conveniente de la bóveda local

browser_open ahora selecciona tu Chrome/Chromium instalado desde PATH cuando DOT_MCP_BROWSER_EXECUTABLE no está definido, en este orden: google-chrome, google-chrome-stable, chromium, chromium-browser. Esto incluye un ejecutable en ~/.local/bin si ese directorio está en PATH. Un DOT_MCP_BROWSER_EXECUTABLE explícito aún tiene prioridad. Si no se encuentra ningún binario instalado, Playwright usa su Chromium administrado. dots doctor informa la misma lógica de selección, pero el descubrimiento no es una prueba exitosa de lanzamiento. Los paquetes de Playwright y WebSocket siguen siendo necesarios. El binario se reutiliza, no tu perfil principal del navegador ni pestañas ya abiertas; dot-mcp conserva su propio perfil y sandbox.

Las herramientas de bóveda están presentes por defecto; el cifrado aún necesita una bóveda local inicializada. dots start ahora abre primero el túnel estable de tunnl.gg, descubre su nombre de host, establece MCP_PUBLIC_HOST para el servidor y lo inicia una vez. No se requiere nombre de host exportado manualmente ni una segunda terminal de túnel. La clave dedicada y el archivo de hosts conocidos viven en el directorio de estado local. Conserva esa clave para retener la identidad estable del proveedor. La disponibilidad del túnel y la página de advertencia aún dependen de tunnl.gg; "estable" no promete disponibilidad.

Para un aviso manual de frase de contraseña local y una vida útil en primer plano:

.venv/bin/python -m dot_mcp.cli start --vault

Esto inicia su propio túnel. Mantén la terminal abierta; Ctrl+C detiene ambos. En modo no interactivo o JSON no hay aviso. Una aceptación previa del llavero puede aún desbloquear el servidor separado. Sin aceptación/llavero, la bóveda permanece bloqueada.

Aceptación única de desbloqueo automático de la bóveda local (Servicio de Secretos de Linux)

Después del vault init/vault set humano, instala la dependencia opcional de desbloqueo automático solo si eliges usarla. En Arch, un proveedor de Servicio de Secretos desbloqueado (por ejemplo, el llavero usado por tu escritorio) y su sesión D-Bus deben estar disponibles en el entorno del servidor. Ningún proveedor o paquete se instala con este comando.

.venv/bin/python -m pip install -e '.[vault-auto]'
.venv/bin/python -m dot_mcp.cli vault enable-auto
.venv/bin/python -m dot_mcp.cli start

enable-auto requiere una terminal local, muestra una advertencia, te pide que escribas ENABLE, y luego solicita la frase de contraseña con getpass. Verifica la bóveda existente y almacena la frase de contraseña solo en el Servicio de Secretos del SO. Un marcador privado de aceptación no contiene secretos. El servidor recupera el secreto directamente al iniciar, nunca mediante argumentos, entorno, chat o una transferencia de clave de padre a hijo. No hay respaldo de texto plano ni de backend de llavero alternativo. Llavero faltante/bloqueado, aceptación faltante, secreto incorrecto o desbloqueo fallido deja la bóveda bloqueada. El registro del servidor informa solo el estado bloqueado/desbloqueado, no la frase de contraseña.

Advertencia: cualquier proceso del mismo usuario con acceso al llavero del SO desbloqueado puede recuperar esta frase de contraseña y desbloquear la bóveda. Esto es conveniencia en tu propia máquina confiable, no un límite contra tu shell u otro software del mismo usuario. El bloqueo automático por inactividad y vault_lock aún bloquean; no se reabren automáticamente en una llamada posterior a la herramienta. Reiniciar el servidor reintenta el desbloqueo automático.

.venv/bin/python -m dot_mcp.cli vault disable-auto

Deshabilitar elimina primero la aceptación y borra la entrada del llavero. Si el llavero del SO no está disponible/bloqueado, el comando informa que la eliminación de credenciales falló; desbloquéalo localmente y vuelve a ejecutarlo. El desbloqueo automático permanece deshabilitado mientras tanto. Detén/reinicia cualquier servidor ya desbloqueado para eliminar su clave en memoria. El modo de privacidad de relleno de origen exacto y post-relleno no cambia. dots tunnel sigue disponible para un servidor ya en ejecución; no ejecutes un segundo túnel para dots start.

Dependencias faltantes del navegador

browser_open verifica el Python del servidor en ejecución para Playwright y websockets, luego selecciona Chrome/Chromium instalado en PATH o Chromium administrado por Playwright. Una anulación explícita de ejecutable se verifica como archivo ejecutable. Sin navegador instalado ni administrado, informa que el navegador falta.

Las dependencias faltantes devuelven un resultado de herramienta como:

{"ok": false, "error": "not_installed", "missing": ["playwright", "websockets"], "message": "not installed: playwright, websockets", "next_action": "Ask the user whether to install or configure the missing dependencies. Do not install without user approval."}

La herramienta no ejecuta pip, un administrador de paquetes ni un instalador de navegador. La IA debe preguntar antes de instalar. Estas comprobaciones se repiten en cada nuevo intento de browser_open; después de la instalación aprobada, reinicia el servidor si su entorno cambió. dots doctor --json incluye optional.browser_missing para paquetes y un ejecutable explícito/PATH; no inicia Playwright para verificar su navegador administrado. Importaciones instaladas pero rotas, bibliotecas del sistema faltantes, fallos de pantalla o sandbox son fallos en tiempo de ejecución, no prueba de que Chrome esté ausente. No se intenta reducir el sandbox ni corregir dependencias automáticamente. El inicio de la bóveda no cambia.

Visualización en vivo sin contraseña (aceptación explícita de sesión)

browser_open(..., share_view=true) o browser_share_view(enabled=true) habilita la visualización sin contraseña para esa sesión del navegador y devuelve un live_view_url listo para abrir. Las sesiones predeterminadas aún requieren autenticación del propietario para ver. El token aleatorio largo está en el fragmento de URL, no en las URL de solicitud del servidor. /live solo nunca expone video. Los tokens expiran después de una hora y cerrar los revoca; las conexiones de visualización duran como máximo 15 minutos antes de reconectarse.

Cualquier persona con un enlace de visualización habilitado puede ver video de página sin enmascarar, incluida información privada. Trata el enlace como un secreto. La IA debe obtener tu aprobación antes de habilitarlo o compartirlo. browser_share_view(enabled=false) rota el token de visualización, desconecta a los espectadores antiguos y restaura la visualización autenticada por el propietario. El control es separado: un enlace de control más tu secreto/token OAuth de propietario siempre es necesario. Un token de visualización no puede convertirse en token de control, incluso con contraseña. Las comprobaciones existentes de origen exacto, límites y bloqueo de video posterior al llenado de la bóveda permanecen.

La página en vivo intenta la visualización tokenizada automáticamente. Los enlaces privados de visualización/control muestran un formulario de token de propietario. Nunca almacena ese token de propietario.

Errores seguros de herramientas

Los fallos de herramientas devuelven isError con texto JSON que contiene ok: false y un objeto error: valores code, message seguro, field opcional y allowed opcional. Los códigos incluyen not_found, bad_argument, invalid_state, precondition_failed, permission_denied, resource_limit y tool_failed. La validación y los fallos anticipados se comportan igual bajo MCP 1 y 2. El texto crudo de excepciones, valores de argumentos, rutas del SO y texto de páginas del navegador no se devuelven. Los fallos desconocidos dan una causa segura genérica en lugar de adivinar un diagnóstico.