ios-multi-simulator-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +219 -0
- package/build/index.js +1179 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Joshua Yoes
|
|
4
|
+
Copyright (c) 2026 Nick Clifford (later additions)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# iOS Multi-Simulator MCP Server
|
|
2
|
+
|
|
3
|
+
Forked from [joshuayoes/ios-simulator-mcp](https://github.com/joshuayoes/ios-simulator-mcp) — all foundational work by Joshua Yoes.
|
|
4
|
+
|
|
5
|
+
An MCP server that lets AI agents create, control, and destroy iOS simulators through session-based lifecycle management. Each session owns its own simulator, enabling multiple agents to work in parallel on separate simulators without conflicts.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
9
|
+
│ Agent A │ │ Agent B │ │ Agent C │
|
|
10
|
+
│ (id: "qa1") │ │ (id: "qa2") │ │ (id: "dev") │
|
|
11
|
+
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
|
|
12
|
+
│ │ │
|
|
13
|
+
└────────────┬────┴────┬────────────┘
|
|
14
|
+
│ │
|
|
15
|
+
┌─────┴─────────┴──────┐
|
|
16
|
+
│ MCP Server │
|
|
17
|
+
│ (single process) │
|
|
18
|
+
└──┬─────────┬──────┬──┘
|
|
19
|
+
│ │ │
|
|
20
|
+
┌──────┴──┐ ┌────┴───┐ ┌┴────────┐
|
|
21
|
+
│ iPhone │ │ iPad │ │ iPhone │
|
|
22
|
+
│ 16 Pro │ │ Air │ │ 16 Pro │
|
|
23
|
+
│ (qa1) │ │ (qa2) │ │ (dev) │
|
|
24
|
+
└─────────┘ └────────┘ └─────────┘
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**What this fork adds:**
|
|
28
|
+
- **Session-based lifecycle** — `start_simulator` / `destroy_simulator` create and tear down simulators on demand, with automatic cleanup on server exit
|
|
29
|
+
- **Multi-agent support** — each session gets an isolated simulator, so parallel agents don't collide
|
|
30
|
+
- **Attach to existing simulators** — `attach_simulator` lets you control a simulator that was created externally (e.g. by Xcode)
|
|
31
|
+
- Removed `get_booted_sim_id` / `open_simulator` / `IDB_UDID` — the session model replaces all of these
|
|
32
|
+
|
|
33
|
+
## Tools
|
|
34
|
+
|
|
35
|
+
All tools take a required `id` (session identifier) parameter.
|
|
36
|
+
|
|
37
|
+
| Tool | Additional Parameters | Description |
|
|
38
|
+
|------|----------------------|-------------|
|
|
39
|
+
| `start_simulator` | `type?` (e.g. "iPhone", "iPad", "iPhone 16 Pro") | Creates, boots, and opens a simulator for the session |
|
|
40
|
+
| `destroy_simulator` | — | Shuts down and deletes the session's simulator |
|
|
41
|
+
| `attach_simulator` | `udid` | Attaches to an existing booted simulator by UDID |
|
|
42
|
+
| `detect_rotation` | — | Detects device rotation and updates coordinate mapping |
|
|
43
|
+
| `ui_describe_all` | — | Returns accessibility tree for the entire screen (JSON) |
|
|
44
|
+
| `ui_tap` | `x`, `y`, `duration?` | Tap at coordinates |
|
|
45
|
+
| `ui_type` | `text` | Type text into the focused field |
|
|
46
|
+
| `ui_swipe` | `x_start`, `y_start`, `x_end`, `y_end`, `duration?`, `delta?` | Swipe gesture |
|
|
47
|
+
| `ui_describe_point` | `x`, `y` | Returns the accessibility element at a point |
|
|
48
|
+
| `ui_view` | — | Returns a compressed screenshot as base64 JPEG |
|
|
49
|
+
| `screenshot` | `output_path`, `type?`, `display?`, `mask?` | Saves a screenshot to a file |
|
|
50
|
+
| `record_video` | `output_path?`, `codec?`, `display?`, `mask?`, `force?` | Starts video recording |
|
|
51
|
+
| `stop_recording` | — | Stops the current recording |
|
|
52
|
+
| `install_app` | `app_path` | Installs a .app or .ipa on the simulator |
|
|
53
|
+
| `launch_app` | `bundle_id`, `terminate_running?` | Launches an app by bundle identifier |
|
|
54
|
+
|
|
55
|
+
## `ui_describe_all` — the key navigation tool
|
|
56
|
+
|
|
57
|
+
`ui_view` lets the agent visually see the screen with a compressed jpg image. While this is sufficient for the agent to determine where to click, it will not work if the screen is rotated. But `ui_describe_all` uses logical coordinates and will work fine for finding buttons to tap. Unless there is a good reason to do otherwise, I'd suggest telling agents to use `ui_describe_all` for navigation (though `ui_view` will work so long as the screen is in portrait)
|
|
58
|
+
|
|
59
|
+
`ui_describe_all` returns a nested JSON accessibility tree. This is another way the agent can "see" the screen to decide what to tap. Example (abbreviated):
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
[
|
|
63
|
+
{
|
|
64
|
+
"type": "Application",
|
|
65
|
+
"frame": { "x": 0, "y": 0, "width": 393, "height": 852 },
|
|
66
|
+
"role_description": "application",
|
|
67
|
+
"title": "Settings",
|
|
68
|
+
"children": [
|
|
69
|
+
{
|
|
70
|
+
"type": "NavigationBar",
|
|
71
|
+
"frame": { "x": 0, "y": 59, "width": 393, "height": 96 },
|
|
72
|
+
"children": [
|
|
73
|
+
{
|
|
74
|
+
"type": "StaticText",
|
|
75
|
+
"frame": { "x": 152, "y": 75, "width": 89, "height": 25 },
|
|
76
|
+
"title": "Settings"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"type": "Cell",
|
|
82
|
+
"frame": { "x": 0, "y": 200, "width": 393, "height": 44 },
|
|
83
|
+
"title": "General",
|
|
84
|
+
"AXAccessibilityElement": true
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The `frame` coordinates map directly to `ui_tap` coordinates — to tap "General", use the centre of its frame.
|
|
92
|
+
|
|
93
|
+
## Example usage
|
|
94
|
+
|
|
95
|
+
**Hot Tip:**
|
|
96
|
+
|
|
97
|
+
You can use cheap agents like Haiku to do navigation and even visual comparison. You do not need Opus to navigate around your app, saving you tons of money and time. Haiku is _almost_ fast enough that you can record demo videos without speeding up ;)
|
|
98
|
+
|
|
99
|
+
**Launch an app and navigate:**
|
|
100
|
+
|
|
101
|
+
> Start an iPhone 16 Pro simulator, open Settings, and navigate to General > About.
|
|
102
|
+
|
|
103
|
+
**Compare a screenshot against expected state:**
|
|
104
|
+
|
|
105
|
+
> Take a screenshot of the simulator and check whether the login screen is showing
|
|
106
|
+
> the "Welcome back" message.
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
**Multi-step agent workflow (great for Haiku subagents):**
|
|
110
|
+
|
|
111
|
+
> You are a QA agent. Start a simulator, install the app at ./build/MyApp.app,
|
|
112
|
+
> launch it (com.example.myapp), then:
|
|
113
|
+
> 1. Tap "Sign Up"
|
|
114
|
+
> 2. Fill in the email field with "test@example.com" and password with "password123"
|
|
115
|
+
> 3. Tap "Submit"
|
|
116
|
+
> 4. Take a screenshot and verify the success message appears
|
|
117
|
+
|
|
118
|
+
## Prerequisites
|
|
119
|
+
|
|
120
|
+
- **Node.js** (v18+)
|
|
121
|
+
- **macOS** (iOS simulators are macOS-only)
|
|
122
|
+
- **Xcode** with iOS simulators installed
|
|
123
|
+
- **Facebook IDB** —
|
|
124
|
+
|
|
125
|
+
### Facebook IDB (Important)
|
|
126
|
+
|
|
127
|
+
This dependency is a little more involved. The official [install guide](https://fbidb.io/docs/installation) can be a little difficult, the easiest way to install it (imo) is to use `pipx`.
|
|
128
|
+
|
|
129
|
+
**MacOS:**
|
|
130
|
+
```
|
|
131
|
+
# Install pipx to make installing python packages easier
|
|
132
|
+
brew install pipx
|
|
133
|
+
pipx ensurepath
|
|
134
|
+
|
|
135
|
+
brew tap facebook/fb
|
|
136
|
+
brew install idb-companion
|
|
137
|
+
pipx install fb-idb
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Installation
|
|
141
|
+
|
|
142
|
+
Please note the `fb-idb` dependecy above!
|
|
143
|
+
|
|
144
|
+
### Cursor
|
|
145
|
+
|
|
146
|
+
Add to `~/.cursor/mcp.json`:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"mcpServers": {
|
|
151
|
+
"ios-multi-simulator": {
|
|
152
|
+
"command": "npx",
|
|
153
|
+
"args": ["-y", "github:zafnz/ios-multi-simulator-mcp"]
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
For local development, build from source and point to the built file:
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"mcpServers": {
|
|
164
|
+
"ios-multi-simulator": {
|
|
165
|
+
"command": "node",
|
|
166
|
+
"args": ["/path/to/ios-multi-simulator-mcp/build/index.js"]
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Claude Code
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
claude mcp add ios-multi-simulator npx -y github:zafnz/ios-multi-simulator-mcp
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
For local development:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
claude mcp add ios-multi-simulator -- node /path/to/ios-multi-simulator-mcp/build/index.js
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Troubleshooting
|
|
185
|
+
|
|
186
|
+
**Rotated screen**
|
|
187
|
+
|
|
188
|
+
The rotated screen is a problem when using `ui_view` due to the tapping and swipping using logical coordinate space, but the ui_view returning the pixel space, which when rotated don't align. Tell the agent to use `ui_describe_all` to navigate -- it uses less tokens anyhow.
|
|
189
|
+
|
|
190
|
+
## Configuration
|
|
191
|
+
|
|
192
|
+
### Environment Variables
|
|
193
|
+
|
|
194
|
+
| Variable | Description | Example |
|
|
195
|
+
|----------|-------------|---------|
|
|
196
|
+
| `IOS_SIMULATOR_MCP_FILTERED_TOOLS` | Comma-separated list of tool names to hide | `screenshot,record_video` |
|
|
197
|
+
| `IOS_SIMULATOR_MCP_DEFAULT_OUTPUT_DIR` | Default directory for screenshots and recordings (default: `~/Downloads`) | `~/Code/project/tmp` |
|
|
198
|
+
| `IOS_SIMULATOR_MCP_IDB_PATH` | Custom path to the IDB executable | `/opt/homebrew/bin/idb` |
|
|
199
|
+
|
|
200
|
+
Example with env vars:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"mcpServers": {
|
|
205
|
+
"ios-multi-simulator": {
|
|
206
|
+
"command": "npx",
|
|
207
|
+
"args": ["-y", "ios-multi-simulator-mcp"],
|
|
208
|
+
"env": {
|
|
209
|
+
"IOS_SIMULATOR_MCP_DEFAULT_OUTPUT_DIR": "~/Code/project/tmp",
|
|
210
|
+
"IOS_SIMULATOR_MCP_IDB_PATH": "/opt/homebrew/bin/idb"
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|