app-screen-mcp
Enables programmatic control over Apple's iOS simulation environment, supporting automated app testing and interaction through simulated gestures and hardware button presses.
Provides comprehensive automation for iOS Simulators, enabling tasks such as device booting, application lifecycle management, and UI interaction via accessibility trees and screenshots.
Leverages macOS-native tools like simctl to automate iOS Simulator instances, allowing for device control, screen capture, and UI state analysis.
Interfaces with Xcode's simulation infrastructure to manage iOS virtual devices, facilitating automated workflows for launching apps and interacting with user interface elements.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@app-screen-mcp Launch the Settings app and show me a screenshot"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Why this exists
Most mobile automation breaks when scripts act without observing current screen state.
app-screen-mcp fixes that by combining:
Accessibility structure from
idb ui describe-allReal pixels from Simulator screenshots
Deterministic interactions (
tap,type_text,swipe, hardware buttons)
This gives agents a closed loop: observe, reason, act, verify.
Related MCP server: ios-agent-driver
What you get
Simulator discovery and boot control
App launch and termination by bundle ID
Full normalized accessibility tree
JPEG screenshots with size/quality controls
Image-hash suppression to skip unchanged screenshots
Semantic actions by text or accessibility ID
Relative-coordinate taps for resolution-independent flows
One-call screen summary (
UI tree + optional screenshot)
Architecture
MCP Client / Agent
|
v
app-screen-mcp
|
+--> xcrun simctl (devices, app lifecycle, screenshots)
|
+--> idb (UI tree, tap, swipe, type, hardware buttons)
|
v
iOS SimulatorPrerequisites
macOS with Xcode + iOS Simulator
Node.js 18+
idbtooling
Manual install for idb:
brew tap facebook/fb
brew install idb-companion
pip3 install fb-idbInstall
Option 1: one-step installer (recommended)
bash <(curl -fsSL https://raw.githubusercontent.com/xmuweili/app-screen-mcp/main/install.sh)The script checks/installs:
Xcode Command Line Tools
Homebrew
Node.js (18+)
idb-companionfb-idbapp-screen-mcp(global npm package)
Option 2: global npm install
npm install -g app-screen-mcpOption 3: from source
git clone https://github.com/xmuweili/app-screen-mcp.git
cd app-screen-mcp
npm install
npm run buildConfigure your MCP client
Claude Desktop
Config file:
~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"ios-simulator": {
"command": "node",
"args": ["/absolute/path/to/app-screen-mcp/dist/index.js"]
}
}
}Cursor / VS Code MCP
Common config paths:
.cursor/mcp.json.vscode/mcp.json
Use the key your client expects: mcpServers or mcp.servers.
{
"mcpServers": {
"ios-simulator": {
"command": "node",
"args": ["/absolute/path/to/app-screen-mcp/dist/index.js"]
}
}
}Restart your MCP client after updating config.
Tool reference (15 tools)
Tool | Purpose |
| List simulators and boot state |
| Boot simulator by UDID |
| Launch app by |
| Force-quit app by |
| Return normalized accessibility tree |
| Capture JPEG screenshot with compression and unchanged-image suppression |
| Return tree + optional screenshot with token-saving options |
| Tap absolute |
| Tap relative |
| Type into focused field |
| Swipe between points with optional duration |
| Press |
| Search tree by label/value/hint text |
| Find best text match and tap target point |
| Tap by accessibility identifier |
Quick usage patterns
1) Observe without image (cheap)
{
"name": "get_screen_summary",
"arguments": {
"include_image": false,
"compact_tree": true
}
}2) Add image when visual confirmation is required
{
"name": "get_screen_summary",
"arguments": {
"include_image": true,
"max_dim": 720,
"quality": 55
}
}3) Skip unchanged screenshots
{
"name": "get_screen_summary",
"arguments": {
"include_image": true,
"only_if_changed": true,
"previous_image_hash": "<last_hash>"
}
}4) Stable interaction flow
1. get_screen_summary(include_image=false)
2. find_elements("Sign In")
3. tap_id("login_email") or tap_text("Email")
4. type_text("user@example.com")
5. tap_text("Sign In")
6. get_screen_summary(include_image=true, only_if_changed=true)Permission prompts
Permission behavior is enforced by the MCP client, not this server.
Claude Code (CLI)
Allow this server in ~/.claude/settings.json:
{
"permissions": {
"allow": ["mcp__ios-simulator__*"]
}
}ios-simulator must match your MCP server name.
Codex CLI
Codex uses command-level approvals. Use “always allow” for recurring safe command prefixes when prompted.
Local development
npm install
npm run build
npm startMain implementation:
src/index.ts
Testing
The integration tests run against a real booted iOS Simulator.
npm testBefore running tests:
Boot an iOS Simulator device.
Build/install demo app under
demo-app/if not already installed.
Test helpers:
tests/helpers/client.tstests/helpers/ui.tstests/helpers/vision.ts
Troubleshooting
No iOS simulator is currently runningBoot a simulator first, or call
boot_simulator.
idbcommand failuresVerify
idb-companionandfb-idbinstallation and PATH.
Missing/weak element matches
Improve app accessibility labels and identifiers.
GUI client cannot find node/module path
Use an absolute path in
argsinstead of relying on shell PATH.
Contributing
Contributions are welcome.
For tool changes:
Update tool schema in
src/index.tsImplement tool handler in
src/index.tsAdd integration coverage in
tests/demo-app.test.tsUpdate Tool Reference in this README
License
MIT
Available Tools
15 toolsboot_simulatorC
Boot an iOS simulator by UDID
Inputs: udid (required).
find_elementsC
Search the UI tree for elements whose label, value, or hint contains query text
Inputs: query (required), udid.
get_screen_summaryC
Get screen context (UI tree and optional screenshot) with token-saving options.
Inputs: udid, include_image, max_dim, quality, +3 more.
get_ui_treeC
Get the full accessibility/UI tree as structured JSON.
Inputs: udid.
launch_appC
Launch an app on a simulator
Inputs: bundle_id (required), udid.
list_simulatorsB
List all available iOS simulators with their state (Booted, Shutdown, etc.)
Inputs: no named parameters.
press_buttonB
Press a hardware button on the simulator
Inputs: button (required), udid.
swipeC
Perform a swipe gesture from one coordinate to another
Inputs: from_x (required), from_y (required), to_x (required), to_y (required), +2 more.
take_screenshotB
Take a JPEG screenshot with optional compression and unchanged-image suppression.
Inputs: udid, max_dim, quality, only_if_changed, +1 more.
tapB
Tap at specific (x, y) coordinates on the simulator screen
Inputs: x (required), y (required), udid.
tap_idA
Find a UI element by its accessibility identifier and tap its center.
Inputs: id (required), udid.
tap_relativeA
Tap using relative coordinates (rx, ry) in [0,1] where (0.5, 0.5) is center.
Inputs: rx (required), ry (required), udid.
tap_textA
Find a UI element by visible text and tap its center.
Inputs: text (required), udid.
terminate_appA
Terminate (force-quit) an app on a simulator
Inputs: bundle_id (required), udid.
type_textC
Type text into the currently focused element on the simulator
Inputs: text (required), udid.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 15 tools
Most tools have distinct purposes with clear boundaries, such as boot_simulator vs. launch_app, or tap vs. swipe. However, some overlap exists between tap, tap_id, tap_relative, and tap_text, which all perform tapping actions but with different targeting methods, which could cause minor confusion in selection.
Tool names consistently follow a verb_noun or verb pattern with snake_case throughout, such as boot_simulator, find_elements, and take_screenshot. This uniformity makes the set predictable and easy to understand at a glance.
With 15 tools, the count is well-scoped for an iOS simulator automation server, covering essential operations like simulator management, UI interaction, and app control without being excessive. Each tool serves a clear purpose, justifying its inclusion.
The toolset provides comprehensive coverage for iOS simulator automation, including simulator booting, app launching/termination, UI navigation, and input actions. A minor gap is the lack of tools for more complex gestures or app state queries, but core workflows are well-supported.
Maintenance
Related MCP Connectors
Give an AI agent an iPhone to see, tap and type on over MCP. Free early access (Simulator).
Let your AI agent control real iPhones: screenshots, tap, swipe, type and open apps.
Cloud iPhone Simulators for AI agents: build the Xcode project, read the screen, tap by label, test.
Cloud iPhones and Macs with Xcode for AI agents: build, run and test iOS apps, use the screen.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA MCP server that enables LLMs to interact with iOS simulators through natural language commands.345Apache 2.0
- AlicenseAqualityDmaintenanceAn MCP server that lets an AI agent drive the iOS Simulator in a loop, enabling tapping, typing, swiping, reading the screen via the accessibility tree, and verifying app state.14MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server for iOS Simulator automation. Enables AI assistants to visually interact with iOS apps running in the simulator.40 npm1MIT
- AlicenseNot gradedqualityDmaintenanceComprehensive MCP server for iOS Simulator automation, enabling AI agents to control simulators via tap, swipe, type, accessibility inspection, app debugging, and device management.64 npm2MIT