
kwin-mcp
io.github.VibeProgrammPublished by GitHub account VibeProgrammv0.9.0Updated Oct 24, 2026
KDE Plasma 6 Wayland GUI automation for AI agents: 30 tools (EIS input, screenshots, AT-SPI2).
Overview
MCP server that lets an AI assistant launch, observe and drive Linux GUI applications on KDE Plasma 6 Wayland, in an isolated virtual session or on a live KWin.
- What you can do
- Start, connect to and stop KWin sessions, virtual or live, and launch apps inside them, list and focus windows, and read app logs or Wayland protocol info and call D-Bus methods in the session. Capture screenshots, optionally as timed frame bursts after an action, and inspect or search the AT-SPI2 accessibility tree and wait for elements to appear. Inject mouse input: click, move, scroll, drag and press or release buttons. Inject keyboard input: type text, type Unicode text, press key combinations and hold or release keys. Inject touch gestures: tap, swipe, pinch and multi-finger swipe. Read and set clipboard text when clipboard support is enabled.
- When to use it
- Use it for end-to-end GUI testing of KDE/Qt/GTK applications, including headless runs in CI, for letting an agent operate desktop apps through the accessibility tree and screenshots, and for live collaboration on a real or containerised KWin desktop.
- Requirements
- Linux with KDE Plasma 6 on Wayland, Python 3.12 or later, and kwin_wayland with virtual-session support, plus libei, spectacle, at-spi2-core, PyGObject and D-Bus bindings. Optional: wl-clipboard for clipboard tools and Unicode typing fallback, wtype for Unicode typing, wayland-utils for protocol listing. Installed from git with uv or pip; no accounts or API keys.
Installation
In SourceWeft
- Open kwin-mcp in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
kwin-mcp
Model Context Protocol server for Linux desktop GUI automation on KDE Plasma 6 Wayland
Actively maintained fork of isac322/kwin-mcp. This fork ships the fixes users were waiting for: MCP Python SDK 2.x support, text input in virtual sessions (host keymap isolation), reliable window focus, bounded startup waits, silent input-drop fix, honest error contracts — see the changelog and releases. Install:
uv tool install git+https://github.com/VibeProgramm/kwin-mcp
[Python 3.12+] [License: MIT] [CI]
A Model Context Protocol (MCP) server that enables AI agents (Claude Code, Cursor, and other MCP clients) to launch, interact with, and observe any Wayland application in a fully isolated virtual KWin session -- without affecting the user's desktop. It also supports live desktop automation by connecting to an existing KWin session (real desktop or container) for collaborative workflows. With 30 MCP tools covering mouse, keyboard, touch, clipboard, accessibility tree inspection, screenshot capture, and window management, kwin-mcp provides everything needed for end-to-end GUI testing and desktop automation on Linux.
Table of Contents
- Why kwin-mcp?
- Use Cases
- Quick Start
- Configuration
- Available Tools
- How It Works
- System Requirements
- Installation
- Limitations
- Contributing
- License
Why kwin-mcp?
- Isolated sessions -- Each session runs in its own
dbus-run-session+kwin_wayland --virtualsandbox. Your host desktop is never affected. - Live session support -- Connect to a real KDE Plasma desktop or a KWin instance inside a container (e.g.
systemd-nspawn) for collaborative "share my screen" workflows. - No screenshots required for interaction -- The AT-SPI2 accessibility tree gives the AI agent structured widget data (roles, names, coordinates, states, available actions), so it can interact with UI elements without relying solely on vision.
- Zero authorization prompts -- Uses KWin's private EIS (Emulated Input Server) D-Bus interface directly, bypassing the XDG RemoteDesktop portal. No user confirmation dialogs.
- Works with any Wayland app -- Anything that runs on KDE Plasma 6 Wayland works: Qt, GTK, Electron, and more. Input is injected via the standard
libeiprotocol. - Full input coverage -- Mouse, keyboard, multi-touch, and clipboard -- all injected through the isolated session for complete desktop automation.
Use Cases
Automated GUI Testing
Run end-to-end GUI tests for KDE/Qt/GTK applications in headless isolated sessions. kwin-mcp launches each app in its own virtual KWin compositor, interacts via mouse, keyboard, and touch input, then verifies results through screenshots and the accessibility tree -- all without a physical display.
AI-Driven Desktop Automation
Let AI agents like Claude Code autonomously operate desktop applications. The agent reads the accessibility tree to understand the UI, performs actions through 30 MCP tools, and observes the results via screenshots -- creating a complete feedback loop for any Wayland application.
Live Desktop Collaboration
Connect to your real desktop session and let Claude observe and interact with what you see. Use session_connect or pass --default-live-session to make live mode the default. Also supports attaching to KWin running inside containers (e.g. systemd-nspawn) for isolated agent desktops.
Headless GUI Testing in CI/CD
Integrate Linux desktop GUI testing into CI/CD pipelines. kwin-mcp's virtual sessions require no X11 or physical display server, making it suitable for headless environments like GitHub Actions or GitLab CI runners on Linux.
Kiosk and Embedded Device Automation
Automate kiosk interfaces and embedded Linux desktops running KDE Plasma or a bare KWin Wayland compositor. Use session_start for isolated virtual testing of kiosk UIs, or session_connect to attach directly to a live kiosk or embedded device session for real-time automation and diagnostics.
Quick Start
Requires KDE Plasma 6 on Wayland. See System Requirements for details.
1. Install
2. Configure Claude Code
Add to your project's .mcp.json:
3. Use it
Ask Claude Code to launch and interact with any GUI application:
Claude Code will autonomously start an isolated session, launch the app, read the accessibility tree to find buttons, click them, and take a screenshot to verify the result.
Configuration
Recommended: install as a plugin
The fastest way to wire kwin-mcp into your editor is to install one of the bundled plugins. Each plugin auto-registers the MCP server and ships the kwin-desktop-automation skill, which teaches the agent which tool to call when (session-mode selection, the observe → act → verify loop, US-QWERTY vs Unicode typing, AT-SPI2 coordinate translation, and other platform pitfalls).
Claude Code — install the plugin from the marketplace:
OpenCode — add the npm plugin to your opencode.json:
For the full integration guide (manual fallback, customising the skill, troubleshooting), see docs/ai-agent-integration.md.
Claude Code
Add to your project's .mcp.json:
Or if installed globally:
Claude Desktop
Add to your claude_desktop_config.json:
Running Directly
Available Tools
Session Management (3 tools)
Observation (3 tools)
Mouse Input (6 tools)
Keyboard Input (5 tools)
Touch Input (4 tools)
Clipboard (2 tools)
Window Management (3 tools)
UI Polling (1 tool)
Advanced (3 tools)
Frame capture: Many action tools accept an optional
screenshot_after_msparameter (e.g.,[0, 50, 100, 200, 500]) that captures screenshots at specified delays (in milliseconds) after the action completes. This is useful for observing transient UI states like hover effects, click animations, and menu transitions without extra MCP round-trips. Frame capture uses the fast KWin ScreenShot2 D-Bus interface (~30-70ms per frame).
How It Works
Triple Isolation (+ Optional Home Isolation)
kwin-mcp provides three layers of isolation from the host desktop:
- D-Bus isolation --
dbus-run-sessioncreates a private session bus. The isolated session's services (KWin, AT-SPI2, portals) are invisible to the host. - Display isolation --
kwin_wayland --virtualcreates its own Wayland compositor with a virtual framebuffer. No windows appear on the host display. - Input isolation -- Input events are injected through KWin's EIS interface into the isolated compositor only. The host desktop receives no input from kwin-mcp.
- Home directory isolation (optional) -- When
isolate_home=trueis set insession_start, a temporary HOME directory is created with isolated XDG directories (XDG_CONFIG_HOME,XDG_DATA_HOME,XDG_CACHE_HOME,XDG_STATE_HOME). Apps in the session cannot read or modify host user settings (e.g.~/.config/kdeglobals), improving test reproducibility and safety.XDG_RUNTIME_DIRis intentionally not isolated because the Wayland socket resides there.
Input Injection
Mouse, keyboard, and touch events are injected through KWin's private org.kde.KWin.EIS.RemoteDesktop D-Bus interface. This returns a libei file descriptor that allows low-level input emulation without requiring the XDG RemoteDesktop portal (which would show a user authorization dialog). The connection uses:
- Absolute pointer positioning for precise coordinate-based interaction
- evdev keycodes with full US QWERTY mapping for keyboard input
- Smooth drag interpolation (10+ intermediate steps) for realistic drag operations
- EIS touch emulation for multi-touch gestures (tap, swipe, pinch, multi-finger swipe)
Screenshot Capture
The screenshot tool captures via the KWin org.kde.KWin.ScreenShot2 D-Bus interface (~30-70ms per frame), with spectacle CLI as a fallback. For action tools with the screenshot_after_ms parameter, the same D-Bus interface is used for fast burst capture. Raw ARGB pixel data is read from a pipe and converted to PNG using Pillow.
Accessibility Tree
The AT-SPI2 accessibility bus within the isolated session is queried via PyGObject (gi.repository.Atspi). This provides a structured tree of all UI widgets with their roles (button, text field, menu item, etc.), names, states (focused, enabled, visible, etc.), screen coordinates, and available actions (click, toggle, etc.).
System Requirements
Optional dependencies:
Installing System Dependencies
Arch Linux / Manjaro
Fedora (KDE Spin)
openSUSE (KDE)
Kubuntu / KDE Neon
Installation
Note: the
kwin-mcpname on PyPI tracks the upstream project (isac322/kwin-mcp, v0.7.0, MCP SDK 1.x). This repository is the actively maintained fork (v0.9.0, MCP SDK 2.x); install it from git or from a source checkout. Theuvx kwin-mcpconfig examples in the Configuration section resolve to the PyPI package.
Using uv (recommended)
Using pip
From source
Limitations
- US QWERTY keyboard layout only --
keyboard_typesupports US QWERTY only. For non-ASCII text (Korean, CJK, etc.), usekeyboard_type_unicode, which requireswtypeorwl-clipboardinstalled. - KDE Plasma 6+ required -- Older KDE versions or other Wayland compositors (GNOME, Sway) are not supported.
- AT-SPI2 availability varies -- Some applications may not fully expose their widget tree via AT-SPI2.
- Touch input is EIS-emulated -- Touch events are emulated through KWin's EIS interface, not from a real touchscreen device. Most applications handle emulated touch correctly, but some may behave differently from physical touch.
- Clipboard requires opt-in -- Clipboard tools (
clipboard_get,clipboard_set) are disabled by default becausewl-copycan hang in isolated sessions. Enable withenable_clipboard=trueinsession_start, and ensurewl-clipboardis installed. - QMenu (native context menus) may not appear in AT-SPI2 -- Qt's AT-SPI2 bridge has incomplete support for popup menus on Wayland. Context menus may not be visible in
accessibility_treeorfind_ui_elements. Workaround: usescreenshotto visually locate menu items and click by coordinates. - Screen edge triggers do not work with EIS input -- Auto-hide panels and layer-shell trigger strips rely on Wayland surface input routing, which may not respond to EIS-injected pointer events. Workaround: use
dbus_callwith KWin scripting or keyboard shortcuts instead. - AT-SPI2 coordinate translation is best-effort -- Wayland clients report window-local coordinates (they do not know their global screen position by design). kwin-mcp translates them to true screen coordinates using each window's compositor-side geometry (queried from KWin scripting, matched by caption). If a window cannot be matched, its coordinates fall back to window-local -- cross-reference with
screenshotto disambiguate.
Troubleshooting & Debugging
Verbose libei/EIS diagnostics (KWIN_MCP_DEBUG_EI=1)
Set the environment variable KWIN_MCP_DEBUG_EI=1 to enable verbose
diagnostics for the EIS input injection path (kwin-mcp's direct libei
connection to KWin):
When enabled, the kwin_mcp.input logger is raised to DEBUG level with a
stderr handler and logs EIS device lifecycle events
(ADDED / REMOVED / RESUMED / PAUSED / SEAT_REMOVED), device stalls, and
connection rebuilds. Use it when input injection silently does nothing or
behaves erratically: the log shows whether KWin is pausing/removing its EIS
devices around input bursts and whether kwin-mcp manages to rebuild the
connection.
Other symptoms
- No input backend available in
session_startoutput — KWin did not expose its EIS RemoteDesktop interface; the session degrades to a screenshot/AT-SPI2-only session (no injection). Check the KWin version (Plasma 6 required) and the server log for the degradation reason. keyboard_type_unicodefails in virtual sessions —kwin_wayland --virtualdoes not expose the virtual-keyboard protocolwtypeneeds; the clipboard fallback (requireswl-clipboard) is the primary path there.
Contributing
Contributions are welcome! See CONTRIBUTING.md for development setup, code style guidelines, and the pull request process.
License
Source: README.md at commit 7cef7af
Tools
0Version history
1- v0.9.0LatestSep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts