hyprland-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@hyprland-mcp Find the 'Login' button on my screen and click it."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
hyprland-mcp
MCP server for Hyprland desktop automation. Gives AI assistants the ability to see the screen, control mouse and keyboard, manage windows, and interact with the desktop — all through Hyprland's native Wayland tools.
Built for Claude Code, but works with any MCP client.
What it does
Screenshots — Capture the full desktop, a specific monitor, window, or region. Images are automatically resized and JPEG-compressed to fit within MCP output limits. Every screenshot includes a coordinate mapping so the AI knows how to translate image positions to screen coordinates.
OCR — Find and click text on screen using Tesseract.
click_text("Send")captures a screenshot, runs OCR, finds the text, and clicks it — all in one tool call. Auto-scopes to the active window for better accuracy.Mouse — Move, click, scroll, and drag. Positioning uses Hyprland's native
movecursor(pixel-accurate, no mouse acceleration issues).Keyboard — Type text or send key combinations. Shortcuts can target specific windows without focusing them.
Window management — List, focus, close, move, resize, fullscreen, and float windows.
Workspaces & monitors — List workspaces, switch between them, query monitor layout and cursor position.
Clipboard — Read and write clipboard text.
App launching — Launch applications through Hyprland (detached, no shell expansion).
Related MCP server: screen-mcp
Requirements
Hyprland (Wayland compositor)
Python 3.10+
System tools:
grim,wtype,ydotool,wl-clipboard,tesseract
The install script checks for all of these and offers to install any that are missing.
Installation
curl -sSL https://raw.githubusercontent.com/alderban107/hyprland-mcp/main/install.sh | bashThe install script handles everything automatically:
Detects your package manager (pacman, apt, dnf, zypper, xbps, emerge, nix)
Installs any missing system dependencies
Installs hyprland-mcp via pipx
Registers the MCP server with Claude Code
Restart Claude Code after installing.
Verify with claude mcp list — you should see hyprland: ✓ Connected.
pipx install git+https://github.com/alderban107/hyprland-mcp.git
claude mcp add --transport stdio --scope user hyprland -- hyprland-mcpOr from a local clone:
git clone https://github.com/alderban107/hyprland-mcp.git
cd hyprland-mcp
python3 -m venv .venv
.venv/bin/pip install -e .
claude mcp add --transport stdio --scope user hyprland -- /path/to/hyprland-mcp/.venv/bin/hyprland-mcpTools (27)
Screenshot & OCR
Tool | Description |
| Capture desktop, monitor, window, or region. Returns inline JPEG + coordinate mapping for translating image positions to screen coordinates. |
| Screenshot + OCR in one call. Returns the image and all detected text. Auto-scopes to active window. |
| Find text on screen via OCR and click it. One tool call replaces screenshot → parse → click. Auto-scopes to active window. |
| Find text on screen via OCR. Returns screen coordinates of all matches, ready for |
| Find a text input field by placeholder text, click it, type, and optionally press Enter. |
Mouse
Tool | Description |
| Move cursor to absolute coordinates (pixel-accurate via Hyprland's |
| Click at position or current location (left/right/middle, single/double) |
| Scroll wheel up/down at position or current location |
| Click-drag from one position to another |
Keyboard
Tool | Description |
| Type text as keyboard input (via |
| Press a key combination like |
| Send a shortcut with explicit modifiers and key, optionally targeting a specific window |
Window Management
Tool | Description |
| List all windows with class, title, size, position (filterable by workspace/monitor) |
| Get details about the currently focused window |
| Focus a window by class or title selector |
| Close a window (WM_CLOSE — apps can show save dialogs) |
| Move a window to a pixel position or workspace |
| Resize a window to exact pixel dimensions |
| Toggle fullscreen or maximize mode |
| Toggle floating mode |
Workspace & Monitor
Tool | Description |
| List connected monitors with resolution, position, refresh rate |
| List active workspaces with window counts |
| Switch to a workspace by name or number |
| Get current cursor position in absolute layout coordinates |
Clipboard & System
Tool | Description |
| Read current clipboard text |
| Write text to clipboard |
| Launch an application (detached, via |
How it works
Screenshot coordinate mapping
Multi-monitor setups and image scaling make coordinate translation tricky. Every screenshot call returns a coordinate mapping alongside the image:
Coordinate mapping: This 941x1030 image covers screen region
starting at absolute (5447, 38), native size 941x1030.
To convert image coordinates to absolute screen coordinates:
screen_x = image_x * 1.00 + 5447
screen_y = image_y * 1.00 + 38This prevents the AI from using image pixel positions directly as screen coordinates — a common failure mode on multi-monitor setups where monitors have different positions in the layout.
OCR and dark themes
Tesseract OCR was designed for black text on white paper. Most desktop apps use dark themes, which tanks OCR accuracy. hyprland-mcp automatically detects dark-background screenshots and inverts them before running OCR, significantly improving text detection.
OCR tools auto-scope to the active window by default (configurable with scope="full" for the entire desktop). Smaller capture area = better OCR accuracy = more reliable coordinate mapping.
Mouse positioning
Mouse movement uses hyprctl dispatch movecursor — Hyprland's native IPC command that sets the cursor to exact pixel coordinates. No mouse acceleration, no relative movement, no coordinate drift. ydotool is only used for click and scroll events (which don't involve positioning).
Screenshot sizing
Screenshots are automatically scaled to fit within MCP output limits. Default: max width 1024px, JPEG quality 60. A 2560x1440 desktop becomes ~80-100KB — small enough for inline display in the conversation.
For reading fine text or UI details, use the region parameter to capture a smaller area at full resolution, or capture a specific window.
Project structure
hyprland_mcp/
server.py # FastMCP instance, all tool definitions, entry point
hyprctl.py # Async wrappers for hyprctl IPC (query, dispatch, batch)
screenshot.py # grim capture + Pillow resize/compress + coordinate mapping
input.py # Mouse (movecursor + ydotool) and keyboard (wtype + sendshortcut)
clipboard.py # wl-copy / wl-paste wrappers
ocr.py # Tesseract OCR with dark-theme preprocessing
errors.py # Exception hierarchy + tool availability checksSafety
close_windowsends WM_CLOSE — apps can show "save changes?" dialogs. There is no force-kill tool.launch_appgoes throughhyprctl dispatch exec— detached from the MCP process, no shell expansion.No file system access — the MCP can see the screen and interact with it, but cannot read or write files.
Missing system tools produce clear error messages listing what to install.
License
MIT
Available Tools
27 toolsclick_textA
Find text on screen and click it — screenshot + OCR + click in one call.
By default, searches only the active window for better accuracy and speed.
Args: target: Text to find and click (case-insensitive) button: Mouse button ("left", "right", "middle") double: Whether to double-click monitor: Limit search to a specific monitor window: Limit search to a specific window (e.g. "class:discord") region: Limit search to a region "X,Y WxH" occurrence: Which match to click if multiple found (1 = first/best, 2 = second, etc.) scope: "auto" (default) searches the active window. "full" searches entire desktop.
Inputs: target (required), button, double, monitor, +4 more. Returns: result
clipboard_readA
Read the current clipboard contents as text.
Inputs: no named parameters. Returns: result
clipboard_writeB
Write text to the clipboard.
Args: text: The text to copy to the clipboard
Inputs: text (required). Returns: result
close_windowA
Close a window (sends WM_CLOSE — apps can show save dialogs).
Args: target: Window selector (e.g. "class:firefox"). If omitted, closes the active window.
Inputs: target. Returns: result
find_text_on_screenA
Find text on screen using OCR. Returns matching locations in screen coordinates.
Take a screenshot, run OCR, and find all occurrences of the target text. Coordinates are in absolute screen space — ready to pass to mouse_click.
Args: target: Text to find (case-insensitive, supports multi-word) monitor: Limit search to a specific monitor window: Limit search to a specific window (e.g. "class:discord") region: Limit search to a region "X,Y WxH" scope: "auto" (default) captures just the active window for better accuracy. "full" captures the entire desktop.
Inputs: target (required), monitor, window, region, +1 more. Returns: result
focus_windowB
Focus a window by class or title.
Args: target: Window selector — "class:firefox", "title:My Document", etc.
Inputs: target (required). Returns: result
get_active_windowB
Get details about the currently focused window.
Inputs: no named parameters. Returns: result
get_cursor_positionA
Get the current cursor position in absolute layout coordinates.
Inputs: no named parameters. Returns: result
key_pressA
Press a key combination.
Uses Hyprland's native sendshortcut — can target specific windows without focusing them.
Args: keys: Key combo string like "ctrl+c", "alt+F4", "super+1", "Return" target: Optional window selector to send the key to (e.g. "class:firefox"). If omitted, sends to the active window.
Inputs: keys (required), target. Returns: result
launch_appB
Launch an application (detached, via Hyprland).
Args: command: The command to run (e.g. "firefox", "kitty", "nautilus ~/Documents")
Inputs: command (required). Returns: result
list_monitorsA
List all connected monitors with resolution, position, and active workspace.
Inputs: no named parameters. Returns: result
list_windowsA
List all open windows with class, title, size, and position.
Args: workspace: Filter to a specific workspace number monitor: Filter to a specific monitor name
Inputs: workspace, monitor. Returns: result
list_workspacesB
List all active workspaces with window counts.
Inputs: no named parameters. Returns: result
mouse_clickA
Click the mouse at a position (or current position if no coordinates given).
Args: button: "left", "right", or "middle" x: X coordinate to click at (optional — clicks at current position if omitted) y: Y coordinate to click at (optional) double: Whether to double-click
Inputs: button, x, y, double. Returns: result
mouse_dragC
Drag from one position to another.
Args: start_x: Starting X coordinate start_y: Starting Y coordinate end_x: Ending X coordinate end_y: Ending Y coordinate button: Mouse button to hold during drag ("left", "right", "middle")
Inputs: start_x (required), start_y (required), end_x (required), end_y (required), +1 more. Returns: result
mouse_moveA
Move the mouse cursor to absolute layout coordinates.
Uses Hyprland's native movecursor — pixel-accurate, no acceleration issues.
Args: x: Target X coordinate y: Target Y coordinate
Inputs: x (required), y (required). Returns: result
mouse_scrollB
Scroll the mouse wheel.
Args: direction: "up" or "down" amount: Number of scroll steps (default 3) x: X coordinate to scroll at (optional) y: Y coordinate to scroll at (optional)
Inputs: direction, amount, x, y. Returns: result
move_windowB
Move a window to a position or workspace.
Args: target: Window selector. If omitted, moves the active window. x: Target X position in pixels y: Target Y position in pixels workspace: Target workspace name/number to move the window to
Inputs: target, x, y, workspace. Returns: result
resize_windowB
Resize a window to exact pixel dimensions.
Args: width: Target width in pixels height: Target height in pixels target: Window selector. If omitted, resizes the active window.
Inputs: width (required), height (required), target. Returns: result
screenshotA
Take a screenshot and return it as an inline image with coordinate mapping.
Returns the image AND a coordinate mapping guide so you can convert image pixel positions to absolute screen coordinates for mouse tools.
Supports three capture modes:
Full desktop/monitor (default): overview at reduced resolution
Window: capture a specific window by class/title
Region: capture a specific rectangle at higher resolution
Args: monitor: Capture a specific monitor (e.g. "DP-1"). Default: all monitors. window: Capture a specific window by selector (e.g. "class:firefox") region: Capture a region as "X,Y WxH" (e.g. "100,200 800x600") max_width: Maximum output width in pixels (default 1024, lower = smaller output) quality: JPEG quality 1-100 (default 60, lower = smaller output) include_cursor: Whether to include the cursor in the screenshot
Inputs: monitor, window, region, max_width, +2 more.
screenshot_with_ocrA
Take a screenshot AND run OCR, returning both the image and extracted text.
More efficient than calling screenshot + find_text_on_screen separately. The text includes screen coordinates for every detected word.
Args: monitor: Capture a specific monitor window: Capture a specific window (e.g. "class:discord") region: Capture a region as "X,Y WxH" max_width: Maximum output width for the image (default 1024) quality: JPEG quality for the image (default 60) scope: "auto" (default) captures the active window. "full" captures entire desktop.
Inputs: monitor, window, region, max_width, +2 more.
send_shortcutB
Send a keyboard shortcut via Hyprland (can target specific windows).
Args: mods: Modifier keys (e.g. "CTRL", "SUPER SHIFT", "ALT CTRL", or "" for none) key: Key name (e.g. "c", "F4", "Return", "space") target: Optional window selector (e.g. "class:firefox"). Empty = active window.
Inputs: mods (required), key (required), target. Returns: result
switch_workspaceB
Switch to a workspace by name or number.
Args: workspace: Workspace name or number (e.g. "1", "3", "special:scratchpad")
Inputs: workspace (required). Returns: result
toggle_floatingB
Toggle floating mode for a window.
Args: target: Window selector. If omitted, toggles the active window.
Inputs: target. Returns: result
toggle_fullscreenA
Toggle fullscreen for the active window.
Args: mode: "fullscreen" for real fullscreen, "maximize" for maximized (keeps bar)
Inputs: mode. Returns: result
type_intoA
Find a text input field, click it, type text, and optionally submit.
Combines focus + OCR + click + type + Enter into one action. Searches for placeholder text in the active window to find the input field.
Args: text: The text to type input_hint: Placeholder or label text near the input field to click on (e.g. "Type a message", "Search", "Message"). If omitted, tries common placeholders. submit: Whether to press Enter after typing (default False) window: Target a specific window (e.g. "class:signal"). Default: active window.
Inputs: text (required), input_hint, submit, window. Returns: result
type_textB
Type text as if from a keyboard.
Args: text: The text to type delay_ms: Delay between keystrokes in milliseconds (0 = instant)
Inputs: text (required), delay_ms. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 27 tools
Most tools have distinct purposes, but there is some overlap between key_press and send_shortcut (both handle keyboard shortcuts) and between find_text_on_screen and screenshot_with_ocr (both involve OCR and text detection). However, descriptions clarify differences like send_shortcut using Hyprland's native method and screenshot_with_ocr combining screenshot and OCR in one call, preventing major confusion.
All tool names follow a consistent snake_case pattern with clear verb_noun structures (e.g., click_text, clipboard_read, focus_window). There are no deviations in naming style, making the set predictable and easy to parse for an agent.
With 27 tools, the count is borderline high for a Hyprland automation server, as it includes many granular actions (e.g., separate mouse_click, mouse_drag, mouse_move). While comprehensive, it may feel heavy and could potentially be streamlined without losing functionality.
The tool set provides extensive coverage for Hyprland window management and automation, including window control (focus, move, resize, close), input simulation (mouse, keyboard, typing), clipboard operations, workspace management, and OCR-based interactions. There are no obvious gaps; agents can perform complex workflows without dead ends.
Maintenance
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
MCP server that lets your AI assistant build and deploy apps, hosting each one at a live URL.
Official MCP server for Agentwork — delegate tasks to AI agents with human-in-the-loop
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA desktop automation MCP server that enables AI agents to interact with Linux environments through screenshots, window inspection, and input simulation. It provides tools for mouse control, keyboard input, and screen capture using xdotool and XDG Desktop Portals.MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP server that gives a model eyes and hands on a Linux Wayland desktop, enabling screenshot capture, mouse/keyboard control, OCR, and icon detection via OmniParser.1-
- AlicenseAqualityAmaintenanceAn MCP server for Hyprland that enables AI agents to control workspaces, windows, mouse, keyboard, and take screenshots on a Wayland desktop.14618 PyPI50MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for controlling Hyprland Wayland compositor: screen capture, mouse/keyboard injection, and automation via native Hyprland IPC and wlr protocols.MIT