AI Tooling Debugging
The Problem

A button does nothing when you tap it. No crash. No exception. The markup compiles, the page renders, the button appears enabled, it just sits there.

Silent binding failures are the most time-consuming class of bug in XAML development because they give you nothing to work with.

If you've built anything with XAML, you've been here. No error. No stack trace. Just a control that quietly ignores your intent.

The traditional debugging path looks like this: read the XAML, scan for typos, check the code-behind, add some debug output, rebuild, run, check output, repeat. Depending on the complexity of the page, that's 15–60 minutes of your life.

There's a faster way.

The Solution

Runtime Inspection with Uno Platform App MCP

Uno Platform provides a local MCP server (App MCP) that connects your AI agent to your running application. Instead of guessing what's happening at runtime, the agent can inspect the live visual tree, check DataContext values, and read binding states directly.

Here's how that changes the debugging workflow.

Walkthrough

A Real Example: The Missing Command

Setup

An EditProfilePage has a Save button. The page uses MVUX with a partial record model. The button is bound to a command:

XAML
<Button Content="Save" Command="{Binding SaveProfile}" />

The model has a method that should generate the command:

C#
public partial record EditProfileModel
{
    public async ValueTask SaveProfle(CancellationToken ct)
    {
        // save logic
    }
}

The app builds. The page renders. The button appears. Nothing happens when you tap it.

1 Inspect the Running App

With the app running, ask your AI agent:

"Using App MCP, inspect the Save button on EditProfilePage. Get a visual tree snapshot focused on the Button element. Call uno_app_get_element_datacontext on the Save button. Report: Command binding value, DataContext type and instance, IsEnabled state."

2 Read the Evidence

The agent reports back:

  • The Button exists in the visual tree
  • IsEnabled is true
  • The DataContext is a valid EditProfileModel instance
  • The Command property is null

That's the diagnosis. The DataContext is fine, the model is injected correctly. But the Command binding resolved to nothing.

3 Cross-Reference the Binding Path

Now you know exactly where to look. The XAML binds to SaveProfile. MVUX generates commands from public methods on the model, using the method name as the command name.

Look at the method name again: SaveProfle. Missing an "i."

MVUX generated a command called SaveProfle (matching the method). The XAML binds to SaveProfile. No match. No error. Just null.

4 Fix and Verify

Rename the method to SaveProfile. Rebuild. Run. Then verify:

"Using App MCP, inspect the Save button again. Confirm the Command property is now non-null. Use uno_app_pointer_click to tap the button and take a screenshot showing the result."

The agent confirms the Command resolves to a non-null IAsyncCommand. The button works.

Total time: ~2 minutes
Why It Works

The key insight is that uno_app_get_element_datacontext tells you the truth about runtime state. When the DataContext is valid but a specific property (like Command) is null, the problem is in the binding path, the name doesn't match what's available on the DataContext. Every time.

Without runtime inspection, you're working backwards from symptoms. With it, you're working forward from evidence.

The Pattern

The Pattern for Any Silent Binding Failure

This isn't specific to commands. The same approach works for any binding that silently fails:

  1. Inspect the element with App MCP's visual tree snapshot
  2. Check the DataContext with uno_app_get_element_datacontext
  3. Compare what the binding expects vs. what the DataContext actually provides
DataContextBound PropertyDiagnosis
NullAnyDataContext not set — check page registration, DI, or navigation
Valid, wrong typeAnyWrong model injected — check route registration
Valid, correct typeNullBinding path doesn't match a property on the model
Valid, correct typeHas valueBinding works — problem is elsewhere (logic, not binding)

That table covers about 90% of silent binding failures.

Checklist

Binding Verification Checklist

Use this after any change that touches bindings:

DataContext is set and non-null
Binding path matches the MVUX-generated property name exactly (case-sensitive)
Property type matches expected type (bool for ToggleSwitch.IsOn, string for TextBlock.Text)
For commands: IAsyncCommand instance is non-null
For two-way bindings: Mode=TwoWay is set in XAML
State updates reflect in visual tree after interaction
Get Started

Getting Started

If you want to try this workflow, you need two things:

  1. Uno Platform App MCP running locally, connected to your running app
  2. An MCP-capable AI agent (Claude Code, Codex CLI, VS Code with Copilot, etc.)

Setup takes about 5 minutes:

Terminal
claude mcp add --scope user --transport stdio "uno-app" -- dotnet dnx -y uno.devserver --mcp-app