146 lines
5.0 KiB
Markdown
146 lines
5.0 KiB
Markdown
# GammaRay 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, materials, and Qt Widgets.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Target Qt/QML App ──TCP──► GammaRay MCP Bridge ──stdio──► LLM / AI Agent
|
|
(GammaRay probe (GammaRay client + (opencode,
|
|
injected) qtmcp MCP server) ZCode, etc.)
|
|
```
|
|
|
|
The bridge is a GammaRay **client**: it connects to a probe injected into a target Qt app, reads the same models the GammaRay GUI uses, and translates them into MCP JSON-RPC tool calls over stdio. Supports both QML Quick apps (SceneGraph, QML items) and Qt Widget apps (widget hierarchy, properties, attributes).
|
|
|
|
## Prerequisites
|
|
|
|
- Qt 6.8+ (system)
|
|
- C++20 compiler (GCC 12+, Clang 16+)
|
|
- GammaRay 3.4.0+ (system package: `gammaray-dev` on Debian/Deepin)
|
|
- [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. Install system dependencies
|
|
|
|
```bash
|
|
# Debian / Deepin
|
|
sudo apt install gammaray-dev gammaray-plugin-quickinspector
|
|
```
|
|
|
|
### 2. Build the bridge
|
|
|
|
```bash
|
|
cd bridge
|
|
cmake -S . -B build -G Ninja
|
|
cmake --build build
|
|
```
|
|
|
|
#### Offline build (using a local qtmcp clone)
|
|
|
|
If you have a local clone of qtmcp (e.g. at `/home/user/Sources/qtmcp`),
|
|
pass `FETCHCONTENT_SOURCE_DIR_QTMcp` to skip the network fetch:
|
|
|
|
```bash
|
|
cd bridge
|
|
cmake -S . -B build -G Ninja \
|
|
-DFETCHCONTENT_SOURCE_DIR_QTMcp=/home/user/Sources/qtmcp \
|
|
-DFETCHCONTENT_FULLY_DISCONNECTED=ON
|
|
cmake --build build
|
|
```
|
|
|
|
### 3. Run
|
|
|
|
```bash
|
|
# Start a probe (inject into a QML app)
|
|
gammaray --inject-only --listen tcp://127.0.0.1:11732 \
|
|
--injector preload /usr/lib/qt6/bin/qml /path/to/app.qml -platform offscreen
|
|
|
|
# Or inject into a widget app
|
|
gammaray --inject-only --listen tcp://127.0.0.1:11732 \
|
|
--injector preload /path/to/widget-app
|
|
|
|
# Start the bridge (stdio MCP server)
|
|
bridge/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.
|
|
|
|
### 4. Build a .deb package (optional)
|
|
|
|
```bash
|
|
cd bridge/build
|
|
cpack -G DEB
|
|
```
|
|
|
|
The package installs the bridge binary (`/usr/bin/gammaray-mcp-bridge`),
|
|
qtmcp shared libs and plugins, and the `run.sh` helper script.
|
|
System dependencies (`gammaray >= 3.4.0`, Qt6 libs) are auto-detected.
|
|
|
|
## 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 |
|
|
|
|
### QML 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 |
|
|
|
|
### Widget inspection
|
|
| Tool | Description |
|
|
|---|---|
|
|
| `listWidgets()` | Recursive QWidget hierarchy (types, names, visibility) |
|
|
| `selectWidget(address)` | Select a widget, populating its property and attribute models |
|
|
| `getWidgetProperties(address)` | Get all Q_PROPERTY values (geometry, font, palette, window flags, etc.) |
|
|
| `getWidgetAttributes(address)` | Get Qt::WidgetAttribute flags (acceptDrops, enabled, etc.) |
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
# QML test suite (requires a QML app probe):
|
|
./tests/run_tests.sh
|
|
|
|
# Widget test suite (requires a widget app probe):
|
|
./tests/run_widget_tests.sh
|
|
|
|
# Unit tests only:
|
|
./tests/run_tests.sh --no-probe
|
|
```
|
|
|
|
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 LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only — we comply under GPL-2.0-only). |