WpfVisualTreeMcp
This MCP server lets AI agents inspect, debug, and drive running WPF applications without modifying their source.
Discover & attach – list running WPF apps, attach by process ID/name, and auto-inject the inspector.
Inspect the UI tree – walk the visual tree, read dependency properties, layout metrics, resources, styles, and templates.
Diagnose bindings – view bindings, capture binding errors, inspect DataContext, evaluate why a property has a value, and explain triggers.
Search & wait – find elements by AutomationId, type, x:Name, visible text, or property filters (shallow/deep), and wait for elements/conditions without sleep loops.
Interact – click (UIA or physical, double/right), set text, send keyboard shortcuts, select items, hover, scroll, drag, and perform native touch gestures.
Capture visuals – take window/element screenshots (render/screen, full-content) and highlight elements.
Live-edit & measure – set dependency properties at runtime, revert edits, and snapshot/diff subtrees to verify changes.
Run diagnostics – produce aggregate reports of errors, disabled/invisible elements, and binding traces.
Record & test – record workflows, replay them, assert property values, and export runnable xUnit tests or workflow JSON.
Export – dump the visual tree as XAML or JSON.
Allows AI agents to inspect, debug, and drive running WPF applications, including visual tree navigation, property inspection, binding analysis, screenshots, element search, and UI automation such as clicking, text input, and keyboard shortcuts.
WpfVisualTreeMcp
Let AI agents see, debug and drive running WPF apps. Snoop + Playwright for AI, exposed over the Model Context Protocol — visual tree, bindings, screenshots, mouse dragging, touch gestures, text input and keyboard. Inspect running apps without source changes; touch behavior depends on the application's input support.

