Terminal MCP

officiel

Offre aux assistants IA une vue partagée et en direct de votre session terminal pour déboguer les CLI et TUI, ou un contrôle autonome du terminal.

Que pouvez-vous faire avec Terminal MCP ?

  • Taper des commandes et envoyer des touches — Demandez à l'IA d'exécuter des commandes shell via type et sendKey, y compris des touches spéciales comme Enter ou Ctrl+C.
  • Lire la sortie du terminal — Récupérez le tampon actuel du terminal sous forme de texte brut avec getContent, ou capturez une capture d'écran au format text, ansi ou png via takeScreenshot.
  • Enregistrer et rejouer des sessions — Démarrez et arrêtez des enregistrements asciicast v2 avec startRecording et stopRecording, puis rejouez-les avec asciinema.
  • Gérer plusieurs sessions — Créez des sessions terminal isolées avec createSession, listez celles actives via listSessions, et nettoyez avec destroySession, chacune étant adressée par sessionId.

Documentation

Terminal MCP

Laissez l'IA voir et interagir avec votre terminal.

Terminal MCP donne aux LLM une vue partagée de votre session de terminal. Parfait pour déboguer des applications CLI et TUI en temps réel, ou laisser l'IA piloter des outils basés sur le terminal de manière autonome.

Installation

npm install -g @ellery/terminal-mcp

Ou via le script d'installation :

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

Configurer vos outils d'IA

Branchez terminal-mcp dans la configuration MCP de chaque outil d'IA installé sur votre machine en une seule fois :

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

Clients pris en charge (chacun reçoit le bon schéma pour son format de configuration) :

ClientFichier de configurationFormat
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

Une .bak de toute configuration préexistante est écrite à côté de l'originale lors de la première installation. L'entrée terminal-mcp est ajoutée sans perturber les autres serveurs ou clés non liées ; relancer setup est une opération sans effet.

Mise à niveau

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

Le mode interactif affichera une bannière au prochain lancement lorsqu'une version plus récente est disponible — terminal-mcp vérifie le registre npm une fois par jour et met en cache le résultat. Les modes sans tête et client MCP ne vérifient ni n'affichent jamais rien (ainsi, stdio MCP reste propre). Pour vous désinscrire complètement, définissez NO_UPDATE_NOTIFIER=1 ou passez --no-update-notifier.

Fonctionnalités

  • Émulation complète du terminal : Utilise xterm.js sans tête pour une émulation VT100/ANSI précise
  • PTY multiplateforme : Prise en charge native des pseudo-terminaux via node-pty (macOS, Linux, Windows)
  • Protocole MCP : Implémente le Model Context Protocol pour l'intégration avec les assistants IA
  • Enregistrement de session : Enregistrez les sessions de terminal au format asciicast pour une lecture avec asciinema
  • API simple : Neuf outils couvrant la saisie, l'observation, l'enregistrement et le cycle de vie des sessions
  • Mode sans tête : Fonctionne comme un serveur MCP autonome sans TTY — idéal pour CI, conteneurs et environnements non interactifs
  • Multi-session : Exécutez plusieurs sessions de terminal isolées dans un seul processus, adressées par sessionId
  • Mode bac à sable : Restrictions de sécurité optionnelles pour l'accès au système de fichiers et au réseau

Compilation à partir des sources

npm install
npm run build

Utilisation

Configuration MCP

Ajoutez à vos paramètres client MCP :

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

Avec des options personnalisées :

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

Options de ligne de commande

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)

Mode sans tête

Par défaut, Terminal MCP utilise une architecture à deux processus : vous exécutez terminal-mcp dans un terminal interactif (qui crée un socket Unix), puis votre client MCP génère une seconde instance qui se connecte à ce socket. Cela nécessite un TTY.

Le mode sans tête (--headless) élimine cette exigence en générant un PTY intégré en interne et en servant MCP directement via stdio dans un seul processus. Pas de session de terminal interactive, pas de socket — juste un serveur MCP autonome avec un terminal intégré.

Quand utiliser le mode sans tête

  • Pipelines CI/CD — aucun TTY disponible
  • Conteneurs Docker — aucun shell interactif à exécuter en parallèle
  • Environnements distants/cloud — serveurs MCP générés par automatisation
  • Configuration simplifiée — un seul processus, aucune coordination de socket nécessaire

Configuration

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

Comment cela fonctionne

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 mode sans tête, la session de terminal est initialisée de manière proactive au démarrage, donc tous les outils (type, sendKey, getContent, takeScreenshot, startRecording, stopRecording, createSession, listSessions, destroySession) sont disponibles immédiatement.

Outils MCP

Tous les outils d'entrée/sortie (type, sendKey, getContent, takeScreenshot) acceptent un argument optionnel sessionId. Omettez-le pour cibler la session par défaut ; passez l'ID retourné par createSession pour piloter une session spécifique.

type

Envoyez une saisie texte au terminal.

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

sendKey

Envoyez des touches spéciales ou des combinaisons de touches.

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

Touches prises en charge :

  • De base : Enter, Tab, Escape, Backspace, Delete
  • Flèches : ArrowUp, ArrowDown, ArrowLeft, ArrowRight
  • Navigation : Home, End, PageUp, PageDown, Insert
  • Fonction : F1 à F12
  • Contrôle : Ctrl+A à Ctrl+Z, Ctrl+C, Ctrl+D, etc.

getContent

