A side-by-side look at the Kwin MCP and Desktop Touch MCP MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.
Verdict: choose Kwin MCP for os automation work as a local process; choose Desktop Touch MCP for os automation as a local process. You can also run both side by side in one mcpServers block.
session_start, session_connect, session_stop.DESKTOP_TOUCH_MCP_HOME, GITHUB_TOKEN, GH_TOKEN, DESKTOP_TOUCH_MCP_ALLOW_UNVERIFIED.desktop_discover, desktop_act, desktop_state.Rows where the two servers differ are marked.
| Spec | K Kwin MCP | |
|---|---|---|
| Category | OS Automation | OS Automation |
| Quality signal | 59/100 · Good | 65/100 · Great |
| Install command | Confirmed | Confirmed |
| Transport | Local subprocess (stdio) | Local subprocess (stdio) |
| Auth | No auth required | No auth required |
| Pricing | Free | Free |
| Required env vars | None listed | DESKTOP_TOUCH_MCP_HOMEGITHUB_TOKENGH_TOKENDESKTOP_TOUCH_MCP_ALLOW_UNVERIFIED |
| Verified owner | Community listing | Community listing |
| GitHub stars | 71 | 22 |
| Directory activity | 1 views 0 installs 0 upvotes | 2 views 0 installs 0 upvotes |
| Tools | 29 | 23 |
| Full listing | View Kwin MCP | View Desktop Touch MCP |
session_startStart an isolated virtual KWin Wayland session (one at a time) with its own `dbus-run-session` bus, `kwin_wayland --virtual` compositor, AT-SPI2 bus and EIS input. `screen_width`/`screen_height` must be positive integers. `enable_clipboard=true` serves the clipboard tools (off by default because `w…session_connectAttach to an already running KWin session: the real desktop or a KWin inside a container. Empty values default to `$DBUS_SESSION_BUS_ADDRESS` and `$WAYLAND_DISPLAY` (a socket name is resolved under `$XDG_RUNTIME_DIR`). Clipboard is always enabled. Actions affect real applications, and `window_close…session_stopEnd the current session. Virtual: terminate the whole session process group (`SIGTERM`, then `SIGKILL` for members that remain), KWin, launched apps and the bus. Live: detach, kill only apps launched through kwin-mcp, restore the accessibility switch. Releases all held input and reports it. Idempot…session_infoReport the current session (or `null`): its kind, Wayland socket, bus address, screen size, enabled backends (input, clipboard, accessibility), retention and artifacts directory, every app launched through kwin-mcp, and the held input. Works without a session.app_launchLaunch a program in the session, split with `shlex` (no shell), in its own process group, with stdin closed. `env` adds environment variables for this process. stdout and stderr go to a log file read with `app_log`. An empty command or unbalanced quotes is an error. A failed launch keeps the sessio…app_logReturn the tail of the captured stdout/stderr of an app launched with `app_launch` (`session_info` lists the PIDs). `last_n_lines=0` returns the whole log.screen_captureCapture the whole workspace, or a `region` rectangle of it, as a PNG via KWin ScreenShot2 (Spectacle fallback). Returns a `Frame`: the file path, the `kwin://screenshots/{name}` URI, the image size, `size_kb`, the image-to-logical `mapping` and `coverage`, plus the `Coordinate space` text line. `ma…element_queryReturn the AT-SPI2 elements matching `locator`, in pre-order, with role, name, description, states, rectangle (or the reason it is unavailable), actions, text content (capped at 200 characters), slider/scrollbar value, `app`, `window_id`, `child_count` and a `ref` to use as a target. `locator.match…element_actInvoke a named AT-SPI action (case-insensitive, e.g. `Press`, `Toggle`, `Activate`) on exactly one element without pointer coordinates: `element={ref}` from `element_query`, or `element={strict: Locator}` for a strict search with the same `match` modes (depth 64, fails closed on any unreadable node…window_listList KWin windows, dialogs, popups and shell surfaces included, with `id`, `app_id`, `caption`, `kind`, `active`, `frame` and `client` rectangles, `moveable`/`resizeable`/`closeable`, and `desktops`. `filter` is the same `WindowSelector` the mutators use, applied as an AND-ed filter: `{active: true…desktop_listList KWin virtual desktops in pager order (`id`, `name`) with the current one marked.window_focusRaise and activate exactly one window through KWin scripting (`workspace.activeWindow`). The result reports the window's observed state afterwards, or that it vanished.desktop_discoverObserve the desktop. Returns interactive entities with leases (UIA, CDP, Terminal, Visual SoM).desktop_actPerform actions (click, type, set a value, select) on entities via lease validation. Returns semantic diffs — plus an optional `roiCapture` (changed-region PNG + next-target preview) on visual-only targets.desktop_stateLightweight check of focus, active window, cursor, and Auto-Perception attention signal.screenshotMulti-mode capture: `detail='text'` (UIA/OCR), `diffMode` (P-frame), `dotByDot` (1:1), and `background`. Returns a cheap `screenshot://by-ref/{id}` link to the saved image instead of inlining pixels every time.screenshot_queryInspect and prune the on-disk screenshot cache behind the by-ref links: `screenshot_query` lists saved captures without re-reading pixels; `screenshot_gc` reclaims space by retention policy (dry-run by default).workspace_snapshotInstant session orientation: all window thumbnails + UI summaries in one call.server_statusDiagnostic check for native engine health and feature activation.keyboardSend keyboard input. Supports background input (WM_CHAR) and IME-safe clipboard bypass.mouse_clickPrecision coordinate-based interaction with homing and force-focus protection.scrollMulti-strategy: `raw` (notches), `to_element`, `smart` (virtual lists), and `capture` (stitch).click_elementLegacy UIA-based click by name/ID (fallback when entities are unavailable).browser_openIdempotent debug-mode launch and reliable navigation.Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.
{
"mcpServers": {
"kwin-mcp-2": {
"command": "uvx",
"args": [
"kwin-mcp"
]
}
}
}
{
"mcpServers": {
"harusame64-desktop-touch-mcp": {
"command": "npx",
"args": [
"-y",
"@harusame64/desktop-touch-mcp"
],
"env": {
"DESKTOP_TOUCH_MCP_HOME": "YOUR_DESKTOP_TOUCH_MCP_HOME_HERE",
"GITHUB_TOKEN": "YOUR_GITHUB_TOKEN_HERE",
"GH_TOKEN": "YOUR_GH_TOKEN_HERE",
"DESKTOP_TOUCH_MCP_ALLOW_UNVERIFIED": "YOUR_DESKTOP_TOUCH_MCP_ALLOW_UNVERIFIED_HERE"
}
}
}
}