Drag-and-drop, move a canvas item, tap, hold, pan, pinch to zoom and rotate — then query controls, fill a form, select an item and diagnose a binding error. The gesture sequence records real WPF input through MCP, targets controls by AutomationId and checks the application's response, just like the automated tests.
Watch the animated demo directly.
New in v0.20.0: Verified support for WPF on .NET 9, .NET 10 and .NET Framework 4.8.1, on both x86 and x64. CI exercises automatic injection and self-hosting across all six supported target frameworks, plus the installed C# SDK from .NET 8, 9 and 10 test projects. The x86 injection helper can also use .NET 9 or 10 when .NET 8 is absent.
The WpfVisualTreeMcp.Automation C# SDK
drives virtualized DataGrids/TreeViews, waits for controls, manages WPF windows and
streams property changes. The 38-tool MCP server and CLI share the inspection and
input engine, including direct AutomationId targeting.
Workflow recording/replay/xUnit export, aggregate diagnostics, full-content screenshots and .NET Framework 4.7.2 support remain available from v0.16.0. Thanks to @miloszkukla for the compatibility and screenshot work in PR #22.
Quickstart (60 seconds)
Download and extract
WpfVisualTreeMcp-vX.Y.Z-win-x64.zipfrom the latest release (requires a .NET 8, 9 or 10 Desktop Runtime).Register it in your MCP client — for Claude Code, add to
.mcp.json:{ "mcpServers": { "wpf-visual-tree": { "command": "C:/path/to/WpfVisualTreeMcp.Server.exe", "args": [] } } }Ask your agent: "Look at my running WPF app and tell me why the Save button is disabled."
Prefer the terminal? The same exe is a full CLI: WpfVisualTreeMcp.Server.exe help.
From v0.14.0, run wpfinspect update (or WpfVisualTreeMcp.Server.exe update)
to update the installation you launched. See updating.
Using Codex? Follow the plugin installation to install the MCP
configuration and skill together.
Related MCP server: screen-use
C# test SDK
WpfVisualTreeMcp.Automation exposes the inspection and input engine as C# objects,
with direct process attachment and AutomationId locators. The package includes the
injection payload and works without starting an MCP server or CLI.
Component | Supported frameworks |
WPF application being automated | .NET Framework 4.7.2, 4.8, 4.8.1; .NET 8, 9, 10 |
C# project consuming the Automation NuGet | .NET 8, 9, 10 |
Architectures | Windows x86 and x64; use an x64 test process to control either |
The application and test project can use different frameworks: for example, a
.NET 10 test can automate a .NET Framework 4.8.1 application. The SDK's net8.0
library works in .NET 9/10 test projects; it is not a .NET Framework test library.
The compatibility matrix is exercised before
release, including actual runtime-version checks. Framework 4.x target builds run
on the installed 4.8.1 runtime, since those runtimes update in place.
dotnet add package WpfVisualTreeMcp.Automation --version 0.20.0using WpfVisualTreeMcp.Automation;
await using var app = await WpfApplication.AttachAsync(processId);
await app.ByAutomationId("LoadButton").ClickAsync();
await app.ByAutomationId("StatusTextBox").WaitForTextAsync(
"loaded", timeout: TimeSpan.FromSeconds(30));
await app.ByAutomationId("Canvas").PanAsync(100, 0);
await app.ByAutomationId("Canvas").ZoomAsync(1.5);Text waits compare the exact property value: not loaded does not match loaded.
Timeouts throw with the expected and last observed values. Property predicates,
cancellation, drag, touch, assertions, inspection and recording/replay are also
available. Attached sessions leave the app running on disposal; launched sessions
own and clean up their process by default.
await app.ByAutomationId("Orders").AsDataGrid()
.RowByKey("Id", "42").Cell("Quantity").SetTextAsync("7");
await app.ByAutomationId("Folders").AsTreeView().Node("Projects", "WPF").SelectAsync();
await app.ByAutomationId("Enabled").CheckAsync();
await using var changes = await app.ByAutomationId("StatusTextBox").ObservePropertyAsync("Text");The SDK is a separate package from the MCP tool WpfVisualTreeMcp.
See installation, API examples and requirements.
Overview
WpfVisualTreeMcp is a Model Context Protocol (MCP) server that allows AI coding agents (Codex, Claude Code, Cursor, GitHub Copilot) to inspect and interact with running WPF applications. Think of it as giving your AI assistant the same capabilities as tools like Snoop WPF or Visual Studio's Live Visual Tree.
Why This Matters
Debugging WPF UI issues traditionally requires manual inspection with specialized tools. This project bridges that gap by exposing WPF inspection capabilities through MCP, enabling AI agents to:
Understand UI structure during code reviews
Diagnose binding errors automatically
Suggest fixes for layout issues
Assist with UI refactoring tasks
Analyze visual tree hierarchies in real-time
Features
Core Inspection
Process Discovery - List all running WPF applications available for inspection
Visual Tree Navigation - Traverse the complete visual tree hierarchy
Logical Tree Access - Navigate the logical tree structure
Property Inspection - Read all dependency properties of any UI element
Binding & Resources
Binding Analysis - Inspect bindings with converter, StringFormat, FallbackValue, MultiBinding support
DataContext Inspection - View DataContext type, properties, INPC status, and inheritance chain
Binding Error Detection - Automatically capture and report binding errors with classification
Resource Enumeration - Browse resource dictionaries at any scope
Style Inspection - View applied styles and templates
Search & Monitoring
Element Search - Find elements by type, name, or property values
Deep Search - Search entire tree including AdornerLayer and Popup elements
Property Watching - Monitor property changes in real-time
Interaction & Export
Touch Gestures (v0.13.0) -
wpf_touch_gesture/ CLItouch: native tap, long press, swipe, pinch and rotation with one or two contacts. Includes an interactive demo and WPF compatibility guidance.Mouse Drag -
wpf_drag/ CLIdrag: drag between visual-tree elements or by a local displacement, with left/right/middle buttons, configurable duration and local start/end points. Supports slider thumbs, splitters and drag-and-drop. See the parameters and examples.Screenshot Capture - Current source uses
autocapture for native hosted content and reports the selected mode; explicit render rejects unsupported native areas. Capture window/element screenshots visible to AI agents;full_content=true/ CLI--full-contentcaptures scrollable content, including virtualized lists, and restores the original scroll positionElement Highlighting - Visually highlight elements in the running app
Control Click (v0.4.0) - Click elements via UI Automation (
Invoke/Toggle/Select/ExpandCollapse) or a real OS mouse clickSet Text (new in v0.5.0) - Fill a TextBox/ComboBox/PasswordBox via UI Automation
IValueProvider.SetValue, with aTextBox.Text/PasswordBox.Password/ reflected-Textfallback, orphysical=trueto type via OS keyboard input (full Unicode BMP)Send Keys (new in v0.5.0) - Send keyboard shortcuts (
Ctrl+S,Alt+F4,F5,Enter,Ctrl+Shift+F, ...) to an element or the focused window via OS keyboard inputLayout Information - Get detailed layout metrics
Tree Export - Export visual tree to XAML or JSON format
Auto-Injection - Inject Inspector into running WPF processes (no source changes needed); multi-architecture since v0.6.0 — a 64-bit server can inject into 32-bit WPF apps via a bundled
WpfInjectorHelper.exe
Dual-Mode CLI (new in v0.4.0)
The same WpfVisualTreeMcp.Server.exe runs as either an MCP stdio server
(no arguments, default) or as a one-shot CLI (any recognised subcommand).
Useful when the MCP server isn't connected, for scripting, and for verifying
the pipeline manually. Run WpfVisualTreeMcp.Server.exe help for the full
command list. Output is JSON on stdout; diagnostics go to stderr.
How it compares
vs. the general tool categories:
WpfVisualTreeMcp | FlaUI / WinAppDriver | Generic computer-use (screenshot + mouse) | ||
Consumer | AI agents (MCP) + humans (CLI) | Humans (GUI) | Test code (C#) | AI agents |
Visual tree, dependency properties | ✅ | ✅ | ❌ (UIA view only) | ❌ |
Data bindings, binding errors, DataContext | ✅ | ✅ | ❌ | ❌ |
Find controls by visible text / properties | ✅ | manual | partial (UIA) | pixel guessing |
Click / type / select / shortcuts | ✅ | ❌ | ✅ | ✅ (blind) |
Wait for UI conditions (no sleep loops) | ✅ | ❌ | ✅ | ❌ |
Element screenshots + popup-aware screen capture | ✅ | ❌ | partial | full screen only |
Works without target source changes | ✅ (auto-injection) | ✅ | ✅ | ✅ |
vs. other WPF MCP servers. Most WPF MCP servers are built on UI Automation (FlaUI): they read the accessibility tree, and can only reach WPF internals — bindings, DataContext, ViewModel state — if you install their in-process probe into the app you want to inspect. This server takes the Snoop route instead: it injects at runtime, so it reads the real visual tree and diagnoses binding errors and DataContext with zero changes to the target app — nothing to add to your build, nothing to ship into production.
WpfVisualTreeMcp | UIA-based servers (FlaUI) | Other injection-based servers | |
Sees the real visual tree (not just the UIA view) | ✅ injection | ❌ accessibility tree | ✅ |
Binding errors + DataContext without a probe in the target | ✅ | ❌ (needs in-process probe) | partial |
Interaction surface | click (UIA + physical, double/right), drag, touch gestures, set-text w/ read-back, send-keys, select-item (virtualized) | click / type / select | usually invoke-only |
Wait for element conditions | ✅ | ✅ | ❌ |
Popup / dropdown / context-menu screenshots | ✅ screen mode | partial | screenshot only |
Cross-architecture injection (x64 ⇄ x86) | ✅ | n/a | ❌ |
Dual-mode: MCP server and one-shot CLI | ✅ | ❌ | ❌ |
Distribution | NuGet ( | varies | varies |
In short: UIA-based tools see what accessibility exposes, and computer-use agents see pixels. This project gives the agent the same insider view a WPF developer has in Snoop — with no probe to install in the target app — plus the widest set of hands to act on it, over a protocol every AI coding tool speaks.
Installation
Prerequisites
Windows 10/11
.NET 8.0 SDK or later
A WPF application to inspect
Building and running the complete compatibility suite requires the .NET 10 SDK, .NET 8/9/10 Desktop runtimes for x64 and x86, and .NET Framework 4.8.1.
Installation
Option 1: .NET tool / NuGet (Recommended)
dotnet tool install -g WpfVisualTreeMcp # installs the `wpfinspect` commandThe package is also published as an MCP server package (PackageType: McpServer),
so MCP clients that support NuGet-hosted servers can launch it directly:
dnx WpfVisualTreeMcp # runs the MCP stdio serverOption 2: Download Release
Download the latest release from GitHub Releases:
Download
WpfVisualTreeMcp-vX.X.X-win-x64.zipExtract to a folder (e.g.,
C:\Tools\WpfVisualTreeMcp)The MCP server executable is
server/WpfVisualTreeMcp.Server.exe
Desktop extension (MCPB)
Clients that support MCP bundles can import
WpfVisualTreeMcp-v0.20.0-win-x64.mcpb.
This Windows x64 bundle includes the server runtime and a self-contained x86
injection helper. A smaller
compact bundle
provides the same tools with a reduced runtime for catalogs with upload limits.
Update either bundle through the client's extension UI. See the
MCPB guide for requirements, packaging and verification.
Option 3: Build from Source
git clone https://github.com/faze79/WpfVisualTreeMcp.git
cd WpfVisualTreeMcp
# Visual Studio Developer PowerShell (C++ v143 toolset + Windows SDK)
./scripts/Build-NativeBootstrapper.ps1
dotnet build -c ReleaseFor injection build requirements, package layout, and troubleshooting, see the Injector README. Injecting into x86 apps requires the x86 .NET 8 runtime for the helper.
Updating
wpfinspect update --check # current/latest stable version; no installation changes
wpfinspect update # download and schedule installation automatically
wpfinspect update --status # confirm completion or inspect a failure
# For an extracted release or a published folder, invoke that exact executable:
C:\Tools\WpfVisualTreeMcp\server\WpfVisualTreeMcp.Server.exe updateupdate is available from v0.14.0. For an older global tool, bootstrap it once:
dotnet tool update -g WpfVisualTreeMcpFor an older portable copy, extract the latest release and use its server folder.
The command updates only the installation it was launched from. Global and
custom --tool-path tools download the exact official NuGet package, then use
dotnet tool update from that staged package (a .NET SDK is required). Temporary
NuGet download failures and publication delays receive up to four attempts, with
10, 20 and 30 seconds between attempts. If preparation fails, installed files are
unchanged; retry later. Portable folders receive the latest stable GitHub release's complete
server payload, verified against its SHA-256 digest. A source build under bin
is left to the source/build workflow; local manifest tools and dnx caches are
left to their package manager. --check explains which installation was detected.
On Windows, installation starts in a hidden worker after the CLI exits so its
executable is unlocked. A scheduled result means the worker was launched, not
that installation finished. Run update --status until it reports updated or
failed; a failed status returns exit code 1. JSON output includes the log path.
Status, logs and portable backups are stored under
%LOCALAPPDATA%\WpfVisualTreeMcp\updates, separately for each installation.
Close other MCP instances using the same files before updating. The updater does not stop applications: occupied files cause an error, and portable replacement failures trigger restoration from backup. Unrelated files and MCP configuration are preserved. After success, restart the MCP client and previously inspected WPF apps so both server and injected Inspector use the new version. Other installed copies and any separately copied self-hosted Inspector require their own update.
Configuration
The server uses the official Microsoft/Anthropic MCP SDK for .NET, providing guaranteed compatibility with Claude Code and other MCP clients.
Claude Code
Option 1: Command Line (Recommended)
Use the claude mcp add command to add the server directly:
# Add to current project only
claude mcp add wpf-visual-tree -- C:/path/to/WpfVisualTreeMcp/publish/WpfVisualTreeMcp.Server.exe
# Add globally (available in all projects)
claude mcp add --scope user wpf-visual-tree -- C:/path/to/WpfVisualTreeMcp/publish/WpfVisualTreeMcp.Server.exeYou can verify the server was added:
claude mcp listOption 2: Project-level JSON Configuration
Create or edit .mcp.json in your project root:
{
"mcpServers": {
"wpf-visual-tree": {
"command": "C:/path/to/WpfVisualTreeMcp/publish/WpfVisualTreeMcp.Server.exe",
"args": []
}
}
}Option 3: Global JSON Configuration
Add to ~/.claude/settings.json:
{
"mcpServers": {
"wpf-visual-tree": {
"command": "C:/path/to/WpfVisualTreeMcp/publish/WpfVisualTreeMcp.Server.exe",
"args": []
}
}
}Important Notes:
Use absolute paths to the built
.exefileUse forward slashes (
/) in paths on WindowsBuild in Release mode for production:
dotnet build -c ReleaseRestart Claude Code after configuration changes
Cursor
Add to your Cursor settings (.cursor/mcp.json):
{
"mcpServers": {
"wpf-visual-tree": {
"command": "C:/path/to/WpfVisualTreeMcp/publish/WpfVisualTreeMcp.Server.exe",
"args": []
}
}
}Codex plugin
The repository includes a WPFVisualTreeMcp Codex plugin that installs the MCP
configuration and a wpfvisualtreemcp skill together. It runs the latest stable NuGet package,
not a build of the checked-out source. No machine-specific executable path is
required.
Prerequisites for this installation method:
Windows 10/11 and a local Codex client with plugin support.
.NET 10 SDK, version 10.0.300 or newer within .NET 10 for
dotnet dnx, plus the .NET 8 runtime.Internet access to nuget.org on each MCP launch to resolve the latest stable version. Downloaded packages are cached by .NET. For x86 injection, install the x86 .NET 8 runtime as well.
From the repository root, register the local marketplace and install the plugin.
You can also download WpfVisualTreeMcp-v0.20.0-codex-plugin.zip from
GitHub Releases,
extract it, and run these commands from the extracted root:
codex plugin marketplace add .
codex plugin add wpfvisualtreemcp@WPFVisualTreeMcpRestart Codex or open a new session, then ask it to inspect your running WPF app.
The skill can also be invoked explicitly as $wpfvisualtreemcp.
Alternatively, install directly from the upstream Git repository without cloning it manually:
codex plugin marketplace add https://github.com/faze79/WPFVisualTreeMcp.git
codex plugin add wpfvisualtreemcp@WPFVisualTreeMcpUse codex plugin list --marketplace WPFVisualTreeMcp to check the installation. This is
a repository marketplace; it does not imply publication in OpenAI's public
plugin directory. If your client lacks codex plugin add, use a plugin-capable
client or the direct MCP configuration below.
To use your own build, or to avoid the .NET 10 SDK requirement, register the published executable directly instead of installing the plugin:
codex mcp add wpf-visual-tree -- "C:/Tools/WpfVisualTreeMcp/server/WpfVisualTreeMcp.Server.exe"Replace the example with the actual executable path. Avoid enabling both this manual entry and the plugin at the same time, which would start two servers.
Plugin files are under plugins/wpfvisualtreemcp/; the marketplace entry is
.agents/plugins/marketplace.json. The plugin uses Codex's supported
.codex-plugin/plugin.json compatibility format. Its manifest version identifies
the plugin configuration and skill, independently of the NuGet server version.
The MCP launch omits a package version and uses --no-http-cache to resolve the
latest stable release from nuget.org on each start. Prereleases are excluded.
Restart the MCP server or Codex to pick up a new server release; a running server
does not update in place. Never add CLI subcommands
such as list to the MCP launch arguments: no subcommand selects stdio mode.
The plugin starts in its own directory and includes a global.json selecting
SDK 10.0.300 or a newer stable .NET 10 SDK. This keeps a target project's older SDK pin
from disabling dotnet dnx. The noninteractive launch and x64/x86 Inspector
injection were verified with SDK 10.0.402 and Codex CLI 0.162.1. The SDK pin keeps
the launch on the tested .NET 10 command-line behavior.
The compatibility MCP configuration uses "cwd": ".", which Codex resolves
relative to the installed plugin root. This resolution was verified through
codex mcp list --json after installation in an isolated profile.
After editing local plugin files, rerun codex plugin add wpfvisualtreemcp@WPFVisualTreeMcp
to refresh the installed copy, then open a new Codex session.
For a Git-backed marketplace, update the plugin configuration and companion skill with:
codex plugin marketplace upgrade WPFVisualTreeMcp
codex plugin add wpfvisualtreemcp@WPFVisualTreeMcpFor a local marketplace, update its source checkout before reinstalling the plugin.
The companion skill covers mouse dragging, touch gestures and update behavior.
wpfinspect update updates a separately installed CLI or portable copy; it does
not refresh a plugin or its skill, and should not be used to modify the plugin's
shared dnx package cache. See Updating for standalone installations.
Self-Hosted Mode (Recommended)
For your WPF application to be inspectable, add a reference to the Inspector DLL and initialize it on startup:
Add a project reference to
WpfVisualTreeMcp.InspectorIn your
App.xaml.cs:
using System.Diagnostics;
using System.Windows;
using WpfVisualTreeMcp.Inspector;
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// Initialize the WPF Visual Tree Inspector
InspectorService.Initialize(Process.GetCurrentProcess().Id);
}
protected override void OnExit(ExitEventArgs e)
{
InspectorService.Instance?.Dispose();
base.OnExit(e);
}
}This enables the MCP server to connect to your application via named pipes for real-time inspection.
Usage Examples
List Running WPF Applications
Use the wpf_list_processes tool to show all running WPF applications.Attach and Inspect Visual Tree
Attach to the MyApp.exe WPF application and show me the visual tree of the main window.Find Binding Errors
Check the attached WPF application for any binding errors and explain what's causing them.Search for Elements
Find all Button elements in the visual tree that have IsEnabled set to false.Export Visual Tree
Export the visual tree of the current window to JSON format so I can analyze the structure.Architecture
┌─────────────────────────────────────────────────────────────┐
│ AI Agent (Claude Code) │
└─────────────────────────┬───────────────────────────────────┘
│ MCP Protocol (stdio)
▼
┌─────────────────────────────────────────────────────────────┐
│ WpfVisualTreeMcp Server │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
│ │ MCP Handler │ │ Tree Navigator │ │ Injector │ │
│ │ (Tools/Res.) │ │ & Inspector │ │ Manager │ │
│ └────────┬────────┘ └────────┬────────┘ └──────┬──────┘ │
└───────────┼────────────────────┼───────────────────┼────────┘
│ │ │
└────────────────────┼───────────────────┘
│ Named Pipes / IPC
▼
┌─────────────────────────────────────────────────────────────┐
│ Target WPF Application │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ Injected Inspector DLL ││
│ │ • VisualTreeHelper access ││
│ │ • LogicalTreeHelper access ││
│ │ • Property/Binding inspection ││
│ │ • Resource dictionary enumeration ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘For detailed architecture documentation, see docs/ARCHITECTURE.md.
Available Tools
Tool | Description |
| List all running WPF applications |
| Attach to a WPF application (supports |
| Get the visual tree hierarchy (default depth: 25, max: 100) |
| Get all dependency properties of an element |
| Query elements by exact AutomationId, type, x:Name, visible text, property values and visibility; results include text, automation id, enabled/visible state and screen bounds |
| Same query filters without result limit, across all windows including adorners/popups |
| Capture a screenshot of the window or element (returns image); |
| Aggregate current binding/validation errors, UI state counts and recent binding traces, with explicit scan limits and coverage |
| Start, stop, inspect or clear a workflow recording with stable selectors |
| Assert a dependency-property value; successful assertions are included in active recordings |
| Replay a workflow against a fresh app, stopping at the first failed step |
| Export a stopped recording as a runnable xUnit project or workflow JSON |
| Get data bindings for an element (includes MultiBinding, converter, StringFormat) |
| List all captured binding errors |
| Clear the captured binding errors list |
| Get DataContext type, properties, INPC status, and inheritance chain |
| Enumerate resource dictionaries |
| Get applied styles and templates |
| Monitor a property for changes |
| Explain why a property has its value — value source, and for bindings a hop-by-hop path resolution pinpointing where a broken binding fails |
| Evaluate Style and ControlTemplate triggers against the current state (condition, current value, active, setters) — 'why doesn't this trigger fire?'; and attribute a property's value to the style setter / active trigger that set it |
| Capture an element subtree's state (layout, visibility, brushes, text) under a label |
| Diff two snapshots — measure exactly what a change moved (property from→to, added/removed) |
| Live-edit a dependency property at runtime (type-converted), to test a change without rebuilding. State-changing, reversible. |
| Undo |
| Visually highlight an element |
| Click a control by handle or AutomationId — pass |
| Move/hover at a local point without clicking. Available from v0.17.0. |
| Wheel input vertically or horizontally; the app decides whether to scroll or zoom. Available from v0.17.0. |
| Drag with the mouse — source and target elements or relative displacement, local points, left/right/middle button, gradual movement and release cleanup. State-changing. |
| Native touch — tap, long press, swipe, two-finger pinch and rotation inside a visible element. Requires application touch support. State-changing. |
| Select an item in a ComboBox/ListBox/ListView/TabControl by visible text or index — works with virtualized items. State-changing. |
| Wait until an element is visible/exists/enabled/hidden, polling in the target app — no sleep-and-retry loops. |
| Set text/value of a TextBox/ComboBox/PasswordBox — UI Automation |
| Send a keyboard shortcut ( |
| Get layout information |
| Export visual tree to XAML or JSON |
For complete tool documentation, see docs/TOOLS_REFERENCE.md.
All input actions accept automation_id instead of element_handle, including
click, mouse movement, scrolling, drag, every touch gesture, selection, text and
keyboard input. Assertions and property edits accept it too. IDs match
AutomationProperties.AutomationId exactly and case-sensitively; duplicates fail.
Use root_handle to scope lookup. Drag destinations accept target_automation_id
and an independent target_root_handle. The same selectors work in recordings
and exported tests.
wpf_touch_gesture(automation_id="Canvas", gesture="tap")
wpf_touch_gesture(automation_id="Canvas", gesture="swipe", delta_x=80)
wpf_touch_gesture(automation_id="Canvas", gesture="pinch", scale=1.5)
wpf_drag(automation_id="Source", target_automation_id="Destination")
wpf_set_text(automation_id="UserName", text="test")
wpf_assert(automation_id="UserName", property_name="Text", expected_value="test")CLI equivalents use --automation-id, --root, --target-automation-id and
--target-root. Touch pan uses swipe, zoom uses pinch; the app must support
touch/manipulations to react to those gestures.
Roadmap
Phase 1: Core Inspection ✅
Project structure and architecture
Process discovery and enumeration
Basic process attachment
Visual tree navigation
Property inspection
Element search
Phase 2: Advanced Features ✅
IPC communication via named pipes
Binding analysis and error detection
Resource dictionary enumeration
Style and template inspection
Property change monitoring (with notifications)
Phase 3: Interaction & Diagnostics ✅
Element highlighting overlay
XAML/JSON export
Screenshot capture (returns MCP
ImageContentBlock)DLL auto-injection into running WPF processes (x64/x86)
AdornerLayer and Popup visual tree traversal
Phase 4: CLI + Driving the App ✅ (v0.4.0 / v0.5.0)
Dual-mode executable (MCP stdio + one-shot CLI) (v0.4.0)
Control click via UI Automation patterns (v0.4.0)
Physical OS mouse click as opt-in fallback (v0.4.0)
User-level Claude Code skill bundling the CLI (v0.4.0)
Set text/value via UI Automation
IValueProvider+ fallbacks (v0.5.0)Physical keyboard typing with Unicode BMP support (v0.5.0)
Keyboard shortcuts (
Ctrl+S,Alt+F4,F5, ...) via OS input (v0.5.0)
Phase 5: Multi-architecture ✅ (v0.6.0)
Cross-bitness auto-injection (64-bit server → 32-bit target)
Architecture-matching
WpfInjectorHelper.exe(32-bit .NET 8)Removes v0.5.0 known limitation; both x86 and x64 WPF apps drivable
Phase 6: Query engine & full driving ✅ (v0.7.0)
Query elements by visible text, property values, visibility
Enriched results: text, automation id, enabled/visible state, screen bounds
wpf_select_item— select in ComboBox/ListBox/TabControl by text or indexDouble / right click; scroll-into-view before physical input
Screen-mode screenshots (popups, dropdowns, context menus visible)
Set-text read-back verification; weak element-handle cache
Critical IPC serialization fix (request parameters were silently dropped)
Phase 7: Distribution & agent ergonomics ✅ (v0.7.1 / v0.8.0)
NuGet package, installable via
dnx/dotnet tool install(MCP server package type)Published to nuget.org (trusted publishing / OIDC) and the official MCP registry
Binding-error capture fixed (was never wired up), IPC parameter-drop fix
wpf_wait_for— wait for an element/condition, no sleep-and-retry loopsConcurrent IPC connections (a long wait no longer blocks other commands)
Next up
Shipped in v0.13.0: mouse dragging and native touch gestures, with MCP/CLI parity, sample demos, input cleanup, and real desktop validation across net48 x86/x64 and net8 x64. Shipped in v0.14.0: CLI self-update with version checks and installation status. Shipped in v0.15.0: Codex plugin marketplace, companion skill and plugin ZIP. Shipped in v0.16.0: workflow recording/replay/xUnit export, aggregate diagnostics, full-content screenshots and .NET Framework 4.7.2 compatibility.
The "change → measure → is it effective?" loop is complete: live-edit a property, then diff a before/after snapshot to see exactly what moved.
wpf_set_property/wpf_revert_property— live-edit a dependency property, then undo (v0.9.0)wpf_snapshot/wpf_diff— before/after snapshot to verify a change's effect (v0.10.0)wpf_evaluate_binding— explain why a property has its value; resolve a binding path hop-by-hop (v0.11.0)wpf_record→wpf_export_test— stable-selector replay and fresh-process xUnit tests, including drag/touch (v0.16.0)wpf_report— bounded aggregate diagnostics with explicit coverage (v0.16.0).NET Framework 4.7.2 and full-content scroll screenshots (v0.16.0)
Inspector-only NuGet package for self-hosted mode (reference instead of injection)
Streaming binding-error / property-change notifications to the MCP client
WinUI 3 support
See docs/ROADMAP.md for the full prioritized plan (rationale, design notes, effort, and suggested sequencing).
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup
Clone the repository:
git clone https://github.com/faze79/WpfVisualTreeMcp.git cd WpfVisualTreeMcpOpen in Visual Studio 2022 or VS Code:
code . # or start WpfVisualTreeMcp.slnBuild and run tests:
dotnet build dotnet testRun the sample WPF app for testing:
dotnet run --project samples/SampleWpfApp
Project Structure
WpfVisualTreeMcp/
├── src/
│ ├── WpfVisualTreeMcp.Server/ # MCP Server (.NET 8) - Uses official MCP SDK
│ │ ├── Program.cs # Server initialization with MCP SDK
│ │ ├── WpfTools.cs # 38 inspection, interaction and workflow tools
│ │ ├── Cli/CliRunner.cs # One-shot CLI front-end (v0.4.0)
│ │ └── Services/ # Process & IPC management
│ ├── WpfVisualTreeMcp.Inspector/ # Injected DLL (Framework 4.7.2/4.8/4.8.1; .NET 8/9/10)
│ ├── WpfVisualTreeMcp.Injector/ # Managed injection logic (CreateRemoteThread; net48 + net8.0)
│ ├── WpfVisualTreeMcp.InjectorHelper/# x86 .NET 8 helper exe for cross-arch injection (v0.6.0)
│ ├── WpfVisualTreeMcp.Bootstrapper/ # Native C++ DLL for CLR hosting
│ └── WpfVisualTreeMcp.Shared/ # Shared models & IPC contracts
├── samples/
│ └── SampleWpfApp/ # Test application
├── tests/
│ ├── WpfVisualTreeMcp.Tests/ # Unit tests
│ └── WpfVisualTreeMcp.IntegrationTests/ # Live WPF integration tests
├── publish/ # Published server + native DLLs
│ └── native/{x64,x86}/ # Architecture-specific bootstrapper
└── docs/ # DocumentationTechnical Details
MCP SDK: Built with the official C# MCP SDK from Microsoft/Anthropic
Protocol: JSON-RPC 2.0 over stdio transport
Target Framework: .NET 8.0 (Server) / .NET Framework 4.7.2, 4.8 and .NET 8.0-windows (Inspector)
IPC: Named Pipes for server-to-application communication
Tools: 38 tools auto-discovered via
[McpServerTool]attributes, covering inspection, diagnostics, interaction and workflow recording/testing. Replay performs recorded actions; full-content screenshots may temporarily scroll controls.CLI: same executable runs as one-shot CLI when given a subcommand (
Program.csroutes viaCliRunner.IsCliCommand)
Acknowledgments
Inspired by Snoop WPF - the original WPF spy utility
Built on the Model Context Protocol by Anthropic
Thanks to the .NET and WPF community
License
This project is licensed under the MIT License - see the LICENSE file for details.
Available Tools
38 toolswpf_assertA
Assert an element's dependency-property value using an exact ordinal comparison of its invariant string value; use {null} for null. Throws on mismatch. Successful assertions are saved while recording. Use wpf_wait_for_element first for asynchronous changes. Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: property_name (required), expected_value (required), root_handle, automation_id, +1 more.
wpf_attachA
Attach to a WPF application by process ID or name. Set auto_inject=true to automatically inject the Inspector into processes that don't have it pre-loaded.
Inputs: process_id, auto_inject, process_name.
wpf_capture_screenshotA
Capture a screenshot of the WPF window or a specific element. Returns an image that can be visually analyzed. Use element_handle to capture a specific element, or omit for the entire window. mode='auto' (default) uses screen capture when native HwndHost content is present, otherwise render; the response states the mode. Native content needs a visible unobstructed desktop. Explicit mode='render' rejects native content instead of returning a blank image, and re-renders the visual off-screen — works even if the window is covered, but CANNOT see open Popups, ComboBox dropdowns, context menus or tooltips. mode='screen' captures the actual on-screen pixels (GDI) and DOES include them — use it right after clicking something that opened a popup/menu; requires the window to be visible and unobstructed. Set full_content=true with render mode to capture all content in a ScrollViewer, including unscrolled and virtualized content; the original scroll position is restored.
Inputs: mode, max_width, max_height, full_content, +1 more.
wpf_clear_binding_errorsA
Clear the captured binding errors list. Useful before testing specific scenarios.
Inputs: no named parameters.
wpf_click_elementA
Click a UI element. Supply exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId; no handle lookup needed). IDs must match a unique control across all open windows, including hidden controls. Use root_handle with automation_id to scope to a window or subtree if IDs repeat. Missing or ambiguous IDs return an error without clicking. By default invokes the control's action via UI Automation (works for buttons, menu items, checkboxes, radio buttons, tabs, list items, expanders) without moving the mouse or focusing the window. Set physical=true to perform a real OS mouse click at the element's on-screen position (works on any visible element but moves the cursor and brings the window forward; auto-scrolls the element into view first). Optional paired x/y select a point in local WPF DIPs and imply physical input; omitted coordinates use the center. click_type: 'single' (default), 'double' (open items), 'right' (context menus) — double and right are always physical. After opening a context menu or dropdown, use wpf_capture_screenshot with mode='screen' to see it. STATE-CHANGING.
Inputs: x, y, physical, click_type, +3 more.
wpf_diffA
Diff two snapshots captured with wpf_snapshot, to measure the effect of a change. Returns a summary (counts) plus, for each element that changed, the exact properties that changed (from → to), keyed by stable element handle; plus elements added or removed between the two snapshots. Use this to verify a planned UI tweak did what you expected (e.g. Margin 0,0,0,0 → 40,40,40,40; Visibility Collapsed → Visible; a child appeared).
Inputs: after (required), before (required).
wpf_dragA
Drag using the real OS mouse: press, move gradually, release. Supply a source handle or automation_id and either target_handle, target_automation_id OR delta_x/delta_y (omitted delta axis is zero). target_root_handle scopes destination ID lookup independently of the source root_handle. start_x/start_y and target_x/target_y are optional coordinate pairs measured from the corresponding element's top-left in WPF DIPs; default is its center. Deltas are in the source element's local DIPs, including its transforms. button: left/right/middle. duration_ms: 100-10000, default 500. Brings the source window forward and moves the cursor. Both endpoints must be visible and unobstructed; no scrolling during the drag. Success reports input delivery, not drop acceptance: verify properties or a screenshot afterwards. STATE-CHANGING. Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: button, delta_x, delta_y, start_x, +10 more.
wpf_evaluate_bindingA
Explain WHY a property has its current value — the go-to tool for 'why is X empty/wrong/disabled?'. Reports the value source (Local, Style, Binding, Inherited, Default, ...), the effective value, and whether it's animated/coerced. When the value comes from a binding, it also resolves the binding path hop-by-hop against the source (DataContext / ElementName / RelativeSource / Source) and reports each segment's value and type, pinpointing exactly where a broken binding fails (e.g. a null intermediate, or a misspelled property that doesn't exist on the DataContext type). Complements wpf_get_bindings (which lists bindings) by actually evaluating one.
Inputs: property_name (required), element_handle (required).
wpf_explain_triggersA
Explain an element's triggers and where a value comes from — for 'why doesn't this trigger fire?' and 'which style/setter set this value?'. Lists the element's Style triggers (walking BasedOn) AND its ControlTemplate triggers (where most visual-state triggers live, e.g. IsMouseOver/IsEnabled on a Button), each EVALUATED against the current state: the condition (property=expected), the property's CURRENT value, whether it matches, whether the trigger is active, and the setters it applies. This tells you a trigger isn't firing because its condition property currently holds a different value. Pass property_name to also attribute that property's effective value to its source: a specific style setter (which style, which setter) or an active trigger (which condition), or local/inherited/default.
Inputs: element_handle (required), property_name.
wpf_export_testA
Export a stopped recording as file-name/content pairs: xunit (default) produces a runnable .NET 8 test project plus workflow.json; json returns only workflow.json. Save these files to a new directory, set WPF_TEST_APP and WPFINSPECT_PATH, then dotnet test. Tests start a fresh app. Explicit recorded assertions verify outcomes.
Inputs: format.
wpf_export_treeC
Export visual tree to XAML or JSON
Inputs: format, element_handle.
wpf_find_elementsA
Query elements across all open windows. Filters combine with AND: automation_id (exact, case-sensitive AutomationProperties.AutomationId), type_name (partial match, e.g. 'Button' matches 'System.Windows.Controls.Button'), element_name (x:Name substring), text (visible text content — matches a Button's caption, TextBlock text, Window title, AutomationProperties.Name, ToolTip; case-insensitive substring), property_filter (object of property name → expected value substring, e.g. {"IsEnabled": "True"}), visible_only (exclude collapsed/hidden elements — recommended when looking for something the user can see). PREFER text over dumping the tree: e.g. text='Save' + type_name='Button' finds the Save button directly. Results include text, automationId, isVisible, isEnabled and screenBounds (device pixels) so you can pick the right element without extra calls. Returns up to max_results (default 50).
Inputs: text, type_name, max_results, root_handle, +4 more.
wpf_find_elements_deepA
Deep search for ALL elements matching criteria (no result limit). Requires at least type_name, element_name, text or automation_id to avoid returning the entire tree. Same filters as wpf_find_elements: automation_id (exact, case-sensitive), type_name (partial match), element_name (x:Name substring), text (visible text content), property_filter, visible_only. Use root_handle to limit scope.
Inputs: text, type_name, root_handle, element_name, +3 more.
wpf_get_binding_errorsA
List all binding errors captured since application start. Errors are detected via WPF trace listener. Use wpf_clear_binding_errors to reset the list.
Inputs: no named parameters.
wpf_get_bindingsB
Get all data bindings for an element with their status
Inputs: element_handle (required).
wpf_get_data_contextA
Get the DataContext for an element, including type info, properties, INPC status, and inheritance chain up the visual tree. Essential for diagnosing binding path errors.
Inputs: element_handle (required).
wpf_get_element_propertiesC
Get all dependency properties of a UI element
Inputs: element_handle (required).
wpf_get_layout_infoC
Get layout information (ActualWidth, ActualHeight, Margin, etc.)
Inputs: element_handle (required).
wpf_get_recordingA
Get the current recording state and versioned workflow JSON, with stable selectors instead of session handles.
Inputs: no named parameters.
wpf_get_resourcesC
Enumerate resource dictionaries and their contents
Inputs: scope, element_handle.
wpf_get_stylesC
Get applied styles and templates for an element
Inputs: element_handle (required).
wpf_get_visual_treeA
Get the visual tree hierarchy. Use root_handle to start from a specific element (from wpf_find_elements). Use max_depth to control depth (1-100, default 25). For deep UIs like AvalonDock, increase max_depth or use root_handle to zoom into a subtree.
Inputs: max_depth, root_handle.
wpf_highlight_elementC
Visually highlight an element in the running application
Inputs: element_handle (required), duration_ms.
wpf_list_processesA
List all running WPF applications available for inspection
Inputs: no named parameters.
wpf_move_mouseA
Move the real mouse to a visible element without clicking. Optional x/y are paired local WPF DIPs, default center. hover_ms (0-5000, default 500) waits with the UI responsive for hover/tooltip handlers. Supports native content hosted in HwndHost. Activates the target window; requires a visible unobstructed desktop. Verify tooltips with a screen screenshot. STATE-CHANGING. Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: x, y, hover_ms, root_handle, +2 more.
wpf_recordA
Start/stop/status/clear a linear workflow recording in the attached app. Captures subsequent input actions (including drag/touch), finds, successful waits and assertions using stable selectors. Stop and export before clearing. Recording persists across CLI invocations until the target exits; values are stored as plain text. Calls must be sequential while recording.
Inputs: action (required), name.
wpf_replayA
Replay a versioned workflow against the attached app, resolving fresh unique selectors. Changes app state; stop recording first. Explicit waits handle async UI changes. Stops at first failure without rollback; failedStep is one-based. Physical actions need an interactive desktop. Deadline max 120 seconds; queries stay available, other mutations are rejected.
Inputs: workflow (required), timeout_ms.
wpf_reportA
Collect a bounded diagnostic report across open windows or a subtree: current binding/validation errors, disabled/invisible/zero-size counts and recent process-wide binding traces. Limits: max_elements 1-2000, max_depth 1-100, max_findings 1-500. State counts are observations, not defects. Includes coverage and truncation reasons; does not realize virtualized items or change the UI.
Inputs: max_depth, root_handle, max_elements, max_findings.
wpf_revert_propertyA
Undo live property edits made with wpf_set_property. By default reverts the most recent edit; pass element_handle and/or property_name to target a specific one, or all=true to undo every pending edit. Restores whatever held the property before (a binding, a local value, or nothing — falling back to style/inherited/default). Returns how many were reverted and how many edits remain pending. Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: all, root_handle, automation_id, property_name, +1 more.
wpf_scrollA
Send a real mouse wheel event over a visible element. delta is signed wheel units: 120 = one notch, positive scrolls up (or right with horizontal=true), negative down/left; nonzero range -12000..12000. Optional paired x/y are local WPF DIPs, default center. Moves the mouse and activates the app. Supports native hosted canvases. The app decides whether to scroll, zoom or ignore input; verify the result. STATE-CHANGING. Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: delta (required), x, y, horizontal, +3 more.
wpf_select_itemA
Select an item in a ComboBox, ListBox, ListView or TabControl by visible text (item_text, case-insensitive substring) or zero-based index. PREFER this over clicking for dropdowns/lists: it works even when items are virtualized (not yet in the visual tree) and raises proper selection events. On failure the error lists the available items. STATE-CHANGING. Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: index, item_text, root_handle, automation_id, +1 more.
wpf_send_keysA
Send a keyboard shortcut / key combination to a WPF element (or to whatever currently has keyboard focus, when both element_handle and automation_id are omitted). Examples: 'Ctrl+S', 'Ctrl+Shift+F', 'Enter', 'Escape', 'F5', 'Alt+F4', 'Win+R'. Modifiers: Ctrl, Shift, Alt, Win. Keys: A-Z, 0-9, F1-F12, Enter, Esc, Tab, Space, Backspace, Delete, Insert, Home, End, PageUp, PageDown, Up, Down, Left, Right. Uses OS keyboard input - brings the target window to the foreground. STATE-CHANGING. Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: keys (required), root_handle, automation_id, element_handle.
wpf_set_propertyA
Live-edit a dependency property on an element at runtime, to test whether a planned UI change is effective without rebuilding. The value is a string converted to the property's type: e.g. property_name='Margin' value='20,0,20,0', property_name='Visibility' value='Collapsed', property_name='Background' value='Red' (or '#FF0000'), property_name='Width' value='300', value='{null}' for null. Returns the coerced value read back and what previously held the property (Binding/Local/Unset). Setting a data-bound property replaces the binding with a local value; wpf_revert_property restores it. Pair with wpf_capture_screenshot to see the effect, then revert. STATE-CHANGING (reversible via wpf_revert_property). Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: value (required), property_name (required), root_handle, automation_id, +1 more.
wpf_set_textA
Set the text/value of a UI element (TextBox, ComboBox, etc.). By default uses UI Automation IValueProvider.SetValue (clean, no focus needed, raises proper events). Falls back to setting TextBox.Text or PasswordBox.Password directly, or a reflected string 'Text' property. Set physical=true to focus the element and type via OS keyboard input (clears existing text with Ctrl+A/Delete first, then types each character; moves window focus). STATE-CHANGING. Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: text (required), physical, root_handle, automation_id, +1 more.
wpf_snapshotA
Capture a snapshot of an element's subtree (layout metrics, visibility, alignment, brushes, text) and store it under a label, to diff later with wpf_diff. Workflow: wpf_snapshot(label='before') → make a change (e.g. wpf_set_property) → wpf_snapshot(label='after') → wpf_diff('before','after') to see exactly what moved. element_handle sets the subtree root (omit for the whole main window); max_depth default 25. Returns the label and how many elements were captured.
Inputs: label, max_depth, element_handle.
wpf_touch_gestureA
Inject native Windows touch input into a visible WPF element. gesture: tap, long_press, swipe (pan), pinch (zoom), rotate. x/y is an optional local WPF DIP pair (default center). swipe requires delta_x/delta_y (omitted axis zero). pinch requires scale (0.1-10, excluding 1; above 1 spreads two fingers). rotate requires angle_degrees (-360 to 360, nonzero; positive clockwise). radius optionally sets initial finger distance from center in local DIPs for pinch/rotate (minimum 4); default fits the element. The complete path must stay visible inside the element. duration_ms defaults: tap 100, long_press 1000, others 700; limits: tap 50-500, long_press 500-10000, others 100-10000. Requires an interactive Windows 8+ desktop. Activates the window. Success means touch input sent, not gesture recognition: the application must support touch/manipulations. STATE-CHANGING. Target by exactly one of element_handle or automation_id (exact, case-sensitive AutomationProperties.AutomationId). Use root_handle with automation_id to scope lookup; missing or duplicate IDs fail before input.
Inputs: gesture (required), x, y, scale, +8 more.
wpf_wait_for_elementA
Wait until an element matching the criteria satisfies a condition, polling in the target app so you don't have to sleep-and-retry. Identify the element with automation_id (exact, case-sensitive), type_name, element_name and/or text (same matching as wpf_find_elements). condition: 'visible' (default — element exists and is on screen), 'exists' (in the tree even if not visible), 'enabled' (visible and IsEnabled=true), 'hidden' (no matching visible element — e.g. a spinner disappeared). Returns matched (bool), waited_ms, and matched_handle/element_type when found. Use after a click that triggers async work (dialog opens, spinner clears, button enables) before the next step. timeout_ms default 10000 (max 25000); poll_interval_ms default 250.
Inputs: text, condition, type_name, timeout_ms, +4 more.
wpf_watch_propertyC
Monitor a property for changes
Inputs: property_name (required), element_handle (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 38 tools
Most tools have clearly distinct purposes, especially the input, inspection, and recording groups. A few areas overlap—wpf_find_elements vs wpf_find_elements_deep, and the binding/trigger/property diagnostic tools—but the descriptions generally explain when to use each.
All tools use a consistent wpf_ snake_case prefix with predictable verb_noun or action naming. The convention is stable throughout despite the large surface.
The server exposes 38 tools, which is well above a manageable set even for a broad WPF inspection/automation domain. Many capabilities are useful, but the set is heavy enough that related tools could likely be consolidated or grouped.
Coverage is very broad: visual tree, properties, layout, styles, bindings, errors, triggers, input simulation, screenshots, recording/replay, and test export. Minor lifecycle gaps remain, such as no explicit detach or window-enumeration tool, but core inspection and automation workflows are well covered.
Maintenance
Related MCP Connectors
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
Real desktops for AI agents, on machines you choose: screenshot, type, click, hire more agents.
Connect ChatGPT, Claude, Cursor or VS Code to your Windows PC: files, terminal, browser, apps.
Live browser debugging for AI assistants — DOM, console, network via MCP.
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables AI coding agents to debug .NET applications with breakpoints, stepping, variable inspection, and GUI automation for WPF, WinForms, and Avalonia apps.13572 PyPI8MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to see, locate UI elements, and operate any Windows desktop app through natural language, using accessibility-tree matching with optional vision-model fallback, plus an autonomous visual loop with introspection and meta-learning.14MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to launch, inspect, and operate WPF, WinForms, and WinUI desktop applications through UI Automation, with compact snapshots, background actions, state verification, and export to regression tests.22MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to inspect and drive native Windows desktop applications (WinForms, WPF, WinUI 3, and WebView2 hybrids) through Microsoft UI Automation by capturing interactive control snapshots, then clicking, filling, and asserting on elements via ephemeral refs or semantic screen-map targets. Mutating actions are dry-run by default and gated behind explicit arming, allow-lists, and a kill switch for lawful, assisted QA testing.MIT