Cross-platform MCP server for automating the Garmin Connect IQ Simulator on Windows and macOS.
Send keys, take screenshots, build apps, and push them to the simulator – all from an AI assistant (Claude Code, Cursor, etc.) via the Model Context Protocol.
Forked from thomaszipf/connectiq-simulator-mcp with macOS support and workflow improvements.
| Tool | Description |
|---|---|
init |
Call first. Detects platform, finds SDK/Java paths, locates simulator window, checks permissions |
send_key |
Send a key press: up, down, enter, esc, menu, back, open_widget |
test_sequence |
Preferred. Interleaved deploy/key/screenshot steps in one call |
screenshot |
Capture the simulator window as PNG |
launch_simulator |
Start the CIQ Simulator (auto-detects SDK path) |
build_app |
Compile a Connect IQ project with monkeyc |
push_app |
Push a .prg to the running simulator with monkeydo |
| Key | Effect |
|---|---|
open_widget |
DOWN + DOWN + ENTER — navigate from watch face into a widget (use after push) |
up / down |
Scroll through lists |
enter |
Select / confirm |
esc / back |
Go back |
menu |
Open menu (F3) |
Both platforms:
- Node.js >= 18
- Garmin Connect IQ SDK installed via the SDK Manager
- Java JDK (auto-detected from
JAVA_HOMEor common paths)
macOS:
- Accessibility permissions (for key sending via System Events)
- Screen Recording permissions (for screenshots)
swiftCLI available (for window discovery)
Windows:
- Windows 10/11 (uses Win32 APIs via PowerShell)
- PowerShell (included with Windows)
git clone https://github.com/wroblisko/garmin-simulator-crossplatform-mcp.git
cd garmin-simulator-crossplatform-mcp
npm install
npm run buildAdd to ~/.claude.json:
{
"mcpServers": {
"connectiq-simulator": {
"command": "node",
"args": ["/path/to/garmin-simulator-crossplatform-mcp/dist/index.js"]
}
}
}Add to claude_desktop_config.json:
{
"mcpServers": {
"connectiq-simulator": {
"command": "node",
"args": ["/path/to/garmin-simulator-crossplatform-mcp/dist/index.js"]
}
}
}The server auto-detects the platform on init and routes all calls to the appropriate implementation.
macOS:
- Window discovery: Swift + CoreGraphics
CGWindowListCopyWindowInfo - Key sending:
osascript→ System Eventskey code - Screenshots:
screencapture -l <windowId> - Build/push: shells out to
monkeyc/monkeydo
Windows:
- Window detection: PowerShell + Win32
GetWindowRect - Key sending: PowerShell
SetForegroundWindow+SendKeys.SendWait - Screenshots: PowerShell
Graphics.CopyFromScreen - Build/push: shells out to
monkeyc.bat/monkeydo.bat
Always start with init. The preferred way to build, deploy and verify is a single test_sequence call with deploy_and_open:
{
"steps": [
{
"action": "deploy_and_open",
"project_path": "/path/to/widget",
"prg_path": "/path/to/widget/App.prg",
"device": "fenix7"
},
{ "action": "screenshot", "label": "initial_view" },
{ "action": "key", "key": "down", "delay": 500 },
{ "action": "screenshot", "label": "after_scroll" }
]
}deploy_and_open combines build_app → push_app → open_widget (DOWN+DOWN+ENTER) in one step.
1. init
2. launch_simulator (if not already running)
3. build_app project_path, optional: jungle_file, device
4. push_app prg_path
5. send_key open_widget
6. screenshot / test_sequence
MIT — see LICENSE