Content
# vterm-mcp
MCP server that lets Claude drive and test TUI applications. Spawns a child
process on a pseudo-terminal, runs its output through
[libghostty-vt](https://crates.io/crates/libghostty-vt) (Ghostty's headless
terminal engine), and exposes tools to read the rendered screen and send keys.
## Tools
| Tool | Purpose |
|---|---|
| `start_session` | Spawn a child on a PTY. Returns `{ session_id }`. |
| `stop_session` | Kill + reap the child. |
| `list_sessions` | Enumerate active sessions. |
| `get_screen` | Snapshot the current viewport (text lines + cursor, optional per-cell styles). |
| `send_keys` | Send named keys (`Enter`, `C-c`, `M-x`, `Up`, `F1`, …) and/or raw text. |
| `wait_for_text` | Block until a substring or regex appears on screen. |
## Build
Requires Zig 0.15.x on `PATH` (used by `libghostty-vt-sys` to build the native
VT engine) and Rust ≥ 1.93.
```sh
cargo build --release
```
Binary at `target/release/vterm-mcp`.
## Register with Claude Code
Add to `~/.claude.json` under `mcpServers`:
```json
"vterm": { "command": "/absolute/path/to/target/release/vterm-mcp" }
```
## Key notation
`Enter Tab Esc Backspace Delete Up Down Left Right Home End PageUp PageDown
Insert Space F1..F12`. Prefix with `C-` (ctrl), `M-` (alt), `S-` (shift),
`D-`/`Super-` — stackable: `C-S-Home`. Single characters (`a`, `7`, `;`) also
accepted.
## Test
```sh
cargo test --release
```
## Future work
- **Image retrieval for kitty graphics / sixel.** libghostty-vt 0.1.x parses
these sequences and reports a "kitty virtual placeholder" flag per row, but
does not expose the image pixel data through its C API. Ghostty 1.4.0 is
tracked to add the missing image APIs — see
<https://github.com/ghostty-org/ghostty/milestone/12>. Once available, extend
`get_screen` to return image payloads instead of just the placeholder flag.