iOS, Android & Web QA agent — MCP server for Claude Code
Project description
Watchr — iOS, Android & Web QA Agent
AI-powered app testing for iOS, Android, and web. Tell Claude Code what to test in plain English — it drives the simulator/emulator/browser or physical device, finds bugs, checks accessibility, and catches crashes automatically.
Supported Platforms
| Platform | How it works |
|---|---|
| iOS Simulator | xcrun simctl + idb — auto-detected |
| iOS Physical Device | WatchrRunner XCTest server via USB — guided setup |
| Android Emulator | adb — auto-detected, zero setup |
| Android Physical Device | adb via USB debugging — auto-detected, zero setup |
| Web Browser | Playwright (Chromium, headless) — device="web" |
Install (one time)
# Add watchr to Claude Code
claude mcp add --scope user watchr -- uvx --python 3.12 --upgrade watchr-mcp
That's it. One command. uvx downloads everything automatically. The --scope user flag makes watchr available in every project.
Platform-specific prerequisites
iOS Simulator:
brew install idb-companion
Android (emulator or physical):
- Android Studio installed (for
adb) - For physical devices: USB debugging enabled
iOS Physical Device:
- Xcode installed, device connected via USB
- Watchr guides you through the one-time XCTest runner setup
Web (browser testing):
pip install playwright && playwright install chromium
If you're missing anything, watchr will tell you exactly what to install when it starts.
Usage
Open Claude Code in any project and tell it what to test:
Boot the simulator, launch com.yourapp.bundleid, and test the sign-up flow
Claude Code will:
- Auto-detect your device (iOS simulator, Android emulator, or USB-connected phone)
- Launch your app
- Navigate the flow you described
- Take screenshots at each step
- Report any bugs, crashes, or issues it finds
Switch platforms manually
If watchr picks the wrong device, tell it:
Use set_device with mode "android"
Use set_device with mode "simulator"
Use set_device with mode "physical"
QA After Code Changes
Use watchr as part of your dev workflow — save a baseline before changes, then compare after.
"Save a baseline of the home screen called 'home'"
Make your code changes, rebuild, then:
"Compare the home screen with the baseline 'home' and report any visual differences"
For a full regression check after a feature branch:
"Launch the app, test sign-up, onboarding, and settings — check for crashes and accessibility issues"
Works great in CI or as a pre-merge check. One prompt replaces a manual test checklist.
Web Testing
Test web apps with the same tools as mobile:
"Navigate to https://myapp.com and test the sign-up flow"
Or be explicit:
navigate("https://myapp.com", device="web")
observe(device="web")
perform(action="tap_element", label="Sign In", device="web")
Watchr launches a headless Chromium browser via Playwright. Fast, no extensions needed. Console errors are automatically captured in observe output.
Cross-Platform Testing (iOS + Android + Web)
Test both platforms at the same time — each tool call targets a specific device independently:
"Test the sign-up flow on both iOS and Android — report any differences"
observe(device="simulator") # iOS screenshot + UI tree
observe(device="android") # Android screenshot + UI tree
No switching, no conflicts. Both devices in the same session.
Example Prompts
"Test the sign-up flow end to end and report any bugs"
"Go to settings, verify all options are visible, check accessibility"
"Run monkey testing on the home screen for 30 seconds"
"Save a baseline screenshot of the landing page, then compare after my changes"
"Navigate to the payment screen and check if the app crashes"
What It Can Do
| Capability | Description |
|---|---|
| Navigate any flow | Describe a user journey in English — it taps, swipes, types, and scrolls through it |
| Crash Detection | Checks if the app is still alive after every action, reads crash logs |
| Accessibility Audit | Finds missing labels, small touch targets, unlabeled buttons |
| Visual Regression | Saves golden screenshots, diffs against them to catch UI changes |
| Performance Timing | Measures screen load times, flags slow screens (>3s) |
| Monkey Testing | Random taps and swipes to find crashes scripted tests would miss |
| Text Verification | Asserts specific text is on screen, like Playwright's expect |
| Auto Bug Reports | Files GitHub issues automatically with device info and error context |
Troubleshooting
| Problem | Fix |
|---|---|
| MCP server won't start | Run uvx watchr-mcp in terminal to see errors |
| "No booted simulator found" | Boot one: xcrun simctl boot "iPhone 16 Pro" |
| "No Android device found" | Start an emulator or connect device with USB debugging |
idb commands fail |
Run idb connect UDID with your simulator's UDID |
| Screenshots are blank | Make sure the Simulator/Emulator is open and visible |
| Physical device not working | Run setup_device("your.bundle.id") and follow the guide |
Update
Watchr updates automatically — uvx fetches the latest version from PyPI each time Claude Code starts the server.
To force an update:
uvx --upgrade watchr-mcp
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file watchr_mcp-0.7.1.tar.gz.
File metadata
- Download URL: watchr_mcp-0.7.1.tar.gz
- Upload date:
- Size: 260.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
173e5458515b4300cb9479f1f580875361557a2984aa398aa37ac03b65d59ad5
|
|
| MD5 |
51f687b6152ce9d7400432e798af8bad
|
|
| BLAKE2b-256 |
0fe12d6ca142fea1badc1cf7f4f5918999bc7db3067150f2f512029fb25b3d4b
|
File details
Details for the file watchr_mcp-0.7.1-py3-none-any.whl.
File metadata
- Download URL: watchr_mcp-0.7.1-py3-none-any.whl
- Upload date:
- Size: 59.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b7184d89ba90691b6767366dccdc0edebf315252f88e974071e0ad8565ebf2e
|
|
| MD5 |
623baa5283fbea86ca030c2c9d92efd9
|
|
| BLAKE2b-256 |
cb14d32939d4dfe9b370a28f1e7312032f53f9c7394f5966ff1f9ffc70fddd96
|