Rhombus.WinFormsMcp
WinForms automation MCP server using FlaUI with UIA2 backend for headless Windows Forms application testing and automation
Ask AI about Rhombus.WinFormsMcp
Powered by Claude Β· Grounded in docs
I know everything about Rhombus.WinFormsMcp. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
fnWindowsMCP - WinForms Automation MCP Server
fnWindowsMCP is a Model Context Protocol (MCP) server that provides headless automation capabilities for WinForms applications. It uses the FlaUI library with the UIA2 backend (MSAA - Microsoft Active Accessibility) to enable full Windows Forms compatibility without requiring visual interaction.
Overview
fnWindowsMCP bridges the gap between Claude Code and WinForms applications, enabling:
- Automated element discovery by AutomationId, Name, ClassName, or ControlType
- UI interaction including clicking, typing, value setting, and drag-drop operations
- Process lifecycle management (launch, attach, close applications)
- Visual validation through screenshot capture and analysis
- Headless operation compatible with CI/CD environments, remote systems, and servers
- Full async/await support for integration with modern .NET applications
Architecture
Project Structure
fnWindowsMCP/
βββ src/
β βββ fnWindowsMCP.Server/ # MCP server implementation
β β βββ Program.cs # MCP stdio transport + tool implementations
β β βββ Automation/
β β β βββ AutomationHelper.cs # Core FlaUI wrapper (428 lines)
β β βββ fnWindowsMCP.Server.csproj
β β
β βββ fnWindowsMCP.TestApp/ # Sample WinForms application for testing
β β βββ Form1.cs / Form1.Designer.cs
β β βββ Program.cs
β β βββ fnWindowsMCP.TestApp.csproj
β β
β βββ fnWindowsMCP.sln # Solution file
β
βββ tests/
β βββ fnWindowsMCP.Tests/ # NUnit test suite
β βββ UnitTest1.cs # AutomationHelper tests
β βββ fnWindowsMCP.Tests.csproj
β
βββ README.md # This file
βββ global.json # .NET 8.0 SDK version pinning
βββ .gitignore # Standard .NET ignores + screenshots
Technology Stack
| Component | Technology | Version | Purpose |
|---|---|---|---|
| Language | C# | - | Full type safety and modern async/await |
| Framework | .NET | 8.0 | Latest LTS, cross-platform compatible |
| Automation | FlaUI | 4.0.0 | UI element discovery and interaction |
| UI Framework | UIA2 (MSAA) | - | Maximum WinForms compatibility |
| Testing | NUnit | 3.14.0 | Comprehensive test coverage |
| Protocol | MCP | stdio transport | JSON-RPC 2.0 compatible |
Core Components
1. AutomationHelper (src/fnWindowsMCP.Server/Automation/AutomationHelper.cs)
Core automation wrapper with 25+ methods:
Process Management
LaunchApp(path, arguments, workingDirectory)- Launch new WinForms applicationAttachToProcess(pid)- Attach to running process by IDAttachToProcessByName(name)- Attach to running process by nameGetMainWindow(pid)- Get application's main window elementCloseApp(pid, force)- Close application gracefully or forcefully
Element Discovery
FindByAutomationId(id, parent, timeoutMs)- Find by automation IDFindByName(name, parent, timeoutMs)- Find by element nameFindByClassName(className, parent, timeoutMs)- Find by class nameFindByControlType(controlType, parent, timeoutMs)- Find by control typeFindAll(condition, parent, timeoutMs)- Find multiple matching elementsElementExists(automationId, parent)- Check if element exists (1000ms timeout)GetAllChildren(element)- Get all child elements
UI Interaction
Click(element, doubleClick)- Click or double-click elementTypeText(element, text, clearFirst)- Type text into elementSetValue(element, value)- Set element value via SendKeysDragDrop(source, target)- Simulate drag-and-drop operationSendKeys(keys)- Send keyboard inputGetProperty(element, propertyName)- Get element property (name, automationId, className, controlType, isOffscreen, isEnabled)
Validation & Monitoring
TakeScreenshot(outputPath, element)- Capture PNG screenshotWaitForElementAsync(automationId, parent, timeoutMs)- Async wait for element appearanceElementExists(automationId, parent)- Check element existence
Implementation Details
- Retry mechanism: All find operations retry every 100ms until timeout
- Default timeout: 5000ms for find operations, 10000ms for async wait
- Thread safety: Locked dictionary for process tracking
- Resource cleanup: IDisposable implementation with automatic process termination
- Headless compatible: No visual interaction required, all operations via window messages
2. MCP Server (src/fnWindowsMCP.Server/Program.cs)
Implements Model Context Protocol with:
Session Management
SessionManagerclass tracks:- Active AutomationHelper instance
- Cached automation elements with unique IDs
- Process contexts for lifecycle tracking
Tool Implementations (14 tools)
Element Tools:
find_element- Discover UI element by identifierclick_element- Interact with elementtype_text- Enter text into fieldset_value- Set element valueget_property- Read element properties
Process Tools:
launch_app- Start WinForms applicationattach_to_process- Connect to running appclose_app- Terminate application
Validation Tools:
take_screenshot- Capture visual stateelement_exists- Check element presencewait_for_element- Wait for element appearance
Interaction Tools:
drag_drop- Drag-and-drop operationsend_keys- Send keyboard input
Future Enhancement:
raise_event- Trigger UI events (not yet implemented)listen_for_event- Monitor UI events (not yet implemented)
Protocol Details
- Transport: stdio with line-based JSON-RPC 2.0
- Message format: Single-line JSON objects
- Error handling: Comprehensive try-catch with JSON error responses
- Session state: Persists across multiple tool calls
3. Test Application (src/fnWindowsMCP.TestApp/)
Sample WinForms application with:
- TextBox - Text input control
- Button - Clickable button with message box
- CheckBox - Toggle checkbox
- ComboBox - Dropdown selection (4 options)
- DataGridView - Table with 2 columns Γ 3 rows
- ListBox - Multi-select list (5 items)
- Labels - Status and descriptive text
All controls configured with proper names for automation discovery.
4. Test Suite (tests/fnWindowsMCP.Tests/)
Comprehensive NUnit tests covering:
- AutomationHelper initialization
- Application launch and process management
- Window discovery and attachment
- Element finding and existence checking
- Screenshot generation
- Async wait operations
- Process cleanup
Test categories:
- Initialization: Verify AutomationHelper setup
- Process lifecycle: Launch, attach, close applications
- Element operations: Find, click, type, get properties
- Validation: Screenshots, element existence, async waits
- Cleanup: Proper resource disposal
Usage
Quick Start with Claude Code
To use this MCP server with Claude Code, see the complete setup guide: Claude Code MCP Setup Guide
Quick configuration for ~/.claude/mcp.json:
{
"mcpServers": {
"winforms-mcp": {
"command": "dotnet",
"args": ["path/to/Rhombus.WinFormsMcp.Server.dll"],
"env": {}
}
}
}
Then use in Claude Code:
@mcp winforms-mcp launch_app {
"path": "C:\\path\\to\\app.exe"
}
Installation
cd C:\dev
git clone <repo-url> fnWindowsMCP
cd fnWindowsMCP
dotnet build
Running the Server
dotnet run --project src/fnWindowsMCP.Server/fnWindowsMCP.Server.csproj
The server listens on stdin/stdout for JSON-RPC messages.
Running Tests
dotnet test
Running the Test Application
dotnet run --project src/fnWindowsMCP.TestApp/fnWindowsMCP.TestApp.csproj
MCP Tool Reference
find_element
Discovers a UI element by various identifiers.
Arguments:
automationId(string, optional) - Element's AutomationIdname(string, optional) - Element's Name propertyclassName(string, optional) - Element's ClassNamepid(int, optional) - Process ID (for future use)
Returns:
{
"success": true,
"elementId": "elem_1",
"name": "Button1",
"automationId": "okButton",
"controlType": "Button"
}
click_element
Clicks on an element.
Arguments:
elementId(string, required) - Cached element ID from find_elementdoubleClick(boolean, optional, default: false) - Double-click if true
Returns:
{"success": true, "message": "Element clicked"}
type_text
Types text into a text field.
Arguments:
elementId(string, required) - Target element IDtext(string, required) - Text to typeclearFirst(boolean, optional, default: false) - Clear field before typing
Returns:
{"success": true, "message": "Text typed"}
set_value
Sets element value (via Ctrl+A + delete + type).
Arguments:
elementId(string, required) - Target elementvalue(string, required) - New value
Returns:
{"success": true, "message": "Value set"}
get_property
Reads element property.
Arguments:
elementId(string, required) - Target elementpropertyName(string, required) - Property name (name, automationid, classname, controltype, isoffscreen, isenabled)
Returns:
{
"success": true,
"propertyName": "name",
"value": "okButton"
}
launch_app
Launches a WinForms application.
Arguments:
path(string, required) - Path to executablearguments(string, optional) - Command-line argumentsworkingDirectory(string, optional) - Working directory
Returns:
{
"success": true,
"pid": 12345,
"processName": "myapp"
}
attach_to_process
Attaches to a running process.
Arguments:
pid(int, optional) - Process IDprocessName(string, optional) - Process name
Returns:
{
"success": true,
"pid": 12345,
"processName": "myapp"
}
close_app
Closes an application.
Arguments:
pid(int, required) - Process IDforce(boolean, optional, default: false) - Force kill if true
Returns:
{"success": true, "message": "Application closed"}
take_screenshot
Captures a screenshot.
Arguments:
outputPath(string, required) - Path to save PNG fileelementId(string, optional) - Element to screenshot (omit for full screen)
Returns:
{
"success": true,
"message": "Screenshot saved to C:\\temp\\screen.png"
}
element_exists
Checks if element exists.
Arguments:
automationId(string, required) - Element's AutomationId
Returns:
{"success": true, "exists": true}
wait_for_element
Waits for element to appear.
Arguments:
automationId(string, required) - Element's AutomationIdtimeoutMs(int, optional, default: 10000) - Timeout in milliseconds
Returns:
{"success": true, "found": true}
drag_drop
Performs drag-and-drop operation.
Arguments:
sourceElementId(string, required) - Element to dragtargetElementId(string, required) - Drop target
Returns:
{"success": true, "message": "Drag and drop completed"}
send_keys
Sends keyboard input.
Arguments:
keys(string, required) - Keys to send (WinForms SendKeys format)
Returns:
{"success": true, "message": "Keys sent"}
Example Workflows
Finding and Clicking a Button
1. launch_app { "path": "C:\\MyApp.exe" }
β { "pid": 5432, "processName": "MyApp" }
2. wait_for_element { "automationId": "okButton", "timeoutMs": 5000 }
β { "found": true }
3. find_element { "automationId": "okButton" }
β { "elementId": "elem_1", "success": true }
4. click_element { "elementId": "elem_1" }
β { "success": true, "message": "Element clicked" }
5. close_app { "pid": 5432 }
β { "success": true, "message": "Application closed" }
Filling a Form
1. find_element { "name": "textBox1" }
β { "elementId": "elem_1" }
2. type_text { "elementId": "elem_1", "text": "John Doe", "clearFirst": true }
β { "success": true }
3. find_element { "name": "comboBox1" }
β { "elementId": "elem_2" }
4. click_element { "elementId": "elem_2" }
β { "success": true }
5. send_keys { "keys": "{DOWN}{DOWN}{ENTER}" }
β { "success": true }
6. take_screenshot { "outputPath": "C:\\temp\\form_filled.png" }
β { "success": true, "message": "Screenshot saved..." }
Configuration
Global Settings
Edit global.json to change .NET SDK version:
{
"sdk": {
"version": "8.0.0",
"rollForward": "latestFeature"
}
}
Environment Variables
FNWINDOWSMCP_TIMEOUT- Default timeout for operations (ms)FNWINDOWSMCP_SCREENSHOT_DIR- Default screenshot directory
Known Limitations
- Event Listening - Event monitoring not yet implemented (placeholder tool returns "not yet implemented")
- Event Raising - Event triggering not yet implemented (placeholder tool returns "not yet implemented")
- Complex Patterns - Some advanced UI Automation patterns (ValuePattern, SelectionPattern) use fallback implementations
- Cross-machine - Designed for local machine automation; remote scenarios may require additional configuration
- UAC - Applications requiring administrator privileges need special handling
Performance Characteristics
| Operation | Typical Time | Notes |
|---|---|---|
| Launch app | 2-5 seconds | Includes WaitForInputIdle |
| Find element | 100-500ms | With 100ms retry interval |
| Click element | <100ms | Direct window message |
| Type text | 10-50ms per character | Via SendKeys |
| Screenshot | 500-2000ms | Depends on window size |
| Close app | 1-5 seconds | Graceful close + timeout |
Troubleshooting
"Element not found" errors
- Ensure element has proper Name property set
- Verify element exists before trying to interact
- Use
wait_for_elementbefore attempting interaction - Increase timeout value if element loads slowly
Screenshot not saving
- Verify output directory exists and is writable
- Ensure full path is provided (not relative)
- Path should use Windows paths (C:\temp) not Unix paths
Process attachment failures
- Verify process is actually running (
tasklist /FI "IMAGENAME eq myapp.exe") - Check process name exactly matches (case-sensitive in some contexts)
- Ensure no UAC elevation mismatch
Headless operation issues
- Some controls may require special handling
- If using visual components, ensure they're initialized
- Test with the included TestApp first
Development
Building from Source
dotnet build -c Release
Running Tests
dotnet test --logger "console;verbosity=detailed"
Building Release Package
dotnet publish -c Release -o publish
Contributing
Contributions welcome! Areas for enhancement:
- Event raising and listening implementation
- Advanced UI patterns (ValuePattern, RangePattern, etc.)
- Performance optimization
- Cross-platform support (Linux/Mac via Wine compatibility)
- Additional control type support
- Keyboard layout detection and handling
License
MIT License - See LICENSE file for details.
Support
For issues, questions, or feature requests, please open an issue on GitHub.
Version History
v1.0.0 (Initial Release)
- Core AutomationHelper with 25+ methods
- MCP server with 14 tools
- Full FlaUI UIA2 integration
- Comprehensive test application
- NUnit test suite
- Complete documentation
fnWindowsMCP enables headless WinForms automation with full type safety, async/await support, and MCP protocol compatibility. Perfect for test automation, CI/CD integration, and programmatic UI control.
