Install
$ agentstack add mcp-hegner123-tui-test-ghost ✓ 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 Used
- ✓ 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
tui-test-ghost
A TUI testing toolkit for programmatic interaction with terminal applications. Built in Zig on Ghostty's ghostty-vt terminal emulation core.
Developed specifically to test Bubble Tea interfaces agentically — letting AI agents spawn, drive, and assert against TUI applications through MCP without needing a display.
Platforms
- macOS (aarch64, x86_64)
- Linux (x86_64)
Quick Start
Install from release
# macOS (Apple Silicon)
curl -fsSL https://github.com/hegner123/tui-test-ghost/releases/latest/download/tui-test-ghost-v0.3.0-macos-aarch64.tar.gz | tar xz
mv tui-test-ghost /usr/local/bin/
# Linux (x86_64)
curl -fsSL https://github.com/hegner123/tui-test-ghost/releases/latest/download/tui-test-ghost-v0.3.0-linux-x86_64.tar.gz | tar xz
mv tui-test-ghost /usr/local/bin/
Install from source
Requires Zig 0.15.1+. Ghostty is fetched automatically.
git clone https://github.com/hegner123/tui-test-ghost.git
cd tui-test-ghost
zig build -Doptimize=ReleaseSafe
just install
Add to Claude Code
claude mcp add tui-test-ghost -- tui-test-ghost
Usage
MCP Server
tui-test-ghost
Starts a JSON-RPC MCP server on stdin/stdout with these tools:
| Tool | Description | |------|-------------| | tui_start | Start a TUI program and return initial screen state. Params: command (required), args, cols (default 80), rows (default 24), region. Returns session_id, text, cursor_row, cursor_col, cols, rows. | | tui_send | Send input and return screen state. Params: session_id (required), keys (array of key tokens), settle_ms (default 50), region. Legacy: text, key, mods. Returns text, cursor_row, cursor_col, cols, rows. | | tui_screen | Get screen content. Params: session_id (required), region. Returns text, cursor_row, cursor_col, cols, rows. | | tui_cell | Inspect a single cell. Params: session_id, row, col (all required). Returns char, bold, italic, underline, strikethrough, dim, fg, bg. | | tui_wait | Wait for a condition and return screen state. Params: session_id (required), plus one of: text, stable_ms, cursor_row+cursor_col. Optional timeout_ms (default 5000, max 30000), region. Returns matched, text, cursor_row, cursor_col, cols, rows. | | tui_resize | Resize terminal and return screen state. Params: session_id, cols, rows (all required), region. Returns text, cursor_row, cursor_col, cols, rows. | | tui_snapshot | Capture screen snapshot. Params: session_id (required), golden_path (optional — compares against baseline if provided, creates it if missing). | | tui_stop | Stop session and get exit code. Params: session_id (required). Returns exit_code. | | tui_record_start | Start recording tool calls to a JSONL file. Params: path (required). | | tui_record_stop | Stop recording and close the file. No params. |
Replay
tui-test-ghost replay test.jsonl
Replays a recorded JSONL session and reports pass/fail for each entry. Action tools (tui_start, tui_send, tui_screen, tui_cell, tui_resize) are re-executed without comparison. Assertion tools (tui_wait, tui_stop, tui_snapshot) compare key result fields against the recorded values.
Exits 0 if all assertions pass, 1 if any fail. Single-session recordings only (one tui_start per file).
JSONL format — one JSON object per line:
{"tool":"tui_start","args":{"command":"myapp"},"result":{"session_id":0,"text":"..."}}
{"tool":"tui_send","args":{"session_id":0,"keys":["down*3","enter"]},"result":{"text":"..."}}
{"tool":"tui_wait","args":{"session_id":0,"text":"Settings"},"result":{"matched":true,"text":"..."}}
{"tool":"tui_stop","args":{"session_id":0},"result":{"exit_code":0}}
CLI
tui-test-ghost --cli --command htop --screen
tui-test-ghost --cli --command vim --send "ihello" --wait-for "hello" --screen
| Flag | Description | |------|-------------| | --command | Program to run (required) | | --send | Text to send to stdin | | --wait-for | Wait until text appears on screen (5s timeout) | | --screen | Print screen content to stdout |
Features
- Real terminal emulation — Ghostty's VT parser handles SGR, cursor movement, alternate screen buffer, scrollback
- PTY-based — programs run in a real pseudo-terminal, behaving exactly as they would in a real terminal
- Cell-level inspection — query individual cell attributes: character, bold, italic, underline, strikethrough, dim, foreground/background color (default, palette, RGB)
- Wait conditions — poll until text appears, screen stabilizes, cursor reaches a position, or process exits
- Golden file snapshots — capture screen state to disk, diff against a baseline on future runs
- Session pool — manage up to 16 concurrent terminal sessions
- Keyboard input — send named keys (enter, tab, escape, arrows, F1-F12) with modifier combinations (ctrl, alt, shift)
- Key batching — send multiple keystrokes in a single MCP call with the
keysarray:["down*5", "enter"] - Auto-screen —
tui_start,tui_send,tui_wait, andtui_resizereturn screen state in every response - Region cropping — return only a portion of the screen with the
regionparameter to reduce token usage - Resize — change terminal dimensions mid-session, delivering SIGWINCH to the child process
- Record/replay — record an agent's MCP tool calls to JSONL, replay them as a repeatable test suite with
tui-test-ghost replay
Key Token Syntax
The keys parameter on tui_send accepts an array of string tokens:
| Token | Meaning | |-------|---------| | "enter" | Single key press | | "ctrl+c" | Modified key (ctrl, alt, shift) | | "down*5" | Repeat key 5 times (max 99) | | "ctrl+shift+up" | Multiple modifiers | | "text:hello world" | Send literal text | | "text:*" | Send literal * (since * is the repeat operator) |
The text: prefix is reserved. Max 64 tokens per call, max 99 repeats.
Region Parameter
Tools that return screen content accept an optional region object to crop the output:
{"region": {"row": 2, "col": 0, "width": 40, "height": 10}}
All fields are optional (defaults: row=0, col=0, width=terminal cols, height=terminal rows). Values are clamped to terminal bounds.
How It Works
TUI Process → PTY → ghostty-vt Terminal Emulator → Screen Query API → MCP / CLI
Programs run in a real PTY backed by Ghostty's VT parser, providing accurate screen state including SGR attributes, cursor positioning, and alternate screen buffer support. Single-threaded with explicit drain — the caller controls when PTY output is consumed and fed to the terminal emulator.
Architecture
| Module | Purpose | |--------|---------| | Pty.zig | PTY open/close/read/write/poll/resize | | Process.zig | Fork/exec, signal handling, wait | | Terminal.zig | Wrapper around ghostty-vt Terminal | | Session.zig | Combines PTY + Process + Terminal into a test session | | SessionPool.zig | Fixed-size pool of up to 16 sessions | | screen.zig | Screen queries: plaintext, cell attributes, cursor position | | wait.zig | Polling wait conditions with timeout | | snapshot.zig | Capture, save, load, and diff screen snapshots | | input.zig | Key encoding using Ghostty's input system | | mcp.zig | JSON-RPC message parsing and serialization | | tools.zig | MCP tool definitions, dispatch, and handlers | | record.zig | JSONL recorder for tool call capture | | replay.zig | Replay engine: load, execute, compare, report |
Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md).
License
MIT License. See [LICENSE](LICENSE).
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: hegner123
- Source: hegner123/tui-test-ghost
- 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.