remote_macos_send_keys
Send keyboard input remotely to a macOS machine using key combinations, special keys, or text. Simplifies control of remote systems via MCP server integration.
Instructions
Send keyboard input to a remote MacOs machine. Uses environment variables for connection details.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| key_combination | No | Key combination to send (e.g., 'ctrl+c', 'cmd+q', 'ctrl+alt+delete', etc.) | |
| special_key | No | Special key to send (e.g., 'enter', 'backspace', 'tab', 'escape', etc.) | |
| text | No | Text to send as keystrokes |
Implementation Reference
- src/action_handlers.py:222-353 (handler)The core handler function that implements the remote_macos_send_keys tool. It connects to the remote MacOS via VNC, processes input arguments (text, special_key, or key_combination), maps keys to X11 keysyms, and sends key events using the VNC client.def handle_remote_macos_send_keys(arguments: dict[str, Any]) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: """Send keyboard input to a remote MacOs machine.""" # Use environment variables host = MACOS_HOST port = MACOS_PORT password = MACOS_PASSWORD username = MACOS_USERNAME encryption = VNC_ENCRYPTION # Get required parameters from arguments text = arguments.get("text") special_key = arguments.get("special_key") key_combination = arguments.get("key_combination") if not text and not special_key and not key_combination: raise ValueError("Either text, special_key, or key_combination must be provided") # Initialize VNC client vnc = VNCClient(host=host, port=port, password=password, username=username, encryption=encryption) # Connect to remote MacOs machine success, error_message = vnc.connect() if not success: error_msg = f"Failed to connect to remote MacOs machine at {host}:{port}. {error_message}" return [types.TextContent(type="text", text=error_msg)] try: result_message = [] # Map of special key names to X11 keysyms special_keys = { "enter": 0xff0d, "return": 0xff0d, "backspace": 0xff08, "tab": 0xff09, "escape": 0xff1b, "esc": 0xff1b, "delete": 0xffff, "del": 0xffff, "home": 0xff50, "end": 0xff57, "page_up": 0xff55, "page_down": 0xff56, "left": 0xff51, "up": 0xff52, "right": 0xff53, "down": 0xff54, "f1": 0xffbe, "f2": 0xffbf, "f3": 0xffc0, "f4": 0xffc1, "f5": 0xffc2, "f6": 0xffc3, "f7": 0xffc4, "f8": 0xffc5, "f9": 0xffc6, "f10": 0xffc7, "f11": 0xffc8, "f12": 0xffc9, "space": 0x20, } # Map of modifier key names to X11 keysyms modifier_keys = { "ctrl": 0xffe3, # Control_L "control": 0xffe3, # Control_L "shift": 0xffe1, # Shift_L "alt": 0xffe9, # Alt_L "option": 0xffe9, # Alt_L (Mac convention) "cmd": 0xffeb, # Command_L (Mac convention) "command": 0xffeb, # Command_L (Mac convention) "win": 0xffeb, # Command_L "super": 0xffeb, # Command_L "fn": 0xffed, # Function key "meta": 0xffeb, # Command_L (Mac convention) } # Map for letter keys (a-z) letter_keys = {chr(i): i for i in range(ord('a'), ord('z') + 1)} # Map for number keys (0-9) number_keys = {str(i): ord(str(i)) for i in range(10)} # Process special key if special_key: if special_key.lower() in special_keys: key = special_keys[special_key.lower()] if vnc.send_key_event(key, True) and vnc.send_key_event(key, False): result_message.append(f"Sent special key: {special_key}") else: result_message.append(f"Failed to send special key: {special_key}") else: result_message.append(f"Unknown special key: {special_key}") result_message.append(f"Supported special keys: {', '.join(special_keys.keys())}") # Process text if text: if vnc.send_text(text): result_message.append(f"Sent text: '{text}'") else: result_message.append(f"Failed to send text: '{text}'") # Process key combination if key_combination: keys = [] for part in key_combination.lower().split('+'): part = part.strip() if part in modifier_keys: keys.append(modifier_keys[part]) elif part in special_keys: keys.append(special_keys[part]) elif part in letter_keys: keys.append(letter_keys[part]) elif part in number_keys: keys.append(number_keys[part]) elif len(part) == 1: # For any other single character keys keys.append(ord(part)) else: result_message.append(f"Unknown key in combination: {part}") break if len(keys) == len(key_combination.split('+')): if vnc.send_key_combination(keys): result_message.append(f"Sent key combination: {key_combination}") else: result_message.append(f"Failed to send key combination: {key_combination}") return [types.TextContent(type="text", text="\n".join(result_message))] finally: vnc.close()
- src/mcp_remote_macos_use/server.py:161-173 (registration)Tool registration in the MCP server's list_tools() function, defining the name, description, and input schema for remote_macos_send_keys.types.Tool( name="remote_macos_send_keys", description="Send keyboard input to a remote MacOs machine. Uses environment variables for connection details.", inputSchema={ "type": "object", "properties": { "text": {"type": "string", "description": "Text to send as keystrokes"}, "special_key": {"type": "string", "description": "Special key to send (e.g., 'enter', 'backspace', 'tab', 'escape', etc.)"}, "key_combination": {"type": "string", "description": "Key combination to send (e.g., 'ctrl+c', 'cmd+q', 'ctrl+alt+delete', etc.)"} }, "required": [] }, ),
- src/mcp_remote_macos_use/server.py:268-269 (registration)Dispatch logic in the MCP server's call_tool() handler that routes calls to the remote_macos_send_keys handler function.elif name == "remote_macos_send_keys": return handle_remote_macos_send_keys(arguments)
- src/mcp_remote_macos_use/server.py:36-36 (registration)Import of the handle_remote_macos_send_keys function from action_handlers.py into the server module.handle_remote_macos_send_keys,