
XamlMcp
io.github.trrahul由 GitHub 帳號 trrahul 發布v1.0.0-preview.2更新於 Oct 24, 2026
Inspect and drive Avalonia, WPF, WinUI, and .NET MAUI apps through MCP.
概覽
一個本機 MCP 伺服器,讓 AI 助理透過視覺化樹狀結構檢視並操控執行中的 Avalonia、WPF、WinUI 3 與 .NET MAUI 應用程式。
- 可以做什麼
- 探索並連接已插入檢測代理的應用程式,中斷連線,列出並管理視窗(驅動程式為選用開啟)。走訪視覺化或邏輯樹狀結構,搜尋節點、查看祖先鏈,讀取屬性、樣式、繫結、資源與失敗證據。寫入屬性、切換偽類,等待節點或對節點做命中測試。擷取螢幕截圖,列舉並開啟封裝資源。合成點擊、按鍵、文字與滾輪輸入,叫用自動化模式與繫結命令。等待並操作檔案選擇器、訊息方塊等原生對話框(Windows,選用開啟)。
- 適用情境
- 適合偵錯或測試桌面與 Android 的 XAML 介面:讓助理查看即時視覺化樹狀結構、檢查繫結與樣式、重現輸入,或驅動對話框與視窗,而不必只靠閱讀原始碼推測。
- 執行需求
- 以 .NET 工具或 dnx 透過 stdio 在本機執行,需要 .NET 10 SDK/執行階段。被檢視的應用程式需參考對應的代理套件(Avalonia 11.3.18+、現代 WPF、非封裝 WinUI 3 或 MAUI 10.0.80),並依建置或啟動明確開啟;Avalonia 的串接寫法需設定 XAML_MCP=1。Android 另需 Android 工作負載與 adb。桌面端僅限 Windows;不支援 iOS 與 Mac Catalyst。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 XamlMcp,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
XamlMcp
XamlMcp is an open-source XAML MCP server and AI inspection toolkit for Avalonia, WPF, WinUI 3, and .NET MAUI. It lets Claude Code, Codex, GitHub Copilot, and other MCP clients inspect and drive a running application: walk the visual or logical tree, read and write properties, inspect styles and resources, capture screenshots, send input, invoke commands and automation patterns, and observe changes over an authenticated local transport.
See the XamlMcp installation and configuration guide for a focused setup path across supported frameworks and AI clients.
The current release is 1.0.0-preview.3. It supports Avalonia, modern .NET WPF,
self-contained unpackaged WinUI 3, and .NET MAUI on Windows and Android. Protocol version 2 is
stable. Native MAUI nodes, iOS, and Mac Catalyst are unsupported.
See the changelog for user-facing release history and the framework feature and tool matrix for per-tool support and capability limits. The preview release guide explains the package roles, installation options, and verification commands.
Packages
Install
Prerequisite: the app you inspect can target .NET 8 or later, but the xamlmcp tool (and
building this repo or the sample from source) needs the .NET 10 SDK/runtime.
Add the agent package for your UI framework:
The agent's floor is Avalonia 11.3.18. If your project pins older references (the
current avalonia.app template pins 11.3.0) restore fails with a NU1605 package-downgrade
error — bump your Avalonia.* package references to at least 11.3.18.
Install the MCP server tool:
You can also run the server without a global installation:
Attach the Avalonia agent
Two entry points provide explicit diagnostic opt-in. Nothing listens unless you enable the agent per build (option B) or per launch (option A):
Why two shapes? [Conditional] requires a void method, so the fluent AppBuilder
overload can't use it and gates on the environment variable instead. And why not a plain
#if DEBUG inside the package? That would gate on how this package was compiled at pack
time and could never see your app's configuration at all. Both overloads instead gate
on your build configuration or your launch environment.
Know the difference: option B's call is gone from your Release binaries; option A's
code ships in Release but stays inert unless XAML_MCP=1 is present at launch — anyone
who controls the launch environment can enable it. If you need hard exclusion with the
fluent shape, wrap the .AttachXamlMcp() line in your own #if DEBUG.
Attach the WPF agent
Call the extension on the WPF Application in OnStartup:
The WPF method is [Conditional("DEBUG")], so the call site disappears from the consuming app's
Release build. There is no environment-enabled WPF overload. The agent uses the
Application.Dispatcher that performs attachment. Windows and controls owned by secondary WPF UI
threads are excluded.
Attach the WinUI agent
Attach on the WinUI UI thread, explicitly register each Window, and keep the calls inside the
application's diagnostic build gate:
Attach() is not conditionally compiled: the caller owns the #if DEBUG or equivalent diagnostic
gate. One session supports one DispatcherQueue and explicitly registered windows on that queue.
The supported floor is Windows App SDK 2.3.1, target framework
net8.0-windows10.0.19041.0, Windows 10 1809 (10.0.17763.0), and win-x64.
WinUI support is unpackaged. Use WindowsPackageType=None,
WindowsAppSDKSelfContained=true, and publish to a fresh directory:
The publish output must retain the generated .xbf and .pri resources. MSIX/package identity,
certificates, Store distribution, XAML Islands, and multiple UI threads are unsupported.
Attach the .NET MAUI agent
Call UseXamlMcp() while building the MAUI app, inside the application's diagnostic build gate:
The same package and UseXamlMcp() call work in unpackaged Windows applications and debuggable
Android applications on MAUI 10.0.80. The package does not inspect the consumer's configuration,
so the caller must own the #if DEBUG or equivalent diagnostic gate. Android projects must set
SupportedOSPlatformVersion to 24.0 or later. Screenshots require API 26 or later.
On Windows, the agent writes a discovery file under %LOCALAPPDATA%/XamlMcp/instances/
(override the directory with XAML_MCP_DIR) and serves JSON-RPC 2.0 on a current-user named pipe.
On Android, it listens only on device loopback and stores a per-launch descriptor in app-private
storage. The server reads that descriptor through debuggable run-as access and creates an owned
adb forward only while connecting. Both transports require the per-launch token before any
inspection call.
To discover an Android app, pass its application ID to the MCP server. Select a device explicitly when more than one authorized device is online:
The Windows build prerequisites are the .NET 10 SDK and MAUI Windows workload. Android also
requires the .NET Android workload and Android SDK platform tools (adb). iOS and Mac Catalyst
are unsupported.
Connect an AI client
XamlMcp is a local stdio MCP server. Claude Code or Codex starts it when the client session needs it; you do not run a persistent server process.
This repository includes portable project configuration for both clients:
.mcp.jsonconfigures Claude Code..codex/config.tomlconfigures Codex in a trusted checkout.
Both configurations run the pinned preview directly from NuGet with dnx, so they require the
.NET 10 SDK but no global tool installation. After cloning the repository, open a new client
session and verify the registration:
To register the pinned preview for your user account or from another project, run:
Alternatively, install the tool globally and register its xamlmcp command:
If a client already has a server named xamlmcp, remove or update that entry before adding the
new one. Use claude mcp remove xamlmcp --scope <local|user|project> or
codex mcp remove xamlmcp as appropriate.
Launch an instrumented application next. Set XAML_MCP=1 when using Avalonia's fluent attachment
form. Then ask the client to call list-apps → attach(instanceId) → any tool below.
Integer PID attach remains a Windows desktop compatibility path.
Three things AI-client authors should know:
-
Targeting: node tools accept either an exact
{snapshotId, nodeId}target or a locator usingautomationId,name,type,text, orstyleClass, optionally scoped bywithin. A locator must resolve uniquely unlessnthis explicit; ambiguity returns typed candidates instead of selecting a node silently. -
Observation: every mutating tool (
set-prop,pseudo-class,input,action) waits a settle window (default 250 ms) and returns a digest of what changed. For rapid sequences passsettleMs: 0orobserve: false. On Avalonia and WPF, the same result includes afailureCursor; pass it tofailuresto retrieve only binding or dispatcher failures observed after that action. Optional exactcategoriesfilter the page. Whentruncatedis true, passnextCursorback to retrieve the next page without skipping evidence. Cursors expire on detach or replacement. -
Snapshots: exact node references remain usable across the current and previous three snapshots while the node stays live. Use locators for workflows that must survive re-querying; a
stale-snapshotorstale-nodeerror means resolve the target again.
WPF capability notes
tree, type/name/textsearch,ancestors, properties, resources, screenshots, routed input, actions, observation, and packaged assets are enabled and live-verified.- WPF has no Avalonia-style class or pseudo-class collection. Style-class/pseudo-class search and
pseudo-classmutation returnunsupported-capability. stylesis enabled but deliberately degraded: WPF exposes declared styles, setters, triggers, and value sources, not a complete applied selector cascade. ReaddegradedanddegradationReasonin the result.bindingsis enabled. It reports simple and composite binding declarations, current status and validation errors, DataContext inheritance, templated parent, and named control/content/item/header template slots. WPF does not retain a converter exception that escapes directly into application code; converter failures represented in the binding expression are reported asconverter-error.failuresis enabled and captures bounded binding trace and dispatcher-exception evidence. It starts capture only before the first mutation orfailuresquery, preserves existing WPF trace listeners, and does not mark dispatcher exceptions handled. WPF requires a process-wide trace refresh that public APIs cannot reverse; detach removes XamlMcp's listener and restores its source level, but the framework's internal tracing infrastructure remains initialized for that process.- Routed input raises WPF events and reports mechanism
routed; it does not claim physical mouse, focus, capture, orMouse.DirectlyOverequivalence. Non-emptymodifiersreturnunsupported-capabilitybecause routed event construction cannot inject modifier state.input-rawis false because the publicInputManager.ProcessInputproof failed those requirements too. - WPF screenshots render through
RenderTargetBitmap. Separate popups must be captured by their own tree ref; native child HWND and GPU/airspace content are outside that render. assetsenumerates SDK-generated*.g.resourcesand opens only identifiers it issued. This is a compiler convention—WPF has no public package-resource enumeration API—and ordinary copiedContentfiles are not advertised.
WinUI capability notes
- Visual
tree, type/name/textsearch, ancestors, resources, screenshots, semantic actions, command slots, unpackaged assets, and bounded observation are enabled and live-verified. tree.logical=falseandprops.complete=false. Property enumeration uses the documented known dependency-property catalog; reads and writes outside it return typed errors rather than a completeness claim.stylesis enabled but degraded because WinUI does not expose a complete applied selector cascade. Screenshots useRenderTargetBitmap; native HWND, airspace/GPU content, and separate top-level surfaces retain the documented rendering limits.inputis enabled only formechanism: "raw"; routed injection returnsunsupported-capability. Raw click, move, wheel, key, and type use guardedSendInput: the registered owner must be the exact foreground root, pointer coordinates must still resolve to that HWND, and an explicit keyboard target must accept focus. These checks and injection are not atomic, so raw input is intended only for explicitly enabled diagnostic sessions.- Pseudo-class mutation and style-class/pseudo-class search remain disabled. Visual states are not presented as pseudo-classes.
bindingsis disabled and returnsunsupported-capability; WinUI does not expose the required binding-expression graph through a complete public inspection API.failuresis disabled until equivalent public framework evidence is implemented in M38.- Assets are rooted in the unpackaged application directory, use opaque
xamlmcp-asset:///identifiers, enforce containment and byte limits, and reject traversal and reparse-point paths. - Observation is a bounded sampled diff with Window/Popup journaling. Requesting a scoped snapshot mints a fresh snapshot and invalidates older node refs, as on the other desktop agents.
.NET MAUI capability notes
treemust usescope: "logical". Node refs identify MAUIIVisualTreeElementobjects only; native handlerPlatformViewobjects are never returned.- Type/name/text/style-class search, ancestors, bindable properties, resources, degraded styles, screenshots, platform actions, packaged assets, and bounded observation are live-verified on Windows and an Android emulator.
- Property enumeration uses public static
BindablePropertyfields and is incomplete by design. Scalar, enum, color, thickness, rectangle, and point writes are supported where the target type permits them; complex object writes return typed errors. - Windows input uses OS-level raw injection and reports
raw; it does not advertise routed input. Android dispatches touch, wheel, key, and text through the activity/view stack and reportsrouted; it never advertises raw input. - Action patterns are node- and platform-dependent. Public
ICommandslots remain available on both platforms. Windows maps WinUI automation providers; Android maps accessibility actions. Android advertises only actions with a verifiable node-local postcondition; generic click/invokeand absolute-percentagescrollare deliberately rejected. Readprops.patternsfor the exact accepted verbs on one node. stylesis deliberately degraded. MAUI visual states are reported as style frames, not protocol pseudo-classes. Pseudo-class mutation/search and native tree scope returnunsupported-capability.bindingsis disabled and returnsunsupported-capability; MAUI does not expose the active binding-expression and source graph required by this contract.failuresis disabled until equivalent public framework evidence is implemented in M38.- Screenshots use WinUI rendering on Windows and PixelCopy with an ordinary-view Canvas fallback on Android. Native/airspace content and unattached handlers retain platform limits.
MauiAssetitems are exposed through opaquemaui-asset:///identifiers generated by the package's manifest target. Only identifiers issued byassetscan be opened.- Observation uses bounded logical fingerprints plus platform lifecycle journals. A scoped snapshot mints new refs; optional pixel hashes follow the platform screenshot limits.
- Android supports API 24+. Screenshots require API 26+. iOS and Mac Catalyst are unsupported.
Native dialogs & window management (Windows, opt-in)
Native file pickers and message boxes are separate Win32 windows — invisible to tree and
unreachable by input. The driver runs inside XamlMcp.Server to cover that boundary. It is
off by default and Windows-only. Enable it in the command registered with your MCP client:
If you installed the global tool, replace dnx [email protected] with xamlmcp.
Remove or update an existing xamlmcp client entry before registering the Driver-enabled command.
The choreography: click the button that opens the dialog (input/action), then
dialog-wait returns a dialog ref plus its structure (button automation ids, whether a
file-name edit exists — never control values), then dialog-act drives it semantically.
window-list/window-act manage the app's own top-level windows (close requires
confirm: true).
Scope and safety:
- Only dialogs owned by the attached app's process are ever matched, and only ones that appeared after your last mutating call — pre-existing windows are never touched.
set-file-namepaths are validated against--driver-file-roots <p1;p2;…>(default: your user profile); anything outside is a typedpath-not-allowederror.- Elevated (UAC) apps and non-interactive sessions are unsupported and report typed errors.
- Dialog refs go stale on detach, dialog close, or app exit — re-run
dialog-wait.
Security model
- Explicit diagnostic opt-in — each framework section shows the caller-owned build or launch gate; nothing listens unless the application opts in.
- Token-first handshake. Every agent transport must authenticate with its per-launch token before any inspection method is dispatched. Unauthenticated calls get a typed error and the connection closes.
- Desktop discovery and pipes. Windows named pipes use
PipeOptions.CurrentUserOnly. Discovery files are written owner-only on Unix (0700 directory, 0600 file) and deleted on graceful shutdown; the server prunes entries whose PID is dead or reused. - Android private discovery. The descriptor stays in app-private storage and is readable by
the server only through debuggable
run-as. The agent binds device loopback, and the server creates and removes the exact ADB forward it owns. Tokens, private paths, device ports, host ports, and raw ADB output never enter MCP results or errors. - Tokens and desktop pipe names never appear in MCP output or error messages.
- One authenticated session at a time; later clients queue at the OS until the current session ends.
Sample
samples/SampleApp
is a small Avalonia app wired with
.AttachXamlMcp() and something for every tool to touch: a menu bar plus tabbed pages covering
selection, tree, toggle, text, picker, and scroll/virtualization controls — the same pages the
control-interaction matrix suite drives end-to-end. Run it and drive it:
samples/MauiSampleApp is the Windows/Android MAUI fixture. Agent
attachment is enabled in Debug builds, and the Windows target runs unpackaged:
Build its Android target with the installed SDK tooling:
(PowerShell: $env:XAML_MCP="1"; dotnet run --project samples/SampleApp.)
samples/WpfSampleApp
is the WPF playground. Its Debug build attaches automatically:
samples/WinUiSampleApp is the self-contained, unpackaged WinUI control
lab. It exposes stable names for inspection, styles and resources, every supported action pattern,
observation digests, screenshots, popup and secondary-window roots, text and binary assets, and a
native file dialog for Driver. Agent attachment remains inside #if DEBUG.
For unattended inspection, pass the sample's off-screen launch switch:
Run its real-process MCP coverage with:
The interactive Driver fact is opt-in because it opens a native desktop dialog:
The guarded raw-input proof is also desktop opt-in because it moves the real pointer and requires the test host to receive foreground ownership:
To verify the deployable unpackaged output, publish Release to a fresh directory:
The output must contain WinUiSampleApp.exe, WinUiSampleApp.pri, the generated .xbf files,
and both Assets/fixture.txt and Assets/fixture.bin.
Building from source
The solution includes net10.0-android, so a full restore/build requires the .NET Android
workload. Device tests remain opt-in: set XAMLMCP_ANDROID_LIVE=1 for the emulator lane and also
set XAMLMCP_ANDROID_PHYSICAL=1 for the physical-device lane. Set XAMLMCP_ANDROID_DEVICE when
ADB reports more than one authorized device.
License
Apache-2.0 — see LICENSE.
來源:README.md,提交 1718f94
工具
0版本歷史
1- v1.0.0-preview.2最新Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分