AI Agent Guide
This server is explicitly intended for AI-assisted WPF debugging and testing. The most effective agents treat the MCP tool catalog as the contract, use discovery first, and separate inspection from mutation.
Recommended workflow
- Discover tools and schemas.
- Confirm
WPFDEVTOOLS_MCP_ALLOWED_TARGETSincludes the reviewed target's exact local absolute executable path, and setWPFDEVTOOLS_MCP_ALLOW_SENSITIVE_READS=truebefore scene, binding, DP, or state reads; unset or malformed values fail closed beforeconnectattaches. - Call
connect()first and let the server auto-discover the target when there is only one visible WPF app. - If auto-discovery returns multiple candidates, call
get_processes(windowFilter)and retryconnect(processId). - Use directly executable scene-level tools such as
get_ui_summaryorget_form_summarybefore falling back to tree-heavy inspection. - Explore the tree or use focused search to obtain stable
elementIdvalues; callget_element_snapshot(elementId)only after a concrete elementId is known. - Run focused diagnostics and prefer the
navigation.recommendedornextStepsguidance returned by each tool. - Perform controlled interaction or mutation only when needed.
- After each interaction or mutation, inspect the recommended follow-up from that response first. If the session has an active snapshot,
get_state_diffis usually the first verification step. - Call
pingonly when you need an explicit health check or reconnect confirmation.
Best practices
0. Keep the server instructions AI-friendly
Follow the same authoring rules that the official MCP and Anthropic guidance emphasize:
- Detailed
tool descriptionsshould explain what a tool does,when to useit,when not to useit, and any important limits or caveats. - JSON schema and SDK annotations help discovery, but they are not
runtime validation; tool handlers still need to validate untrusted arguments explicitly at runtime. - Prefer realistic client workflows, prompts, and resources over raw protocol walkthroughs when writing public quickstarts.
1. Discover before assuming
Do not hard-code argument shapes from stale prompts or screenshots. Use the tool metadata exposed by the server and adapt to the current schema.
2. Treat elementId as runtime state
elementId values are session-specific runtime identifiers. Always fetch them from the current tree instead of caching them across runs.
3. Distinguish inspection from mutation
Inspection tools are typically safe to call repeatedly. Mutation tools change the running UI and should be used with clear intent.
For stateful validation, prefer this sequence:
capture_state_snapshot- Inspect and mutate once
- Verify by following
navigation.recommendedornextSteps - If the snapshot is still active, call
get_state_diff restore_state_snapshotif the app should be left unchanged
Local policy gates must be confirmed close to any prompt or example that uses
high-risk tools. WPFDEVTOOLS_MCP_ALLOWED_TARGETS must include the target's
exact local absolute executable path before connect. In addition,
WPFDEVTOOLS_MCP_ALLOW_DESTRUCTIVE_TOOLS gates mutation, interaction,
render-measurement, and session state-consuming tools such as click_element,
set_dp_value, capture_state_snapshot, restore_state_snapshot,
drain_events, and batch_mutate;
WPFDEVTOOLS_MCP_ALLOW_SCREENSHOTS gates element_screenshot;
WPFDEVTOOLS_MCP_ALLOW_SENSITIVE_READS gates target UI text, DependencyProperty
and binding values, event payloads, tree/scene summaries, and runtime state
snapshots; and
WPFDEVTOOLS_MCP_ALLOW_VIEWMODEL_INSPECTION gates get_viewmodel and
get_commands. execute_command requires both
WPFDEVTOOLS_MCP_ALLOW_VIEWMODEL_INSPECTION and
WPFDEVTOOLS_MCP_ALLOW_DESTRUCTIVE_TOOLS.
Examples of mutation tools:
set_dp_valueclear_dp_valuemodify_viewmodeloverride_style_setterclick_elementsimulate_keyboarddrag_and_dropfocus_element
4. Respect tool semantics
Some tools sound similar but have different intent:
click_elementsimulates a logical button click and is the right choice for invoking button behavior.fire_routed_eventraises an event route; it is not a replacement for an input gesture.simulate_keyboardis best when keyboard focus matters, andget_focus_stateshould usually be checked first.drag_and_dropis intended for controlled payload transfer and currently works best with explicit text payload scenarios.
5. Parse structured results carefully
Tool calls can fail at multiple layers:
- MCP protocol layer
- Tool execution layer
- Inspector response layer
- Injection/bootstrap layer
Check these fields when present:
successerrorerrorCodeerrorDatadiagnosticKindsourceKind
Also use MCP discovery surfaces instead of relying on memory:
- prompts such as
debug_binding_issue - resources such as
wpf://capabilities
Some clients may render these as client-specific shortcuts such as /mcp__wpf-devtools__debug_binding_issue or @wpf-devtools:capabilities, but the standard prompt name and resource URI are the portable contract.
When present, parse these follow-up fields as part of the contract:
nextStepsnavigation.recommendednavigation.alternativesnavigation.prefetchToolsnavigation.contextRefs
nextSteps remains the compatibility field for older clients. Newer clients should prefer navigation.recommended and treat alternatives as optional human-guided branches.
If the next action is already obvious, capable clients may pass navigation=false on get_binding_errors to omit nextSteps and navigation from that response and save tokens. Schema-driven clients can rely on that opt-out there because the parameter is advertised in the get_binding_errors tool schema today, and should not assume other tools accept it unless their schema advertises it too.
6. Prefer scene-level aggregation before screenshots or tree dumps
The fastest agent workflows now start with one of these tools:
get_ui_summaryfor fast semantic contextget_element_snapshot(elementId)for one-element triage after a concrete elementId is knownget_form_summaryfor form state and submit readinessget_state_diffafter an interaction or mutation
Use tree tools when exact structure matters, not as the default first step.
7. Prefer compact diagnostics unless verbose detail is required
get_binding_errorsdefaults tocompact=true; keep that default unless you explicitly need full per-error message text.- Use
get_affected_elementsbefore broad recursive binding inspection when you already know the suspect binding path or property. - Use
drain_eventswhen you need an explicit read of bufferedBindingError,DpChange, or validation events instead of relying on opportunistic piggyback fields.
8. Use sequential mutation orchestration deliberately
When a workflow needs multiple ordered live mutations, prefer batch_mutate over improvising several destructive calls in one reasoning step. It keeps the sequence explicit, preserves per-operation results, and is easier to verify with get_state_diff, drain_events, or focused follow-up tools.
Prompt patterns that work well
Scene-first prompt
Confirm WPFDEVTOOLS_MCP_ALLOWED_TARGETS contains the WPF test app's exact local absolute executable path and WPFDEVTOOLS_MCP_ALLOW_SENSITIVE_READS=true is set for scene and tree reads; unset or malformed values fail closed before connect() attaches. Then connect with connect(), get_ui_summary(depthMode: "semantic"), and inspect the visual tree only if the summary is insufficient.
Binding triage prompt
Confirm WPFDEVTOOLS_MCP_ALLOWED_TARGETS contains the target WPF app's exact local absolute executable path and WPFDEVTOOLS_MCP_ALLOW_SENSITIVE_READS=true is set for binding and element reads; unset or malformed values fail closed before connect() attaches. Then connect with connect(), inspect binding errors with compact defaults, use get_affected_elements or get_element_snapshot(elementId) after identifying a concrete failing element, and explain which bindings are failing and why. Do not modify the UI unless a fix requires it.
Safe interaction prompt
Confirm WPFDEVTOOLS_MCP_ALLOWED_TARGETS contains the target WPF app's exact local absolute executable path, WPFDEVTOOLS_MCP_ALLOW_SENSITIVE_READS=true is set for form, event, and state reads, and WPFDEVTOOLS_MCP_ALLOW_DESTRUCTIVE_TOOLS=true is set before clicking; unset or malformed values fail closed before connect() attaches. Then connect with connect(), get_form_summary or get_interaction_readiness for the target form, find the Save button, confirm its command metadata, click it, drain buffered runtime events if present, and report the state diff.
Snapshot-safe mutation prompt
Confirm WPFDEVTOOLS_MCP_ALLOWED_TARGETS contains the target WPF app's exact local absolute executable path, WPFDEVTOOLS_MCP_ALLOW_SENSITIVE_READS=true is set for snapshot, state, and previous-value reads, and WPFDEVTOOLS_MCP_ALLOW_DESTRUCTIVE_TOOLS=true is set before mutation; unset or malformed values fail closed before connect() attaches. Then connect with connect(), capture a state snapshot, locate the target control, apply one UI mutation or an ordered batch_mutate sequence, verify the result with get_state_diff, and restore the snapshot before finishing.
Anti-patterns
- Reusing old
elementIdvalues from a previous run. - Calling mutation tools before confirming the target element.
- Skipping
capture_state_snapshotbefore a mutation that may need rollback. - Treating
fire_routed_eventas a guaranteed substitute for user input. - Assuming the target process is x64 without checking
get_processes(windowFilter)when auto-discovery is ambiguous. - Ignoring architecture or bootstrapper requirements when
connectfails.
Golden sequence for automation
For end-to-end automated validation, use this order whenever possible:
- Confirm
WPFDEVTOOLS_MCP_ALLOWED_TARGETScontains the target's exact local absolute executable path and setWPFDEVTOOLS_MCP_ALLOW_SENSITIVE_READS=truebefore scene, binding, event, DP, or state reads; unset or malformed values fail closed beforeconnect()attaches connect()- If needed,
get_processes(windowFilter)andconnect(processId) get_ui_summaryorget_form_summary- One or more focused diagnostics; use
get_element_snapshot(elementId)only after a concrete elementId is known - One mutation or interaction at a time
- Follow
navigation.recommendedornextStepsfrom the latest tool result - If the session has an active snapshot, call
get_state_diff - If the session has buffered runtime events, call
drain_events - Use another focused verification tool only when more detail is still required
This keeps failures easy to localize and makes agent traces easier to trust.