NPCterm
The ultimate harness agent tool. A headless, in-memory terminal emulator for AI agents, exposed via MCP (Model Context Protocol).
NPCterm gives AI agents full terminal access. The ability to spawn shells, run arbitrary commands, read screen output, send keystrokes, and interact with TUI applications. This is one of the most powerful capabilities you can grant an AI agent: it is effectively equivalent to giving it access to a computer.
Use with precautions. A terminal is an unrestricted execution environment. Any command the agent can type, the system will run. This includes installing software, modifying files, accessing the network, and anything else a shell user can do. Deploy NPCterm in sandboxed or controlled environments, and always apply the principle of least privilege. Do not expose it to untrusted agents without appropriate safeguards.
Full system monitoring with btop, launched, read, and navigated entirely by an AI agent through MCP tools.
Features
- Full ANSI/VT100 terminal emulation with PTY spawning via
portable-pty
- 17 MCP tools for complete terminal control over JSON-RPC stdio
- Built on TurboMCP 3.0 -- production-grade MCP SDK with auto-generated tool schemas
- Multi-version MCP protocol support -- compatible with clients using
2024-11-05, 2025-06-18, or 2025-11-25 spec versions
- Incremental screen reads with dirty-row tracking for efficient output consumption
- Process state detection: knows when a command is running, idle, waiting for input, or exited
- Event system: ring buffer of terminal events (CommandFinished, WaitingForInput, Bell, etc.)
- AI-friendly coordinate overlay for precise screen navigation
- Mouse, selection, and scroll support for interacting with TUI applications
- Multiple concurrent terminals with short 2-character IDs
- Built-in web debug viewer -- live terminal rendering and activity log in the browser, controllable via MCP tools
Install
cargo install npcterm
Install for any AI CLI / IDE
Installs the binary and auto-configures it for every MCP client detected: Claude Code, Claude Desktop, Codex, OpenCode, OpenClaw.
curl -fsSL https://raw.githubusercontent.com/alejandroqh/marketplace/main/h39.sh | bash
Pre-built binaries
Pre-built binaries are available in the dist/ directory for:
- macOS ARM64 (Apple Silicon) / x64 (Intel)
- Linux ARM64 / x64
- Windows x64
Download the binary for your platform and place it somewhere in your PATH.
Build from source
cargo build --release
The binary will be at target/release/npcterm.
MCP config
Add to your MCP client config:
{
"mcpServers": {
"npcterm": {
"command": "npcterm"
}
}
}
Usage
NPCterm is an MCP server. It communicates over stdin/stdout using JSON-RPC. To use it, configure it as an MCP server in your AI agent's MCP configuration (see install instructions above).
Available Tools
| Tool | Description |
|---|
terminal_create | Spawn a new terminal (80x24, 120x40, 160x40, or 200x50). Optional shell param to specify shell path |
terminal_destroy | Destroy a terminal and its PTY |
terminal_list | List all active terminals |
terminal_send_key | Send a single keystroke |
terminal_send_keys | Send a sequence of keystrokes |
terminal_mouse | Send mouse events (click, scroll, drag) |
terminal_read_screen | Read the screen with coordinate overlay (full or mode: "changes" for incremental reads) |
terminal_show_screen | Read screen as plain text without coordinates |
terminal_read_rows | Read specific rows from the screen |
terminal_read_region | Read a rectangular region of the screen |
terminal_status | Get terminal status, process state, and has_new_content flag |
terminal_poll_events | Poll the event queue |
terminal_select | Select text on screen |
terminal_scroll | Scroll the terminal viewport |
viewer_start | Start the web debug viewer (default port 8039, auto-probes if busy) |
viewer_stop | Stop the web debug viewer |
viewer_open | Open the debug viewer in the system browser (starts it if needed) |
Example: Yes, your agent now can quit Vim
// MCP Flow
// 1. Create a terminal
// -> terminal_create {}
// <- {"id": "a0", "cols": 80, "rows": 24}
// 2. Open vim
// -> terminal_send_keys {"id": "a0", "input": [{"text": "vim"}, {"key": "Enter"}]}
// <- {"success": true}