Install
$ agentstack add mcp-lightos-interactive-shell-mcp ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Interactive Shell MCP
[](LICENSE) [](https://nodejs.org) [](https://modelcontextprotocol.io)
MCP server for interactive shell sessions with TUI support. Gives AI agents persistent terminals, interactive prompt navigation, rendered screen reading, and output search.
Demo
| Without MCP | With MCP | |:-----------:|:--------:| | | | | "htop is interactive and can't run" | Launches htop, reads screen, extracts process data (2x speed) |
Why This Exists
Most AI coding tools run shell commands in isolation: each command starts a fresh shell, interactive prompts are impossible, and TUI apps just dump raw escape codes. This MCP server provides persistent PTY sessions with a virtual terminal emulator (@xterm/headless) so agents can maintain shell state, navigate interactive prompts with arrow keys, and read rendered terminal screens as clean text.
Three output modes:
| Mode | Best for | What you get | |------|----------|-------------| | streaming | Regular commands (ls, git, npm) | Raw sequential output, cleared after read | | snapshot | Live-updating apps (top, htop) | Current terminal buffer tail | | screen | TUI apps, prompts, anything visual | Rendered 2D text grid (what a human sees) |
Quick Start
git clone https://github.com/lightos/interactive-shell-mcp.git
cd interactive-shell-mcp
npm install && npm run build
claude mcp add interactive-shell node dist/src/server.js
Then ask Claude: "monitor htop and tell me what's using the most CPU"
Features
- Rendered screen reading from TUI apps via
@xterm/headless waitForIdleacross all read tools (no more guessing with sleep)- Screen search with text and regex pattern matching
- Rectangular region extraction with row/col coordinates
- Shell allowlist: bash, zsh, fish, sh, dash, ksh, powershell.exe, pwsh, cmd.exe
- Auto-cleanup after 10min idle, exit code detection for 60s after process exit
- Cross-platform: Unix/Linux/macOS + Windows
Use Cases
- Interactive scaffolding & migrations:
npx create-next-app,drizzle-kit push,prisma migrate,npm init, or any inquirer/clack-based CLI - System monitoring:
htop,btop,top,iftop,dufwith process search and region extraction - DevOps TUIs:
lazydocker,lazygit,k9s,terraform console - Remote sessions:
sshinto servers, including nested TUI apps over SSH - Database CLIs:
psql,mysql,redis-cli,mongoshin interactive mode - Network tools:
netcat/ncat,nmap,airodump-ng,tcpdump - REPLs & debuggers:
python,node,irb,gdb/lldb - Text editors:
vim,nano,emacs -nw
MCP Configuration
Claude Code (CLI)
claude mcp add interactive-shell node /path/to/interactive-shell-mcp/dist/src/server.js
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"interactive-shell": {
"command": "node",
"args": ["/path/to/interactive-shell-mcp/dist/src/server.js"]
}
}
}
VS Code / Cursor
Add to your MCP settings (.vscode/mcp.json or ~/.cursor/mcp.json):
{
"mcpServers": {
"interactive-shell": {
"command": "node",
"args": ["/path/to/interactive-shell-mcp/dist/src/server.js"]
}
}
}
Tools Reference
start_shell_session
Spawn a new PTY shell with a virtual terminal emulator.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | cols | number | no | Terminal columns (default: 120, max: 500) | | rows | number | no | Terminal rows (default: 40, max: 200) | | shell | string | no | Shell to use (default: $SHELL or bash) | | cwd | string | no | Working directory (default: server cwd) |
Returns { sessionId, cols, rows }
send_shell_input
Write input to the PTY. Appends carriage return by default.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | sessionId | string | yes | Session ID | | input | string | yes | Text to send. Raw mode: \x1b[A (up), \x1b[B (down), \r (enter) | | raw | boolean | no | Send without appending CR. Parses escape sequences. (default: false) |
read_shell_output
Read output from the PTY. Three modes: streaming (default), snapshot, screen.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | sessionId | string | yes | Session ID | | mode | string | no | "streaming", "snapshot", or "screen" | | waitForIdle | number | no | Wait for N ms of silence before reading (max: 5000ms) | | maxBytes | number | no | Max bytes for streaming mode (default: 100KB) | | snapshotSize | number | no | Snapshot buffer size (default: 50KB) | | rows | number | no | Screen mode: start row (0-based) | | rowEnd | number | no | Screen mode: end row (exclusive) | | includeEmpty | boolean | no | Screen mode: include trailing empty lines (default: true) | | trimWhitespace | boolean | no | Screen mode: trim trailing whitespace per line (default: false) |
Screen mode returns cursor position, terminal dimensions, and alternate buffer state in metadata.
get_screen_region
Extract text from a rectangular region of the screen.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | sessionId | string | yes | Session ID | | startRow | number | yes | Start row (0-based, inclusive) | | startCol | number | yes | Start column (0-based, inclusive) | | endRow | number | yes | End row (exclusive) | | endCol | number | yes | End column (exclusive) | | trimWhitespace | boolean | no | Trim trailing whitespace per line (default: false) | | waitForIdle | number | no | Wait for N ms of silence before reading (max: 5000ms) |
get_screen_cursor
Get cursor position and current line text.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | sessionId | string | yes | Session ID | | waitForIdle | number | no | Wait for N ms of silence before reading (max: 5000ms) |
Returns { cursor: { x, y }, currentLine, isAlternateBuffer }
search_screen
Search the terminal screen for text or regex. Returns up to 50 matches.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | sessionId | string | yes | Session ID | | pattern | string | yes | Text or regex pattern | | regex | boolean | no | Treat pattern as regex (default: false) | | waitForIdle | number | no | Wait for N ms of silence before reading (max: 5000ms) |
Returns { results: [{ row, col, text }], count }
list_sessions
List all active sessions with metadata. No parameters.
Returns { sessions: [{ sessionId, shell, cols, rows, isAlternateBuffer, idleSeconds }] }
resize_shell
Resize an active session's terminal.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | sessionId | string | yes | Session ID | | cols | number | yes | New columns (1-500) | | rows | number | yes | New rows (1-200) |
end_shell_session
Close the PTY and clean up resources.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | sessionId | string | yes | Session ID |
Usage Examples
> These show the MCP tool call patterns for developers building integrations. End users just talk to their AI agent naturally.
Reading a TUI App
await send_shell_input(sessionId, "htop");
const { output, metadata } = await read_shell_output(sessionId, {
mode: "screen",
waitForIdle: 500
});
// output: rendered htop as clean text (CPU bars, process table, etc.)
// metadata.isAlternateBuffer: true (htop uses alternate screen)
// Extract just the process list (rows 6-30)
const processes = await get_screen_region(sessionId, {
startRow: 6, startCol: 0, endRow: 30, endCol: 120,
trimWhitespace: true
});
Navigating Interactive Prompts
// Send arrow keys and enter in raw mode
await send_shell_input(sessionId, "\\x1b[B", { raw: true }); // down arrow
await send_shell_input(sessionId, " ", { raw: true }); // space to select
await send_shell_input(sessionId, "\\r", { raw: true }); // enter to confirm
// Read what the prompt looks like now
const screen = await read_shell_output(sessionId, {
mode: "screen", waitForIdle: 300
});
Waiting for Command Output
await send_shell_input(sessionId, "npm install");
const output = await read_shell_output(sessionId, {
waitForIdle: 1000 // wait for 1s of silence
});
Searching for Content
// Find all error lines
const errors = await search_screen(sessionId, {
pattern: "error|Error|ERROR",
regex: true,
waitForIdle: 500
});
// [{ row: 12, col: 0, text: "Error" }, ...]
Session Behavior
- Auto-cleanup: Sessions idle >10 minutes are disposed automatically
- Exit detection: When a shell exits, tools return
"Session exited with code N"for 60 seconds instead of a generic invalid ID error - Shell allowlist: Only known shells can be spawned (bash, zsh, fish, sh, dash, ksh, powershell.exe, pwsh, cmd.exe). Unknown values fall back to platform default.
License
MIT
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: lightos
- Source: lightos/interactive-shell-mcp
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.