Terminal Control MCP Server - provides interactive terminal session management for LLM agents with tools for opening sessions, sending input, capturing output, and managing multiple terminal instances via tmux
Terminal Control MCP has well-structured tool definitions with clear naming, detailed descriptions, and complete parameter schemas. All 6 tools follow verb_noun naming convention (list_*, get_*, send_*, open_*, await_*, exit_*). Descriptions are comprehensive (averaging ~300 chars), exceeding the 10-1024 char baseline. Input schemas are present and typed for all tools. However, output schemas are documented only in prose within descriptions rather than as explicit JSON Schema, and error handling lacks actionable recovery guidance. No tool annotations (readOnlyHint/destructiveHint) despite clear risk markers. Security considerations are present but not formalized. The server demonstrates solid foundational quality but misses production-grade polish in output specification and error guidance.
Wait for specific regex pattern to appear in terminal output Parameters (AwaitOutputRequest): - session_id: str - Session ID to monitor - pattern: str - Regular expression pattern to match - timeout: float - Maximum time to wait in seconds (default: 10.0) Returns AwaitOutputResponse with: - success: bool - True if pattern was found before timeout - session_id: str - Echo of the requested session ID - match_text: str | None - The matched text if found, None if timeout - screen_content: str - Current full screen content - elapsed_time: float - Time elapsed before match or timeout - timestamp: str - ISO timestamp when pattern matched/timeout occurred - error: str | None - Error message if operation failed Use with: `open_terminal`, `send_input`, `get_screen_content`, `list_terminal_sessions`, and `exit_terminal`
Close and clean up a terminal session Parameters (DestroySessionRequest): - session_id: str - ID of the session to destroy Returns DestroySessionResponse with: - success: bool - True if session was found and destroyed - session_id: str - Echo of the requested session ID - message: str - "Session destroyed" or "Session not found" Use with: `open_terminal`, `get_screen_content`, `send_input`, `list_terminal_sessions`, and `await_output`
Get terminal content from a session with precise control over what content is returned Parameters (GetScreenContentRequest): - session_id: str - Session ID (from `open_terminal` or `list_terminal_sessions`) - content_mode: "screen" | "since_input" | "history" | "tail" - Content retrieval mode (default: "screen") * "screen": Current visible screen only (default) * "since_input": Output since last input command * "history": Full terminal history * "tail": Last N lines (requires line_count) - line_count: int | None - Number of lines for "tail" mode (ignored for other modes) Returns GetScreenContentResponse with: - success: bool - Operation success status - session_id: str - Echo of the requested session ID - process_running: bool - Whether process is still active - screen_content: str | None - Terminal content based on content_mode - timestamp: str - ISO timestamp when content was captured
Output schemas documented only in prose descriptions, not as formal JSON Schema structures. LLMs cannot parse 'Returns ListSessionsResponse with: success: bool, sessions: List[SessionInfo]' as machine-readable structure. Need explicit jsonschema definitions in tool output declarations.
Tool annotations missing. Tools are marked with Risk levels (READ_ONLY, DESTRUCTIVE, WRITE) in metadata but these are not exposed as toolAnnotations (readOnlyHint, destructiveHint, idempotentHint) in the MCP protocol. Agents cannot determine operation safety from tool definitions alone.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 61 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 45 | - | v1 |
Show all active terminal sessions No parameters required. Returns ListSessionsResponse with: - success: bool - Operation success status - sessions: List[SessionInfo] - List of active sessions with session_id, command, state, timestamps, and web URLs (if web interface enabled) - total_sessions: int - Total number of active sessions (max 50) Use with: `get_screen_content`, `send_input`, `exit_terminal`, `open_terminal`, and `await_output`
Open a new interactive terminal session with specified shell Parameters (OpenTerminalRequest): - shell: str - Shell to use (bash, zsh, fish, sh, etc.) (default: bash) - working_directory: str | None - Working directory to start in (default: current directory) - environment: dict[str, str] | None - Additional environment variables (default: inherit from parent) Returns OpenTerminalResponse with: - success: bool - True if terminal was opened successfully - session_id: str - Unique session identifier for further operations - shell: str - The shell that was opened - web_url: str | None - Web interface URL for this session (if web interface enabled) - screen_content: str | None - Initial terminal screen content - timestamp: str - ISO timestamp when session was created - error: str | None - Error message if failed Use with: `get_screen_content`, `send_input`, `await_output`, `list_terminal_sessions`, and `exit_terminal`
Send input to an interactive terminal session Parameters (SendInputRequest): - session_id: str - Session ID to send input to - input_text: str - Text/commands to send (supports newlines, tabs, special keys like C-c, C-d, etc.) Returns SendInputResponse with: - success: bool - True if input was sent successfully - session_id: str - Echo of the requested session ID - message: str - Status message - screen_content: str | None - Current terminal screen content after input - timestamp: str - When screen was captured - process_running: bool | None - Whether process is still active - error: str | None - Error message if failed Supported special inputs: - "C-c" or "\u0003": Send Ctrl+C (SIGINT) - "C-d" or "\u0004": Send Ctrl+D (EOF) - "C-z" or "\u001a": Send Ctrl+Z (SIGSTOP) - "ENTER" or "\n": Send Enter key - "TAB" or "\t": Send Tab key - "SPACE": Send space character Use with: `open_terminal`, `get_screen_content`, `list_terminal_sessions`, `await_output`, and `exit_terminal`
Error handling lacks actionable recovery guidance. Descriptions mention success/failure bool returns but do not specify what error conditions look like, what values are returned on failure, or what the agent should do next. E.g., 'Session not found' is mentioned but not formalized as error response structure.
Parameter dependencies undocumented. get_screen_content has a conditional dependency: 'line_count' is only meaningful in 'tail' mode but is marked nullable for all modes. The description hints at this but does not explicitly state the mutual exclusivity or validation rules.
Default shell hardcoded to 'bash' in open_terminal. No validation that the specified shell exists on the system. LLM may request 'zsh' or 'fish' and receive silent fallback to bash or an error with no guidance on available shells.
Special key handling in send_input not formally validated. Description lists supported special inputs (C-c, C-d, ENTER, TAB, SPACE) but does not specify what happens if an LLM passes an unsupported special sequence like 'ALT-F2' or 'CTRL-SHIFT-C'.
Timeout behavior in await_output underspecified. Default timeout is 10s, but behavior on timeout is unclear: does the tool return early, or block fully? What is the exact response structure when timeout occurs vs. pattern match? Is match_text null or absent?