Terminal MCP

oficial

Proporciona a los asistentes de IA una vista compartida y en vivo de tu sesión de terminal para depurar CLIs y TUIs, o control autónomo de la terminal.

¿Qué puedes hacer con Terminal MCP?

  • Escribir comandos y enviar teclas — Pídele a la IA que ejecute comandos de shell mediante type y sendKey, incluyendo teclas especiales como Enter o Ctrl+C.
  • Leer la salida del terminal — Recupera el búfer actual del terminal como texto plano con getContent, o captura una captura de pantalla en formato text, ansi o png mediante takeScreenshot.
  • Grabar y reproducir sesiones — Inicia y detén grabaciones asciicast v2 con startRecording y stopRecording, y luego reprodúcelas con asciinema.
  • Gestionar múltiples sesiones — Crea sesiones de terminal aisladas con createSession, lista las activas mediante listSessions, y limpia con destroySession, cada una identificada por sessionId.

Documentación

Terminal MCP

Permite que la IA vea e interactúe con tu terminal.

Terminal MCP brinda a los LLM una vista compartida de tu sesión de terminal. Perfecto para depurar aplicaciones CLI y TUI en tiempo real, o permitir que la IA maneje herramientas basadas en terminal de forma autónoma.

Instalación

npm install -g @ellery/terminal-mcp

O mediante el script de instalación:

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

Configura tus herramientas de IA

Conecta terminal-mcp en la configuración MCP de cada herramienta de IA instalada en tu máquina de una sola vez:

terminal-mcp setup                      # detect & install for all detected tools
terminal-mcp setup --dry-run            # preview without writing
terminal-mcp setup --client claude-code,gemini   # specific tools only
terminal-mcp setup --uninstall          # remove the entry from each tool

Clientes compatibles (cada uno recibe el esquema correcto para su formato de configuración):

ClienteArchivo de configuraciónFormato
OpenAI Codex CLI~/.codex/config.tomlTOML
GitHub Copilot CLI~/.copilot/mcp-config.jsonJSON
Gemini CLI~/.gemini/settings.jsonJSON
OpenCode~/.config/opencode/opencode.jsonJSON
Claude Code~/.claude.jsonJSON
Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.json (macOS) / %APPDATA%\Claude\claude_desktop_config.json (Windows)JSON

Se escribe una .bak de cualquier configuración preexistente junto al original en la primera instalación. La entrada terminal-mcp se agrega sin alterar otros servidores ni claves no relacionadas; ejecutar setup nuevamente no tiene efecto.

Actualización

npm install -g @ellery/terminal-mcp@latest

El modo interactivo mostrará un banner en el próximo lanzamiento cuando haya una versión más reciente disponible — terminal-mcp consulta el registro npm una vez al día y almacena el resultado en caché. Los modos headless y cliente MCP nunca consultan ni imprimen nada (para que stdio de MCP se mantenga limpio). Para optar por no participar por completo, establece NO_UPDATE_NOTIFIER=1 o pasa --no-update-notifier.

Características

  • Emulación completa de terminal: Usa xterm.js headless para emulación precisa de VT100/ANSI
  • PTY multiplataforma: Soporte nativo de pseudo-terminal mediante node-pty (macOS, Linux, Windows)
  • Protocolo MCP: Implementa el Model Context Protocol para integración con asistentes de IA
  • Grabación de sesiones: Graba sesiones de terminal en formato asciicast para reproducirlas con asciinema
  • API simple: Nueve herramientas que cubren entrada, observación, grabación y ciclo de vida de sesiones
  • Modo headless: Ejecuta como servidor MCP independiente sin TTY — ideal para CI, contenedores y entornos no interactivos
  • Multi-sesión: Ejecuta múltiples sesiones de terminal aisladas en un solo proceso, identificadas por sessionId
  • Modo sandbox: Restricciones de seguridad opcionales para acceso a sistema de archivos y red

Compilación desde el código fuente

npm install
npm run build

Uso

Configuración MCP

Agrega a la configuración de tu cliente MCP:

