{
  "markdown": "# XamlMcp\n\n<!-- mcp-name: io.github.trrahul/xamlmcp -->\n\n[XamlMcp](https://www.rahultr.dev/xamlmcp/) is an open-source XAML MCP server and AI inspection\ntoolkit for Avalonia, WPF, WinUI 3, and .NET MAUI. It lets Claude Code, Codex, GitHub Copilot, and\nother MCP clients inspect and drive a running application: walk the visual or logical tree, read\nand write properties, inspect styles and resources, capture screenshots, send input, invoke\ncommands and automation patterns, and observe changes over an authenticated local transport.\n\nSee the [XamlMcp installation and configuration guide](https://www.rahultr.dev/xamlmcp/) for a\nfocused setup path across supported frameworks and AI clients.\n\nThe current release is `1.0.0-preview.3`. It supports Avalonia, modern .NET WPF,\nself-contained unpackaged WinUI 3, and .NET MAUI on Windows and Android. Protocol version 2 is\nstable. Native MAUI nodes, iOS, and Mac Catalyst are unsupported.\n\nSee the [changelog](CHANGELOG.md) for user-facing release history and the\n[framework feature and tool matrix](docs/framework-feature-matrix.md) for per-tool support and\ncapability limits. The [preview release guide](docs/preview-release.md) explains the package roles,\ninstallation options, and verification commands.\n\n## Packages\n\n| Package | What it is |\n|---|---|\n| `XamlMcp.Avalonia` | In-process agent for Avalonia apps (net8.0, Avalonia 11.3.18+ and 12.x) |\n| `XamlMcp.Wpf` | In-process agent for modern .NET WPF apps (net8.0-windows) |\n| `XamlMcp.WinUI` | In-process agent for unpackaged WinUI 3 apps (Windows App SDK 2.3.1) |\n| `XamlMcp.Maui` | Logical agent for .NET MAUI 10.0.80 (`net10.0`, Windows, and Android API 24+; screenshots require API 26+) |\n| `XamlMcp.Windows.Input` | Shared guarded Win32 raw-input core used by Windows framework agents |\n| `XamlMcp.Agent.Hosting` | Framework-neutral desktop discovery, authentication, and named-pipe host |\n| `XamlMcp.Protocol` | Shared JSON-RPC contract — DTOs and framing; no UI-framework dependency |\n| `XamlMcp.Server` | Stdio MCP server: a `dotnet tool` named `xamlmcp` that connects AI clients to running agents |\n\n## Install\n\nPrerequisite: the app you inspect can target .NET 8 or later, but the `xamlmcp` tool (and\nbuilding this repo or the sample from source) needs the **.NET 10 SDK/runtime**.\n\nAdd the agent package for your UI framework:\n\n```\ndotnet add package XamlMcp.Avalonia --version 1.0.0-preview.3\ndotnet add package XamlMcp.Wpf --version 1.0.0-preview.3\ndotnet add package XamlMcp.WinUI --version 1.0.0-preview.3\ndotnet add package XamlMcp.Maui --version 1.0.0-preview.3\n```\n\nThe agent's floor is **Avalonia 11.3.18**. If your project pins older references (the\ncurrent `avalonia.app` template pins 11.3.0) restore fails with a NU1605 package-downgrade\nerror — bump your `Avalonia.*` package references to at least 11.3.18.\n\nInstall the MCP server tool:\n\n```\ndotnet tool install --global XamlMcp.Server --version 1.0.0-preview.3\n```\n\nYou can also run the server without a global installation:\n\n```\ndnx XamlMcp.Server@1.0.0-preview.3\n```\n\n## Attach the Avalonia agent\n\nTwo entry points provide explicit diagnostic opt-in. Nothing listens unless you enable the agent\nper build (option B) or per launch (option A):\n\n```csharp\nusing XamlMcp.Avalonia;\n\n// Option A - fluent, in BuildAvaloniaApp. Compiled in, but INERT unless the\n// XAML_MCP=1 environment variable is set when the app launches.\npublic static AppBuilder BuildAvaloniaApp()\n    => AppBuilder.Configure<App>()\n        .UsePlatformDetect()\n        .AttachXamlMcp();\n\n// Option B - on the Application instance (e.g. in OnFrameworkInitializationCompleted).\n// Marked [Conditional(\"DEBUG\")]: the CALL SITE disappears from YOUR Release builds.\npublic override void OnFrameworkInitializationCompleted()\n{\n    this.AttachXamlMcp();\n    base.OnFrameworkInitializationCompleted();\n}\n```\n\nWhy two shapes? `[Conditional]` requires a `void` method, so the fluent `AppBuilder`\noverload can't use it and gates on the environment variable instead. And why not a plain\n`#if DEBUG` inside the package? That would gate on how *this package* was compiled at pack\ntime and could never see *your* app's configuration at all. Both overloads instead gate\non your build configuration or your launch environment.\n\nKnow the difference: option B's call is **gone** from your Release binaries; option A's\ncode ships in Release but stays inert unless `XAML_MCP=1` is present at launch — anyone\nwho controls the launch environment can enable it. If you need hard exclusion with the\nfluent shape, wrap the `.AttachXamlMcp()` line in your own `#if DEBUG`.\n\n## Attach the WPF agent\n\nCall the extension on the WPF `Application` in `OnStartup`:\n\n```csharp\nusing System.Windows;\nusing XamlMcp.Wpf;\n\npublic partial class App : Application\n{\n    protected override void OnStartup(StartupEventArgs e)\n    {\n        this.AttachXamlMcp();\n        base.OnStartup(e);\n    }\n}\n```\n\nThe WPF method is `[Conditional(\"DEBUG\")]`, so the call site disappears from the consuming app's\nRelease build. There is no environment-enabled WPF overload. The agent uses the\n`Application.Dispatcher` that performs attachment. Windows and controls owned by secondary WPF UI\nthreads are excluded.\n\n## Attach the WinUI agent\n\nAttach on the WinUI UI thread, explicitly register each `Window`, and keep the calls inside the\napplication's diagnostic build gate:\n\n```csharp\nusing Microsoft.UI.Xaml;\nusing XamlMcp.WinUI;\n\npublic partial class App : Application\n{\n    private WinUiXamlMcpSession? _xamlMcp;\n    private IDisposable? _windowRegistration;\n\n    protected override void OnLaunched(LaunchActivatedEventArgs args)\n    {\n        var window = new MainWindow();\n#if DEBUG\n        var session = WinUiXamlMcp.Attach();\n        _xamlMcp = session;\n        _windowRegistration = session.RegisterWindow(window);\n        window.Closed += async (_, _) =>\n        {\n            _windowRegistration?.Dispose();\n            await session.DisposeAsync();\n        };\n#endif\n        window.Activate();\n    }\n}\n```\n\n`Attach()` is not conditionally compiled: the caller owns the `#if DEBUG` or equivalent diagnostic\ngate. One session supports one `DispatcherQueue` and explicitly registered windows on that queue.\nThe supported floor is Windows App SDK 2.3.1, target framework\n`net8.0-windows10.0.19041.0`, Windows 10 1809 (`10.0.17763.0`), and `win-x64`.\n\nWinUI support is unpackaged. Use `WindowsPackageType=None`,\n`WindowsAppSDKSelfContained=true`, and publish to a fresh directory:\n\n```powershell\ndotnet publish MyWinUiApp.csproj -c Release -r win-x64 --self-contained true -o artifacts/winui\n```\n\nThe publish output must retain the generated `.xbf` and `.pri` resources. MSIX/package identity,\ncertificates, Store distribution, XAML Islands, and multiple UI threads are unsupported.\n\n## Attach the .NET MAUI agent\n\nCall `UseXamlMcp()` while building the MAUI app, inside the application's diagnostic build gate:\n\n```csharp\nusing XamlMcp.Maui;\n\npublic static MauiApp CreateMauiApp()\n{\n    var builder = MauiApp.CreateBuilder()\n        .UseMauiApp<App>();\n\n#if DEBUG\n    builder.UseXamlMcp();\n#endif\n\n    return builder.Build();\n}\n```\n\nThe same package and `UseXamlMcp()` call work in unpackaged Windows applications and debuggable\nAndroid applications on MAUI 10.0.80. The package does not inspect the consumer's configuration,\nso the caller must own the `#if DEBUG` or equivalent diagnostic gate. Android projects must set\n`SupportedOSPlatformVersion` to `24.0` or later. Screenshots require API 26 or later.\n\nOn Windows, the agent writes a discovery file under `%LOCALAPPDATA%/XamlMcp/instances/`\n(override the directory with `XAML_MCP_DIR`) and serves JSON-RPC 2.0 on a current-user named pipe.\nOn Android, it listens only on device loopback and stores a per-launch descriptor in app-private\nstorage. The server reads that descriptor through debuggable `run-as` access and creates an owned\n`adb forward` only while connecting. Both transports require the per-launch token before any\ninspection call.\n\nTo discover an Android app, pass its application ID to the MCP server. Select a device explicitly\nwhen more than one authorized device is online:\n\n```powershell\nclaude mcp add xamlmcp -- xamlmcp --android-package dev.example.app --android-device emulator-5554\n```\n\nThe Windows build prerequisites are the .NET 10 SDK and MAUI Windows workload. Android also\nrequires the .NET Android workload and Android SDK platform tools (`adb`). iOS and Mac Catalyst\nare unsupported.\n\n## Connect an AI client\n\nXamlMcp is a local stdio MCP server. Claude Code or Codex starts it when the client session needs\nit; you do not run a persistent server process.\n\nThis repository includes portable project configuration for both clients:\n\n- [`.mcp.json`](.mcp.json) configures Claude Code.\n- [`.codex/config.toml`](.codex/config.toml) configures Codex in a trusted checkout.\n\nBoth configurations run the pinned preview directly from NuGet with `dnx`, so they require the\n.NET 10 SDK but no global tool installation. After cloning the repository, open a new client\nsession and verify the registration:\n\n```powershell\nclaude mcp get xamlmcp\ncodex mcp get xamlmcp\n```\n\nTo register the pinned preview for your user account or from another project, run:\n\n```powershell\nclaude mcp add --scope user xamlmcp -- dnx XamlMcp.Server@1.0.0-preview.3\ncodex mcp add xamlmcp -- dnx XamlMcp.Server@1.0.0-preview.3\n```\n\nAlternatively, install the tool globally and register its `xamlmcp` command:\n\n```powershell\ndotnet tool install --global XamlMcp.Server --version 1.0.0-preview.3\nclaude mcp add --scope user xamlmcp -- xamlmcp\ncodex mcp add xamlmcp -- xamlmcp\n```\n\nIf a client already has a server named `xamlmcp`, remove or update that entry before adding the\nnew one. Use `claude mcp remove xamlmcp --scope <local|user|project>` or\n`codex mcp remove xamlmcp` as appropriate.\n\nLaunch an instrumented application next. Set `XAML_MCP=1` when using Avalonia's fluent attachment\nform. Then ask the client to call **`list-apps`** → **`attach(instanceId)`** → any tool below.\nInteger PID attach remains a Windows desktop compatibility path.\n\n| Tool | Purpose |\n|---|---|\n| `list-apps` | Running instrumented apps (opaque instance id, platform, and sanitized metadata; desktop entries also include pid) |\n| `attach` | Connect to one app; reports its per-tool capability flags |\n| `detach` | Release the current app connection and its transport resources |\n| `tree` | Visual/logical tree snapshot; the source of node ids |\n| `search` | Find nodes by automation id / type / name / style class / pseudo-class / text |\n| `ancestors` | Ancestor chain of a node |\n| `props` | Properties with value, source/priority, automation patterns, command slots |\n| `set-prop` | Write a property, or clear a local value (`unset`) |\n| `styles` | Applied style selectors and setters (capability-gated) |\n| `bindings` | Active bindings, source/path/status/errors, DataContext origin, and template identity |\n| `failures` | Bounded binding/dispatcher failure evidence after an optional action correlation cursor |\n| `resources` | Resolved resources visible at a node or app scope |\n| `pseudo-class` | Toggle `:pointerover`, `:pressed`, … |\n| `screenshot` | PNG of a window or node, with an optional same-capture node map — returned as a real MCP image |\n| `wait-for` | Bounded polling for existence, visibility, enabled/focused state, or a property predicate |\n| `hit-test` | Deepest-first visual stack at logical coordinates, with node references and scaling |\n| `input` | Synthesized clicks, keys, text, wheel |\n| `action` | Automation patterns (invoke/toggle/select/…) and bound `ICommand`s |\n| `assets` | Enumerate opaque framework asset identifiers (`avares://`, WPF pack, `xamlmcp-asset:///`, or `maui-asset:///`) |\n| `open-asset` | Read an asset (images as images, text as text) |\n| `dialog-wait` | Driver, opt-in: wait for a native dialog (file picker, message box) the app opened |\n| `dialog-act` | Driver, opt-in: act on it — `set-file-name`, `accept`, `cancel`, `select-button` |\n| `window-list` | Driver, opt-in: the app's top-level windows with state and bounds |\n| `window-act` | Driver, opt-in: `activate` / `move` / `resize` / `close` a window |\n\nThree things AI-client authors should know:\n\n- **Targeting:** node tools accept either an exact `{snapshotId, nodeId}` target or a locator using\n  `automationId`, `name`, `type`, `text`, or `styleClass`, optionally scoped by `within`. A locator\n  must resolve uniquely unless `nth` is explicit; ambiguity returns typed candidates instead of\n  selecting a node silently.\n\n- **Observation:** every mutating tool (`set-prop`, `pseudo-class`, `input`, `action`)\n  waits a settle window (default 250 ms) and returns a digest of what changed. For rapid\n  sequences pass `settleMs: 0` or `observe: false`. On Avalonia and WPF, the same result includes a\n  `failureCursor`; pass it to `failures` to retrieve only binding or dispatcher failures observed\n  after that action. Optional exact `categories` filter the page. When `truncated` is true, pass\n  `nextCursor` back to retrieve the next page without skipping evidence. Cursors expire on detach\n  or replacement.\n- **Snapshots:** exact node references remain usable across the current and previous three snapshots\n  while the node stays live. Use locators for workflows that must survive re-querying; a\n  `stale-snapshot` or `stale-node` error means resolve the target again.\n\n### WPF capability notes\n\n- `tree`, type/name/text `search`, `ancestors`, properties, resources, screenshots, routed input,\n  actions, observation, and packaged assets are enabled and live-verified.\n- WPF has no Avalonia-style class or pseudo-class collection. Style-class/pseudo-class search and\n  `pseudo-class` mutation return `unsupported-capability`.\n- `styles` is enabled but deliberately degraded: WPF exposes declared styles, setters, triggers,\n  and value sources, not a complete applied selector cascade. Read `degraded` and\n  `degradationReason` in the result.\n- `bindings` is enabled. It reports simple and composite binding declarations, current status and\n  validation errors, DataContext inheritance, templated parent, and named control/content/item/header\n  template slots. WPF does not retain a converter exception that escapes directly into application\n  code; converter failures represented in the binding expression are reported as `converter-error`.\n- `failures` is enabled and captures bounded binding trace and dispatcher-exception evidence. It\n  starts capture only before the first mutation or `failures` query, preserves existing WPF trace\n  listeners, and does not mark dispatcher exceptions handled. WPF requires a process-wide trace\n  refresh that public APIs cannot reverse; detach removes XamlMcp's listener and restores its source\n  level, but the framework's internal tracing infrastructure remains initialized for that process.\n- Routed input raises WPF events and reports mechanism `routed`; it does not claim physical mouse,\n  focus, capture, or `Mouse.DirectlyOver` equivalence. Non-empty `modifiers` return\n  `unsupported-capability` because routed event construction cannot inject modifier state.\n  `input-raw` is false because the public `InputManager.ProcessInput` proof failed those\n  requirements too.\n- WPF screenshots render through `RenderTargetBitmap`. Separate popups must be captured by their\n  own tree ref; native child HWND and GPU/airspace content are outside that render.\n- `assets` enumerates SDK-generated `*.g.resources` and opens only identifiers it issued. This is a\n  compiler convention—WPF has no public package-resource enumeration API—and ordinary copied\n  `Content` files are not advertised.\n\n### WinUI capability notes\n\n- Visual `tree`, type/name/text `search`, ancestors, resources, screenshots, semantic actions,\n  command slots, unpackaged assets, and bounded observation are enabled and live-verified.\n- `tree.logical=false` and `props.complete=false`. Property enumeration uses the documented known\n  dependency-property catalog; reads and writes outside it return typed errors rather than a\n  completeness claim.\n- `styles` is enabled but degraded because WinUI does not expose a complete applied selector\n  cascade. Screenshots use `RenderTargetBitmap`; native HWND, airspace/GPU content, and separate\n  top-level surfaces retain the documented rendering limits.\n- `input` is enabled only for `mechanism: \"raw\"`; routed injection returns\n  `unsupported-capability`. Raw click, move, wheel, key, and type use guarded `SendInput`: the\n  registered owner must be the exact foreground root, pointer coordinates must still resolve to\n  that HWND, and an explicit keyboard target must accept focus. These checks and injection are not\n  atomic, so raw input is intended only for explicitly enabled diagnostic sessions.\n- Pseudo-class mutation and style-class/pseudo-class search remain disabled. Visual states are not\n  presented as pseudo-classes.\n- `bindings` is disabled and returns `unsupported-capability`; WinUI does not expose the required\n  binding-expression graph through a complete public inspection API.\n- `failures` is disabled until equivalent public framework evidence is implemented in M38.\n- Assets are rooted in the unpackaged application directory, use opaque `xamlmcp-asset:///`\n  identifiers, enforce containment and byte limits, and reject traversal and reparse-point paths.\n- Observation is a bounded sampled diff with Window/Popup journaling. Requesting a scoped snapshot\n  mints a fresh snapshot and invalidates older node refs, as on the other desktop agents.\n\n### .NET MAUI capability notes\n\n- `tree` must use `scope: \"logical\"`. Node refs identify MAUI `IVisualTreeElement` objects only;\n  native handler `PlatformView` objects are never returned.\n- Type/name/text/style-class search, ancestors, bindable properties, resources, degraded styles,\n  screenshots, platform actions, packaged assets, and bounded observation are live-verified on\n  Windows and an Android emulator.\n- Property enumeration uses public static `BindableProperty` fields and is incomplete by design.\n  Scalar, enum, color, thickness, rectangle, and point writes are supported where the target type\n  permits them; complex object writes return typed errors.\n- Windows input uses OS-level raw injection and reports `raw`; it does not advertise routed input.\n  Android dispatches touch, wheel, key, and text through the activity/view stack and reports\n  `routed`; it never advertises raw input.\n- Action patterns are node- and platform-dependent. Public `ICommand` slots remain available on\n  both platforms. Windows maps WinUI automation providers; Android maps accessibility actions.\n  Android advertises only actions with a verifiable node-local postcondition; generic\n  click/`invoke` and absolute-percentage `scroll` are deliberately rejected. Read\n  `props.patterns` for the exact accepted verbs on one node.\n- `styles` is deliberately degraded. MAUI visual states are reported as style frames, not protocol\n  pseudo-classes. Pseudo-class mutation/search and native tree scope return\n  `unsupported-capability`.\n- `bindings` is disabled and returns `unsupported-capability`; MAUI does not expose the active\n  binding-expression and source graph required by this contract.\n- `failures` is disabled until equivalent public framework evidence is implemented in M38.\n- Screenshots use WinUI rendering on Windows and PixelCopy with an ordinary-view Canvas fallback\n  on Android. Native/airspace content and unattached handlers retain platform limits.\n- `MauiAsset` items are exposed through opaque `maui-asset:///` identifiers generated by the\n  package's manifest target. Only identifiers issued by `assets` can be opened.\n- Observation uses bounded logical fingerprints plus platform lifecycle journals. A scoped\n  snapshot mints new refs; optional pixel hashes follow the platform screenshot limits.\n- Android supports API 24+. Screenshots require API 26+. iOS and Mac Catalyst are unsupported.\n\n## Native dialogs & window management (Windows, opt-in)\n\nNative file pickers and message boxes are separate Win32 windows — invisible to `tree` and\nunreachable by `input`. The **driver** runs inside `XamlMcp.Server` to cover that boundary. It is\noff by default and Windows-only. Enable it in the command registered with your MCP client:\n\n```powershell\nclaude mcp add --scope user xamlmcp -- dnx XamlMcp.Server@1.0.0-preview.3 --enable-driver\ncodex mcp add xamlmcp -- dnx XamlMcp.Server@1.0.0-preview.3 --enable-driver\n```\n\nIf you installed the global tool, replace `dnx XamlMcp.Server@1.0.0-preview.3` with `xamlmcp`.\nRemove or update an existing `xamlmcp` client entry before registering the Driver-enabled command.\n\nThe choreography: click the button that opens the dialog (`input`/`action`), then\n`dialog-wait` returns a dialog ref plus its structure (button automation ids, whether a\nfile-name edit exists — never control values), then `dialog-act` drives it semantically.\n`window-list`/`window-act` manage the app's own top-level windows (`close` requires\n`confirm: true`).\n\nScope and safety:\n\n- Only dialogs **owned by the attached app's process** are ever matched, and only ones that\n  appeared after your last mutating call — pre-existing windows are never touched.\n- `set-file-name` paths are validated against `--driver-file-roots <p1;p2;…>` (default: your\n  user profile); anything outside is a typed `path-not-allowed` error.\n- Elevated (UAC) apps and non-interactive sessions are unsupported and report typed errors.\n- Dialog refs go stale on detach, dialog close, or app exit — re-run `dialog-wait`.\n\n## Security model\n\n- **Explicit diagnostic opt-in** — each framework section shows the caller-owned build or launch\n  gate; nothing listens unless the application opts in.\n- **Token-first handshake.** Every agent transport must authenticate with its per-launch token\n  before any inspection method is dispatched. Unauthenticated calls get a typed error and the\n  connection closes.\n- **Desktop discovery and pipes.** Windows named pipes use `PipeOptions.CurrentUserOnly`.\n  Discovery files are written owner-only on Unix (0700 directory, 0600 file) and deleted on\n  graceful shutdown; the server prunes entries whose PID is dead or reused.\n- **Android private discovery.** The descriptor stays in app-private storage and is readable by\n  the server only through debuggable `run-as`. The agent binds device loopback, and\n  the server creates and removes the exact ADB forward it owns. Tokens, private paths, device\n  ports, host ports, and raw ADB output never enter MCP results or errors.\n- Tokens and desktop pipe names never appear in MCP output or error messages.\n- **One authenticated session at a time**; later clients queue at the OS until the\n  current session ends.\n\n## Sample\n\n[`samples/SampleApp`](https://github.com/trrahul/XamlMcp/tree/master/samples/SampleApp)\nis a small Avalonia app wired with\n`.AttachXamlMcp()` and something for every tool to touch: a menu bar plus tabbed pages covering\nselection, tree, toggle, text, picker, and scroll/virtualization controls — the same pages the\ncontrol-interaction matrix suite drives end-to-end. Run it and drive it:\n\n```\nXAML_MCP=1 dotnet run --project samples/SampleApp\n```\n\n[`samples/MauiSampleApp`](samples/MauiSampleApp) is the Windows/Android MAUI fixture. Agent\nattachment is enabled in Debug builds, and the Windows target runs unpackaged:\n\n```powershell\ndotnet run --project samples/MauiSampleApp -f net10.0-windows10.0.19041.0\n```\n\nBuild its Android target with the installed SDK tooling:\n\n```powershell\ndotnet build samples/MauiSampleApp/MauiSampleApp.csproj -f net10.0-android -c Debug\n```\n\n(PowerShell: `$env:XAML_MCP=\"1\"; dotnet run --project samples/SampleApp`.)\n\n[`samples/WpfSampleApp`](https://github.com/trrahul/XamlMcp/tree/master/samples/WpfSampleApp)\nis the WPF playground. Its Debug build attaches automatically:\n\n```\ndotnet run --project samples/WpfSampleApp\n```\n\n[`samples/WinUiSampleApp`](samples/WinUiSampleApp) is the self-contained, unpackaged WinUI control\nlab. It exposes stable names for inspection, styles and resources, every supported action pattern,\nobservation digests, screenshots, popup and secondary-window roots, text and binary assets, and a\nnative file dialog for Driver. Agent attachment remains inside `#if DEBUG`.\n\n```powershell\ndotnet run --project samples/WinUiSampleApp -c Debug -p:Platform=x64\n```\n\nFor unattended inspection, pass the sample's off-screen launch switch:\n\n```powershell\ndotnet run --project samples/WinUiSampleApp -c Debug -p:Platform=x64 -- --hidden\n```\n\nRun its real-process MCP coverage with:\n\n```powershell\ndotnet test tests/XamlMcp.WinUI.Tests/XamlMcp.WinUI.Tests.csproj -c Debug --filter FullyQualifiedName~LiveWinUiSampleTests\n```\n\nThe interactive Driver fact is opt-in because it opens a native desktop dialog:\n\n```powershell\n$env:XAMLMCP_DESKTOP_TESTS = \"1\"\ndotnet test tests/XamlMcp.WinUI.Tests/XamlMcp.WinUI.Tests.csproj -c Debug --filter FullyQualifiedName~WinUiDriverLiveTests\n```\n\nThe guarded raw-input proof is also desktop opt-in because it moves the real pointer and requires\nthe test host to receive foreground ownership:\n\n```powershell\n$env:XAMLMCP_DESKTOP_TESTS = \"1\"\ndotnet test tests/XamlMcp.WinUI.Tests/XamlMcp.WinUI.Tests.csproj -c Debug --filter FullyQualifiedName~LiveWinUiInputTests\n```\n\nTo verify the deployable unpackaged output, publish Release to a fresh directory:\n\n```powershell\n$publishDir = \"artifacts/winui-sample/$([Guid]::NewGuid().ToString('N'))\"\ndotnet publish samples/WinUiSampleApp/WinUiSampleApp.csproj -c Release -r win-x64 `\n  --self-contained true -p:Platform=x64 -p:WindowsPackageType=None -o $publishDir\n```\n\nThe output must contain `WinUiSampleApp.exe`, `WinUiSampleApp.pri`, the generated `.xbf` files,\nand both `Assets/fixture.txt` and `Assets/fixture.bin`.\n\n## Building from source\n\n```\ndotnet build                                 # XamlMcp.slnx\ndotnet test                                  # suite on Avalonia 11.3.x\ndotnet test -p:AvaloniaTestVersion=12.1.0    # same suite on the 12.x line\n```\n\nThe solution includes `net10.0-android`, so a full restore/build requires the .NET Android\nworkload. Device tests remain opt-in: set `XAMLMCP_ANDROID_LIVE=1` for the emulator lane and also\nset `XAMLMCP_ANDROID_PHYSICAL=1` for the physical-device lane. Set `XAMLMCP_ANDROID_DEVICE` when\nADB reports more than one authorized device.\n\n## License\n\nApache-2.0 — see [LICENSE](LICENSE).\n",
  "bytes": 26457,
  "sha": "8749dbd8e43d3950edc37f5231996be00cb92d0f17caa5b9f558741c26f4c17a",
  "repo_slug": "trrahul/xamlmcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_trrahul_xamlmcp_50778bc3/readme"
}