UNPKG

mcpretentious

Version:

MCPretentious - Universal Terminal MCP. High-performance terminal automation for iTerm2 (WebSocket) and tmux (control mode). Cross-platform support with cursor position, colors, and layered screenshots.

617 lines (560 loc) 17.5 kB
# MCPretentious API Reference This document contains technical API details for developers who want to understand the tool internals. ## Backend Support MCPretentious supports multiple terminal backends: - **iTerm2** (macOS only): Uses iTerm2's WebSocket API with Protocol Buffers for high-performance control - **tmux** (cross-platform): Works with tmux sessions on Linux, macOS, and other Unix-like systems - **Auto mode**: Automatically selects the best available backend ### Backend Selection Set the backend using the `MCP_TERMINAL_BACKEND` environment variable: - `auto` (default): Automatically detect and use the best available backend - `iterm`: Force iTerm2 backend (macOS only) - `tmux`: Force tmux backend ### Terminal ID Format Terminal IDs vary by backend: - iTerm2: `iterm-{windowId}-{tabIndex}` (e.g., `iterm-12345-1`) - tmux: `tmux:{sessionName}` (e.g., `tmux:mcp-session-123`) ## Available Tools ### `mcpretentious-open` Opens a new terminal session with optional size specification. The backend used depends on availability and configuration (iTerm2 on macOS, tmux on any platform). **Parameters**: - `columns` (number, optional): Initial width in columns (20-500, default: 80) - `rows` (number, optional): Initial height in rows (5-200, default: 24) **Returns**: Terminal ID for subsequent operations **Example Response**: ```json { "terminalId": "iterm-12345-1" // iTerm2 backend // or "terminalId": "tmux:session-name" // tmux backend } ``` ### `mcpretentious-type` Send text and keystrokes to a terminal. **Parameters**: - `terminalId` (string, required): ID of the terminal - `input` (string | number | object | array): Input to send, can be: - **String**: Normal text to type (e.g., `"ls -la"`) - **Number**: ASCII/extended ASCII code 0-255 (e.g., `32` for space, `169` for ©) - **Object**: Special key as `{key: 'name'}` (e.g., `{key: "enter"}`) - **Array**: Mix of the above for complex sequences **Supported Special Keys**: - Navigation: `tab`, `shift-tab`, `enter`, `return`, `escape`, `esc`, `backspace`, `delete` - Arrows: `up`, `down`, `left`, `right` - Movement: `home`, `end`, `pageup`, `pagedown` - Control: `ctrl-a` through `ctrl-z` - Function: `f1` through `f12` ### `mcpretentious-read` Reads the current screen contents from a terminal session. Always returns what's visible on screen (viewport), not scrollback history. **Parameters**: - `terminalId` (string, required): ID of the terminal - `lines` (number, optional): Number of lines to read from the bottom of the screen **Returns**: Plain text of the terminal screen content ### `mcpretentious-close` Closes the terminal session associated with the terminal ID. **Parameters**: - `terminalId` (string, required): ID of the terminal ### `mcpretentious-list` Lists all currently open terminal sessions across all available backends (iTerm2, tmux, etc.). **Returns**: JSON array of session objects with terminal IDs, backend names, and session metadata ### `mcpretentious-info` Gets terminal metadata including dimensions and session information. **Parameters**: - `terminalId` (string, required): ID of the terminal **Returns**: JSON with terminal metadata: - Terminal ID - Session ID - Window ID (if available) - Dimensions (columns × rows) ### `mcpretentious-resize` Resizes a terminal to specified dimensions. **Parameters**: - `terminalId` (string, required): ID of the terminal - `columns` (number, required): Width in columns (20-500) - `rows` (number, required): Height in rows (5-200) **Returns**: Success message with new dimensions ### `mcpretentious-mouse` Send mouse events to a terminal using SGR mouse protocol. Provides direct control over mouse button presses, releases, and drag events. **Parameters**: - `terminalId` (string, required): ID of the terminal to send mouse events to - `event` (string, required): Mouse event type: - `"press"`: Mouse button down - `"release"`: Mouse button up - `"drag"`: Mouse movement with button held down - `x` (number, required): X coordinate (column position, 0-based) - `y` (number, required): Y coordinate (row position, 0-based) - `button` (string, required): Mouse button, can be: - Named buttons: `"left"`, `"middle"`, `"right"`, `"scrollUp"`, `"scrollDown"` - Direct button codes: `"button-0"` through `"button-127"` for SGR protocol codes - `shift` (boolean, optional): Shift key modifier (default: false) - `alt` (boolean, optional): Alt/Option key modifier (default: false) - `ctrl` (boolean, optional): Control key modifier (default: false) **Returns**: Success message with event details **Examples**: ```javascript // Simple left click at position (10, 5) await use_mcp_tool("mcpretentious", "mcpretentious-mouse", { terminalId: "iterm-12345-1", event: "press", x: 10, y: 5, button: "left" }); await use_mcp_tool("mcpretentious", "mcpretentious-mouse", { terminalId: "iterm-12345-1", event: "release", x: 10, y: 5, button: "left" }); // Drag from (5, 5) to (15, 10) await use_mcp_tool("mcpretentious", "mcpretentious-mouse", { terminalId: "iterm-12345-1", event: "press", x: 5, y: 5, button: "left" }); await use_mcp_tool("mcpretentious", "mcpretentious-mouse", { terminalId: "iterm-12345-1", event: "drag", x: 15, y: 10, button: "left" }); await use_mcp_tool("mcpretentious", "mcpretentious-mouse", { terminalId: "iterm-12345-1", event: "release", x: 15, y: 10, button: "left" }); // Right-click with Ctrl held await use_mcp_tool("mcpretentious", "mcpretentious-mouse", { terminalId: "iterm-12345-1", event: "press", x: 20, y: 15, button: "right", ctrl: true }); await use_mcp_tool("mcpretentious", "mcpretentious-mouse", { terminalId: "iterm-12345-1", event: "release", x: 20, y: 15, button: "right", ctrl: true }); // Scroll up await use_mcp_tool("mcpretentious", "mcpretentious-mouse", { terminalId: "iterm-12345-1", event: "press", x: 40, y: 12, button: "scrollUp" }); ``` ### `mcpretentious-screenshot` Takes a layered screenshot of the terminal screen with configurable data layers to minimize output size. **Parameters**: - `terminalId` (string, required): ID of the terminal - `layers` (array, optional): Data layers to include. Default: `["text", "cursor"]`. Options: - `"text"`: Terminal text content - `"cursor"`: Cursor position (absolute and relative) - `"fgColors"`: Foreground color map with palette - `"bgColors"`: Background color map with palette - `"styles"`: Combined style encoding (all attributes in one layer) - `"bold"`: Bold text markers only - `"italic"`: Italic text markers only - `"underline"`: Underline text markers only - `region` (object, optional): Specific viewport rectangle: - `left`: Starting column from left (0-based) - `top`: Starting row from top (0-based) - `width`: Width in columns - `height`: Height in rows - `aroundCursor` (number, optional): Number of lines to show around cursor (e.g., 5 shows 11 lines total) - `compact` (boolean, optional): Skip empty lines and trim trailing spaces. Default: false **Returns**: JSON with layered screen data: ```json { "terminal": { "width": 80, "height": 24 }, "viewport": { "mode": "aroundCursor", // "region", "aroundCursor", or "full" "left": 0, "top": 10, "width": 80, "height": 11 }, "cursor": { "left": 35, // Column position from left "top": 15, // Row position from top "relLeft": 35, // Relative to viewport left "relTop": 5 // Relative to viewport top }, "text": ["line1", "line2", ...], // If "text" layer requested "styles": ["..b..i..u..", ...], // If "styles" layer requested "styleLegend": { // Included with style layers ".": null, "b": "bold", "i": "italic", "u": "underline", "I": "bold+italic", "U": "bold+underline", "J": "italic+underline", "X": "bold+italic+underline" }, "bold": [" X X ", ...], // If "bold" layer requested "italic": [" X X ", ...], // If "italic" layer requested "underline": [" XX", ...], // If "underline" layer requested "fgColors": ["aaabbcccc", ...], // If "fgColors" layer requested "bgColors": ["000000000", ...], // If "bgColors" layer requested "colorPalette": { // Included with color layers "0": null, // default "a": "#ff0000", "b": "#00ff00" } } ``` **Style Encoding**: - Combined styles use single lowercase for single attributes, uppercase for combinations - Individual style layers use 'X' for active, space for inactive - Color layers use single characters mapped to palette entries - Empty/default values can use '.' or '0' for clarity ## Usage Examples for LLM Interaction ### Basic Terminal Interaction ```javascript // Open a new terminal with custom size const terminal = await use_mcp_tool("mcpretentious", "mcpretentious-open", { columns: 120, rows: 40 }); // Returns terminalId like "iterm-12345-1" or "tmux:mcp-session-123" // Get terminal info const info = await use_mcp_tool("mcpretentious", "mcpretentious-info", { terminalId: terminal.terminalId }); // Resize terminal await use_mcp_tool("mcpretentious", "mcpretentious-resize", { terminalId: terminal.terminalId, columns: 80, rows: 24 }); // Execute a command await use_mcp_tool("mcpretentious", "mcpretentious-type", { terminalId: terminal.terminalId, input: ["ls -la", {key: "enter"}] }); // Read the output const output = await use_mcp_tool("mcpretentious", "mcpretentious-read", { terminalId: terminal.terminalId }); ``` ### TUI Application Testing #### Example 1: Minimal Screenshot (text and cursor only) ```javascript const minimalScreen = await use_mcp_tool("mcpretentious", "mcpretentious-screenshot", { terminalId: terminal.terminalId, layers: ["text", "cursor"] }); ``` **Sample Response:** ```json { "terminal": { "width": 80, "height": 24 }, "viewport": { "mode": "full", "left": 0, "top": 0, "width": 80, "height": 24 }, "cursor": { "left": 15, "top": 10, "relLeft": 15, "relTop": 10 }, "text": [ "$ ls -la", "total 64", "drwxr-xr-x 12 user staff 384 Jan 15 10:30 .", "drwxr-xr-x 8 user staff 256 Jan 14 09:15 ..", "-rw-r--r-- 1 user staff 2048 Jan 15 10:30 README.md", "-rw-r--r-- 1 user staff 1024 Jan 15 09:45 package.json", "$ ", "", "", "..." ] } ``` #### Example 2: Screenshot Around Cursor with Styles ```javascript const aroundCursor = await use_mcp_tool("mcpretentious", "mcpretentious-screenshot", { terminalId: terminal.terminalId, layers: ["text", "cursor", "styles"], aroundCursor: 3 }); ``` **Sample Response:** ```json { "terminal": { "width": 80, "height": 24 }, "viewport": { "mode": "aroundCursor", "left": 0, "top": 7, "width": 80, "height": 7 }, "cursor": { "left": 2, "top": 10, "relLeft": 2, "relTop": 3 }, "text": [ "drwxr-xr-x 8 user staff 256 Jan 14 09:15 ..", "-rw-r--r-- 1 user staff 2048 Jan 15 10:30 README.md", "-rw-r--r-- 1 user staff 1024 Jan 15 09:45 package.json", "$ vim README.md", "~", "~", "-- INSERT --" ], "styles": [ "bbbbbbbbbbb...................................", "..............................................", "..............................................", "..bbb.........................................", "I.............................................", "I.............................................", "bbbbbbbbbbbb.................................." ], "styleLegend": { ".": null, "b": "bold", "I": "bold+italic" } } ``` #### Example 3: Region with Colors ```javascript const region = await use_mcp_tool("mcpretentious", "mcpretentious-screenshot", { terminalId: terminal.terminalId, layers: ["text", "fgColors", "bgColors"], region: { left: 0, top: 0, width: 40, height: 5 } }); ``` **Sample Response:** ```json { "terminal": { "width": 80, "height": 24 }, "viewport": { "mode": "region", "left": 0, "top": 0, "width": 40, "height": 5 }, "cursor": { "left": 15, "top": 10, "relLeft": -1, // Cursor is outside viewport "relTop": -1 // Cursor is outside viewport }, "text": [ "$ git status", "On branch main", "Changes not staged for commit:", " modified: README.md", " modified: package.json" ], "fgColors": [ "0000000000000", "aaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "00cccccccccc00ddddddddd", "00cccccccccc00eeeeeeeeeeeee" ], "bgColors": [ "0000000000000", "0000000000000", "0000000000000", "0000000000000", "0000000000000" ], "colorPalette": { "0": null, "a": "#00ff00", "b": "#ffff00", "c": "#ff0000", "d": "#ffffff", "e": "#cccccc" } } ``` #### Example 4: Combined Styles with Colors ```javascript const combined = await use_mcp_tool("mcpretentious", "mcpretentious-screenshot", { terminalId: terminal.terminalId, layers: ["text", "cursor", "styles", "fgColors", "bgColors"], region: { left: 0, top: 5, width: 50, height: 8 } }); ``` **Sample Response:** ```json { "terminal": { "width": 80, "height": 24 }, "viewport": { "mode": "region", "left": 0, "top": 5, "width": 50, "height": 8 }, "cursor": { "left": 25, "top": 8, "relLeft": 25, "relTop": 3 }, "text": [ "┌────────────────────────────────────────────────┐", "│ File Edit View Help │", "├────────────────────────────────────────────────┤", "│ README.md │", "│ ============ │", "│ │", "│ This is **bold** and _italic_ and __underline__│", "│ Combined: ***bold italic*** text │" ], "styles": [ "...................................................", "..bbbb..bbbb..bbbb..bbbb.........................", "...................................................", "..bbbbbbbbb.......................................", "..UUUUUUUUUUUU....................................", "...................................................", "..........bbbbbbbb.....iiiiiiiii....uuuuuuuuuuuu.", "...........XXXXXXXXXXXXXXb........................" ], "styleLegend": { ".": null, "b": "bold", "i": "italic", "u": "underline", "U": "bold+underline", "X": "bold+italic+underline" }, "fgColors": [ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "a0bbbb00bbbb00bbbb00bbbb00000000000000000000000a", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "a0cccccccccc0000000000000000000000000000000000a", "a0dddddddddddddd0000000000000000000000000000000a", "a00000000000000000000000000000000000000000000000a", "a0000000000eeeeeee00000fffffff00000ggggggggggg0a", "a00000000000hhhhhhhhhhhhhhhh00000000000000000000a" ], "bgColors": [ "11111111111111111111111111111111111111111111111111", "10222222222222222222222222222222222222222222221", "11111111111111111111111111111111111111111111111111", "10000000000000000000000000000000000000000000001", "10000000000000000000000000000000000000000000001", "10000000000000000000000000000000000000000000001", "10000000000000000000000000000000000000000000001", "10000000003333333333333300000000000000000000001" ], "colorPalette": { "0": null, "1": "#1e1e1e", "2": "#2d2d30", "3": "#ffff00", "a": "#808080", "b": "#ffffff", "c": "#569cd6", "d": "#4ec9b0", "e": "#ce9178", "f": "#d7ba7d", "g": "#b5cea8", "h": "#c586c0" } } ``` #### Example 5: Individual Style Layers with Compact Mode ```javascript const fullStyles = await use_mcp_tool("mcpretentious", "mcpretentious-screenshot", { terminalId: terminal.terminalId, layers: ["text", "bold", "italic", "underline"], compact: true, aroundCursor: 2 }); ``` **Sample Response:** ```json { "terminal": { "width": 80, "height": 24 }, "viewport": { "mode": "aroundCursor", "left": 0, "top": 8, "width": 80, "height": 5 }, "cursor": { "left": 10, "top": 10, "relLeft": 10, "relTop": 2 }, "text": [ "Welcome to Vim", "Press i for insert mode", "Hello World", "Type :q to quit", "~" ], "bold": [ "XXXXXXXXXXXXXXX ", " X ", "XXXXX XXXXX ", " ", "X " ], "italic": [ " ", " XXXXXXXXXXXXXXXXXXXX ", " ", " XX ", " " ], "underline": [ " ", " ", " XXXXX ", "XXXX ", " " ] } ```