Skip to main content
Glama
GNOME Desktop MCP
by sbuysse

Gnome-MCP

Desktop automation for GNOME Wayland via MCP. Take screenshots, manage windows, and inject keyboard/mouse input from AI assistants like Claude Code.

GNOME Desktop MCP server

Claude Code  ──MCP──▶  gnome-desktop-mcp (Python)  ──D-Bus──▶  GNOME Shell Extension

Why

GNOME Wayland blocks external processes from taking screenshots or injecting input. This extension runs inside the compositor, bypassing those restrictions, and exposes a D-Bus API. The MCP server bridges that API to any MCP-compatible client.

Related MCP server: deskwright

Features

  • 30 MCP tools: screenshots, window management, input injection, workspace control

  • Privacy indicator: top bar icon shows connection status (red = active, grey = idle)

  • Consent dialog: first-use confirmation before enabling automation

  • Access gating: master kill switch to disable all automation instantly

Requirements

  • GNOME Shell 45-49 (Wayland)

  • Python 3.12+

Installation

Quick install (development)

git clone https://github.com/sbuysse/gnome-mcp.git
cd gnome-mcp
./install.sh

Then log out and back in (required for Wayland), and enable:

gnome-extensions enable desktop-automation@gnomemcp.github.io

MCP server only (from PyPI)

pip install gnome-desktop-mcp

Claude Code Configuration

Add to ~/.claude/settings.json:

{
  "mcpServers": {
    "desktop-automation": {
      "command": "gnome-desktop-mcp"
    }
  }
}

Tools

Screenshots

Tool

Description

screenshot

Full screen capture

screenshot_window

Capture a specific window

screenshot_area

Capture a rectangular region

pick_color

Get pixel color at coordinates

cleanup_screenshots

Remove temp screenshot files

Windows

Tool

Description

list_windows

List all open windows

get_window

Get detailed window properties

focus_window

Focus and raise a window

move_resize_window

Move and resize a window

minimize_window / unminimize_window

Minimize/restore

maximize_window / unmaximize_window

Maximize/restore

close_window

Close a window

list_workspaces

List all workspaces

activate_workspace

Switch workspace

Input

Tool

Description

key_press

Press a single key ("Return", "F5", "a")

key_combo

Key combination ("Ctrl+Alt+t")

type_text

Type text character by character

mouse_move

Move mouse to coordinates

mouse_click

Click at coordinates

mouse_double_click

Double-click

mouse_down / mouse_up

Press/release mouse button

mouse_drag

Drag from point A to point B

mouse_scroll

Scroll at coordinates

Utility

Tool

Description

ping

Check extension is alive

get_enabled / set_enabled

Check/toggle automation

get_monitors

List monitors with geometry

