MCP TUI Test
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP TUI Testlaunch htop in buffer mode and capture screen output"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP TUI Test
Like Playwright, but for Terminal User Interfaces
An MCP (Model Context Protocol) server that enables AI assistants to test Terminal User Interface (TUI) applications. This server provides tools to launch, interact with, and verify TUI applications programmatically.
📚 View Documentation
Features
Dual Testing Modes: Choose between stream mode (for CLI tools) or buffer mode (for full TUIs with position awareness)
Launch TUI Applications: Start any terminal-based application with configurable dimensions
Send Keyboard Input: Simulate user typing, special keys, and control combinations
Capture Screen Output: Read and analyze the current terminal display
Position-Based Testing: Verify text at specific screen coordinates (buffer mode)
Cursor Tracking: Monitor cursor position in real-time (buffer mode)
Wait for Text: Asynchronously wait for specific content to appear
Assertions: Verify that expected content is present in the output
Session Management: Run multiple TUI applications simultaneously
Related MCP server: MCP Console Automation Server
Testing Modes
Stream Mode (Default)
Best for: CLI tools, command-line applications, simple interactive programs
Uses: pexpect for stream-based testing
Features: Text matching, pattern waiting, output capture
Example use cases: git, npm, grep, interactive shell scripts
Buffer Mode
Best for: Full TUI applications, ncurses apps, dialog boxes, menus
Uses: pexpect + pyte for screen buffer emulation
Features: All stream features PLUS position-based assertions, cursor tracking, region extraction
Example use cases: htop, vim, dialog, interactive menus
When to use which mode:
Use stream mode for applications that output text sequentially
Use buffer mode for applications that draw complex UIs with cursor movement
Installation
Prerequisites
Python 3.10 or higher
Install
Once published to PyPI, no install is needed — run it straight from uvx:
uvx mcp-tui-testFor development:
uv venv
source .venv/bin/activate
uv pip install -e ".[dev]"Go implementation
A sibling Go implementation lives in go/ — the same tool contract
(same tool names, same structured result shapes, same tui://{session_id}/screen
resource), as a single static binary with zero runtime dependencies:
go install github.com/GeorgePearse/mcp-tui-test/go/cmd/mcp-tui-test@latest{
"mcpServers": {
"tui-test": { "command": "mcp-tui-test" }
}
}Built on the official Go MCP SDK,
creack/pty, and vt10x for buffer-mode screen emulation. The Python package
remains the home of the pytest plugin; the two share the tool schema, so clients
can't tell them apart.
Structured results
Every tool returns structured content (with an output schema), not prose: a
success flag plus typed fields (screen, outcome, passed, row/col,
screen_excerpt on failed assertions, error when something broke). Agents and
scripts branch on fields instead of parsing ✓/✗ strings.
The current screen is also exposed as an MCP resource at
tui://{session_id}/screen.
For harness-side loops, result handling, and session ordering, see Composing TUI tests in a coding harness.
Session limits & cleanup
Sessions are capped and reaped automatically:
MCP_TUI_MAX_SESSIONS(default 8) — launching past the cap returns a structured error.MCP_TUI_SESSION_TTL_S(default 900) — sessions older than this are closed on the next access.Dead processes are reaped on every registry access and reported by
list_sessions.All sessions are force-closed (SIGKILL escalation) at interpreter exit — no zombies.
pytest plugin
The same engine drives deterministic CI tests with no LLM in the loop. Installing
the package registers a tui fixture:
def test_app_header(tui):
s = tui.launch("my-app --demo", mode="buffer", dimensions=(120, 40))
s.wait_until_contains("Dashboard", timeout=10)
s.assert_at("Dashboard", 0, 2)
s.send("q")TuiHandle offers send, send_ctrl, expect, assert_contains, assert_at,
wait_until_contains, screen, line, and cursor; failures raise
AssertionError with the current screen attached. Sessions are closed at test
teardown, pass or fail.
Usage
Running the MCP Server
python server.pyOr if installed as a package:
mcp-tui-testConfigure in Claude Desktop
Add this to your claude_desktop_config.json:
{
"mcpServers": {
"tui-test": {
"command": "uvx",
"args": ["mcp-tui-test"]
}
}
}(A local checkout also works: "command": "python", "args": ["/path/to/mcp-tui-test/server.py"].)
## Available Tools
### `launch_tui`
Launch a TUI application for testing.
**Parameters:**
- `command` (required): The command to launch the TUI application
- `session_id` (optional): Unique identifier for this session (default: "default")
- `timeout` (optional): Command timeout in seconds (default: 30)
- `dimensions` (optional): Terminal dimensions as WIDTHxHEIGHT (default: "80x24")
- `mode` (optional): Testing mode - "stream" or "buffer" (default: "stream")
**Examples:**
```python
# Stream mode for CLI tools
launch_tui(command="python example_tui_app.py", session_id="test1")
# Buffer mode for full TUI applications
launch_tui(command="htop", session_id="test2", mode="buffer", dimensions="120x40")send_keys
Send keyboard input to a TUI application.
Parameters:
keys(required): Keys to send. Use\nfor Enter,\tfor Tab,\x1bfor Escapesession_id(optional): Session identifier (default: "default")delay(optional): Delay in seconds after sending keys (default: 0.1)
Example:
send_keys(keys="1\n", session_id="test1")send_ctrl
Send a Ctrl+Key combination to the TUI application.
Parameters:
key(required): The key to combine with Ctrl (e.g., 'c', 'd', 'z')session_id(optional): Session identifier (default: "default")
Example:
send_ctrl(key="c", session_id="test1")capture_screen
Capture the current screen output of a TUI application.
Parameters:
session_id(optional): Session identifier (default: "default")include_ansi(optional): Whether to include ANSI escape codes in stream mode (default: False)use_buffer(optional): Force buffer/stream mode. Auto-detects if None (default: None)
Examples:
# Auto-detect mode based on session
capture_screen(session_id="test1")
# Force buffer mode capture
capture_screen(session_id="test1", use_buffer=True)expect_text
Wait for specific text to appear in the TUI output.
Parameters:
pattern(required): Text or regex pattern to wait forsession_id(optional): Session identifier (default: "default")timeout(optional): Maximum time to wait in seconds (default: 10)
Example:
expect_text(pattern="Welcome", session_id="test1", timeout=5)assert_contains
Assert that the current screen contains specific text.
Parameters:
text(required): Text to search for in the current screensession_id(optional): Session identifier (default: "default")use_buffer(optional): Check buffer/stream mode. Auto-detects if None (default: None)
Example:
assert_contains(text="Counter value: 1", session_id="test1")assert_at_position (Buffer Mode Only)
Assert that specific text appears at a screen position.
Parameters:
text(required): Text to verify at the positionrow(required): Row number (0-indexed)col(required): Column number (0-indexed)session_id(optional): Session identifier (default: "default")
Example:
# Verify "Error" appears at row 5, column 10
assert_at_position(text="Error", row=5, col=10, session_id="test1")get_cursor_position (Buffer Mode Only)
Get the current cursor position.
Parameters:
session_id(optional): Session identifier (default: "default")
Example:
get_cursor_position(session_id="test1")
# Returns: "Cursor position (session: test1): row 10, column 25"get_screen_region (Buffer Mode Only)
Extract a rectangular region of the screen.
Parameters:
row_start(required): Starting row (0-indexed, inclusive)row_end(required): Ending row (0-indexed, exclusive)col_start(optional): Starting column (0-indexed, inclusive, default: 0)col_end(optional): Ending column (0-indexed, exclusive, default: end of line)session_id(optional): Session identifier (default: "default")
Example:
# Extract rows 5-10, full width
get_screen_region(row_start=5, row_end=10, session_id="test1")
# Extract rows 5-10, columns 20-60
get_screen_region(row_start=5, row_end=10, col_start=20, col_end=60, session_id="test1")get_line (Buffer Mode Only)
Get a specific line from the screen buffer.
Parameters:
row(required): Row number (0-indexed)session_id(optional): Session identifier (default: "default")
Example:
get_line(row=3, session_id="test1")
# Returns: "Line 3 (session: test1): [line content]"close_session
Close a TUI testing session.
Parameters:
session_id(optional): Session identifier (default: "default")
Example:
close_session(session_id="test1")list_sessions
List all active TUI testing sessions.
Example:
list_sessions()Example Test Scenario
Here's how you might use this MCP to test a TUI application:
Launch the application:
launch_tui(command="python example_tui_app.py")Wait for it to load:
expect_text(pattern="Welcome to the Example TUI Application")Interact with it:
send_keys(keys="1\n")Verify output:
assert_contains(text="Hello, TUI Tester!")Clean up:
close_session()
Testing the Example App
This repository includes an example TUI application (example_tui_app.py) that you can use to test the MCP server.
Run it directly:
python example_tui_app.pyOr test it through the MCP:
launch_tui(command="python example_tui_app.py")
send_keys(keys="1\n")
capture_screen()Use Cases
Automated Testing: Verify TUI applications behave correctly
Integration Testing: Test command-line tools and interactive CLIs
Documentation: Generate screenshots and examples from TUI apps
Debugging: Inspect the state of TUI applications during development
CI/CD: Add TUI testing to your continuous integration pipeline
Technical Details
This MCP server uses:
FastMCP: For the MCP server implementation
pexpect: For spawning and controlling terminal applications
pyte: For terminal emulation and screen buffer management (buffer mode)
ScreenSession wrapper: Combines pexpect and pyte for hybrid testing
Architecture
Stream Mode: pexpect directly captures output stream
Buffer Mode: pexpect output → pyte terminal emulator → screen buffer
Auto-detection: Tools automatically use appropriate mode based on session
Limitations
Currently designed for Unix-like systems (Linux, macOS)
Windows support may require modifications (consider using
winptyor similar)Mouse support in TUIs is not currently available
Buffer mode requires slightly more memory for screen emulation
Position-based assertions only work in buffer mode
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
License
MIT License - see LICENSE file for details
Related Projects
Playwright - Browser automation (inspiration for this project)
pexpect - Python module for spawning child applications
pyte - Python terminal emulator
MCP - Model Context Protocol specification
Author
Created for testing TUI applications with AI assistance.
Documentation development
The site uses Material for MkDocs, matching VisionChain and Bayesian Filters.
uv venv .venv-docs
uv pip install --python .venv-docs/bin/python -r docs-requirements.txt
.venv-docs/bin/mkdocs serve
.venv-docs/bin/mkdocs build --strictFor a build you can open directly from disk with local search, use
MKDOCS_OFFLINE=true .venv-docs/bin/mkdocs build --strict --site-dir /tmp/mcp-tui-test-offline.
Offline builds use .html page URLs; normal builds retain the published directory URLs.
Available Tools
12 toolsassert_at_positionB
Assert text appears at (row, col) — buffer mode only.
| Name | Required | Description | Default |
|---|---|---|---|
| col | Yes | ||
| row | Yes | ||
| text | Yes | ||
| session_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | Yes | |
| found | Yes | |
| passed | Yes | |
| success | Yes | |
| expected | Yes | |
| session_id | Yes | |
| screen_excerpt | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It states nothing about what happens on a failed assertion (raise an error? return a boolean? abort the session?) or about success output, which is the single most important behavior for an assert tool. The "buffer mode only" caveat is the only behavioral detail offered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the assertion condition front-loaded and the mode restriction last. No filler, though the em-dash clause is doing a lot of unelaborated work.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Since an output schema exists, return values need not be explained, and the description does state the mode restriction. However, for a zero-annotation, zero-schema-coverage assertion tool it leaves the failure behavior, coordinate conventions, and session parameter unexplained, so it is only minimally viable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It names `text` and implies row/col, but gives no coordinate semantics (0-based vs 1-based, screen vs buffer origin) and never mentions `session_id` at all. Three of four parameters are only implicitly acknowledged.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (assert) and the exact condition tested (`text` at (row, col)), which cleanly separates it from the weaker sibling assert_contains and from expect_text. It stops short of explicitly contrasting itself with those siblings, so it's clear but not fully self-differentiating.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"buffer mode only" is a real usage constraint — it tells the agent this tool is not for screen-scraping assertions — but it is stated as a restriction without naming the alternative (e.g. expect_text / capture_screen) or explaining when buffer mode is the right choice. Usage is implied rather than directed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assert_containsB
Assert the current screen contains text; on failure includes a screen excerpt.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| session_id | No | default | |
| use_buffer | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | Yes | |
| found | Yes | |
| passed | Yes | |
| success | Yes | |
| expected | Yes | |
| session_id | Yes | |
| screen_excerpt | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses failure behavior ('on failure includes a screen excerpt'), which is the key trait of an assertion tool, but says nothing about success behavior, whether it blocks/waits/polls, timeouts, or how failure is signalled to the agent (error vs. status flag).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the assertion condition front-loaded and the failure side-effect appended. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value documentation is not required. For a simple assertion tool that is adequate, but the two undocumented optional parameters and the absence of any annotation coverage or session/buffer semantics leave gaps an agent must guess at.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across three parameters. The description clarifies only `text` (the required match string); `session_id` (which session's screen is asserted) and `use_buffer` (an undocumented anyOf/null flag) get no explanation in either schema or description, leaving real ambiguity for a multi-session tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: assert that the current screen contains `text`. It is clearly distinguished from positional siblings like assert_at_position and get_screen_region, but it does not differentiate itself from the similar-sounding expect_text, which an agent would also consider for this task.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use or when-not-to-use guidance, and never mentions the close alternative expect_text or any prerequisites (e.g. that a TUI session must be launched and active first). Usage is only inferable from the word 'assert'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
capture_screenC
Capture the current screen (buffer display in buffer mode, cleaned stream otherwise).
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | No | default | |
| use_buffer | No | ||
| include_ansi | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| mode | Yes | |
| error | Yes | |
| screen | Yes | |
| success | Yes | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It hints that output shape depends on mode ('buffer display in buffer mode, cleaned stream otherwise'), but never confirms this is a read-only, non-mutating operation, nor describes session prerequisites, error behavior, or how include_ansi interacts with the two output modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with a parenthetical qualifier; no filler or repetition. It is efficient, though the brevity is partly under-specification rather than disciplined conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, but for a zero-annotation, zero-parameter-documentation tool the description is too thin. It leaves mode selection, session targeting, and interaction of include_ansi with the output modes unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across all 3 parameters, so the description must compensate. 'Buffer mode' loosely maps to use_buffer and 'cleaned stream' loosely to include_ansi, but session_id is never mentioned and the default/null semantics of use_buffer are unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Capture the current screen') and the parenthetical clarifies what the capture yields. It implicitly separates this from line/region siblings like get_line and get_screen_region by scoping to the whole screen, though it never names them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to prefer this over get_screen_region, get_line, or get_cursor_position, nor any stated preconditions (e.g., an active session). The agent must infer usage purely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
close_sessionB
Close a session and reap its process.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | Yes | |
| success | Yes | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are absent, so the description carries the full behavioral burden. 'Reap its process' usefully discloses that a backing process is terminated, which goes beyond the tool name, but it omits idempotency, behavior on an unknown/already-closed session, and whether termination is graceful or forced.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence with the effect front-loaded and no filler. Nothing is wasted or buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, but with no annotations and 0% parameter coverage the definition leaves the session targeting (including the 'default' value) and failure behavior entirely unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the single parameter and it does not mention session_id at all. The schema's odd default of 'default' is left unexplained, so an agent gets no help understanding which session is targeted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Close') and resource ('a session'), plus a second effect ('reap its process'). No sibling in the list also closes a session, so the tool is distinguishable, but the description never names the complementary tools (list_sessions, launch_tui) to sharpen the contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use or when-not-to-use guidance, and no alternative is named. That it is the teardown counterpart to launch_tui must be inferred from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
expect_textB
Wait until a regex/text pattern appears in the output (or timeout/EOF).
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | ||
| timeout | No | ||
| session_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | Yes | |
| outcome | Yes | |
| pattern | Yes | |
| success | Yes | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does disclose the key blocking semantics and the two termination conditions (timeout, EOF), which is meaningful for a wait tool. It does not say what happens on timeout (error vs. silent return) or whether this blocks the session, leaving the most important behavioral question unanswered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler. The action, the target, and the exit conditions are all stated up front with no redundant restatement of the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. But for a blocking wait tool with no annotations and undocumented parameters, the definition should at minimum state timeout units and the outcome on timeout. As written, an agent can call it but cannot predict failure behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% with three parameters, so the description must compensate. It clarifies that 'pattern' accepts a regex or plain text and implies the timeout behavior, but the timeout unit (seconds?) is unstated despite a default of 10, and session_id is never mentioned, so the compensation is only partial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Wait until a regex/text pattern appears in the output.' An agent immediately knows this is a blocking wait-for-pattern tool. However, it makes no attempt to distinguish itself from the sibling assert_contains, which presumably serves a similar matching role, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance and no mention of alternatives such as assert_contains or capture_screen. The closest thing to routing information is the parenthetical '(or timeout/EOF)', which describes behavior rather than when to select this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_cursor_positionB
Current cursor (row, col) — buffer mode only.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| col | Yes | |
| row | Yes | |
| error | Yes | |
| success | Yes | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It usefully discloses the 'buffer mode only' scope constraint, which affects invocation validity, but says nothing about what happens in screen mode (error vs. empty result) or whether it is a non-destructive read, leaving a gap for a tool with zero annotation cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short line with zero waste, front-loading the resource and the mode constraint. Nothing is padded or repeated from structured fields beyond the return shape that adds real value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema exists, so return values need not be explained, and the description nonetheless gives the (row, col) shape. For a one-parameter getter with no annotations, however, the undocumented session_id and the unexplained screen-mode behavior leave it only minimally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and there is one parameter (session_id) that the description never mentions. The name and default make it semi-inferable from siblings like list_sessions, but the description does not compensate for the schema's silence on which session is being queried.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and return shape: the current cursor as (row, col). It is distinguishable from siblings like get_screen_region and assert_at_position, though it never names them. The purpose is clear without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'buffer mode only' functions as an explicit exclusion, telling the agent this does not apply to screen mode, which is implied usage guidance. However, no alternative is named (e.g. use get_screen_region or assert_at_position in screen mode), so the routing guidance is incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_lineC
Get one screen-buffer line — buffer mode only.
| Name | Required | Description | Default |
|---|---|---|---|
| row | Yes | ||
| session_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| text | Yes | |
| error | Yes | |
| success | Yes | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and falls short: it implies a read but never states what happens outside buffer mode (error? empty result?), whether it requires an active session, or any other constraint. 'Buffer mode only' hints at a limitation without disclosing its consequence.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the core action front-loaded and no wasted words. The brevity is efficient, though the trailing qualifier is under-explained rather than merely terse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values needn't be described, but the definition still leaves the 'buffer mode' restriction, both undocumented parameters, and the tool's relationship to its many siblings unaddressed. For a 2-param tool with zero annotation and zero schema-description coverage, this is too thin.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so neither 'row' nor 'session_id' is documented anywhere. The description implies a line index via 'one screen-buffer line' but says nothing about valid ranges, the default session, or how row maps to the buffer, so it fails to compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Get one screen-buffer line'), which is clear enough to distinguish from full-screen siblings like capture_screen or get_screen_region. The trailing 'buffer mode only' adds a scope qualifier but never explains what buffer mode is, so the differentiation is only partial.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only usage signal is the cryptic 'buffer mode only' constraint. No sibling tool is named as an alternative, no condition is given for preferring this over get_screen_region or capture_screen, and the mode restriction is left undefined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_screen_regionC
Extract a rectangular screen region — buffer mode only.
| Name | Required | Description | Default |
|---|---|---|---|
| col_end | No | ||
| row_end | Yes | ||
| col_start | No | ||
| row_start | Yes | ||
| session_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| text | Yes | |
| error | Yes | |
| success | Yes | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. 'Buffer mode only' is a genuinely useful operational constraint, but there is no disclosure of the coordinate origin, indexing base, behaviour of the open-ended col_end, error conditions, or session semantics. The rest of the safety and behavior profile is left to inference.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or repetition. It is efficient, though its brevity shades into under-specification rather than active concision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, but with 5 parameters at 0% schema coverage and no annotations, the definition leaves the agent without coordinate conventions, mode limitations, or session behavior. For a region-extraction tool where off-by-one and mode errors are easy, this is too thin.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 5 parameters, so the description must compensate and does not. It never clarifies whether row/col indices are 0-based, whether row_end/col_end are inclusive or exclusive, or what a null col_end (the default) means — precisely the ambiguities that would cause a mis-call.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('extract') and resource ('rectangular screen region'), which naturally distinguishes it from siblings like capture_screen (whole screen) and get_line (single line). It does not explicitly name those siblings, but the scope of the operation is clear from the description alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only guidance is the constraint 'buffer mode only', which tells the agent this won't work in some other (unspecified) mode but never says when to prefer this over capture_screen, get_line, or get_cursor_position, nor what to use instead in non-buffer modes. No conditions, prerequisites, or alternatives are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
launch_tuiB
Launch a TUI application for testing.
Args: command: The command to launch. session_id: Unique identifier for this session. timeout: Default pexpect timeout in seconds. dimensions: Terminal dimensions as WIDTHxHEIGHT. mode: "stream" for CLI tools, "buffer" for full TUIs (position/cursor aware).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | stream | |
| command | Yes | ||
| timeout | No | ||
| dimensions | No | 80x24 | |
| session_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| mode | Yes | |
| error | Yes | |
| width | Yes | |
| height | Yes | |
| command | Yes | |
| success | Yes | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, and it discloses little beyond the parameters. It does not say a session is spawned and must be closed with close_session, whether the call blocks, what happens on timeout, or whether sessions persist across calls. Only the mode distinction (buffer = position/cursor aware) hints at runtime behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single purpose sentence followed by a compact argument list — front-loaded correctly with no padding. Minor waste in restating trivially named parameters ('command: The command to launch'), but nothing obstructive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. However, as a mutation-ish tool that spawns a process with no annotations, the description should cover session lifecycle, error/timeout behavior, and the prerequisite relationship to close_session — none of which appear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description does the documenting: it explains all five parameters, gives units for timeout ('seconds'), a format for dimensions ('WIDTHxHEIGHT'), and semantics for mode. This is a genuine addition over the bare schema, though the entries for command and session_id largely restate their names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Launch a TUI application for testing'), which clearly identifies it as the session-creation entry point among siblings like send_keys, capture_screen, and close_session. It does not explicitly name those siblings or spell out the relationship, so it stops short of 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this versus alternatives, but the mode guidance ('stream' for CLI tools, 'buffer' for full TUIs) implicitly tells the agent which scenario each configuration serves. Usage is implied rather than explicit, and the obvious prerequisite (call this before send_keys/expect_text) is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sessionsA
List active sessions (dead/expired ones are reaped and reported).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| reaped | Yes | |
| success | Yes | |
| sessions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, and it does disclose a non-obvious side effect: dead/expired sessions are 'reaped', meaning this read-like call can mutate session state. That is genuinely useful context an agent would not get from the empty schema, though permissions or failure behavior are not covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with the core action front-loaded and the behavioral caveat in a compact parenthetical. Nothing is wasted and nothing important is buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the zero-parameter schema requires no parameter guidance. The description covers purpose and the reaping side effect; it could say slightly more about what happens if no sessions exist, but it is essentially complete for this tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline of 4 applies. The parenthetical scope note ('active sessions') usefully defines what the empty-argument call returns.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: 'List active sessions' is unambiguous and clearly distinct from the mutation-oriented siblings like close_session and launch_tui. It stops short of explicitly naming a sibling it is not, so it does not reach a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied — an agent can infer this is the discovery/read step before close_session, but the description never states when to call it or when to prefer an alternative. No exclusions or prerequisites are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_ctrlB
Send a Ctrl+ combination (e.g. key='c' sends Ctrl-C).
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | ||
| session_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | Yes | |
| success | Yes | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It conveys the keystroke effect but says nothing about side effects, whether it blocks or waits, what happens on an invalid key, or what error/response results when no matching session exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with the core behavior front-loaded and an inline example that earns its place; there is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema is present, so return values need not be explained. However, for an input-injecting tool with no annotations and a session-scoped parameter, the definition omits session targeting, required session state, and failure behavior — leaving meaningful gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does clarify the required 'key' parameter's meaning via the Ctrl-C example, which is genuinely useful, but the second parameter (session_id, default 'default') is never mentioned, leaving its targeting semantics undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — sending a Ctrl+<key> combination — with a concrete example ('c' sends Ctrl-C) that makes the effect unambiguous. It does not differentiate itself from the sibling send_keys, so an agent must infer that this tool is the Ctrl-modifier specialization.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance: it never says to prefer this over send_keys for modifier combinations, nor when to use plain send_keys instead. The existence of a session_id parameter implies it acts on an existing TUI session, but no precondition (session must exist / be active) is stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_keysC
Send keyboard input. Escapes like \n, \t, \x1b are decoded unless raw=True.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | ||
| keys | Yes | ||
| delay | No | ||
| session_id | No | default |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | Yes | |
| success | Yes | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose one genuinely behavioral fact beyond the schema: escape sequences are decoded unless raw=True. It omits other important traits such as which session receives the input, whether it blocks, and what timing behavior applies, so the disclosure is partial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the core action front-loaded and no filler; the raw-flag caveat is placed immediately after the main verb. It is appropriately sized, though extremely terse for the behavioral burden it must carry.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, but for a 4-parameter, zero-annotation mutation-style tool the definition is under-specified: session targeting, delay semantics, and interaction with expect_text/capture_screen are all absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 4 parameters, so the description must compensate. It partially clarifies 'keys' and 'raw', but says nothing about 'delay' (units? per-key or total?) or 'session_id' (which session is targeted, and the 'default' fallback), leaving half the parameters undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Send keyboard input'), which is unambiguous against read-oriented siblings like get_cursor_position or capture_screen. It does not, however, distinguish itself from the closest sibling send_ctrl, leaving the boundary between 'keys' and 'control keys' implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no when-to-use guidance, no prerequisites (e.g. a session must already be launched via launch_tui), and no routing advice against send_ctrl or expect_text. An agent must infer the intended workflow entirely from context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v0.3.0- First observed
assert_at_position - First observed
assert_contains - First observed
capture_screen - First observed
close_session - First observed
expect_text - First observed
get_cursor_position - First observed
get_line - First observed
get_screen_region - First observed
launch_tui - First observed
list_sessions - First observed
send_ctrl - First observed
send_keys
TDQS
Scored across 12 tools
Session lifecycle (launch_tui, close_session, list_sessions), input (send_keys, send_ctrl), and assertions (assert_contains, assert_at_position) are clearly distinct. There is mild overlap among screen-reading tools (get_line, get_screen_region, capture_screen) and between send_keys/send_ctrl and expect_text/assert_contains, but descriptions resolve these boundaries well.
All names are snake_case and verb-first, which is highly consistent. The only slight wrinkle is that screen reads mix verbs (get_line, get_screen_region vs capture_screen), but each verb still conveys the action clearly.
12 tools is well within the ideal range and each maps to a distinct testing need (session management, input, screen inspection, waiting, assertions). No tool feels redundant or bolted on.
The surface covers the full TUI testing loop: launch/close/list sessions, send input, read screen state, wait for patterns, and assert on content/position. Minor gaps exist — no terminal resize after launch and no mouse/click input — but core workflows are fully supported.
Maintenance
Related MCP Connectors
Launch and verify high-fidelity mobile simulations from an AI agent.
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
- AIVAOAuthworks.aiva
No-code, AI-assisted UI testing: record new tests, run existing ones, and monitor the results.
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI agents to interact with terminal-based TUI applications by capturing visual terminal output as PNG screenshots and simulating keyboard input through a virtual X11 display.42Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to fully interact with console applications, monitor output, detect errors, and automate terminal workflows across multiple sessions. Similar to how Playwright works for web browsers but for command-line interfaces.138 npm52MIT
- AlicenseNot gradedqualityCmaintenanceEnables spawning, interacting with, and capturing screen output from terminal-based programs for debugging PTY/TTY/TUI applications.9 npm7MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to spawn and interact with real terminal sessions, capturing screenshots of rendered TUI output and sharing live sessions for debugging.1 npm1MIT