Model Context Protocol implementation for Tabby terminal emulator, providing tools for terminal session management and command execution
The Tabby MCP Server exposes 4 terminal interaction tools with reasonable naming (verb_noun pattern: get_*, exec_*) and comprehensive descriptions. However, significant gaps exist in schema completeness, parameter validation, and error handling. Tools 1, 3, and 4 have well-written descriptions (150-300 chars, exceeding baseline 72 chars for params), but Tool 2 (exec_command) lacks detailed parameter descriptions. Input schemas are present and use proper JSON Schema with type definitions, but lack enum constraints and min/max bounds for numeric parameters. Error handling includes documented error messages but lacks recovery guidance (e.g., 'try search_users() first'). Security review: no credentials in parameters (acceptable for terminal SSH wrapper), but no permission gates or audit trail patterns visible. Tool composition is sound, each tool has one responsibility, but the schema for exec_command lacks clarity on optional parameters and timeout behavior.
Executes a shell command in a terminal session and retrieves the output. This tool allows executing shell commands in terminal sessions and handles command execution, output capture, and result formatting.
Retrieves the full or paginated output of a previously executed command using its outputId. USE CASES: - Get the complete output of a command that was truncated - Retrieve specific portions of a long command output - Access historical command results LIMITATIONS: - The outputId must be from a recent command execution - Maximum of 250 lines can be retrieved in a single request - Command output is stored temporarily and may be lost after session restart RETURNS: { "command": "original command text", "output": "paginated command output text", "promptShell": "shell prompt (e.g., user@host:~$)", "exitCode": 0, // Command exit code "aborted": false, // Whether the command was aborted "pagination": { "startLine": 1, // Starting line of this page "endLine": 250, // Ending line of this page "totalLines": 1000, // Total lines in the complete output "part": 1, // Current page number "totalParts": 4, // Total number of pages "maxLines": 250 // Maximum lines per page } } RELATED TOOLS: - exec_command: Execute commands and get outputId - get_ssh_session_list: Find available terminal sessions EXAMPLE USAGE: 1. Execute a command: result = exec_command({ command: "find / -name '*.log'" }) 2. If output is truncated, get the outputId from the result 3. Get the first page: get_command_output({ outputId: "abc123", startLine: 1, maxLines: 250 }) 4. Get the next page: get_command_output({ outputId: "abc123", startLine: 251, maxLines: 250 }) POSSIBLE ERRORS: - "Command output with ID {outputId} not found" - The outputId is invalid or expired - "Failed to retrieve command output" - An error occurred while retrieving the output
Returns a list of all available terminal sessions (SSH and local) with their IDs and status information. USE CASES: - Find available terminal sessions before executing commands - Determine which terminal is currently focused - Check terminal activity status RETURNS: An array of terminal session objects with the following structure: [ { "id": "0", // Unique ID to use with other terminal tools "title": "bash", // Terminal title "customTitle": "My Terminal", // User-defined title if set "hasActivity": false, // Whether there is activity in the terminal "hasFocus": true // Whether this terminal is currently focused }, ... ] RELATED TOOLS: - exec_command: Execute commands in a terminal session - get_terminal_buffer: Get the current content of a terminal EXAMPLE USAGE: 1. Get available sessions: get_ssh_session_list() 2. Use the returned ID with exec_command: exec_command({ command: "ls", tabId: "0" }) NOTES: - If no terminal sessions are available, an empty array will be returned - Always check for available sessions before executing commands
exec_command description is minimal (55 chars vs baseline 194 expected) and lacks WHEN to use it, prerequisites, and retry/idempotency guidance. Description: 'Executes a shell command in a terminal session and retrieves the output. This tool allows executing shell commands in terminal sessions and handles command execution, output capture, and result formatting.', repetitive and lacks actionable context for LLM selection.
exec_command input schema lacks descriptions for parameter 'explanation' and is terse for others. Parameter 'maxWaitTime' has no min/max bounds, LLM could pass 0 or 999999999, causing hangs or timeouts. No enum or validation guidance for 'command' parameter.
get_command_output schema lacks min/max for numeric parameters (startLine, maxLines). Spec says maxLines defaults to 250 and maximum is 1000, but schema does not enforce bounds, LLM could request 0 or negative lines. Parameter 'startLine' description mentions '1-based' but schema has no minimum constraint.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 67 | <=2025-11-25 | v2 |
| 2026-03-09 | D | 58 | - | v1 |
Retrieves the current content (text buffer) of a terminal session with options to specify line ranges. USE CASES: - Check the current state of a terminal - Analyze command output after execution - Verify if a command completed successfully - Extract information from the terminal display LIMITATIONS: - Maximum of 200 lines can be retrieved at once - ANSI color codes and formatting are stripped from the output - Very long lines may be wrapped or truncated by the terminal RETURNS: { "lines": ["line1", "line2", ...], // Array of text lines from the terminal "totalLines": 500, // Total number of lines in the buffer "startLine": 1, // The starting line number requested "endLine": 200 // The ending line number returned } RELATED TOOLS: - get_ssh_session_list: Find available terminal sessions - exec_command: Execute commands in a terminal EXAMPLE USAGE: 1. Get all terminal sessions: get_ssh_session_list() 2. Get the last 50 lines: get_terminal_buffer({ tabId: "0", startLine: 1, endLine: 50 }) 3. Get lines 100-200: get_terminal_buffer({ tabId: "0", startLine: 100, endLine: 200 }) POSSIBLE ERRORS: - "No terminal session found with ID {tabId}" - Use get_ssh_session_list to find valid IDs - "Failed to get terminal buffer" - The terminal may be in an invalid state
get_terminal_buffer startLine/endLine parameters lack min/max and type clarity. Description states 'startLine' is from bottom (1-based) and mentions default 1, but schema does not declare minimum: 1 or type number constraints. 'endLine' defaults to -1 for all lines, non-standard convention that could confuse LLMs.
Error responses documented in tool descriptions (e.g., get_command_output lists 'Command output with ID {outputId} not found') but no recovery guidance. Error messages do not suggest next steps: 'The outputId is invalid or expired' does not tell LLM whether to retry, call a different tool, or ask user. Lacks pattern: recovery-guide.
No idempotency or confirmation pattern for exec_command. This tool modifies terminal state (executes commands with side effects). Description does not clarify if retrying the same exec_command with identical params is safe or will execute twice. For destructive commands (e.g., 'rm -rf /'), no dry-run or confirmation option exists.
get_ssh_session_list returns array without pagination or limit. If hundreds of SSH sessions exist, response could bloat context. No documented cap on result size or pagination guidance. Baseline pattern: paginated-result expects offset/limit and total count.
Output schemas for all tools documented in descriptions (RETURNS blocks) but not in formal JSON Schema. Schema definitions visible in Input sections but Output structure is prose-only. This forces LLM to parse natural language rather than read structured type definitions.
exec_command description lacks clarity on what is returned. Tool says 'retrieves the output' but does not specify: Is output truncated? Is there an outputId for pagination? What are the response fields? LLM must infer from get_command_output docs that exec_command returns outputId.