# PySide6 MCP (pypi · pyside6-mcp)

Playwright-style MCP to inspect, control, and debug PySide6 desktop GUIs.

- Trust score: 60/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-20

## Components

- pypi · `pyside6-mcp`: 60/100 (this document), [markdown](https://verifymcp.io/servers/com55-pyside6-mcp/pyside6-mcp.md), [page](https://verifymcp.io/servers/com55-pyside6-mcp/pyside6-mcp)

## Channel facts

- Registry: `pypi`
- Package: `pyside6-mcp`
- Version: `0.1.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-09-20.

- **Supply Chain Security**: 50/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised native-build step with no shell scripting around it.
  - 1 of 23 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 14 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 74/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 2507 tokens (~113/item across 22 items; 22 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 50/100
  - Stability observed for 15 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 85/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 46% of tool parameters carry a description.
  - Structured output schemas are declared (95% of tools); any adoption earns full credit.
- **Tool Safety**: 75/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - 0 of 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "eval_python" implies "eval" and declares no destructiveHint at all, which the MCP spec reads as destructive by default.
  - An AI judge read all 23 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the PySide6 MCP server?

PySide6 MCP runs locally as a PyPI package, launched with uvx pyside6-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add com55-pyside6-mcp -- uvx pyside6-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "com55-pyside6-mcp": {
      "command": "uvx",
      "args": [
        "pyside6-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "com55-pyside6-mcp": {
      "command": "uvx",
      "args": [
        "pyside6-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add com55-pyside6-mcp -- uvx pyside6-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "com55-pyside6-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "pyside6-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add com55-pyside6-mcp --command uvx --arg pyside6-mcp
```

### Hermes

```yaml
mcp_servers:
  com55-pyside6-mcp:
    command: "uvx"
    args: ["pyside6-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "com55-pyside6-mcp": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "pyside6-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add com55-pyside6-mcp -t stdio -c uvx -a pyside6-mcp
```

### Other

```json
{
  "mcpServers": {
    "com55-pyside6-mcp": {
      "command": "uvx",
      "args": [
        "pyside6-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-20 (score 60, +1)

No change was recorded against any check on this day. Stability & Change Management went from 47 to 50. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 15 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-18 (score 59, +1)

No change was recorded against any check on this day. Stability & Change Management went from 40 to 43. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 13 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-16 (score 58, +1)

No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-14 (score 57, +1)

No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-13 (score 56, +3)

- [functional improvement] Stability: unverified → 0.27

### 2026-09-10 (score 53, 0)

- [functional regression] Security disclosure: unverified → fail

### 2026-09-09 (score 53, −1)

- [security regression] Malware scan: fail → unverified
- [functional regression] Security disclosure: fail → unverified

### 2026-09-08 (score 54, +1)

- [security regression] Malware scan: unverified → fail

## MCP tools (22)

### `screenshot` (~80 tokens)

Screenshot

Capture a screenshot of the app window (or a specific widget by ID).
Returns the image so you can see the current UI state.
Call this first to orient yourself.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `widget_id`

### `get_widget_tree` (~85 tokens)

Get Widget Tree

Get the full widget hierarchy of all visible windows as JSON.
Each widget has: id, class, object_name, visible, enabled, geometry, text, children.
Use widget IDs from this tree in other tools.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.

Output parameters:

- `result` (string)

### `get_widget_info` (~75 tokens)

Get Widget Info

Get detailed properties and state of a specific widget.
Includes geometry, text, enabled/visible state, and dynamic Qt properties.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `widget_id` (string, required)

Output parameters:

- `result` (string)

### `get_app_state` (~65 tokens)

Get App State

Get app-level state: active window, focused widget, screen info.
Useful to understand focus before sending keyboard events.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.

Output parameters:

- `result` (string)

### `find_widget` (~118 tokens)

Find Widget

Search for widgets by class, objectName, text content, or visibility.
Returns a list of matching widgets with their IDs.
Examples:
  find_widget(class_name="QPushButton")
  find_widget(text="Apply Mods")
  find_widget(object_name="enabledCheckBox")

Input parameters:

- `class_name`
- `object_name`
- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `text`
- `visible`

Output parameters:

- `result` (string)

### `click` (~137 tokens)

Click

Click a widget or screen coordinate.
\- widget_id only: clicks the center of that widget
\- widget_id + x/y: clicks at (x, y) relative to the widget's top-left
\- x/y only: clicks at (x, y) relative to the main window
button: 'left' (default), 'right', or 'middle'

Input parameters:

- `button` (string)
- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `widget_id`
- `x`
- `y`

Output parameters:

- `result` (string)

### `double_click` (~71 tokens)

Double Click

Double-click a widget. Sends two rapid left-clicks.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `widget_id` (string, required)
- `x`
- `y`

Output parameters:

- `result` (string)

### `type_text` (~79 tokens)

Type Text

Type text into a widget (focuses it first) or the currently focused widget.
For special characters use press_key instead.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `text` (string, required)
- `widget_id`

Output parameters:

- `result` (string)

### `press_key` (~125 tokens)

Press Key

Press a key on the currently focused widget.
Named keys: enter, return, escape, tab, backtab, backspace, delete,
            up, down, left, right, space, home, end, pageup, pagedown,
            f1–f6
Single characters: pass the character directly, e.g. 'a', 'A', '1'

Input parameters:

- `key` (string, required)
- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.

Output parameters:

- `result` (string)

### `scroll` (~102 tokens)

Scroll

Scroll a widget. dy > 0 scrolls down, dy < 0 scrolls up.
dx: horizontal scroll (positive = right).
widget_id: target widget; omit to scroll the main window.

Input parameters:

- `dx` (integer)
- `dy` (integer, required)
- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `widget_id`

Output parameters:

- `result` (string)

### `get_logs` (~74 tokens)

Get Logs

Get the last n log messages captured from the app's Python logging system.
Includes timestamp, level, logger name, and message.

Input parameters:

- `n` (integer)
- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.

Output parameters:

- `result` (string)

### `get_app_output` (~133 tokens)

Get App Output

Get the last n lines of the launched app's real stdout/stderr: print()
output, uncaught tracebacks, and Qt/console warnings.

This is the app's actual console output, captured because launch_app
redirects it to a log file. Use this to debug crashes or startup failures.
For structured Python logging records use get_logs() instead.

Only works for apps started via launch_app on this server.

Input parameters:

- `n` (integer)
- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.

Output parameters:

- `result` (string)

### `eval_python` (~132 tokens)

Eval Python

Evaluate a Python expression or execute a statement inside the app process.
Context provides:
  \- app: QApplication instance
  \- widgets: dict mapping widget_id → QWidget
Examples:
  eval_python("app.activeWindow().windowTitle()")
  eval_python("widgets['3'].isEnabled()")
  eval_python("list(app.allWidgets())")
WARNING: runs arbitrary code in the app — use only for debugging.

Input parameters:

- `code` (string, required)
- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.

Output parameters:

- `result` (string)

### `get_launch_help` (~47 tokens)

Get Launch Help

Return how to call launch_app — especially the script parameter.

Call this before launch_app when you are unsure which entry .py to use or
whether script should include a subfolder path.

Output parameters:

- `result` (string)

### `launch_app` (~239 tokens)

Launch App

Launch a PySide6 app with the MCP bridge injected, then wait until the UI is ready.

Input parameters:

- `app_args`: Optional CLI arguments forwarded to the script, e.g. ['--verbose'].
- `command`: DEPRECATED — ignored. Do not use. Older MCP schemas listed this as required; pass cwd instead.
- `cwd` (string, required): REQUIRED. Absolute path to the PySide6 project root — the folder that contains pyproject.toml (same directory you would cd into before running the app). Example: C:/dev/my-app or /home/dev/my-app
- `script` (string): Entry .py path RELATIVE to cwd (not absolute). Default: main.py. Omit or keep default when main.py is at project root. Use script='app.py' if the entry has another name at root. Use script='src/run.p…
- `timeout` (integer): Seconds to wait for UI readiness. Default 45; use 60–90 for cold starts.

Output parameters:

- `result` (string)

### `wait_until_ready` (~120 tokens)

Wait Until Ready

Wait until the app UI is ready: a visible top-level window that has been
quiet (no layout/paint activity) for `quiet_ms` milliseconds.

Use after an action that reloads or rebuilds the UI. Returns the readiness
snapshot. Does not launch anything — the app must already be running.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `quiet_ms` (integer)
- `timeout` (integer)

Output parameters:

- `result` (string)

### `wait_for_idle` (~107 tokens)

Wait For Idle

Wait until the app's UI has been quiet (no layout/paint activity) for
\`quiet_ms` ms, or until `timeout` seconds elapse. Call after a click or
action that triggers async work, before taking a screenshot.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `quiet_ms` (integer)
- `timeout` (number)

Output parameters:

- `result` (string)

### `get_app_status` (~86 tokens)

Get App Status

Report combined health of a launched app: whether the process is alive,
its exit code, whether the bridge responds, and whether the main thread is
likely blocked by a modal dialog (process alive but bridge unresponsive).

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.

Output parameters:

- `result` (string)

### `list_actions` (~70 tokens)

List Actions

List all QActions (menu items, toolbar actions) in visible windows with their
name, text, shortcut, and enabled/checked state.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.

Output parameters:

- `result` (string)

### `trigger_action` (~96 tokens)

Trigger Action

Trigger a QAction directly by objectName (`name`) or visible label (`text`),
without clicking through menus. Useful to avoid opening modal menus and to
reach toolbar/menu actions reliably. Provide at least one of name/text.

Input parameters:

- `name`
- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.
- `text`

Output parameters:

- `result` (string)

### `list_apps` (~36 tokens)

List Apps

List apps launched by this MCP server. Each entry is {pid}.
Pass pid= to other tools when more than one app is running.

Output parameters:

- `result` (string)

### `stop_app` (~62 tokens)

Stop App

Stop a previously launched app (started via launch_app).
Omit pid to stop the last launched app.

Input parameters:

- `pid`: App pid from launch_app. Omit to target the last launched app. Required only when several apps are running and you need a specific one.

Output parameters:

- `result` (string)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/com55-pyside6-mcp/pyside6-mcp#diagnostics

## Score history

- 2026-09-20: 60
- 2026-09-19: 59
- 2026-09-18: 59
- 2026-09-17: 58
- 2026-09-16: 58
- 2026-09-15: 57
- 2026-09-14: 57
- 2026-09-13: 56
- 2026-09-12: 53
- 2026-09-11: 53
- 2026-09-10: 53
- 2026-09-09: 53
- 2026-09-08: 54
- 2026-09-07: 53
- 2026-09-06: 54
- 2026-09-05: 53

## Common questions

### What is the PySide6 MCP server?

PySide6 MCP is listed in the public MCP registry as io.github.com55/pyside6-mcp. Playwright-style MCP to inspect, control, and debug PySide6 desktop GUIs. This page covers its PyPI package (pyside6-mcp).

### Is the PySide6 MCP server safe to use?

PySide6 MCP scores 60 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the PySide6 MCP server expose?

PySide6 MCP exposes 22 tools: screenshot, get_widget_tree, get_widget_info, get_app_state, find_widget, and 17 more. Their descriptions and schemas cost roughly 2,139 tokens of context every time the server is loaded.

### Is the PySide6 MCP server still maintained?

PySide6 MCP is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the PySide6 MCP server under?

PySide6 MCP declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/pyside6-mcp/
- Socket report: https://socket.dev/pypi/package/pyside6-mcp
- Repository: https://github.com/com55/pyside6-mcp
- Changelog RSS feed: https://verifymcp.io/servers/com55-pyside6-mcp/pyside6-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/com55-pyside6-mcp/pyside6-mcp.json
- HTML version of this page: https://verifymcp.io/servers/com55-pyside6-mcp/pyside6-mcp