{
  "mcpServers": {
    "terminal": {
      "command": "terminal-mcp"
    }
  }
}

Con opciones personalizadas:

{
  "mcpServers": {
    "terminal": {
      "command": "terminal-mcp",
      "args": ["--cols", "100", "--rows", "30", "--shell", "/bin/zsh"]
    }
  }
}

Opciones de línea de comandos

terminal-mcp [OPTIONS]

Options:
  --cols <number>        Terminal width in columns (default: 120)
  --rows <number>        Terminal height in rows (default: 40)
  --shell <path>         Shell to use (default: $SHELL or bash)
  --headless             Run in headless mode (embedded PTY + MCP over stdio, no TTY needed)
  --sandbox              Enable sandbox mode (restricts filesystem/network)
  --sandbox-config <path> Load sandbox config from JSON file
  --version, -v          Show version number
  --help, -h             Show help message

Recording Options:
  --record [mode]     Enable recording (default mode: always)
                      Modes: always, on-failure, off
  --record-dir <dir>  Recording output directory
                      (default: ~/.local/state/terminal-mcp/recordings)
  --idle-time-limit <sec>   Max idle time between events (default: 2s)
  --max-duration <sec>      Max recording duration (default: 3600s)
  --inactivity-timeout <sec>  Stop after no output (default: 600s)

Multi-Session Options:
  --max-sessions <n>           Max concurrent sessions (default: 5)
  --session-idle-timeout <sec> Idle non-default sessions are auto-destroyed
                               after this period (default: 600s)

Modo headless

Por defecto, Terminal MCP usa una arquitectura de doble proceso: ejecutas terminal-mcp en una terminal interactiva (que crea un socket Unix), luego tu cliente MCP inicia una segunda instancia que se conecta a ese socket. Esto requiere un TTY.

El modo headless (--headless) elimina este requisito al iniciar un PTY embebido internamente y servir MCP directamente sobre stdio en un solo proceso. Sin sesión de terminal interactiva, sin socket — solo un servidor MCP autónomo con una terminal integrada.

Cuándo usar el modo headless

  • Pipelines de CI/CD — sin TTY disponible
  • Contenedores Docker — sin shell interactivo para ejecutar en paralelo
  • Entornos remotos/nube — servidores MCP iniciados por automatización
  • Configuración simplificada — un solo proceso, sin coordinación de sockets

Configuración

{
  "mcpServers": {
    "terminal": {
      "command": "terminal-mcp",
      "args": ["--headless", "--cols", "120", "--rows", "40"]
    }
  }
}

Cómo funciona

MCP Client (Claude Code, etc.)
    │ STDIO (JSON-RPC)
    ▼
terminal-mcp --headless
    ├── MCP Server (stdio transport)
    ├── Terminal Emulator (@xterm/headless)
    └── Embedded PTY (node-pty)
            │
            ▼
        Shell Process (bash, zsh, etc.)

En modo headless, la sesión de terminal se inicializa de forma anticipada al inicio, por lo que todas las herramientas (type, sendKey, getContent, takeScreenshot, startRecording, stopRecording, createSession, listSessions, destroySession) están disponibles de inmediato.

Herramientas MCP

Todas las herramientas de entrada/salida (type, sendKey, getContent, takeScreenshot) aceptan un argumento opcional sessionId. Omítelo para apuntar a la sesión predeterminada; pasa el ID devuelto por createSession para controlar una sesión específica.

type

Envía entrada de texto a la terminal.

{
  "name": "type",
  "arguments": {
    "text": "echo hello"
  }
}

sendKey

Envía teclas especiales o combinaciones de teclas.

{
  "name": "sendKey",
  "arguments": {
    "key": "Enter"
  }
}

Teclas compatibles:

  • Básicas: Enter, Tab, Escape, Backspace, Delete
  • Flechas: ArrowUp, ArrowDown, ArrowLeft, ArrowRight
  • Navegación: Home, End, PageUp, PageDown, Insert
  • Función: F1 hasta F12
  • Control: Ctrl+A hasta Ctrl+Z, Ctrl+C, Ctrl+D, etc.

