mcp-terminal-bridge
v1.0.0
Published
Cross-platform Interactive Terminal Bridge MCP Server for AI Agents (AWS SSM & SSH support)
Maintainers
Readme
MCP Terminal Bridge (mcp-terminal-bridge)
A cross-platform Model Context Protocol (MCP) server that provides AI agents (Cursor, Windsurf, Claude Code, Antigravity, etc.) with persistent, interactive pseudo-terminals (PTYs).
Standard AI agent execution tools rely on basic child-process pipes (child_process.exec / spawn), which fail on interactive operations (like AWS SSM sessions, SSH prompts, sudo passwords, and REPLs) and pollute LLM context with ANSI escape noise. This project bridges that gap by running true pseudo-terminals (PTYs) with headless VT100 emulation, deterministic exit-code probing, concurrent execution queuing, and an embedded zero-config Web TUI mirror.
Setup & Installation
Add terminal-bridge to your MCP settings (Cursor, Claude Desktop, Windsurf, Claude Code, etc.):
{
"mcpServers": {
"terminal-bridge": {
"command": "npx",
"args": ["-y", "mcp-terminal-bridge"]
}
}
}The Problem Solved
- AWS SSM Sessions (
aws ssm start-session): Fails or hangs becausesession-manager-pluginrequires an interactive TTY and terminal dimensions. - SSH Connections (
ssh user@host): Fails with "Pseudo-terminal will not be allocated because stdin is not a terminal". - Interactive Questions & Prompts: Prompts like
Are you sure you want to continue connecting (yes/no)?,[Y/n]confirmations, or password challenges freeze because standard tools wait indefinitely for process exit. - Concurrent Input Collisions: When an AI agent fires multiple commands simultaneously, characters collide on screen and corrupt the shell prompt.
- ANSI & Escape Noise: Raw terminal streams contain thousands of VT100 control codes that waste tokens and confuse LLM parsers.
The Solution:
- Cross-Platform PTY Layer (
node-pty): Spawns true pseudo-terminals using Windows ConPTY on Windows and POSIX PTY (openpty) on Linux & macOS (identical to VS Code's integrated terminal). - Headless Terminal Emulation (
@xterm/headless): Parses raw ANSI streams into clean, human-readable 2D text grids and scrollback lines without inflating token usage. - Three-Tier Completion Engine:
- Sentinel Probing: Deterministically captures command exit codes (
$?) without terminating the remote session. - Idle Quiescence: Detects interactive prompts when output pauses (e.g.
(yes/no)?) so the agent can respond usingterminal_send_input. - Prompt Regex: Fallback detection for custom shell prompts.
- Sentinel Probing: Deterministically captures command exit codes (
- Concurrent Execution Queuing: Parallel command executions on the same session are chained via a sequential mutex queue (
executionQueue), preventing overlapping input, character scrambling, and screen corruption. - Embedded Web TUI Mirror: Built-in HTTP and WebSocket server running at
http://localhost:4040(with Hub & Satellite multi-client support). Developers can watch the AI agent type live at 60 FPS, see live queued command badges (⏳ X queued), and toggle Interactive Takeover to type into the terminal directly from the browser. - Asciinema Auto-Recording: Every session is automatically recorded into standard Asciinema v2 format (
.castfile in~/.mcp-terminal-bridge/recordings/) for post-mortem replay and auditing.
Exposed MCP Tools
| Tool | Description | Key Parameters |
| :----------------------------- | :------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------- |
| terminal_ssm_connect | Connects to an AWS EC2 instance via SSM or SSH-over-SSM | target (Instance ID: i-xxxx), region, profile, useSsh, sshUser, sshKeyPath |
| terminal_spawn | Spawns a persistent local shell or custom interactive CLI | command (default shell), args, cwd, name, cols, rows |
| terminal_execute | Runs a command in an active session and waits for completion/prompt | sessionId, command, timeoutMs, useSentinel, idleTimeoutMs |
| terminal_send_input | Sends text answers, passwords, or control keys (ctrl_c, enter, tab) | sessionId, input, specialKey, waitMs |
| terminal_read_screen | Reads the current clean 2D screen text (like a screenshot in plain text) | sessionId, scrollbackLines |
| terminal_list_sessions | Lists all active sessions, process IDs, and uptimes | None |
| terminal_close | Gracefully exits or terminates a session | sessionId, force |
| terminal_check_prerequisites | Validates presence of AWS CLI, Session Manager Plugin, and OpenSSH | None |
Example AI Agent Workflows
Scenario 1: AWS SSM Session
- Agent initiates SSM:
// Tool Call: terminal_ssm_connect { "target": "i-0123456789abcdef0", "region": "us-east-1" } - Agent runs commands on the remote EC2 instance:
// Tool Call: terminal_execute { "sessionId": "term-xxxx", "command": "uname -a && cat /etc/os-release" } - Agent stops a runaway process with Ctrl+C:
// Tool Call: terminal_send_input { "sessionId": "term-xxxx", "specialKey": "ctrl_c" }
Scenario 2: Handling Interactive Prompts
- Agent runs
sudo apt install nginx. - Output stops with
Do you want to continue? [Y/n]. - Server returns status
"idle_prompt"with the question text. - Agent calls:
// Tool Call: terminal_send_input { "sessionId": "term-xxxx", "input": "Y\n" }
Architecture
mcp-terminal-bridge/
├── src/
│ ├── index.ts # FastMCP server entry point (stdio & HTTP stream)
│ ├── osal/ # Operating System Abstraction Layer
│ │ ├── detector.ts # Platform and shell auto-detection (Linux, macOS, Windows)
│ │ ├── paths.ts # Binary resolution for aws, session-manager-plugin, ssh
│ │ └── keys.ts # Terminal keystroke and control sequences
│ ├── pty/ # Pseudo-terminal & Emulation
│ │ ├── virtual_terminal.ts# @xterm/headless 2D screen buffer & ANSI sanitization
│ │ ├── completion.ts # Sentinel exit code detector & quiescence debounce
│ │ ├── session.ts # Stateful PTY session wrapper
│ │ └── manager.ts # Multi-session lifecycle registry
│ └── tools/ # FastMCP Tool Registrations
│ └── index.ts # Tool schemas and execution logic
├── test/
│ └── test_session.ts # Integration test suite
├── package.json
└── tsconfig.jsonLicense
MIT
