
porterminal v1.2.0
Túnel de terminal web/mcp rápido y sencillo para tu teléfono y PC
Entrega un ordenador a un agente, control total, y míralo trabajar.
Un comando, una URL. (También un terminal elegante para tu propio teléfono.)
1. uvx ptn
2. Entrega la URL a un agente de IA, o escanea el QR tú mismo
3. Míralo trabajar en cualquier navegador, y toma el control cuando quieras
[!WARNING] Esa URL completa es acceso total a este ordenador. Contiene un código de acceso aleatorio por lanzamiento, y cualquiera (o cualquier agente de IA) a quien se la entregues obtiene un shell real en tu máquina. Trata la URL y el código QR como un secreto, compártelos solo con personas y agentes de confianza, y lee Seguridad antes de apuntar Porterminal a algo importante.
Por qué
Necesito algo peligrosamente fácil para acceder remotamente a un ordenador.
ngrok requiere registro y el plan gratuito es malo. Cloudflare Tunnel es una infraestructura excelente, pero por sí solo solo te da un túnel, no un terminal cómodo para el teléfono. Tailscale es genial cuando controlas ambos extremos, pero sigue implicando unir dispositivos a una red privada. Termius requiere una configuración complicada: reenvío de puertos, reglas de firewall, gestión de claves...
Así que construí algo más simple: ejecuta un comando, escanea un QR, empieza a escribir.
Y entonces lo entendí: el mismo truco (un comando, una URL) es la forma más fácil de darle a un agente de IA un terminal real en cualquier ordenador. Sin servidor MCP que escribir, sin claves SSH, sin Docker, sin configuración. Ejecuta uvx ptn, entrega la URL, y el agente ejecuta comandos, lee la pantalla y responde a los prompts en esa máquina. Y como es un terminal web, puedes abrir la misma sesión en cualquier navegador para verlo trabajar en directo, o tomar el teclado y hacerse cargo.
Características
- Entrega un ordenador a un agente, control total, y míralo trabajar - Dale a un agente de IA la URL y obtiene un terminal real en la máquina vía MCP o REST simple. Abre la misma sesión en cualquier navegador para verlo trabajar en directo, y toma el teclado cuando quieras. Sin claves, sin Docker. El agente aprende cómo hacerlo desde
<url>/llms.txty<url>/.well-known/mcp.json. Consulta Acceso de agentes. - Un comando, acceso instantáneo -
uvx ptny tú (o un agente) obtienes un terminal real en esta máquina. Sin SSH, sin reenvío de puertos, sin archivos de configuración. Túnel de Cloudflare + código QR. - Realmente usable en móvil - Optimizado para táctil con desplazamiento con inercia, zoom con pinza, gestos de deslizamiento y teclas modificadoras (Ctrl, Alt).
- Aplicaciones de terminal completas - vim, htop, less, tmux funcionan correctamente con un manejo adecuado del búfer de pantalla alternativa.
- Sesiones multi-pestaña persistentes - Las sesiones sobreviven a las desconexiones. Cierra el navegador, cambia de red, reconéctate desde otro dispositivo, y tu shell y procesos en ejecución siguen ahí. Tú y un agente podéis compartir una sesión: míralo trabajar, o toma el control.
- Multiplataforma - Windows (PowerShell, CMD, WSL), Linux/macOS (Bash, Zsh, Fish, Nushell, y cualquier shell vía
$SHELL). Detecta tus shells automáticamente. - Difícil de adivinar por defecto - Cada lanzamiento añade una ruta de acceso aleatoria independiente de 128 bits. El nombre de host del túnel sin más y cualquier ruta incorrecta devuelven 404. La URL se oculta en pantalla, pero el QR contiene la credencial completa, así que mantén ambos en privado. Pulsa
cpara copiar las instrucciones del agente y la URL, oupara copiar solo la URL.
Instalación
| Método | Instalar | Actualizar |
|---|---|---|
| uvx (sin instalación) | uvx ptn | uvx ptn@latest |
| uv tool | uv tool install ptn | uv tool upgrade ptn |
| pipx | pipx install ptn | pipx upgrade ptn |
| pip | pip install ptn | pip install -U ptn |
Instalación en una línea (uv + ptn):
| SO | Comando |
|---|---|
| Windows | powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/lyehe/porterminal/master/install.ps1 | iex" |
| macOS/Linux | curl -LsSf https://raw.githubusercontent.com/lyehe/porterminal/master/install.sh | sh |
Requiere Python 3.12+ y cloudflared (se instala automáticamente si falta).
Uso
ptn # Start in current directory
ptn ~/projects/myapp # Start in specific folder
| Flag | Descripción |
|---|---|
-n, --no-tunnel | Solo red local (sin túnel de Cloudflare) |
--mcp-only | Control de shell MCP sin código QR, terminal de navegador ni API REST |
-p, --password | Solicitar contraseña para proteger esta sesión |
-sp, --save-password | Guardar o borrar la contraseña en la configuración |
-tp, --toggle-password | Establecer el requisito de contraseña (on/off/toggle) |
-v, --verbose | Mostrar registros de inicio detallados |
-i, --init | Crear .ptn/ptn.yaml con scripts de proyecto autodescubiertos como botones |
-if, --init-from URL/PATH | Crear .ptn/ptn.yaml desde una URL o archivo local |
-c, --compose | Habilitar el modo compose por defecto |
-k, --keep-qr | Mantener el código QR visible tras la primera conexión |
-u, --check-update | Comprobar si hay una versión más reciente disponible |
-V, --version | Mostrar la versión |
Mientras se ejecuta: con un túnel activo, la URL de conexión se oculta en pantalla por privacidad. Pulsa c para copiar las instrucciones del agente y la URL, incluyendo /mcp, /api/agent/run y /llms.txt; pulsa u para copiar solo la URL; o escanea el QR para conectarte. Ctrl+C detiene el servidor.
Acceso de agentes (MCP + REST)
Para el control de shell completamente en segundo plano, ejecuta ptn --mcp-only.
La interfaz de terminal local permanece abierta: pulsa c para copiar el prompt del agente y la dirección MCP, o u para copiar solo la dirección MCP. Estas teclas también funcionan con --no-tunnel.
Conecta tu cliente MCP al endpoint generado
<url>/mcp. Este modo no muestra código QR y deshabilita el terminal web,
los WebSockets del navegador y la API REST, por lo que los comandos no pueden
ser vistos ni introducidos a través del navegador. El descubrimiento MCP y /llms.txt siguen disponibles.
La URL MCP completa sigue otorgando control de shell del ordenador.
La misma URL también funciona para agentes de IA. Los clientes compatibles con MCP pueden usar <url>/mcp (Streamable HTTP) para herramientas tipadas nativas. Los agentes que no pueden registrar un servidor MCP pueden usar el fallback REST en <url>/api/agent/run con peticiones HTTP ordinarias. Cualquiera de las dos rutas crea un shell de agente persistente, mostrado como una pestaña 🤖 que puedes ver y controlar desde tu teléfono.
Entrega al agente la URL completa generada, incluyendo su código de acceso. Los clientes MCP pueden autodescubrir el servidor desde <url>/.well-known/mcp.json (el descriptor server.json de MCP), y hay un <url>/llms.txt legible por humanos/agentes con el uso. La página base también incluye pistas visibles para accesibilidad para agentes que controlan el navegador, mientras que la interfaz humana se mantiene compacta. Ejemplo de configuración de cliente:
{
"mcpServers": {
"porterminal": { "url": "https://<your-tunnel>.trycloudflare.com/<access-code>/mcp" }
}
}
Herramientas MCP: run_command (salida limpia + código de salida), read_screen, send_keys, send_signal (Ctrl-C / EOF).
Fallback REST:
curl -s -X POST https://<your-tunnel>.trycloudflare.com/<access-code>/api/agent/run \
-H "content-type: application/json" \
-d '{"command":"echo hello","timeout":30}'
La respuesta incluye un session_id; reutilízalo con <url>/api/agent/screen,
<url>/api/agent/keys, <url>/api/agent/signal, y
DELETE <url>/api/agent/session.
Cuando abres Porterminal en tu teléfono, el botón de copiar de arriba a la derecha copia el mismo texto para compartir listo para agentes. Los agentes solo de navegador también obtienen un fallback en la página base: un espejo Terminal screen legible por DOM y una Terminal input claramente etiquetada.
Seguridad:
<url>significa la URL completa generada, incluyendo su código de acceso aleatorio. El nombre de host del túnel sin más no expone nada, pero cualquiera (o cualquier agente) con la URL completa obtiene acceso completo al shell, sin privilegios elevados. Consulta docs/agent-access.md.
Gestos móviles
| Gesto | Acción |
|---|---|
| Toque | Enfocar el terminal, borrar la selección |
| Pulsación larga | Iniciar la selección de texto |
| Doble toque | Seleccionar palabra |
| Deslizar izquierda/derecha | Teclas de flecha (← →) |
| Desplazar | Desplazamiento con inercia y física |
| Pinza | Zoom del texto (10-24px) |
Teclas modificadoras (Ctrl, Alt, Shift): Toca una vez para fijar (una pulsación), doble toque para bloquear.
Modo compose (botón ▤): Activa un campo de entrada de texto donde puedes escribir o dictar, editar tu texto con funciones completas de edición móvil (autocorrección, sugerencias, posicionamiento del cursor), y luego enviarlo al terminal. Útil para comandos largos o entrada por voz.
Configuración
Ejecuta ptn --init para crear una configuración inicial. Autodescubre scripts de proyecto desde package.json, pyproject.toml o Makefile y los añade como botones:
ptn -i
# Created: .ptn/ptn.yaml
# Discovered 3 project script(s): build, dev, test
O crea ptn.yaml manualmente:
# Terminal settings
terminal:
default_shell: nu # Default shell ID
shells: # Custom shell definitions
- id: nu
name: Nushell
command: nu
args: []
# Custom buttons (appear in toolbar)
# row: 1 = default row, 2+ = additional rows
buttons:
- label: "claude"
send:
- "claude"
- 100 # delay in ms
- "\r"
- label: "build"
send: "npm run build\r"
row: 2 # second button row
# Update checker settings
update:
notify_on_startup: true # Show update notification
check_interval: 86400 # Seconds between checks (default: 24h)
# Security settings
security:
require_password: true # Always require password at startup
password_hash: "" # Saved password hash (use ptn -sp to set)
max_auth_attempts: 5 # Max failed attempts before disconnect
La configuración se busca en orden: $PORTERMINAL_CONFIG_PATH, ./ptn.yaml, ./.ptn/ptn.yaml, ~/.ptn/ptn.yaml.
Seguridad
Cada lanzamiento crea una nueva ruta aleatoria de 128 bits como
https://<tunnel>.trycloudflare.com/<access-code>/. Todas las rutas de navegador, WebSocket,
MCP, REST, health y estáticas requieren ese prefijo exacto; el host sin más
y las rutas incorrectas devuelven 404. Esto hace que la fuerza bruta sobre un nombre de host de túnel descubierto
sea poco práctica.
La URL completa generada sigue siendo una credencial de portador: cualquiera que la obtenga tiene acceso al shell. Reinicia Porterminal para rotar el código si se filtra. La contraseña opcional añade autenticación a los WebSockets del navegador, pero MCP y REST siguen confiando en la URL completa para que los agentes puedan usar el flujo de trabajo de un solo enlace.
Un navegador recuerda una contraseña correcta en almacenamiento en texto plano limitado a esa URL de lanzamiento completa. Guardar una contraseña para un lanzamiento más reciente en el mismo origen retira las entradas de contraseña de Porterminal más antiguas; borrar o rechazar una contraseña recordada las elimina todas sin tocar otro almacenamiento del navegador. En consecuencia, los lanzamientos concurrentes en el mismo origen pueden volver a solicitarla, mientras que una conexión ya autenticada permanece conectada.
Desde la interfaz: Abre Ajustes (icono de engranaje) y usa la sección Seguridad para establecer/cambiar la contraseña y alternar el requisito de contraseña. Los cambios requieren reiniciar el servidor.
Desde la CLI:
# One-time password (prompt each session)
ptn -p
# Save password to config (no prompt needed)
ptn -sp
# Password: ****
# Confirm password: ****
# Clear saved password (enter empty password)
ptn -sp
# Password: [press Enter]
# Set or toggle password requirement
ptn -tp # Toggle on/off
Consulta docs/security.md para más detalles.
Solución de problemas
¿Falla la conexión? Usa la URL completa generada, incluyendo su código de acceso. Los problemas del túnel de Cloudflare también se pueden resolver reiniciando el servidor (Ctrl+C, luego ptn) para obtener un túnel y una ruta de acceso nuevos.
¿uvx ptn sigue ejecutando una versión antigua? Una instalación existente de uv tool
puede tener prioridad. Ejecuta uv tool upgrade ptn, o evita las herramientas instaladas con
uvx --isolated ptn@latest.
¿No se detecta el shell? Establece tu variable de entorno $SHELL o configura los shells en ptn.yaml.
Contribuir
Este proyecto no acepta contribuciones externas (pull requests o cambios de código) por razones de seguridad (consulta CONTRIBUTING.md). Eres bienvenido a hacer un fork y ejecutar tu propia copia bajo AGPL-3.0.
Ejecutar desde el código fuente:
git clone https://github.com/lyehe/porterminal
cd porterminal
uv sync --frozen
uv run --frozen ptn