Obtenez le tampon du terminal sous forme de texte brut.

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

takeScreenshot

Capturez l'état du terminal. Prend en charge trois formats de sortie :

FormatDescription
text (par défaut)JSON avec contenu texte brut, position du curseur et dimensions
ansiJSON avec codes d'échappement de couleur ANSI préservés dans le champ de contenu
pngCapture d'écran couleur en image PNG (nécessite @resvg/resvg-js)
{
  "name": "takeScreenshot",
  "arguments": { "format": "text" }
}

Le format ansi reconstruit les séquences d'échappement SGR à partir du tampon de cellules du terminal, préservant les attributs de couleur 16 couleurs, 256 couleurs et truecolor 24 bits ainsi que les styles gras, atténué, italique et souligné.

Le format png retourne un bloc de contenu MCP image avec des données PNG encodées en base64, rendu avec le thème de couleurs One Dark et un habillage de fenêtre de style macOS.

startRecording

Commencez à enregistrer la sortie du terminal dans un fichier asciicast v2.

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

Options :

  • mode : always (tout enregistrer) ou on-failure (enregistrer uniquement en cas de sortie non nulle)
  • outputDir : Répertoire de sortie personnalisé
  • idleTimeLimit : Secondes maximales entre les événements (plafonne les pauses lors de la lecture)
  • maxDuration : Arrêt automatique après N secondes
  • inactivityTimeout : Arrêt automatique après N secondes sans sortie

stopRecording

Arrêtez un enregistrement et finalisez le fichier asciicast.

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

createSession

Créez une nouvelle session de terminal et retourne ses métadonnées. Utilisez le sessionId retourné pour cibler cette session dans les appels d'outils ultérieurs.

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

Tous les arguments sont optionnels. Retourne :

{
  "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

Listez toutes les sessions actives, y compris la session par défaut. Signale les limites configurées.

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

destroySession

Détruisez une session par ID. La session par défaut ne peut pas être détruite.

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

Multi-session

Par défaut, chaque appel d'outil sans sessionId cible une seule session par défaut créée automatiquement — le même comportement que le projet a toujours eu. Passez sessionId pour piloter plusieurs PTY isolés depuis un seul processus.

  • La session par défaut est créée lors de la première utilisation et ne peut pas être détruite.
  • Les sessions supplémentaires sont créées par createSession et suivies jusqu'à ce qu'elles soient détruites ou expulsées après inactivité (--session-idle-timeout, 600s par défaut).
  • Les sessions simultanées sont plafonnées à --max-sessions (5 par défaut).
  • Un enregistrement actif capture la sortie de toutes les sessions du processus.

Cas d'utilisation typique : un agent IA pilotant une compilation longue dans une session tout en exécutant des diagnostics dans une autre, sans entrelacement de commandes.

Mode bac à sable

Exécutez le terminal avec un accès restreint au système de fichiers et au réseau :

# Interactive permission configuration
terminal-mcp --sandbox

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

Le mode interactif affiche une boîte de dialogue TUI pour configurer les permissions :

Sandbox Permissions Dialog

- **Lecture/Écriture** : Accès complet (répertoire courant, /tmp, caches) - **Lecture seule** : Peut lire mais pas modifier (répertoire personnel) - **Bloqué** : Aucun accès (clés SSH, identifiants cloud, jetons d'authentification)

Exemple de fichier de configuration :

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

Prise en charge des plateformes :

  • macOS : Prise en charge complète via sandbox-exec (Seatbelt)
  • Linux : Prise en charge complète via bubblewrap (nécessite bwrap installé)
  • Windows : Repli gracieux (s'exécute sans bac à sable)

Voir Documentation du bac à sable pour les options de configuration détaillées.

Enregistrement

Terminal MCP peut enregistrer des sessions au format asciicast v2, compatible avec asciinema pour la lecture.

Démarrage rapide

# 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>

Lecture

Installez asciinema pour lire les enregistrements :

# 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

Modes d'enregistrement

  • always (par défaut) : Enregistrez chaque session
  • on-failure : Enregistrez uniquement si la session se termine avec un code non nul (utile pour déboguer des exécutions CI échouées)
# Only save recordings when something fails
terminal-mcp --record=on-failure

Enregistrement via outil MCP

Les assistants IA peuvent également contrôler l'enregistrement par programmation via les outils MCP :

  1. Appelez startRecording pour commencer la capture
  2. Effectuez les opérations du terminal
  3. Appelez stopRecording pour finaliser et enregistrer

Cela permet des flux de travail pilotés par IA comme « enregistrer cette session de débogage » ou « capturer cette démonstration ».

Architecture

Terminal MCP a trois modes de fonctionnement :

ModeIndicateurStdinDescription
Interactif(par défaut)TTYL'utilisateur obtient un shell ; l'IA se connecte via socket Unix
Client(par défaut)non-TTYSe connecte au socket d'une session interactive, sert MCP via stdio
Sans tête--headlessquelconqueAutonome : PTY intégré + serveur MCP via stdio

Mode sans tête (recommandé pour les configurations 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.)

Mode interactif + client (deux processus)

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)

Exemple de session

# 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":{}}}

Développement

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

Documentation

Voir le dossier docs pour une documentation détaillée :

Exigences

  • Node.js 18.0.0 ou ultérieur
  • Windows 10 version 1809 ou ultérieure (pour la prise en charge ConPTY)

Licence

MIT