getContent

Obtiene el búfer de la terminal como texto plano.

{
  "name": "getContent",
  "arguments": {
    "visibleOnly": false
  }
}

takeScreenshot

Captura el estado de la terminal. Admite tres formatos de salida:

FormatoDescripción
text (predeterminado)JSON con contenido de texto plano, posición del cursor y dimensiones
ansiJSON con códigos de escape de color ANSI conservados en el campo de contenido
pngCaptura de pantalla a color como imagen PNG (requiere @resvg/resvg-js)
{
  "name": "takeScreenshot",
  "arguments": { "format": "text" }
}

El formato ansi reconstruye secuencias de escape SGR desde el búfer de celdas de la terminal, conservando atributos de color de 16 colores, 256 colores y truecolor de 24 bits, junto con estilos de negrita, atenuado, cursiva y subrayado.

El formato png devuelve un bloque de contenido MCP image con datos PNG codificados en base64, renderizado con el tema de color One Dark y el marco de ventana estilo macOS.

startRecording

Inicia la grabación de la salida de la terminal en un archivo asciicast v2.

{
  "name": "startRecording",
  "arguments": {
    "mode": "always",
    "idleTimeLimit": 2,
    "maxDuration": 3600
  }
}

Opciones:

  • mode: always (guardar todo) o on-failure (guardar solo si la salida es distinta de cero)
  • outputDir: Directorio de salida personalizado
  • idleTimeLimit: Máximo de segundos entre eventos (limita las pausas en la reproducción)
  • maxDuration: Detención automática después de N segundos
  • inactivityTimeout: Detención automática después de N segundos sin salida

stopRecording

Detiene una grabación y finaliza el archivo asciicast.

{
  "name": "stopRecording",
  "arguments": {
    "recordingId": "abc123"
  }
}

createSession

Crea una nueva sesión de terminal y devuelve sus metadatos. Usa el sessionId devuelto para apuntar a esta sesión en llamadas posteriores a herramientas.

{
  "name": "createSession",
  "arguments": {
    "shell": "/bin/zsh",
    "cols": 100,
    "rows": 30
  }
}

Todos los argumentos son opcionales. Devuelve:

{
  "sessionId": "3029d",
  "shell": "/bin/zsh",
  "cols": 100,
  "rows": 30,
  "createdAt": "2026-04-25T12:58:01.072Z",
  "lastActivityAt": "2026-04-25T12:58:01.072Z",
  "isDefault": false
}

listSessions

Lista todas las sesiones activas, incluida la predeterminada. Informa los límites configurados.

{ "name": "listSessions", "arguments": {} }

destroySession

Destruye una sesión por ID. La sesión predeterminada no se puede destruir.

{
  "name": "destroySession",
  "arguments": { "sessionId": "3029d" }
}

Multi-sesión

Por defecto, cada llamada a una herramienta sin sessionId apunta a una única sesión predeterminada creada automáticamente — el mismo comportamiento que el proyecto siempre ha tenido. Pasa sessionId para controlar múltiples PTY aislados desde un solo proceso.

  • La sesión predeterminada se crea en el primer uso y no se puede destruir.
  • Las sesiones adicionales se crean mediante createSession y se rastrean hasta que se destruyen o se desalojan por inactividad (--session-idle-timeout, predeterminado 600s).
  • Las sesiones concurrentes están limitadas a --max-sessions (predeterminado 5).
  • Una grabación activa captura la salida de todas las sesiones en el proceso.

Caso de uso típico: un agente de IA que controla una compilación de larga duración en una sesión mientras ejecuta diagnósticos en otra, sin intercalar comandos.

Modo sandbox

Ejecuta la terminal con acceso restringido al sistema de archivos y la red:

# Interactive permission configuration
terminal-mcp --sandbox

# With a config file
terminal-mcp --sandbox --sandbox-config ~/.terminal-mcp-sandbox.json

El modo interactivo muestra un diálogo TUI para configurar permisos:

Sandbox Permissions Dialog