Privacy

  • Top bar indicator shows when automation is active

  • Toggle switch to disable all automation instantly

  • Activity log tracks last 20 method calls (name + timestamp only, no data)

  • D-Bus access gating: all methods blocked when disabled

  • Session bus trust model: any local user process can call the API (consistent with GNOME's security model)

Architecture

The GNOME Shell extension (desktop-automation@gnomemcp.github.io) runs inside the Wayland compositor. It exports io.github.gnomemcp.DesktopAutomation on the session D-Bus with privileged access to:

  • Shell.Screenshot — silent screenshots (no permission dialog)

  • Meta.Window — window management

  • Clutter.VirtualInputDevice — keyboard/mouse injection

The Python MCP server (gnome-desktop-mcp) translates MCP tool calls into D-Bus method calls via dasbus.

Development

# Install in development mode
pip install -e mcp-server[dev]

# Run tests
python -m pytest tests/ -v

# Watch extension logs
journalctl /usr/bin/gnome-shell -f

# Test D-Bus directly
gdbus call --session --dest org.gnome.Shell \
  --object-path /io/github/gnomemcp/DesktopAutomation \
  --method io.github.gnomemcp.DesktopAutomation.Ping

License

GPL-3.0

Available Tools

30 tools
activate_workspaceB

Switch to a workspace by index (0-based).

Inputs: index (required). Returns: result

cleanup_screenshotsB

Remove all temporary screenshot files.

Inputs: no named parameters. Returns: result

close_windowC

Close a window.

Inputs: window_id (required). Returns: result

focus_windowB

Focus and raise a window.

Args: window_id: The window's stable ID (from list_windows).

Inputs: window_id (required). Returns: result

get_enabledB

Check if automation is enabled.

Inputs: no named parameters. Returns: result

get_monitorsB

List all monitors with their geometry and scale.

Inputs: no named parameters. Returns: result

get_windowA

Get detailed properties of a specific window.

Args: window_id: The window's stable ID (from list_windows).

Inputs: window_id (required). Returns: result

key_comboB

Press a key combination.

Args: keys: Combo like "Ctrl+Alt+t", "Shift+F5", "Super+l".

Inputs: keys (required). Returns: result

key_pressA

Press and release a single key.

Args: key: Key name like "Return", "a", "F5", "Ctrl", "Escape".

Inputs: key (required). Returns: result

list_windowsA

List all open windows with their properties.

Returns JSON array with id, title, wmClass, position, size, state, workspace.

Inputs: no named parameters. Returns: result

list_workspacesB

List all workspaces with their properties.

Inputs: no named parameters. Returns: result

maximize_windowB

Maximize a window.

Inputs: window_id (required). Returns: result

minimize_windowC

Minimize a window.

Inputs: window_id (required). Returns: result

mouse_clickA

Click at screen coordinates. button: 1=left, 2=middle, 3=right.

Inputs: x (required), y (required), button. Returns: result

mouse_double_clickB

Double-click at screen coordinates.

Inputs: x (required), y (required), button. Returns: result

mouse_downB

Press mouse button down without releasing.

Inputs: x (required), y (required), button. Returns: result

mouse_dragC

Drag from one position to another.

Inputs: x1 (required), y1 (required), x2 (required), y2 (required), +1 more. Returns: result

mouse_moveA

Move the mouse to absolute screen coordinates.

Inputs: x (required), y (required). Returns: result

mouse_scrollB

Scroll at screen coordinates. dy negative=up, positive=down.

Inputs: x (required), y (required), dx (required), dy (required). Returns: result

mouse_upC

Release mouse button.

Inputs: x (required), y (required), button. Returns: result

move_resize_windowA

Move and resize a window. Unmaximizes first if needed.

Args: window_id: The window's stable ID. x: New X position. y: New Y position. width: New width. height: New height.

Inputs: window_id (required), x (required), y (required), width (required), +1 more. Returns: result

pick_colorA

Get the pixel color at screen coordinates.

Args: x: X coordinate in pixels. y: Y coordinate in pixels.

Returns: JSON with r, g, b values (0.0-1.0).

Inputs: x (required), y (required). Returns: result

pingA

Check if the extension is running and responding.

Inputs: no named parameters. Returns: result

screenshotA

Take a full screenshot of the entire screen.

Args: include_cursor: Whether to include the mouse cursor. format: "path" returns filepath, "base64" returns base64-encoded PNG.

Inputs: include_cursor, format. Returns: result

screenshot_areaA

Take a screenshot of a rectangular screen region.

Args: x: Left edge in pixels. y: Top edge in pixels. width: Width in pixels. height: Height in pixels. include_cursor: Whether to include the mouse cursor. format: "path" returns filepath, "base64" returns base64-encoded PNG.

Inputs: x (required), y (required), width (required), height (required), +2 more. Returns: result

screenshot_windowA

Take a screenshot of a specific window.

Args: window_id: The window's stable ID (from list_windows). include_frame: Whether to include window decorations. include_cursor: Whether to include the mouse cursor. format: "path" returns filepath, "base64" returns base64-encoded PNG.

Inputs: window_id (required), include_frame, include_cursor, format. Returns: result

set_enabledC

Enable or disable automation.

Inputs: enabled (required). Returns: result

type_textB

Type text character by character.

Args: text: Text to type.

Inputs: text (required). Returns: result

unmaximize_windowB

Unmaximize a window.

Inputs: window_id (required). Returns: result

unminimize_windowB

Unminimize (restore) a window.

Inputs: window_id (required). Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 30 tools

    Disambiguation4/5

    Most tools have distinct purposes with clear boundaries, such as separate mouse actions (click, drag, scroll) and window operations (maximize, minimize, move_resize). However, some overlap exists between key_press and key_combo, which could cause confusion if an agent needs to press a single key versus a combination, though descriptions help clarify.

    Naming Consistency5/5

    All tool names follow a consistent snake_case pattern with clear verb_noun structure, such as activate_workspace, close_window, and screenshot_area. There are no deviations in naming conventions, making the set predictable and easy to parse.

    Tool Count3/5

    With 30 tools, the count is borderline high for a desktop automation server, as it includes many granular actions like separate mouse_down and mouse_up. While comprehensive, it may feel heavy and could be streamlined by grouping related operations, though it covers a broad scope reasonably.

    Completeness5/5

    The tool set provides complete coverage for GNOME desktop automation, including window management (list, focus, close, resize), workspace control, input simulation (keyboard, mouse, typing), screenshots (full, area, window), and system checks (ping, enable/disable). No obvious gaps exist; agents can perform end-to-end automation tasks without dead ends.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Linux desktop HAL for AI agents. One daemon, one socket, every desktop action. GNOME, KDE, Hyprland, X11. Ships in one command.
      31
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI agents to operate a real GNOME Wayland desktop through accessibility-tree widget actions, pointer/keyboard input, OCR, window management, and screen capture, optionally on a private headless session.
      33
      11
      Apache 2.0
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to automate and observe Linux desktop GUIs on KDE Plasma 6 Wayland through isolated virtual sessions or live desktop connections, providing 30 tools for input, clipboard, accessibility tree inspection, screenshots, and window management.
      2
      MIT