mcp-terminal-bridge
by SHTO88
README.md
# 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.):
```json
{
"mcpServers": {
"terminal-bridge": {
"command": "npx",
"args": ["-y", "mcp-terminal-bridge"]
}
}
}
```
---
## The Problem Solved
- **AWS SSM Sessions** (`aws ssm start-session`): Fails or hangs because `session-manager-plugin` requires 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:
1. **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).
2. **Headless Terminal Emulation (`@xterm/headless`)**: Parses raw ANSI streams into clean, human-readable 2D text grids and scrollback lines without inflating token usage.
3. **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 using `terminal_send_input`.
- **Prompt Regex**: Fallback detection for custom shell prompts.
4. **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.
5. **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.
6. **Asciinema Auto-Recording**: Every session is automatically recorded into standard Asciinema v2 format (`.cast` file in `~/.mcp-terminal-bridge/recordings/`) for post-mortem replay and auditing.
<p align="center">
<img src="assets/live-terminal-preview.jpg" alt="MCP Terminal Bridge Live Web TUI" width="100%" />
<br>
<em>Real-time browser terminal mirror at <code>http://localhost:4040/session/:id</code> with View Only and Interactive Takeover modes.</em>
</p>
---
## 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
1. **Agent initiates SSM**:
```json
// Tool Call: terminal_ssm_connect
{
"target": "i-0123456789abcdef0",
"region": "us-east-1"
}
```
2. **Agent runs commands on the remote EC2 instance**:
```json
// Tool Call: terminal_execute
{
"sessionId": "term-xxxx",
"command": "uname -a && cat /etc/os-release"
}
```
3. **Agent stops a runaway process with Ctrl+C**:
```json
// Tool Call: terminal_send_input
{
"sessionId": "term-xxxx",
"specialKey": "ctrl_c"
}
```
### Scenario 2: Handling Interactive Prompts
1. Agent runs `sudo apt install nginx`.
2. Output stops with `Do you want to continue? [Y/n]`.
3. Server returns status `"idle_prompt"` with the question text.
4. Agent calls:
```json
// 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.json
```
## License
MIT
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessNo issues