- **Lectura/Escritura**: Acceso completo (directorio actual, /tmp, cachés) - **Solo lectura**: Puede leer pero no modificar (directorio de inicio) - **Bloqueado**: Sin acceso (claves SSH, credenciales de nube, tokens de autenticación)

Ejemplo de archivo de configuración:

{
  "filesystem": {
    "readWrite": [".", "/tmp", "~/.cache"],
    "readOnly": ["~"],
    "blocked": ["~/.ssh", "~/.aws", "~/.gnupg"]
  },
  "network": {
    "mode": "all"
  }
}

Soporte de plataformas:

  • macOS: Soporte completo mediante sandbox-exec (Seatbelt)
  • Linux: Soporte completo mediante bubblewrap (requiere bwrap instalado)
  • Windows: Repliegue elegante (se ejecuta sin sandbox)

Consulta la Documentación de sandbox para opciones de configuración detalladas.

Grabación

Terminal MCP puede grabar sesiones en formato asciicast v2, compatible con asciinema para reproducción.

Inicio rápido

# Start with recording enabled
terminal-mcp --record

# Run your commands, then exit
exit

# Output shows the saved file path:
# Recordings saved:
#   ~/.local/state/terminal-mcp/recordings/20240115_143022.cast
#
# Play with: asciinema play <file>

Reproducción

Instala asciinema para reproducir grabaciones:

# macOS
brew install asciinema

# Linux/pip
pip install asciinema

# Play a recording
asciinema play ~/.local/state/terminal-mcp/recordings/20240115_143022.cast

# Play at 2x speed
asciinema play -s 2 recording.cast

Modos de grabación

  • always (predeterminado): Guarda cada grabación
  • on-failure: Solo guarda si la sesión sale con un código distinto de cero (útil para depurar ejecuciones de CI fallidas)
# Only save recordings when something fails
terminal-mcp --record=on-failure

Grabación con herramientas MCP

Los asistentes de IA también pueden controlar la grabación programáticamente mediante herramientas MCP:

  1. Llama a startRecording para comenzar a capturar
  2. Realiza operaciones en la terminal
  3. Llama a stopRecording para finalizar y guardar

Esto permite flujos de trabajo impulsados por IA como "graba esta sesión de depuración" o "captura esta demostración".

Arquitectura

Terminal MCP tiene tres modos de operación:

ModoIndicadorStdinDescripción
Interactivo(predeterminado)TTYEl usuario obtiene un shell; la IA se conecta mediante socket Unix
Cliente(predeterminado)no-TTYSe conecta al socket de una sesión interactiva, sirve MCP sobre stdio
Headless--headlesscualquieraAutónomo: PTY embebido + servidor MCP sobre stdio

Modo headless (recomendado para configuraciones MCP)

MCP Client (Claude Code, etc.)
    │ STDIO (JSON-RPC)
    ▼
terminal-mcp --headless
    ├── MCP SDK (@modelcontextprotocol/sdk)
    ├── Terminal Emulator (@xterm/headless)
    └── Embedded PTY (node-pty)
            │
            ▼
        Shell Process (bash, zsh, etc.)

Modo interactivo + cliente (dos procesos)

terminal-mcp (interactive, in your terminal)
    ├── User shell (stdin/stdout)
    └── Unix socket server (/tmp/terminal-mcp.sock)
            ▲
            │ JSON-RPC over socket
            ▼
terminal-mcp (client, spawned by MCP client)
    └── MCP server (stdio transport)

Sesión de ejemplo

# Type a command
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"type","arguments":{"text":"ls -la"}}}

# Send Enter key
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"sendKey","arguments":{"key":"Enter"}}}

# Get the output
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"getContent","arguments":{}}}

Desarrollo

npm run build    # Compile TypeScript
npm run dev      # Run with tsx (development)

Documentación

Consulta la carpeta docs para documentación detallada:

Requisitos

  • Node.js 18.0.0 o posterior
  • Windows 10 versión 1809 o posterior (para soporte ConPTY)

Licencia

MIT