# QML SceneGraph MCP Bridge A [MCP](https://modelcontextprotocol.io/) server that bridges [GammaRay](https://github.com/KDAB/GammaRay) probe introspection data into MCP tools, enabling LLMs to inspect and debug Qt Quick / QML scene graphs, items, geometry, and materials. ## Architecture ``` Target Qt/QML App ──TCP──► GammaRay MCP Bridge ──stdio──► LLM / AI Agent (GammaRay probe (GammaRay client + (opencode, injected) qtmcp MCP server) Claude Desktop, etc.) ``` The bridge is a GammaRay **client**: it connects to a probe injected into a target Qt/QML app, reads the same models the GammaRay GUI uses, and translates them into MCP JSON-RPC tool calls over stdio. ## Prerequisites - Qt 6.8+ (system) - C++20 compiler (GCC 12+, Clang 16+) - GammaRay 3.4.0+ built from source (see [build instructions](#building-gammaray)) - [qtmcp](https://github.com/signal-slot/qtmcp) (consumed via FetchContent — no manual install) - Python 3.10+ with `pytest` (for running the test suite) ## Building ### 1. Build and install GammaRay ```bash cmake -S /path/to/GammaRay -B /path/to/GammaRay/build \ -DCMAKE_INSTALL_PREFIX=$(pwd)/install-prefix cmake --build /path/to/GammaRay/build cmake --install /path/to/GammaRay/build --prefix $(pwd)/install-prefix ``` ### 2. Build the bridge ```bash cd bridge cmake -S . -B build -G Ninja -DCMAKE_PREFIX_PATH=$(pwd)/../install-prefix cmake --build build ``` ### 3. Run ```bash # Start a probe (inject into a QML app) install-prefix/bin/gammaray --inject-only --listen tcp://127.0.0.1:11732 \ --injector preload /usr/lib/qt6/bin/qml /path/to/app.qml -platform offscreen # Start the bridge (stdio MCP server) ./run.sh ``` The bridge starts in lazy-connect mode. Call `connectProbe("127.0.0.1", 11732)` from your MCP client once the probe is up. ## MCP Tools ### Connection management | Tool | Description | |---|---| | `connectProbe(host, port)` | Connect to a GammaRay probe (defaults: 127.0.0.1:11732) | | `connectProbeDefault()` | Convenience: connect to 127.0.0.1:11732 | | `disconnectProbe()` | Drop connection and forget URL | | `probeStatus()` | Report connection state | ### Navigation | Tool | Description | |---|---| | `listQuickWindows()` | List QQuickWindows in the target app | | `selectQuickWindow(index)` | Select a window for scene graph introspection | | `listQuickItems()` | Recursive QQuickItem tree with types and flags | | `listScenegraphNodes()` | Recursive QSGNode tree (all node types) | ### QML Item inspection | Tool | Description | |---|---| | `selectQuickItem(address)` | Select a QML item by address, populating its properties model | | `getItemProperties(address)` | Get all Q_PROPERTY values (x, y, width, height, opacity, visible, z, anchors, text, font, etc.) | ### SG Node inspection | Tool | Description | |---|---| | `selectScenegraphNode(address)` | Select a SG node, populating geometry/material sub-models | | `getNodeVertices(address)` | Read vertex data of a GeometryNode | | `getNodeAdjacency(address)` | Read adjacency/drawing mode of a GeometryNode | | `getMaterialShaders(address)` | List shader stages for a node's material | | `getShaderSource(row)` | Get shader source code (async via MaterialExtensionInterface) | | `getMaterialProperties(address)` | Get material property name/value pairs | ### Rendering visualization | Tool | Description | |---|---| | `setRenderMode(mode)` | Set render mode (NormalRendering, VisualizeOverdraw, etc.) | | `setSlowMode(enabled)` | Toggle continuous rendering | ## Testing ```bash # Unit tests only (no probe needed): ./tests/run_tests.sh --no-probe # Full integration test suite (probe required): ./tests/run_tests.sh --no-probe # skips probe-dependent tests ./tests/run_tests.sh -v # verbose ``` See `tests/README.md` for details. ## License GPL-2.0-or-later. The bridge links GammaRay libraries (GPL-2.0-or-later) and uses qtmcp (available under GPL-2.0-only).