qtpy-mcp
MCP server that lets an AI agent find, screenshot, GIF-record and drive Qt widgets in running applications and DCCs (Houdini, Blender, Maya, Nuke, ...), built on Qt.py so it works with PySide6, PyQt6, PySide2 and PyQt5.
It is a fork of 0xCarbon/qt-mcp (MIT OR Apache-2.0): same tool set, plus Qt.py, many-apps-at-once routing, semantic widget search and GIFs.
"screenshot the PIPE-1234 window's docked Render Queue" ┌────────────────────┐
"now the widget labelled 'Name goes here:' in DEV-1515" ──► │ Houdini pid 4121 │ probe
"record a GIF of Houdini process 1252151's 'Foo bar'" ├────────────────────┤
│ │ Houdini pid 1252 │ probe
MCP client ──stdio──► qtpy-mcp ── registry + JSON-RPC ───► ├────────────────────┤
(routes) (127.0.0.1, token) │ Blender pid 7770 │ probe
└────────────────────┘
What you can ask for
- Find by meaning, not by ref: text, window title, class,
objectName, placeholder, tooltip, whatsThis, statusTip, accessible name, tab text, dynamic properties, even style sheet. Fuzzy-ranked; each hit says which field matched. - Screenshot a whole window, a dialog, or any sub-widget such as a docked panel. A match on a
label like
Name goes here:captures the form around it (expand="auto"; alsoself,parent,buddy,window). - Record a GIF (
qt_record_gif, orqt_record_start/qt_record_stopwhile you interact). The probe grabs frames withQWidget.grab()and Pillow encodes them, so it behaves the same on Windows, Linux and macOS: no ffmpeg or screen-capture APIs. - Many applications at once. Several Houdinis, Blender and Maya can be open together; one agent connection addresses any of them (see below).
- Everything upstream provides: widget tree snapshots, properties, click / type / keys, menus, signals, layout checks, QGraphicsScene and VTK inspection.
Install
Two pieces: the probe lives inside the Qt application; the server runs next to your MCP client.
# MCP client side (any Python 3.10+):
uvx qtpy-mcp # or: pip install qtpy-mcp
# Inside a DCC, whose Python already has a Qt binding: install without dependencies
hython -m pip install --no-deps qtpy-mcp Qt.py # Houdini
<blender-python> -m pip install --no-deps qtpy-mcp Qt.py PySide6-Essentials # Blender
Standalone apps can use an extra: pip install "qtpy-mcp[pyside6]" (or pyqt6, pyqt5, pyside2).
Choose a binding with QT_PREFERRED_BINDING=PyQt6 (Qt.py's own variable).
MCP client config:
{ "mcpServers": { "qtpy": { "command": "uvx", "args": ["qtpy-mcp"] } } }
Put the probe in your app
from qtpy_mcp.probe import install
install(name="houdini") # after the QApplication exists
or set QTPY_MCP_PROBE=1 in the environment before launching (no code change).
Working examples: examples/houdini,
examples/blender.
Talking to several apps
Every tool takes an optional instance. The server finds running apps through a per-user
registry, so apps may start and stop at any time. A reference can be any of:
| You say | instance |
|---|---|
| a window title or part of one | "PIPE-1234", "DEV-1515" |
| a process id | 1252151, "1252151", "pid:1252151", "houdini-1252151" |
| an app name (if unique) | "blender" |
| the instance id | "houdini-1252151" |
If a reference matches more than one app, the tool errors with the candidates (pid, name,
window titles) rather than guessing. With one app running, instance can be omitted.
qt_list_instances shows what is running; qt_find_anywhere searches every app for a
description and names the owner of each hit; qt_select_instance sets a default.
Routing is covered by tests against fake probes, and against real separate Qt processes
(tests/test_multiprocess.py).
Tools
| Instances | qt_list_instances, qt_select_instance, qt_find_anywhere |
| Finding | qt_find_widget (semantic: describe, window_title, class_name, object_name, search_fields, min_score), qt_snapshot, qt_object_tree, qt_list_windows |
| Pictures | qt_screenshot (by ref or by description), qt_record_gif, qt_record_start, qt_record_stop, qt_vtk_screenshot |
| Driving | qt_click, qt_type, qt_key_press, qt_trigger_action, qt_set_property, qt_invoke_slot, qt_wait_for, qt_batch |
| Inspecting | qt_widget_details, qt_get_text, qt_menu_items, qt_active_popup, qt_signals, qt_layout_check, qt_thread_check, qt_messages, qt_scene_snapshot, qt_vtk_scene_info |
Configuration
| Variable | Meaning |
|---|---|
QTPY_MCP_PROBE=1 |
auto-install the probe when a QApplication is created |
QTPY_MCP_NAME |
label for this instance (default: application name) |
QTPY_MCP_PORT |
fixed probe port (default: ephemeral); on the server side, connect to this one port and skip the registry |
QTPY_MCP_HOST |
host the server connects to in fixed-port mode |
QTPY_MCP_TOKEN |
shared secret instead of a random one |
QTPY_MCP_REGISTRY_DIR |
where instances register (default: per-user runtime dir) |
QTPY_MCP_SCREENSHOT_MAX_WIDTH / _HEIGHT |
cap screenshot size |
QT_PREFERRED_BINDING |
Qt.py: PySide6, PyQt6, PySide2, PyQt5 |
Security
The probe can click, type and call slots in the host application. It listens on 127.0.0.1
only, on an ephemeral port, and every request needs a per-process token kept in a registry
file readable only by your user. See SECURITY.md.
Development
See CONTRIBUTING.md. Quality gates in CI: ruff, mypy --strict, tests on
PySide6 / PyQt6 / PyQt5 (Linux, Windows, macOS), a Blender smoke test, build checks and
pip-audit. Pushing a vX.Y.Z tag publishes to PyPI.
License
MIT OR Apache-2.0, at your option (LICENSE-MIT, LICENSE-APACHE).
Portions derive from qt-mcp; see NOTICE.
Metadata
Release files for qtpy-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| qtpy_mcp-0.1.0.tar.gz | 85.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qtpy_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 149.8 kB
Release files / qtpy_mcp-0.1.0.tar.gz
| Download URL | qtpy_mcp-0.1.0.tar.gz |
|---|---|
| Size | 85.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
68da9b533f06d22df274b3659ddb0c59411f73106967d1f741e802422cdd38db
|
|
BLAKE2b-256 checksum How to use checksums |
b13b1e672c5a561856e47a3747d0e0c22ad69de1493ed8f937ee0217726561fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / qtpy_mcp-0.1.0-py3-none-any.whl
| Download URL | qtpy_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 64.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c34241c0cd1454c0c2159bb88f19f43a069435aecc2a801ebfff4d9351699fda
|
|
BLAKE2b-256 checksum How to use checksums |
89fbc3f044c7ba1782ae4b2b3d90f0c59015ec847c991aa99ca60b91f46feffa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for qtpy-mcp 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for qtpy_mcp-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.