interactive-cli
Enables AI agents to interact with interactive CLI processes via a real PTY, allowing them to send keystrokes, read screen output, and handle interactive prompts.
README
interactive-cli
MCP server that lets AI coding agents interact with interactive CLI processes. Uses a real PTY + xterm headless to render terminal output as clean text — no ANSI escape soup.
Works with Claude Code, Cursor, Windsurf, or any MCP-compatible client.
Why
AI agents can run shell commands, but they choke on anything interactive:
$ eas build --platform ios
✔ Select a build profile › (waiting for input...)
This MCP server bridges that gap — spawn the process, read the screen, send keystrokes.
Quick Start
Claude Code
claude mcp add-json interactive-cli '{"command":"npx","args":["-y","interactive-cli-mcp"]}'
Or add to ~/.claude/settings.json manually:
{
"mcpServers": {
"interactive-cli": {
"command": "npx",
"args": ["-y", "interactive-cli-mcp"]
}
}
}
From Source
git clone https://github.com/ohernandezdev/interactive-cli.git
cd interactive-cli
npm install && npm run build
claude mcp add-json interactive-cli '{"command":"node","args":["/absolute/path/to/interactive-cli/dist/index.js"]}'
Other MCP Clients
Point your client's MCP config at:
command: node
args: ["/path/to/interactive-cli/dist/index.js"]
transport: stdio
Tools
| Tool | Description | Read-only |
|---|---|---|
spawn |
Start an interactive process in a PTY | No |
send_input |
Type text (appends Enter by default) | No |
send_keys |
Send special keys in sequence (arrows, ctrl combos, etc.) | No |
get_screen |
Capture current terminal screen, optional regex search | Yes |
wait_for |
Block until a regex pattern appears in output | No |
wait_for_exit |
Block until the process exits | No |
resize |
Change terminal dimensions | No |
list_sessions |
List all active sessions | Yes |
close |
Kill process, clean up session | No |
Typical Flow
sequenceDiagram
participant Agent as AI Agent
participant MCP as interactive-cli
participant PTY as Process (PTY)
Agent->>MCP: spawn("eas build --platform ios")
MCP->>PTY: Start process in PTY
PTY-->>MCP: Initial output
MCP-->>Agent: sessionId + screen
Agent->>MCP: get_screen(sessionId)
MCP-->>Agent: "Select profile: ❯ dev staging prod"
Agent->>MCP: send_keys(["down","down","enter"])
MCP->>PTY: ↓ ↓ ⏎
PTY-->>MCP: "✔ Selected: production"
MCP-->>Agent: updated screen
Agent->>MCP: wait_for("Build complete|error", 600s)
loop Every 1s
MCP->>PTY: check output
end
PTY-->>MCP: "Build complete"
MCP-->>Agent: matched + screen
Agent->>MCP: close(sessionId)
MCP->>PTY: SIGTERM
MCP-->>Agent: final screen + exit code
spawn
spawn({
command: "ssh user@server.com", // full command string
cwd: "/path/to/project", // optional working directory
env: { "NODE_ENV": "production" }, // optional extra env vars
cols: 120, // terminal width (default 120)
rows: 30, // terminal height (default 30)
waitMs: 3000, // ms to wait for initial output (default 2000)
})
Commands run through your shell ($SHELL or /bin/zsh), so pipes, redirects, and builtins work.
send_input
send_input({
sessionId: "s1",
text: "yes", // text to type
pressEnter: true, // append Enter (default true). false for password fields
waitMs: 2000, // ms to wait for response (default 2000)
})
send_keys
Send one or more keys in sequence with a small delay between each:
send_keys({
sessionId: "s1",
keys: ["down", "down", "enter"], // navigate menu
delayBetweenMs: 50, // ms between keys (default 50)
waitMs: 1500, // ms to wait after last key (default 1500)
})
Supported keys: enter tab escape space up down left right backspace delete home end page_up page_down f1–f12 ctrl+c ctrl+d ctrl+z ctrl+l ctrl+a ctrl+e ctrl+r ctrl+w ctrl+u ctrl+k ctrl+p ctrl+n y n 0–9
get_screen
get_screen({
sessionId: "s1",
search: "error|warning", // optional regex to highlight matching lines
})
// Returns: { screen, cursor: { row, col }, searchResults, stats }
wait_for
wait_for({
sessionId: "s1",
pattern: "\\$|#|>", // regex to match (case-insensitive)
timeoutMs: 30000, // max wait (default 30s)
intervalMs: 1000, // check interval (default 1s)
})
// Returns: { matched: true/false, screen, elapsed }
wait_for_exit
wait_for_exit({
sessionId: "s1",
timeoutMs: 60000,
})
// Returns: { alive: false, exitCode: 0, screen }
Resources
Sessions are exposed as MCP resources:
interactive-cli://sessions— JSON list of all sessionsinteractive-cli://sessions/{id}/screen— live screen content
Prompt Templates
Pre-built prompt templates for common flows (appear as slash commands in Claude Code):
eas_build— EAS build with credential handlingssh_session— SSH connection with command executionrepl_session— Start a REPL (Python, Node, psql, etc.)docker_interactive— Run an interactive Docker container
How It Works
graph LR
A[AI Agent] <-->|MCP Protocol| B[interactive-cli server]
B --> C[Session Manager]
C --> D[node-pty<br/><i>real PTY</i>]
C --> E[xterm headless<br/><i>screen render</i>]
C --> F[Truncation<br/><i>80K limit</i>]
D <--> G[Child Process<br/>ssh, eas, python...]
- node-pty spawns a real pseudo-terminal, so the child process thinks it's talking to a human
- xterm headless maintains a virtual terminal buffer that renders ANSI sequences into a clean 2D text grid
- Output is truncated at 80K chars (MCP clients like Claude Code cap at 100K) with smart middle-truncation preserving start and end
- Tool annotations (
readOnlyHint,destructiveHint) tell the client which tools are safe to run in parallel and which need permission
Requirements
- Node.js >= 18
- macOS or Linux (node-pty uses native PTY)
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.