@blitzdev/iphone-mcp 0.1.7
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 +21 -0
- package/README.md +219 -0
- package/dist/child-env.d.ts +1 -0
- package/dist/child-env.js +61 -0
- package/dist/child-env.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +318 -0
- package/dist/cli.js.map +1 -0
- package/dist/device-client.d.ts +2 -0
- package/dist/device-client.js +15 -0
- package/dist/device-client.js.map +1 -0
- package/dist/execution-context.d.ts +33 -0
- package/dist/execution-context.js +66 -0
- package/dist/execution-context.js.map +1 -0
- package/dist/idb/ax-scan-client.d.ts +27 -0
- package/dist/idb/ax-scan-client.js +244 -0
- package/dist/idb/ax-scan-client.js.map +1 -0
- package/dist/idb/idb-client.d.ts +34 -0
- package/dist/idb/idb-client.js +288 -0
- package/dist/idb/idb-client.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.js +6 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp-server.d.ts +2 -0
- package/dist/mcp-server.js +649 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/types.d.ts +75 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/ui-filters.d.ts +11 -0
- package/dist/ui-filters.js +100 -0
- package/dist/ui-filters.js.map +1 -0
- package/dist/viewer/server.d.ts +5 -0
- package/dist/viewer/server.js +233 -0
- package/dist/viewer/server.js.map +1 -0
- package/dist/wda/device-discovery.d.ts +12 -0
- package/dist/wda/device-discovery.js +91 -0
- package/dist/wda/device-discovery.js.map +1 -0
- package/dist/wda/wda-client.d.ts +38 -0
- package/dist/wda/wda-client.js +314 -0
- package/dist/wda/wda-client.js.map +1 -0
- package/dist/wda/wda-manager.d.ts +29 -0
- package/dist/wda/wda-manager.js +263 -0
- package/dist/wda/wda-manager.js.map +1 -0
- package/dist/wda/wda-scan.d.ts +3 -0
- package/dist/wda/wda-scan.js +41 -0
- package/dist/wda/wda-scan.js.map +1 -0
- package/package.json +40 -0
- package/src/idb/ax-scan/Makefile +30 -0
- package/src/idb/ax-scan/ax-scan.m +168 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Blitz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="BlitzBlue.png" width="100" />
|
|
3
|
+
<br /><br />
|
|
4
|
+
<p>MCP server that lets AI use an iPhone</p>
|
|
5
|
+
|
|
6
|
+
[](https://blitz.dev/)
|
|
7
|
+
[](https://discord.gg/wJQ6dA95S6)
|
|
8
|
+
[](https://www.npmjs.com/package/@blitzdev/iphone-mcp)
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
# @blitzdev/iphone-mcp
|
|
12
|
+
|
|
13
|
+
<!-- NOTE: Video showing a 30-second demo of Claude Code tapping through an app on a simulator, scanning UI, and taking a screenshot -->
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @blitzdev/iphone-mcp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### Global (use in any project)
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx @blitzdev/iphone-mcp --setup-all
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This installs dependencies and configures `@blitzdev/iphone-mcp` for all your AI agents. It automatically sets up Claude Code, and if you have Cursor, Codex, or OpenCode installed, those get configured too.
|
|
30
|
+
|
|
31
|
+
NOTE: For Cursor, you need to enable the blitz-iphone MCP server in Cursor Settings
|
|
32
|
+
|
|
33
|
+
### Project-scoped (one project only)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd your-project
|
|
37
|
+
npx @blitzdev/iphone-mcp --setup-here
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This prompts you to choose which AI agents to configure (Claude Code, Cursor, Codex, OpenCode) and writes the config files into your project directory. `@blitzdev/iphone-mcp` will only be available when you open an agent inside that directory.
|
|
41
|
+
|
|
42
|
+
### Then just ask
|
|
43
|
+
|
|
44
|
+
Open a new AI agent session and ask:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
> scan the simulator screen and tell me what you see
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
> connect to my iPhone and test the login flow
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
> find bugs in my app — tap around, try edge cases, report anything weird
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
<!-- NOTE: Video showing Claude Code responding to "test my app", scanning UI, tapping buttons, finding a bug, and screenshotting the result -->
|
|
59
|
+
|
|
60
|
+
## What can it do?
|
|
61
|
+
|
|
62
|
+
| Capability | Simulator | Physical iPhone |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| Tap, swipe, type text | Yes | Yes |
|
|
65
|
+
| Press buttons (Home, Lock, Siri) | Yes | Yes |
|
|
66
|
+
| Scan UI elements with coordinates | Yes | Yes |
|
|
67
|
+
| Take screenshots | Yes | Yes |
|
|
68
|
+
| List & launch installed apps | Yes | Yes |
|
|
69
|
+
| Auto-detect devices | Yes | Yes |
|
|
70
|
+
| Live screen viewer in browser | -- | Yes |
|
|
71
|
+
|
|
72
|
+
<!-- NOTE: Image showing a split view — left side has Claude Code terminal with scan_ui output, right side shows the corresponding simulator screen with UI elements highlighted -->
|
|
73
|
+
|
|
74
|
+
## Simulators
|
|
75
|
+
|
|
76
|
+
Boot any iPhone simulator, then ask your AI agent to interact with it. No extra setup needed beyond `--setup-all` or `--setup-here`.
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
> what apps are installed on the simulator?
|
|
80
|
+
> launch Safari and go to example.com
|
|
81
|
+
> take a screenshot
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
<!-- NOTE: Image showing terminal output of the list_apps tool with clean formatted app list -->
|
|
85
|
+
|
|
86
|
+
## Physical iPhones
|
|
87
|
+
|
|
88
|
+
Connect your iPhone via USB or make sure it's on the same Wi-Fi network (home/office networks work, public cafe Wi-Fi won't).
|
|
89
|
+
|
|
90
|
+
**First-time setup** — your iPhone needs:
|
|
91
|
+
1. **Developer Mode** enabled (Settings > Privacy & Security > Developer Mode)
|
|
92
|
+
2. **Trust this computer** when prompted on the phone
|
|
93
|
+
|
|
94
|
+
Then ask your agent:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
> connect to my iPhone
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The agent will build and install WebDriverAgent on your phone (takes 1-3 minutes the first time), then give you a URL like `http://localhost:5152?udid=...` — open it in your browser to see a live view of your phone screen.
|
|
101
|
+
|
|
102
|
+
<!-- NOTE: Image showing the browser-based viewer with an iPhone screen displayed in a dark bezel frame -->
|
|
103
|
+
|
|
104
|
+
## Example session
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
You: test the checkout flow in my app
|
|
108
|
+
Agent: Let me scan the simulator to see what's on screen.
|
|
109
|
+
|
|
110
|
+
[calls scan_ui]
|
|
111
|
+
|
|
112
|
+
I can see the home screen. Let me launch your app first.
|
|
113
|
+
|
|
114
|
+
[calls launch_app with bundleId "com.myapp"]
|
|
115
|
+
[calls get_screenshot]
|
|
116
|
+
|
|
117
|
+
The app is open on the main screen. I see a "Shop" tab at the bottom.
|
|
118
|
+
Let me tap it and walk through the checkout flow.
|
|
119
|
+
|
|
120
|
+
[calls device_action: tap on "Shop" tab]
|
|
121
|
+
[calls scan_ui]
|
|
122
|
+
|
|
123
|
+
I see a list of products. Let me add one to cart...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
<!-- NOTE: Video showing a full end-to-end testing session — agent launches app, navigates through screens, finds a UI bug, screenshots it, and reports the issue -->
|
|
127
|
+
|
|
128
|
+
## MCP Tools reference
|
|
129
|
+
|
|
130
|
+
These are the tools your AI agent can call:
|
|
131
|
+
|
|
132
|
+
| Tool | What it does |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `get_execution_context` | Find available simulators and iPhones |
|
|
135
|
+
| `scan_ui` | Find tappable elements — buttons, links, text fields — with their coordinates |
|
|
136
|
+
| `describe_screen` | Full UI element hierarchy (more detail than scan_ui) |
|
|
137
|
+
| `device_action` | Tap, swipe, press buttons, type text, press keys |
|
|
138
|
+
| `device_actions` | Run multiple actions in sequence |
|
|
139
|
+
| `get_screenshot` | Save a screenshot and return the file path |
|
|
140
|
+
| `list_devices` | List all simulators and physical devices |
|
|
141
|
+
| `launch_app` | Launch an app by bundle ID |
|
|
142
|
+
| `list_apps` | List installed apps |
|
|
143
|
+
| `setup_device` | Build & install WebDriverAgent on a physical iPhone |
|
|
144
|
+
|
|
145
|
+
## Requirements
|
|
146
|
+
|
|
147
|
+
- macOS
|
|
148
|
+
- Xcode (install from App Store or `xcode-select --install`)
|
|
149
|
+
- Node.js 18+
|
|
150
|
+
- Homebrew (for installing idb dependencies)
|
|
151
|
+
|
|
152
|
+
The `--setup-all` / `--setup-here` command handles installing everything else automatically.
|
|
153
|
+
|
|
154
|
+
## Manual MCP configuration
|
|
155
|
+
|
|
156
|
+
If you'd rather configure things yourself:
|
|
157
|
+
|
|
158
|
+
**Claude Code** — add to `~/.claude.json` (global) or `.mcp.json` (project):
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"mcpServers": {
|
|
163
|
+
"blitz-iphone": {
|
|
164
|
+
"command": "npx",
|
|
165
|
+
"args": ["@blitzdev/iphone-mcp"]
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Cursor** — add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project):
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"mcpServers": {
|
|
176
|
+
"blitz-iphone": {
|
|
177
|
+
"command": "npx",
|
|
178
|
+
"args": ["@blitzdev/iphone-mcp"]
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Codex** — add to `~/.codex/config.toml` (global) or `.codex/config.toml` (project):
|
|
185
|
+
|
|
186
|
+
```toml
|
|
187
|
+
[mcp_servers.blitz-iphone]
|
|
188
|
+
command = "npx"
|
|
189
|
+
args = ["@blitzdev/iphone-mcp"]
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**OpenCode** — add to `opencode.json` in your project root:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"$schema": "https://opencode.ai/config.json",
|
|
197
|
+
"mcp": {
|
|
198
|
+
"blitz-iphone": {
|
|
199
|
+
"type": "local",
|
|
200
|
+
"command": ["npx", "-y", "@blitzdev/iphone-mcp"],
|
|
201
|
+
"enabled": true
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Troubleshooting
|
|
208
|
+
|
|
209
|
+
**"No booted simulator found"** — Open Simulator.app or run `xcrun simctl boot "iPhone 16"` first.
|
|
210
|
+
|
|
211
|
+
**Physical device not detected** — Make sure Developer Mode is on, the phone is connected via USB, and you've tapped "Trust" on the phone.
|
|
212
|
+
|
|
213
|
+
**WDA build fails** — Open Xcode > Settings > Accounts and make sure an Apple ID is signed in. Xcode needs a signing identity to build WDA.
|
|
214
|
+
|
|
215
|
+
**"Connection refused" errors** — The idb companion may have crashed. Run `npx @blitzdev/iphone-mcp --setup-all` again to re-initialize.
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function childEnv(): Record<string, string>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import { execFileSync } from 'node:child_process';
|
|
4
|
+
let _loginShellPath = null;
|
|
5
|
+
function getLoginShellPath() {
|
|
6
|
+
if (_loginShellPath !== null)
|
|
7
|
+
return _loginShellPath;
|
|
8
|
+
try {
|
|
9
|
+
const shell = process.env.SHELL || '/bin/zsh';
|
|
10
|
+
const out = execFileSync(shell, ['-ilc', 'echo $PATH'], {
|
|
11
|
+
encoding: 'utf8',
|
|
12
|
+
timeout: 5000,
|
|
13
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
14
|
+
});
|
|
15
|
+
_loginShellPath = out.trim();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
_loginShellPath = '';
|
|
19
|
+
}
|
|
20
|
+
return _loginShellPath;
|
|
21
|
+
}
|
|
22
|
+
export function childEnv() {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
24
|
+
const { NODE_ENV, ...baseEnv } = process.env;
|
|
25
|
+
const home = os.homedir();
|
|
26
|
+
const pathParts = [];
|
|
27
|
+
// Inherited PATH
|
|
28
|
+
pathParts.push(baseEnv.PATH ?? '');
|
|
29
|
+
// Login shell PATH
|
|
30
|
+
const loginPath = getLoginShellPath();
|
|
31
|
+
if (loginPath) {
|
|
32
|
+
pathParts.push(loginPath);
|
|
33
|
+
}
|
|
34
|
+
// Common bin directories
|
|
35
|
+
const extraPaths = [
|
|
36
|
+
'/opt/homebrew/bin',
|
|
37
|
+
'/opt/homebrew/sbin',
|
|
38
|
+
'/usr/local/bin',
|
|
39
|
+
'/usr/local/sbin',
|
|
40
|
+
// blitz-iphone-mcp paths (primary)
|
|
41
|
+
path.join(home, '.blitz-iphone-mcp/python/bin'),
|
|
42
|
+
path.join(home, '.blitz-iphone-mcp/idb-companion/bin'),
|
|
43
|
+
// blitz paths (fallback)
|
|
44
|
+
path.join(home, '.blitz/python/bin'),
|
|
45
|
+
path.join(home, '.blitz/idb-companion/bin'),
|
|
46
|
+
'/usr/bin',
|
|
47
|
+
'/bin',
|
|
48
|
+
'/usr/sbin',
|
|
49
|
+
'/sbin',
|
|
50
|
+
];
|
|
51
|
+
for (const p of extraPaths) {
|
|
52
|
+
pathParts.push(p);
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
...baseEnv,
|
|
56
|
+
PATH: pathParts.join(':'),
|
|
57
|
+
LANG: baseEnv.LANG ?? 'en_US.UTF-8',
|
|
58
|
+
HOME: baseEnv.HOME ?? home,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=child-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"child-env.js","sourceRoot":"","sources":["../src/child-env.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,IAAI,eAAe,GAAkB,IAAI,CAAA;AACzC,SAAS,iBAAiB;IACxB,IAAI,eAAe,KAAK,IAAI;QAAE,OAAO,eAAe,CAAA;IACpD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,UAAU,CAAA;QAC7C,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE;YACtD,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAA;QACF,eAAe,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,GAAG,EAAE,CAAA;IACtB,CAAC;IACD,OAAO,eAAe,CAAA;AACxB,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,6DAA6D;IAC7D,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC,GAA6B,CAAA;IAEtE,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;IACzB,MAAM,SAAS,GAAa,EAAE,CAAA;IAE9B,iBAAiB;IACjB,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;IAElC,mBAAmB;IACnB,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAA;IACrC,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC3B,CAAC;IAED,yBAAyB;IACzB,MAAM,UAAU,GAAG;QACjB,mBAAmB;QACnB,oBAAoB;QACpB,gBAAgB;QAChB,iBAAiB;QACjB,mCAAmC;QACnC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,8BAA8B,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,qCAAqC,CAAC;QACtD,yBAAyB;QACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,0BAA0B,CAAC;QAC3C,UAAU;QACV,MAAM;QACN,WAAW;QACX,OAAO;KACR,CAAA;IACD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,OAAO;QACL,GAAG,OAAO;QACV,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QACzB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,aAAa;QACnC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;KAC3B,CAAA;AACH,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, symlinkSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { exec, execSync } from 'child_process';
|
|
6
|
+
import { promisify } from 'util';
|
|
7
|
+
import { createInterface } from 'readline';
|
|
8
|
+
import checkbox from '@inquirer/checkbox';
|
|
9
|
+
import { log } from './logger.js';
|
|
10
|
+
const execAsync = promisify(exec);
|
|
11
|
+
const VERSION = '0.1.0';
|
|
12
|
+
function printUsage() {
|
|
13
|
+
process.stderr.write(`
|
|
14
|
+
@blitzdev/iphone-mcp v${VERSION}
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
npx @blitzdev/iphone-mcp Start the MCP server (stdio)
|
|
18
|
+
npx @blitzdev/iphone-mcp --setup-all Install deps + configure globally (Claude Code, Cursor, Codex, OpenCode)
|
|
19
|
+
npx @blitzdev/iphone-mcp --setup-here Install deps + configure for current directory
|
|
20
|
+
npx @blitzdev/iphone-mcp --setup Interactive setup (prompts for scope)
|
|
21
|
+
npx @blitzdev/iphone-mcp --version Print version
|
|
22
|
+
npx @blitzdev/iphone-mcp --help Show this help
|
|
23
|
+
`);
|
|
24
|
+
}
|
|
25
|
+
async function prompt(question) {
|
|
26
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
27
|
+
return new Promise(resolve => {
|
|
28
|
+
rl.question(question, (answer) => {
|
|
29
|
+
rl.close();
|
|
30
|
+
resolve(answer.trim());
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
async function runSetup(scope) {
|
|
35
|
+
const mcpHome = join(homedir(), '.blitz-iphone-mcp');
|
|
36
|
+
const blitzHome = join(homedir(), '.blitz');
|
|
37
|
+
// Steps 1-5: Check/install dependencies (silent when everything is OK)
|
|
38
|
+
try {
|
|
39
|
+
execSync('xcode-select -p', { stdio: 'pipe' });
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
process.stderr.write('\n Xcode is required. Install from the App Store or run:\n');
|
|
43
|
+
process.stderr.write(' xcode-select --install\n\n');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
execSync('which brew', { stdio: 'pipe' });
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
process.stderr.write('\n Homebrew is required. Install from https://brew.sh\n\n');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
const mcpIdb = join(mcpHome, 'python', 'bin', 'idb');
|
|
54
|
+
const blitzIdb = join(blitzHome, 'python', 'bin', 'idb');
|
|
55
|
+
if (existsSync(mcpIdb)) {
|
|
56
|
+
// already installed
|
|
57
|
+
}
|
|
58
|
+
else if (existsSync(blitzIdb)) {
|
|
59
|
+
mkdirSync(join(mcpHome, 'python', 'bin'), { recursive: true });
|
|
60
|
+
try {
|
|
61
|
+
symlinkSync(join(blitzHome, 'python'), join(mcpHome, 'python'), 'junction');
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
symlinkSync(blitzIdb, mcpIdb);
|
|
65
|
+
}
|
|
66
|
+
const blitzCompanion = join(blitzHome, 'idb-companion');
|
|
67
|
+
if (existsSync(blitzCompanion) && !existsSync(join(mcpHome, 'idb-companion'))) {
|
|
68
|
+
try {
|
|
69
|
+
symlinkSync(blitzCompanion, join(mcpHome, 'idb-companion'), 'junction');
|
|
70
|
+
}
|
|
71
|
+
catch { /* ignore */ }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
process.stderr.write('\n Installing idb (this may take a few minutes)...\n');
|
|
76
|
+
mkdirSync(join(mcpHome, 'python'), { recursive: true });
|
|
77
|
+
mkdirSync(join(mcpHome, 'idb-companion'), { recursive: true });
|
|
78
|
+
try {
|
|
79
|
+
process.stderr.write(' Installing idb_companion via Homebrew...\n');
|
|
80
|
+
await execAsync('brew tap facebook/fb && brew install idb-companion', { timeout: 300_000 });
|
|
81
|
+
process.stderr.write(' Installing fb-idb via pip...\n');
|
|
82
|
+
await execAsync(`python3 -m venv "${join(mcpHome, 'python')}" && "${join(mcpHome, 'python', 'bin', 'pip')}" install fb-idb`, { timeout: 300_000 });
|
|
83
|
+
process.stderr.write(' idb installed successfully\n');
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
process.stderr.write(` Warning: idb installation failed: ${e.message}\n`);
|
|
87
|
+
process.stderr.write(' You can install manually: brew install idb-companion && pip install fb-idb\n');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const wdaPath = join(mcpHome, 'wda-build', 'WebDriverAgent');
|
|
91
|
+
const blitzWda = join(blitzHome, 'wda-build', 'WebDriverAgent');
|
|
92
|
+
if (existsSync(join(wdaPath, 'WebDriverAgent.xcodeproj'))) {
|
|
93
|
+
// already installed
|
|
94
|
+
}
|
|
95
|
+
else if (existsSync(join(blitzWda, 'WebDriverAgent.xcodeproj'))) {
|
|
96
|
+
mkdirSync(join(mcpHome, 'wda-build'), { recursive: true });
|
|
97
|
+
try {
|
|
98
|
+
symlinkSync(blitzWda, wdaPath);
|
|
99
|
+
}
|
|
100
|
+
catch { /* ignore */ }
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
process.stderr.write(' Cloning WebDriverAgent...\n');
|
|
104
|
+
mkdirSync(join(mcpHome, 'wda-build'), { recursive: true });
|
|
105
|
+
try {
|
|
106
|
+
await execAsync(`git clone --depth 1 https://github.com/appium/WebDriverAgent.git "${wdaPath}"`, { timeout: 120_000 });
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
process.stderr.write(` Warning: WDA clone failed: ${e.message}\n`);
|
|
110
|
+
process.stderr.write(' Physical device support requires WDA. You can clone manually.\n');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const mcpAxScan = join(mcpHome, 'bin', 'ax-scan');
|
|
114
|
+
const blitzAxScan = join(blitzHome, 'bin', 'ax-scan');
|
|
115
|
+
if (existsSync(mcpAxScan)) {
|
|
116
|
+
// already installed
|
|
117
|
+
}
|
|
118
|
+
else if (existsSync(blitzAxScan)) {
|
|
119
|
+
mkdirSync(join(mcpHome, 'bin'), { recursive: true });
|
|
120
|
+
try {
|
|
121
|
+
symlinkSync(blitzAxScan, mcpAxScan);
|
|
122
|
+
}
|
|
123
|
+
catch { /* ignore */ }
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
try {
|
|
127
|
+
const axScanDir = join(import.meta.dirname, 'idb', 'ax-scan');
|
|
128
|
+
if (!existsSync(join(axScanDir, 'Makefile'))) {
|
|
129
|
+
const distAxScanDir = join(import.meta.dirname, '..', 'src', 'idb', 'ax-scan');
|
|
130
|
+
if (existsSync(join(distAxScanDir, 'Makefile'))) {
|
|
131
|
+
await execAsync(`make -C "${distAxScanDir}" install INSTALL_DIR="${join(mcpHome, 'bin')}"`, { timeout: 60_000 });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
await execAsync(`make -C "${axScanDir}" install INSTALL_DIR="${join(mcpHome, 'bin')}"`, { timeout: 60_000 });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch { /* silent fallback */ }
|
|
139
|
+
}
|
|
140
|
+
// Configure MCP clients
|
|
141
|
+
const configured = [];
|
|
142
|
+
if (scope === 'all') {
|
|
143
|
+
// Global: always configure Claude Code, silently try Cursor and Codex if their dirs exist
|
|
144
|
+
configured.push(...writeClaudeCodeConfig(join(homedir(), '.claude.json')));
|
|
145
|
+
if (existsSync(join(homedir(), '.cursor'))) {
|
|
146
|
+
configured.push(...writeCursorConfig(join(homedir(), '.cursor', 'mcp.json')));
|
|
147
|
+
}
|
|
148
|
+
if (existsSync(join(homedir(), '.codex'))) {
|
|
149
|
+
configured.push(...writeCodexConfig(join(homedir(), '.codex', 'config.toml')));
|
|
150
|
+
}
|
|
151
|
+
if (existsSync(join(process.cwd(), 'opencode.json')) || existsSync(join(process.cwd(), 'opencode.jsonc'))) {
|
|
152
|
+
configured.push(...writeOpenCodeConfig(join(process.cwd(), 'opencode.json')));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else if (scope === 'here') {
|
|
156
|
+
// Project-scoped: checkbox prompt for which clients to configure
|
|
157
|
+
const choices = await checkbox({
|
|
158
|
+
message: 'Which AI agents should have access to @blitzdev/iphone-mcp?',
|
|
159
|
+
choices: [
|
|
160
|
+
{ name: 'Claude Code', value: 'claude-code', checked: true },
|
|
161
|
+
{ name: 'Cursor', value: 'cursor' },
|
|
162
|
+
{ name: 'Codex', value: 'codex' },
|
|
163
|
+
{ name: 'OpenCode', value: 'opencode' },
|
|
164
|
+
],
|
|
165
|
+
}, { output: process.stderr });
|
|
166
|
+
if (choices.includes('claude-code')) {
|
|
167
|
+
configured.push(...writeClaudeCodeConfig(join(process.cwd(), '.mcp.json')));
|
|
168
|
+
}
|
|
169
|
+
if (choices.includes('cursor')) {
|
|
170
|
+
mkdirSync(join(process.cwd(), '.cursor'), { recursive: true });
|
|
171
|
+
configured.push(...writeCursorConfig(join(process.cwd(), '.cursor', 'mcp.json')));
|
|
172
|
+
}
|
|
173
|
+
if (choices.includes('codex')) {
|
|
174
|
+
mkdirSync(join(process.cwd(), '.codex'), { recursive: true });
|
|
175
|
+
configured.push(...writeCodexConfig(join(process.cwd(), '.codex', 'config.toml')));
|
|
176
|
+
}
|
|
177
|
+
if (choices.includes('opencode')) {
|
|
178
|
+
configured.push(...writeOpenCodeConfig(join(process.cwd(), 'opencode.json')));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Interactive --setup: ask scope first, then configure
|
|
183
|
+
const answer = await prompt('\n Install MCP config:\n 1. System-wide (all projects) [recommended]\n 2. Current directory only\n Choose (1/2): ');
|
|
184
|
+
if (answer === '2') {
|
|
185
|
+
configured.push(...writeClaudeCodeConfig(join(process.cwd(), '.mcp.json')));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
configured.push(...writeClaudeCodeConfig(join(homedir(), '.claude.json')));
|
|
189
|
+
if (existsSync(join(homedir(), '.cursor'))) {
|
|
190
|
+
configured.push(...writeCursorConfig(join(homedir(), '.cursor', 'mcp.json')));
|
|
191
|
+
}
|
|
192
|
+
if (existsSync(join(homedir(), '.codex'))) {
|
|
193
|
+
configured.push(...writeCodexConfig(join(homedir(), '.codex', 'config.toml')));
|
|
194
|
+
}
|
|
195
|
+
if (existsSync(join(process.cwd(), 'opencode.json')) || existsSync(join(process.cwd(), 'opencode.jsonc'))) {
|
|
196
|
+
configured.push(...writeOpenCodeConfig(join(process.cwd(), 'opencode.json')));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (configured.length > 0) {
|
|
201
|
+
process.stderr.write(`\n Configured: ${configured.join(', ')}\n`);
|
|
202
|
+
}
|
|
203
|
+
process.stderr.write('\n Setup complete! Restart your AI agent to activate.\n\n');
|
|
204
|
+
}
|
|
205
|
+
function writeJsonMcpConfig(configPath) {
|
|
206
|
+
const mcpServers = {
|
|
207
|
+
'blitz-iphone': {
|
|
208
|
+
command: 'npx',
|
|
209
|
+
args: ['@blitzdev/iphone-mcp'],
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
try {
|
|
213
|
+
let existing = {};
|
|
214
|
+
if (existsSync(configPath)) {
|
|
215
|
+
existing = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
216
|
+
}
|
|
217
|
+
const merged = {
|
|
218
|
+
...existing,
|
|
219
|
+
mcpServers: {
|
|
220
|
+
...(existing.mcpServers ?? {}),
|
|
221
|
+
...mcpServers,
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
writeFileSync(configPath, JSON.stringify(merged, null, 2) + '\n');
|
|
225
|
+
process.stderr.write(` Written: ${configPath}\n`);
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
catch (e) {
|
|
229
|
+
process.stderr.write(` Warning: Could not write ${configPath}: ${e.message}\n`);
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function writeClaudeCodeConfig(configPath) {
|
|
234
|
+
return writeJsonMcpConfig(configPath) ? ['Claude Code'] : [];
|
|
235
|
+
}
|
|
236
|
+
function writeCursorConfig(configPath) {
|
|
237
|
+
return writeJsonMcpConfig(configPath) ? ['Cursor'] : [];
|
|
238
|
+
}
|
|
239
|
+
function writeOpenCodeConfig(configPath) {
|
|
240
|
+
const mcpEntry = {
|
|
241
|
+
'blitz-iphone': {
|
|
242
|
+
type: 'local',
|
|
243
|
+
command: ['npx', '-y', '@blitzdev/iphone-mcp'],
|
|
244
|
+
enabled: true,
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
try {
|
|
248
|
+
let existing = {};
|
|
249
|
+
if (existsSync(configPath)) {
|
|
250
|
+
existing = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
251
|
+
}
|
|
252
|
+
const merged = {
|
|
253
|
+
...existing,
|
|
254
|
+
mcp: {
|
|
255
|
+
...(existing.mcp ?? {}),
|
|
256
|
+
...mcpEntry,
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
writeFileSync(configPath, JSON.stringify(merged, null, 2) + '\n');
|
|
260
|
+
process.stderr.write(` Written: ${configPath}\n`);
|
|
261
|
+
return ['OpenCode'];
|
|
262
|
+
}
|
|
263
|
+
catch (e) {
|
|
264
|
+
process.stderr.write(` Warning: Could not write ${configPath}: ${e.message}\n`);
|
|
265
|
+
return [];
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function writeCodexConfig(configPath) {
|
|
269
|
+
const tomlBlock = `\n[mcp_servers.blitz-iphone]\ncommand = "npx"\nargs = ["@blitzdev/iphone-mcp"]\n`;
|
|
270
|
+
try {
|
|
271
|
+
let existing = '';
|
|
272
|
+
if (existsSync(configPath)) {
|
|
273
|
+
existing = readFileSync(configPath, 'utf8');
|
|
274
|
+
}
|
|
275
|
+
if (existing.includes('[mcp_servers.blitz-iphone]')) {
|
|
276
|
+
process.stderr.write(` Codex config already has blitz-iphone, skipping\n`);
|
|
277
|
+
return ['Codex'];
|
|
278
|
+
}
|
|
279
|
+
writeFileSync(configPath, existing + tomlBlock);
|
|
280
|
+
process.stderr.write(` Written: ${configPath}\n`);
|
|
281
|
+
return ['Codex'];
|
|
282
|
+
}
|
|
283
|
+
catch (e) {
|
|
284
|
+
process.stderr.write(` Warning: Could not write ${configPath}: ${e.message}\n`);
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async function main() {
|
|
289
|
+
const args = process.argv.slice(2);
|
|
290
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
291
|
+
printUsage();
|
|
292
|
+
process.exit(0);
|
|
293
|
+
}
|
|
294
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
295
|
+
process.stderr.write(`@blitzdev/iphone-mcp v${VERSION}\n`);
|
|
296
|
+
process.exit(0);
|
|
297
|
+
}
|
|
298
|
+
if (args.includes('--setup-all')) {
|
|
299
|
+
await runSetup('all');
|
|
300
|
+
process.exit(0);
|
|
301
|
+
}
|
|
302
|
+
if (args.includes('--setup-here')) {
|
|
303
|
+
await runSetup('here');
|
|
304
|
+
process.exit(0);
|
|
305
|
+
}
|
|
306
|
+
if (args.includes('--setup')) {
|
|
307
|
+
await runSetup();
|
|
308
|
+
process.exit(0);
|
|
309
|
+
}
|
|
310
|
+
// Default: start MCP server
|
|
311
|
+
const { startServer } = await import('./index.js');
|
|
312
|
+
await startServer();
|
|
313
|
+
}
|
|
314
|
+
main().catch(e => {
|
|
315
|
+
log('CLI', 'error', `Fatal error: ${e}`);
|
|
316
|
+
process.exit(1);
|
|
317
|
+
});
|
|
318
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getIDBClient } from './idb/idb-client.js';
|
|
2
|
+
import { WDAClient } from './wda/wda-client.js';
|
|
3
|
+
import { wdaManager } from './wda/wda-manager.js';
|
|
4
|
+
import { isPhysicalDeviceUdid } from './types.js';
|
|
5
|
+
export async function getDeviceClient(udid = 'booted') {
|
|
6
|
+
if (isPhysicalDeviceUdid(udid)) {
|
|
7
|
+
const existing = WDAClient.getExistingInstance(udid);
|
|
8
|
+
if (existing)
|
|
9
|
+
return existing;
|
|
10
|
+
const tunnelIP = await wdaManager.getTunnelAddress(udid);
|
|
11
|
+
return WDAClient.getInstance(udid, 8100, tunnelIP);
|
|
12
|
+
}
|
|
13
|
+
return getIDBClient(udid);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=device-client.js.map
|