# kurojs/wayland-mcp architecture

> Architecture diagram of the GitHub repository kurojs/wayland-mcp, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/kurojs/wayland-mcp
- Repository: https://github.com/kurojs/wayland-mcp

## Overview

Wayland MCP Server exposes desktop automation and screen-analysis tools to an MCP client. The principal workflow is a tool request routed by the server to screen capture or pointer/keyboard control; capability probing selects suitable backends, while optional VLM providers analyze or compare captured images. Action chains compose multiple automation operations. The README documents these capabilities, but several provider and backend implementations were not sampled, so those branches are represented at their supported directory paths; uncertain internal calls are omitted.

Main entry points: [`wayland_mcp/server_mcp.py`](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/server_mcp.py) (Tool server), [`wayland_mcp/backends/detect.py`](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/detect.py) (Backend selection), [`wayland_mcp/backends`](https://github.com/kurojs/wayland-mcp/tree/main/wayland_mcp/backends) (Input backends), [`wayland_mcp/screen_utils.py`](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/screen_utils.py) (Screen utilities)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["MCP interface"]
  node_server["Tool server<br/>[server_mcp.py]"]
end

subgraph group_workflow["Desktop workflows"]
  node_chain["Action chains<br/>[chain_processor.py]"]
  node_screen["Screen utilities<br/>[screen_utils.py]"]
  node_capture["Screen capture<br/>[app.py]"]
  node_rulers["Ruler overlays<br/>[add_rulers.py]"]
  node_vlm["Image analysis<br/>[app.py]"]
  node_pointer["Pointer control<br/>[mouse_utils.py]"]
  node_keyboard["Keyboard control<br/>[keyboard_utils.py]"]
end

subgraph group_selection["Backend selection"]
  node_capabilities["Capability probes<br/>[base.py]"]
  node_selector["Backend selection<br/>[detect.py]"]
end

subgraph group_integrations["System integrations"]
  node_capture_backends["Capture backends"]
  node_input_backends["Input backends"]
  node_portal["Portal transport<br/>[portal.py]"]
  node_keycodes["Key translation<br/>[keycodes.py]"]
  node_keymap["Evemu keymap<br/>[keymap.py]"]
  node_session["Session recovery<br/>[session_env.py]"]
  node_state["Restore token<br/>[input_portal.py]"]
end

node_client(("MCP client"))
node_vision_provider["Vision API"]
node_desktop["Wayland desktop"]

node_client -->|"sends tools"| node_server
node_server -->|"dispatches chains"| node_chain
node_server -->|"calls analysis"| node_screen
node_server -->|"routes pointer tools"| node_pointer
node_server -->|"routes keyboard tools"| node_keyboard
node_server -->|"recovers variables"| node_session
node_chain -->|"runs pointer actions"| node_pointer
node_chain -->|"runs keyboard actions"| node_keyboard
node_screen -->|"captures images"| node_capture
node_screen -->|"adds overlays"| node_rulers
node_screen -->|"requests analysis"| node_vlm
node_vlm -->|"sends images"| node_vision_provider
node_capture -->|"selects backend"| node_selector
node_selector -->|"probes system"| node_capabilities
node_selector -->|"selects capture"| node_capture_backends
node_selector -->|"selects input"| node_input_backends
node_capture_backends -.->|"captures screen"| node_desktop
node_pointer -->|"selects backend"| node_selector
node_keyboard -->|"selects backend"| node_selector
node_input_backends -.->|"injects input"| node_desktop
node_input_backends -->|"uses portal calls"| node_portal
node_input_backends -->|"translates keys"| node_keycodes
node_input_backends -->|"maps evemu keys"| node_keymap
node_portal -->|"persists restore token"| node_state

click node_server "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/server_mcp.py"
click node_chain "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/chain_processor.py"
click node_screen "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/screen_utils.py"
click node_capture "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/app.py"
click node_rulers "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/add_rulers.py"
click node_vlm "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/app.py"
click node_pointer "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/mouse_utils.py"
click node_keyboard "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/keyboard_utils.py"
click node_capabilities "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/base.py"
click node_selector "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/detect.py"
click node_capture_backends "https://github.com/kurojs/wayland-mcp/tree/main/wayland_mcp/backends"
click node_input_backends "https://github.com/kurojs/wayland-mcp/tree/main/wayland_mcp/backends"
click node_portal "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/portal.py"
click node_keycodes "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/keycodes.py"
click node_keymap "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/keymap.py"
click node_session "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/session_env.py"
click node_state "https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/input_portal.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_server,node_client toneBlue
class node_chain,node_screen,node_capture,node_rulers,node_vlm,node_pointer,node_keyboard toneAmber
class node_capabilities,node_selector,node_vision_provider toneMint
class node_capture_backends,node_input_backends,node_portal,node_keycodes,node_keymap,node_session,node_state toneRose
class node_desktop toneIndigo
```

## Components

### MCP interface

- [Tool server](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/server_mcp.py): `wayland_mcp/server_mcp.py`

### Desktop workflows

- [Action chains](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/chain_processor.py): `wayland_mcp/chain_processor.py`
- [Screen utilities](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/screen_utils.py): `wayland_mcp/screen_utils.py`
- [Screen capture](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/app.py): `wayland_mcp/app.py`
- [Ruler overlays](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/add_rulers.py): `wayland_mcp/add_rulers.py`
- [Image analysis](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/app.py): `wayland_mcp/app.py`
- [Pointer control](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/mouse_utils.py): `wayland_mcp/mouse_utils.py`
- [Keyboard control](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/keyboard_utils.py): `wayland_mcp/keyboard_utils.py`

### Backend selection

- [Capability probes](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/base.py): `wayland_mcp/backends/base.py`
- [Backend selection](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/detect.py): `wayland_mcp/backends/detect.py`

### System integrations

- [Capture backends](https://github.com/kurojs/wayland-mcp/tree/main/wayland_mcp/backends): `wayland_mcp/backends`
- [Input backends](https://github.com/kurojs/wayland-mcp/tree/main/wayland_mcp/backends): `wayland_mcp/backends`
- [Portal transport](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/portal.py): `wayland_mcp/backends/portal.py`
- [Key translation](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/keycodes.py): `wayland_mcp/backends/keycodes.py`
- [Evemu keymap](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/keymap.py): `wayland_mcp/keymap.py`
- [Session recovery](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/session_env.py): `wayland_mcp/session_env.py`
- [Restore token](https://github.com/kurojs/wayland-mcp/blob/main/wayland_mcp/backends/input_portal.py): `wayland_mcp/backends/input_portal.py`

### Other components

- **MCP client**
- **Vision API**
- **Wayland desktop**

## Connections

- MCP client → Tool server: sends tools (evidence: `README.md`)
- Tool server → Action chains: dispatches chains (evidence: `wayland_mcp/server_mcp.py`)
- Tool server → Screen utilities: calls analysis (evidence: `wayland_mcp/server_mcp.py`)
- Tool server → Pointer control: routes pointer tools (evidence: `wayland_mcp/server_mcp.py`)
- Tool server → Keyboard control: routes keyboard tools (evidence: `wayland_mcp/server_mcp.py`)
- Tool server → Session recovery: recovers variables (evidence: `wayland_mcp/server_mcp.py`)
- Action chains → Pointer control: runs pointer actions (evidence: `README.md`)
- Action chains → Keyboard control: runs keyboard actions (evidence: `README.md`)
- Screen utilities → Screen capture: captures images (evidence: `wayland_mcp/screen_utils.py`)
- Screen utilities → Ruler overlays: adds overlays (evidence: `wayland_mcp/screen_utils.py`)
- Screen utilities → Image analysis: requests analysis (evidence: `wayland_mcp/screen_utils.py`)
- Image analysis → Vision API: sends images (evidence: `wayland_mcp/app.py`)
- Screen capture → Backend selection: selects backend (evidence: `wayland_mcp/app.py`)
- Backend selection → Capability probes: probes system (evidence: `wayland_mcp/backends/detect.py`)
- Backend selection → Capture backends: selects capture (evidence: `wayland_mcp/backends/detect.py`)
- Backend selection → Input backends: selects input (evidence: `wayland_mcp/backends/detect.py`)
- Capture backends → Wayland desktop: captures screen (evidence: `README.md`)
- Pointer control → Backend selection: selects backend (evidence: `wayland_mcp/mouse_utils.py`)
- Keyboard control → Backend selection: selects backend (evidence: `wayland_mcp/keyboard_utils.py`)
- Input backends → Wayland desktop: injects input (evidence: `README.md`)
- Input backends → Portal transport: uses portal calls (evidence: `wayland_mcp/backends/input_portal.py`)
- Input backends → Key translation: translates keys (evidence: `wayland_mcp/backends/input_portal.py`)
- Input backends → Evemu keymap: maps evemu keys (evidence: `wayland_mcp/backends/input_evemu.py`)
- Portal transport → Restore token: persists restore token (evidence: `wayland_mcp/backends/input_portal.py`)
