Playwright-style MCP server for PySide6 apps — inspect, control, and debug via MCP
pyside6-mcp has 20 tools with consistent naming (verb-starting: screenshot, click_widget, get_widget_tree, etc.) and detailed descriptions. Most tools have complete input schemas with parameter types and descriptions. However, output schemas are not documented, the server lacks explicit response schemas showing what fields each tool returns, forcing LLMs to infer structure. Tool descriptions are generally good (150-300 chars) but some lack clarity on return values and error conditions. The 'eval' tool is high-risk (arbitrary Python execution) and lacks safety guardrails. Schema completeness varies: some tools have minimal parameters (list_apps, get_launch_help), others have well-documented optional pid fields. Overall solid naming and description practices, but missing formal output schema documentation and error recovery guidance cost points.
Click at absolute screen coordinates (x, y). Useful for clicking buttons or areas not covered by widget IDs.
Click on a widget by ID. Simulates a mouse click at the widget's center.
Evaluate Python code in the app process (advanced). Returns the result. Use with caution.
Find widgets matching a query (class name, object name, or text content). Returns matching widget IDs.
Retrieve captured application logs (from Python logging handlers). Useful for debugging.
Read the app's captured stdout/stderr. Useful for debugging launch failures or app errors.
Check if the app process is still alive, if the bridge is responsive, and detect modal blocks.
No explicit output schemas documented for any tool. LLMs must infer response structure from descriptions alone. Returns from 'get_widget_tree', 'list_apps', 'list_actions', 'get_app_status' etc. are undocumented, forcing agents to guess field names and types.
'eval' tool (arbitrary Python code execution in app process) lacks safety guardrails and error recovery guidance. Description says 'Use with caution' but provides no mitigation, sandboxing, or examples of safe use. This is a critical security and reliability risk.
No pagination support documented for list tools. 'get_app_logs' and 'get_app_output' accept 'n' parameter (tail count), but no documented limit, no total count returned, and no cursor-based pagination. Large result sets could exhaust context window.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 69 | 2026-07-28+ | v2 |
Get detailed help on how to call launch_app, including examples and common mistakes.
Get detailed info about a single widget by ID (geometry, state, properties, parent, children).
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.
Start a PySide6 app with the bridge pre-injected. Returns {pid}. Call this first before any other tool. The bridge is automatically injected — no code changes needed.
List all QActions in the app (menus, toolbars, context menus). Each action can be triggered by trigger_action.
List all currently running apps managed by this MCP server (returns their pids).
Press a keyboard key or key combination (e.g., 'Return', 'Tab', 'Escape', 'Ctrl+A', 'Shift+Tab').
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.
Scroll in the app window or a specific widget (mouse wheel delta in pixels).
Stop a running app (by pid or the last launched). Sends SIGTERM first, then SIGKILL if needed.
Trigger a QAction by name (e.g., from File menu). Useful for menu/toolbar actions.
Type text into a focused or specified widget. Clears existing text first if clear=true.
Wait for the app to become ready (visible window with non-zero size, and UI quiet for N ms). Blocks until ready or timeout.
Error handling descriptions are minimal. Tools reference '_bridge_unreachable_error()' internally but do not document what errors are retryable, user-fixable, or fatal. LLMs have no recovery guidance.
Optional 'pid' parameter present in nearly all tools, but the fallback behavior ('Omit to target the last launched app') is implicit. This violates the principle of explicit defaults. If an agent omits pid and a different app is now active, the wrong app is targeted silently.
'launch_app' has extensive, good description in instructions, but the actual tool description (in the tools list) is shorter and less detailed. Tool descriptions should be self-contained; not rely on server instructions.