A terminal interaction layer that exposes session lifecycle (create/list/get/delete), I/O (input, resize), output polling, and readiness as MCP tools. Supports both HTTP and stdio transports.
teemule demonstrates solid tool design with clear verb-noun naming (start_session, send_input, read_output) and comprehensive parameter descriptions. All 11 tools have descriptions (avg ~120 chars) and input schemas with typed parameters. However, output schemas are not documented in the visible code, and several tools lack parameter constraints (enums, ranges). Error handling descriptions are minimal, tools do not guide recovery or categorize errors as retryable vs fatal. Risk annotations (WRITE, READ_ONLY, DESTRUCTIVE) are present but not formalized as tool annotations in the MCP schema.
Poll a session until its program appears ready for input (e.g. a prompt was emitted), or until timeout_ms elapses. Defaults to a 2000ms timeout. Returns ready:true once ready.
Close a session and stop tracking it.
Get the summary of a single session by id.
List all currently tracked terminal sessions.
Read output frames captured since a tick (poll snapshot). Frames have monotonically increasing ticks; pass since=0 for all output. Each frame carries a lossy UTF-8 text field plus a base64 payload.
Read the current terminal screen as a cell grid (plus cursor and dimensions) for a session whose profile uses the 'screen' interpreter. The grid reflects the FINAL rendered state — overwritten cells show their latest value, scrolls applied — not every repaint concatenated. Use this to 'see' a TUI the way a human does.
Output schemas not documented. Tools return session summaries, frame lists, screen grids, and readiness flags, but the response structure is not visible in the provided code. LLMs cannot plan downstream calls without knowing what fields to expect.
No parameter constraints (enums, ranges, patterns). 'key' in send_key accepts free-form strings (e.g. 'Up', 'C-c', 'F1') but no enum is declared. 'pace_ms' in type_text has no min/max bounds. LLMs may pass invalid values.
Error handling lacks recovery guidance. Tool descriptions do not explain what errors are possible, whether they are retryable, or what the LLM should do next. E.g., 'unknown session' errors are not mentioned.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | <=2025-11-25 | v2 |
Resize a session's PTY window to the given rows and columns.
Send raw keystrokes/text to a session. If enter is set, a trailing carriage return is appended (terminals use \r for Enter).
Press a named key on a session — Enter, Tab, Esc, Backspace, arrows (Up/Down/Left/Right), Home, End, PageUp/Down, Insert, Delete, F1-F12, plus chords C-<x> (Ctrl), M-<x> / A-<x> (Alt/Meta), S-<arrows> (Shift). teemule emits the canonical xterm bytes; callers never hand-build escape sequences.
Start a terminal session from a registered profile name (preferred) or an ad-hoc command. Returns the session summary.
Type a string into a session in small paced chunks (default 8 runes, ~12ms apart). The pacing fixes burst-write races where a TUI's input parser strands the final byte (the observed 'Enter didn't submit' failure with Claude Code). Set pace_ms=0 to write all bytes in one syscall.
Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are not formalized in the MCP schema. Risk labels (READ_ONLY, WRITE, DESTRUCTIVE) exist in comments but are not machine-readable.
Composition: start_session accepts both 'profile' (registered) and 'command' (ad-hoc), but the mutual exclusivity and precedence are not documented. LLMs may pass both or neither, causing ambiguous failures.