qt-commander
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| qt_list_processesA | List running Qt processes that may be attachable. |
| qt_attachA | Inject the helper library into a running Qt process and open a session. Find the target pid with qt_list_processes first (only Qt processes are listed, each with its qt_version/arch/bitness). The build artifacts in .qt-commander/bin must match the target process: same Qt major (qt_major used in qt_build), same toolchain (msvc/mingw), same Debug/Release build type, same 64/32-bit — a mismatch makes injection fail with code 2002. A process that is already attached fails with 2006; detach first. If the build has not been completed, this returns error code 2001 with the steps to follow (qt_detect_msvc_and_qt → AskUserQuestion → qt_build → qt_attach again); it does not build automatically. Injection modifies the target process (loads a DLL, starts a local RPC thread/listener). If the target process exits, the session goes dead: operations then fail with connection/timeout errors — check qt_list_sessions and re-attach. |
| qt_detachA | Disconnect from a Qt process session.
|
| qt_list_sessionsA | List all active sessions. |
| qt_detect_msvc_and_qtA | Detect MSVC (Visual Studio), MinGW toolchains, and Qt installations available for building. IMPORTANT — this tool only discovers and displays what is found on this machine. It does NOT select an environment automatically. After calling this tool, the AI MUST use Returns three lists: |
| qt_buildA | Build the Qt injection library and injector for the specified environment.
Before calling this tool, the AI MUST present available build
environments (from The AI MUST also ask the user whether to enable QML/QQuick support
( The AI MUST also ask the user to choose the
|
| qt_snapshotA | Capture the UI element tree of the session's windows. The tree is NOT in this result — it is written to the file exposed at
the returned
ID LIFECYCLE: this call rebuilds the element map, so every element_id and window_id from previous snapshots/finds becomes invalid. The snapshot runs on the target process's GUI thread (brief UI freeze); if the target is busy, calls can time out after ~30s. |
| qt_prune_snapshotA | Occlusion-prune a saved snapshot.
Reads the saved snapshot JSON and computes what is actually visible:
elements fully covered by higher-z opaque elements are removed (their
still-visible descendants are reparented up), partially covered ones
get a The solver is a geometric heuristic (axis-aligned rects, per-window z-order with same-z tree order; widgets and QML rectangles/images occlude unless semi-transparent, transparent containers, text and custom QML components do not; a parent never occludes its own children). Occlusion is per top-level window on purpose: the agent must stay able to operate an app that the user has covered or minimised, so windows never occlude each other. The objIDs in the pruned file expire with the next snapshot/find refresh like any other id. |
| qt_find_elementA | Find UI elements matching a query in a session. Query fields (all AND-ed): Example: {"text_contains": "OK", "type_inherits": "QPushButton", "depth": "shallow"} or {"object_name": "searchBox", "limit": 5}. Result: {"ok": true, "count": N, "elements": [{id, className, objectName, ...}]}; when nothing matches: {"ok": false, "message": "No matching element found"} — adjust the query or set include_hidden: true. No prior snapshot is needed; this call rebuilds the element map itself. ID LIFECYCLE: the rebuild invalidates EVERY element_id/window_id from previous snapshots/finds. Use the returned ids immediately — if an operation reports "Element not found: id=N", the id is stale or the element was destroyed: re-run qt_find_element (or a snapshot) and retry with the fresh id; never reuse old ids. |
| qt_get_propertyA | Read a property from a UI element. Read-only, no side effects on the target. Note: hidden, disabled and zero-size elements are rejected even for reads ("Element is not visible") — pass an id from a recent find/snapshot of a visible element. |
| qt_set_propertyA | Write a property value on a UI element. DESTRUCTIVE: directly modifies the target application's state (may trigger property-notify signals, change geometry/visibility/business state) with no undo. Prefer real user input (clicks/typing) to simulate user actions; use this only when a direct API write is intended.
|
| qt_call_methodA | Invoke a QMetaObject-invokable method on a UI element. DESTRUCTIVE: directly changes the target application's state with no
undo. Methods like |
| qt_screenshotA | Capture a screenshot of a UI element or the entire window.
|
| qt_mouse_clickA | Send a mouse click to a UI element (direct delivery). For plain QtWidgets (QPushButton, QLineEdit, ...) direct delivery
works and is the cheapest option. Use qt_mouse_click_region (element
center) or qt_mouse_click_at (exact coordinates) for QML custom
components (buttons, nav rows, list items) — those route through the
real Qt input pipeline with real hit testing and are far more
reliable. |
| qt_mouse_dbl_clickB | Send a double-click to a UI element (direct delivery). x/y are optional logical-pixel coordinates relative to the element's top-left corner; either both or neither (omitted = element center). |
| qt_mouse_click_atA | Click at an exact window coordinate, exactly like a real mouse click at that position. x/y are relative to the target window's client area (same space as screenshots, logical pixels — DPI is handled internally). The click goes through the real Qt input pipeline, so the hit test (scene graph for QML, widget tree for QtWidgets) determines what receives it — identical behavior to a human clicking there, including real consequences (menus, close buttons, destructive actions). window_id: id of a top-level window from the MOST RECENT snapshot/find (ids expire on refresh); 0 uses the session's first visible top-level window — pass it explicitly when the session has multiple windows. |
| qt_mouse_click_regionA | Click at the center of an element's on-screen region. Unlike qt_mouse_click (which delivers straight to the element), this routes through the real Qt input pipeline with real hit testing: for a QML container (e.g. a Rectangle with a MouseArea inside) the scene graph hit test delivers the click to the MouseArea, exactly as a human click would. |
| qt_mouse_pressA | Press a mouse button on an element WITHOUT releasing it. Pair with qt_mouse_release to split a click, or qt_mouse_move for a drag (press -> move -> release). x/y are optional logical-pixel coordinates relative to the element's top-left corner; either both or neither (omitted = element center). IMPORTANT: after a press you must release in the same session, or the target app stays in a pressed/ dragging state. |
| qt_mouse_releaseA | Release a previously pressed mouse button on an element. Completes a press/release pair (a click) or finishes a drag started with qt_mouse_press + qt_mouse_move. x/y are optional logical-pixel coordinates relative to the element's top-left corner; either both or neither (omitted = element center). |
| qt_mouse_wheelA | Scroll the mouse wheel over an element. dx/dy are the wheel deltas in either pixel ( |
| qt_mouse_moveA | Move the mouse pointer to an element-local position (no buttons). Use between qt_mouse_press and qt_mouse_release to drag, or alone to hover. x/y are coordinates relative to the element's top-left corner. |
| qt_mouse_context_menuA | Open the context menu at an element (right-click menu). x/y are optional logical-pixel coordinates relative to the element's top-left corner; either both or neither (omitted = element center). |
| qt_keyboard_inputA | Send keyboard input (typed text) to a UI element. Real input: the text lands in whatever the target would receive — it can overwrite existing text and trigger real app behaviour. If element_id is 0 or does not resolve, the input goes to the widget that currently has focus (be careful: a stale id silently redirects the text). Widgets that rely on focus (QLineEdit etc.) may ignore input to an unfocused element — call qt_focus first when text does not land. Use qt_key_combo for shortcuts like Enter or Ctrl+C. |
| qt_key_comboA | Send a keyboard shortcut to an element, e.g. "Ctrl+C", "Ctrl+Shift+A". Format: modifier names ("Ctrl", "Alt", "Shift", "Meta") joined with '+' followed by the key name ("C", "F5", "Enter", "Tab", "Escape", "Home", arrows, ...). element_id 0 targets the widget that currently has focus. Delivered as a real key press/release pair with the modifier state set — shortcuts can trigger real app actions (close window, save, submit). |
| qt_focusA | Set focus on a UI element. Best effort: QWidget focus works directly; some QML items may need an explicit focus request from within the app and report ok without changing focus. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tiefeiyu/qt-commander'
If you have feedback or need assistance with the MCP directory API, please join our Discord server