hyperb1iss/ghostty-automator-python · Archived

ghostty-terminal-automation

Automate Ghostty terminal sessions via MCP. Use when you need to send commands to terminals, read terminal output, capture screenshots, resize windows, open new tabs/windows, or interact with TUI apps like Neovim, htop, or any CLI tool running in Ghostty.

First seen Jul 2, 2026

Installation

$ npx skills add hyperb1iss/ghostty-automator-python --skill ghostty-terminal-automation

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

License LICENSE
Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,635 B
  • docs SUMMARY.md 290 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Ghostty Terminal Automation

Control Ghostty terminals programmatically via the MCP server. Built on the ghostty-automator library with Playwright-style ergonomics.

Available MCP Tools

list_terminals

List all open terminal surfaces. Returns IDs, titles, dimensions, focus state, and working directory.

[
  {
    "id": "0x13604ba00",
    "title": "~/dev/project",
    "rows": 33,
    "cols": 135,
    "focused": true,
    "pwd": "/Users/bliss/dev/project"
  }
]

terminal

Interact with a specific terminal. Single supertool with 18 actions.

Required: terminal_id, action

Input Actions

Action Params Description
send text Send command + Enter
type text, delay_ms? Type text without Enter
key key, mods? Press key combination

Mouse Actions

Action Params Description
click x, y, button?, mods? Click at position
double_click x, y, button? Double-click
drag fromx, fromy, tox, toy, steps? Drag operation
scroll deltay, deltax?, mods? Scroll terminal

Screen Actions

Action Params Returns
read screen_type? {text, plaintext, cursorx, cursor_y}
cells screen_type? {cells: [...], cursorx, cursory, rows, cols}
screenshot output_path {path}

Waiting Actions (Critical for Automation!)

Action Params Description
wait_text pattern, regex?, timeout_ms? Wait for text/regex to appear
wait_prompt promptpattern?, timeoutms? Wait for shell prompt
wait_idle stablems?, timeoutms? Wait for screen to stabilize

Assertion Actions

Action Params Description
expect text, timeout_ms? Assert text is present
expect_not text, timeout_ms? Assert text is NOT present

Management Actions

Action Params Description
focus - Bring window to front
close - Close terminal
resize rows?, cols? Change dimensions

new_terminal

Create a new Ghostty window or tab.

Param Type Description
type "window" or "tab" Type of terminal to create
command list[str]? Optional command to run

Returns: {terminal_id, title, pwd}

Core Workflow

  1. Discover terminals with list_terminals
  2. Read current state with action="read" to see what's on screen
  3. Send commands with action="send"
  4. Wait for completion with action="waittext" or action="waitprompt"
  5. Verify results by reading again or taking a screenshot

Examples

Run a Command and Wait for Output

1. list_terminals                                    # Get terminal_id
2. terminal(id, action="send", text="npm test")      # Run command
3. terminal(id, action="wait_text", pattern="PASS")  # Wait for result
4. terminal(id, action="read")                       # Read output

Press Keys

# Press Enter
terminal(id, action="key", key="Enter")

# Ctrl+C to interrupt
terminal(id, action="key", key="KeyC", mods="ctrl")

# Arrow keys for navigation
terminal(id, action="key", key="ArrowUp")

# Tab completion
terminal(id, action="key", key="Tab")

# Escape (exit modes in vim, etc)
terminal(id, action="key", key="Escape")

Key names follow W3C standard: Enter, Tab, Escape, Backspace, Delete, Space, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Home, End, PageUp, PageDown, F1-F12, KeyA-KeyZ, Digit0-Digit9.

Type Without Executing

# Type partial input (no Enter)
terminal(id, action="type", text="git commit -m \"")

# Type slowly for effect
terminal(id, action="type", text="Hello", delay_ms=50)

Wait for Shell Prompt

# After running a long command
terminal(id, action="send", text="npm install")
terminal(id, action="wait_prompt")  # Waits for $ or similar
terminal(id, action="send", text="npm start")

Wait for Screen to Stabilize

# For streaming output or animations
terminal(id, action="send", text="curl https://example.com")
terminal(id, action="wait_idle", stable_ms=1000)  # Wait for 1s of no changes

Assertions

# Assert success message appears
terminal(id, action="expect", text="Build successful")

# Assert no errors
terminal(id, action="expect_not", text="ERROR")

Mouse Interactions

# Click at pixel position
terminal(id, action="click", x=100, y=200)

# Double-click to select word
terminal(id, action="double_click", x=100, y=200)

# Drag to select text
terminal(id, action="drag", from_x=50, from_y=100, to_x=200, to_y=100)

# Scroll down
terminal(id, action="scroll", delta_y=3)

Get Styled Cell Data (for TUI inspection)

# Get cell-level data with colors and formatting
terminal(id, action="cells")

# Returns cells with: char, x, y, fg, bg, bold, italic, underline, etc.

Screenshots

terminal(id, action="screenshot", output_path="/tmp/capture.png")
# Then use Read tool on /tmp/capture.png to view

Create New Terminal

# New window
new_terminal(type="window")

# New tab with command
new_terminal(type="tab", command=["python", "-i"])

Working with TUI Apps

Neovim

1. terminal(id, action="send", text="nvim file.py")
2. terminal(id, action="wait_text", pattern="file.py")
3. terminal(id, action="key", key="KeyI")           # Enter insert mode
4. terminal(id, action="type", text="print('hello')")
5. terminal(id, action="key", key="Escape")
6. terminal(id, action="type", text=":wq")
7. terminal(id, action="key", key="Enter")

htop / btop

1. terminal(id, action="send", text="htop")
2. terminal(id, action="wait_idle")                  # Wait for UI to render
3. terminal(id, action="screenshot", output_path="/tmp/htop.png")
4. terminal(id, action="key", key="KeyQ")           # Quit

Python Client

For scripting, use the ghostty-automator library directly:

from ghostty_automator import Ghostty

async with Ghostty.connect() as ghostty:
    # Get first terminal
    terminal = await ghostty.terminals.first()

    # Run command and wait for output
    await terminal.send("ls -la")
    await terminal.wait_for_text("package.json")

    # Assert text present
    await terminal.expect.to_contain("src/")

    # Take screenshot
    await terminal.screenshot("/tmp/result.png")

Sync API also available:

from ghostty_automator.sync_api import Ghostty

with Ghostty.connect() as ghostty:
    terminal = ghostty.terminals.first()
    terminal.send("echo hello")
    terminal.wait_for_prompt()

Tips

  • Always discover first: Call list_terminals before assuming terminal IDs
  • Use wait actions: Don't assume commands complete instantly
  • Read before sending: Check screen state to understand context
  • Use wait_prompt after commands: Ensures shell is ready for next command
  • Use cells for TUI inspection: Get color and style information
  • Screenshot for verification: Visual confirmation of complex operations