MCP server for managing persistent terminal sessions using node-pty
Persistent Terminal MCP has visible tool definitions with reasonable schemas and descriptions. However, the evaluation reveals significant gaps in definition quality: (1) Inconsistent description depth, some tools like create_terminal have rich parameter docs while others like open_terminal_ui lack meaningful context. (2) Parameters lack validation constraints, no enum definitions for the 'mode' parameter in read_terminal despite listing valid options ('full', 'head', 'tail', 'head-tail'); LLMs will guess. (3) Missing output schema documentation, no description of what each tool returns; agents cannot plan downstream steps. (4) Error handling guidance absent, tools describe what they do but not how to recover from failures. (5) Security concern: no visible input sanitization for shell execution (create_terminal accepts arbitrary 'shell' and 'env' parameters). (6) Composition issue: two near-identical tools (create_terminal and create_terminal_basic) introduce cognitive load for LLM selection without clear differentiation. The schema for read_terminal has typed parameters but the descriptions do not explain the semantic difference between 'head', 'tail', and 'head-tail' modes clearly enough to guide tool use. Overall, definitions are functional but below production baseline, they lack the LLM-optimized descriptions and error recovery guidance expected of A-grade tools.
Create a new persistent terminal session with optional shell and working directory configuration
Create a new terminal with simplified parameters using default shell
Get statistics about a terminal session including line count, byte size, and estimated token count
Terminate a terminal session
List all active and inactive terminal sessions
Open the web-based UI for terminal management
Read output from a terminal session with multiple reading modes (full, head, tail, head-tail)
Missing output schema documentation for all tools. LLMs cannot plan multi-step workflows or extract downstream data without knowing return types and field names.
Enum constraint missing for 'mode' parameter in read_terminal. Tool description lists valid options ('full', 'head', 'tail', 'head-tail') but parameter is typed as string. LLMs will hallucinate invalid modes like 'last-100' or 'all'. Declare as enum in schema.
Duplicate tool semantics (create_terminal vs create_terminal_basic). Both create terminals with no clear role differentiation in descriptions. LLM must reason which to pick, wasting tokens. Consolidate or explicitly document: when is 'basic' preferred?
Inferred effective spec: 2025-06-18+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 55 | 2025-06-18+ | v2 |
| 2026-03-09 | F | 49 | - | v1 |
Wait for terminal output to stabilize before reading
Send input to a terminal session
Security: create_terminal accepts arbitrary 'shell' and 'env' parameters. No visible input validation or sanitization against command injection or path traversal. Shell parameter should validate absolute paths; env should validate key=value format.
No error recovery guidance. Tools lack descriptions of failure modes and what agents should do next. E.g., 'If terminalId not found, call list_terminals() to see available sessions.' Critical for kill_terminal (destructive operation).
Destructive tool (kill_terminal) lacks confirmation/dry-run pattern. No description of idempotency (safe to retry?). Agents may kill a terminal and then retry, causing confusion.
Parameter validation rules missing. cols, rows (numeric) lack min/max bounds. timeout, stabilityThreshold lack ranges. port (numeric) lacks valid range (1-65535?). LLMs will pass absurd values (cols=0, timeout=999999999, port=99999).
list_terminals lacks pagination support (limit, offset, cursor). If 100+ terminals exist, returning all risks context window exhaustion. Tool description must state result limits and pagination support.
Unclear tool purpose: open_terminal_ui does not explain when an agent should call it. Is it a discovery tool? A browser launcher? Side effects (blocks? spawns subprocess?) are undocumented.
Tool composition: no chaining documentation. E.g., create_terminal returns a terminalId, does write_terminal accept it directly? Must agents know the ID structure? Responses must include all IDs downstream tools need.