quickshell-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., "@quickshell-mcpscreenshot window 0 and inspect its object tree"
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.
quickshell-mcp
An MCP server that gives a coding agent hands and eyes on a quickshell (QML) app.
Point it at your app. The agent sees screenshots, reads the widget tree, and changes QML state, so it can build a UI and check its own work instead of asking you what the screen looks like.
What the agent does with it
The server drives one app in a loop:
screenshotreturns the window as a PNG.treeandfindmap the widgets and their names.get_property,set_property,invoke,qml_eval, andmacrochange state.screenshotagain shows the result.
The agent learns this loop when it connects.
Every observation puts a PNG in the agent's context.
Related MCP server: kwin-mcp
Does it fit your setup
Your app must be a quickshell config directory with a QML entry file.
screenshot needs each window's content item to hold exactly one visual child
that covers the window.
The agent reaches a widget by its objectName, or by a child-index path from
the window root. A path changes when you edit the layout, so set objectName
on every widget the agent should drive.
The server runs the app under a headless sway with the pixman software
renderer, so it works over SSH and in CI. Linux only, because the app needs a
wayland compositor with layer-shell.
Tested on x86_64-linux and aarch64-linux, if you run other platforms, add i.e. riscv64-linux to flake.nix,
run python examples/check.py, and open a PR with the output.
Nix supplies every dependency: quickshell, sway, and cue.
One server drives one app. You can run more servers for iterating on multiple apps.
Try it
Run the counter example:
nix run github:hsjobeki/quickshell-mcp#demoIt starts a compositor, boots the counter app, drives it, and saves a screenshot per step:
window 0: Counter, 1276x693
count: 0 -> quickshell-mcp-demo/1-start.png
count: 1 -> quickshell-mcp-demo/2-increment.png
count: 41 -> quickshell-mcp-demo/3-macro.png
count: 0 -> quickshell-mcp-demo/4-reset.pngOpen 3-macro.png. The label reads count: 41, set through the server. Those
four PNGs are what your agent sees.
Connect it to your agent
Add the server to your MCP client config, or ask your agent to do it:
{
"mcpServers": {
"quickshell": {
"command": "nix",
"args": [
"run",
"github:hsjobeki/quickshell-mcp",
"--",
"--profile",
"/absolute/path/to/your-app/profile.json"
]
}
}
}The client spawns this command directly, without a shell, so the profile path
is absolute. It speaks MCP over stdio. --profile is required.
The server boots the app on the agent's first tool call and tears everything
down when the client disconnects. nix run re-evaluates the flake on every
start. To cut that from each session, run nix build once and point command
at the absolute path of result/bin/quickshell-mcp.
To point your agent at the counter example instead of your own app, use
github:hsjobeki/quickshell-mcp#counter as the flake reference above and drop
the -- and --profile arguments.
The profile
A profile is a small JSON file, one per app. It tells the server which config directory to run, which entry file to load, which backend processes to start, and which macros to offer.
The smallest profile runs a self-contained app:
{ "config_dir": "." }config_dir is the only required field. It is absolute, or relative to the
profile file. entry defaults to shell.qml.
Inside any string value, ${PROFILE_DIR}, ${CONFIG_DIR}, ${WORK}, and
${XDG_RUNTIME_DIR} expand at boot.
A macro names a QML expression and its parameters, so the agent triggers an app action by name instead of composing the expression:
{
"name": "set_count",
"params": ["n"],
"expr": "(function(){win(0).count=${n};return win(0).count;})()"
}Every field lives in
quickshell_mcp/profile.cue, with a doc-comment
on each. The loader runs cue vet against that schema before boot, so a broken
profile fails at start with the schema error.
Generate a JSON Schema for your editor from the same source:
cue def --out jsonschema -e '#Profile' quickshell_mcp/profile.cueExamples
Each example doubles as an end-to-end test. Its check.py boots it for real
and asserts the states it renders.
python examples/check.py # every example
python examples/check.py counter # one of themcounter: a tiny QML app with one macro.async-form: a form flow over a fake backend on a unix socket. It covers validation, keyed in-flight state, and a streaming setup flow with prompts. Its profile shows a backend with a readiness gate, a seeded fixture, andenv_out. Seeexamples/async-form/README.mdfor the state tables and the selectors.
Contributing
Launch the dev-shell:
nix develop .pytest tests runs the unit tests: they stub the harness, so they need no
compositor. nix flake check runs the same tests in a sandbox. The examples
double as the end-to-end checks and do boot a real compositor:
python examples/check.py.
MCP_BACKEND_DELAY_MS passes to every backend a profile spawns. A backend that
honours it slows async transitions enough to observe them between screenshots.
The agent-facing instructions live in
quickshell_mcp/server.py.
This server cannot be deployed
Maintenance
Related MCP Connectors
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
remote debug iOS/Android/Unity/Godot/Flutter/RN/Web on real-device.ui-tree/screenshots/taps,tests.
- TabfleetOAuthcom.tabfleet
Launch, inspect, control, and share isolated cloud browsers for your agents.
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
Related MCP Servers
- FlicenseNot gradedqualityFmaintenanceProvides screenshot, analysis, mouse and keyboard control tools for modern Linux desktops via Wayland.17-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to automate Linux desktop GUI by launching and interacting with Wayland applications in isolated virtual KWin sessions, or connecting to live desktops for collaborative automation.48MIT
- AlicenseAqualityAmaintenanceMCP server for automating and introspecting native Qt applications (QWidget and QML) without source changes. Enables AI agents to control running Qt apps through UI snapshots, element lookup, and real input simulation.252MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to start and stop local read-only Windows 11 screen observation sessions, then inspect redacted screen state, UI trees, frames, and wait for changes, title matches, or idle periods through stdio tools.Apache 2.0