@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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +219 -0
  3. package/dist/child-env.d.ts +1 -0
  4. package/dist/child-env.js +61 -0
  5. package/dist/child-env.js.map +1 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +318 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/device-client.d.ts +2 -0
  10. package/dist/device-client.js +15 -0
  11. package/dist/device-client.js.map +1 -0
  12. package/dist/execution-context.d.ts +33 -0
  13. package/dist/execution-context.js +66 -0
  14. package/dist/execution-context.js.map +1 -0
  15. package/dist/idb/ax-scan-client.d.ts +27 -0
  16. package/dist/idb/ax-scan-client.js +244 -0
  17. package/dist/idb/ax-scan-client.js.map +1 -0
  18. package/dist/idb/idb-client.d.ts +34 -0
  19. package/dist/idb/idb-client.js +288 -0
  20. package/dist/idb/idb-client.js.map +1 -0
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.js +15 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/logger.d.ts +3 -0
  25. package/dist/logger.js +6 -0
  26. package/dist/logger.js.map +1 -0
  27. package/dist/mcp-server.d.ts +2 -0
  28. package/dist/mcp-server.js +649 -0
  29. package/dist/mcp-server.js.map +1 -0
  30. package/dist/types.d.ts +75 -0
  31. package/dist/types.js +7 -0
  32. package/dist/types.js.map +1 -0
  33. package/dist/ui-filters.d.ts +11 -0
  34. package/dist/ui-filters.js +100 -0
  35. package/dist/ui-filters.js.map +1 -0
  36. package/dist/viewer/server.d.ts +5 -0
  37. package/dist/viewer/server.js +233 -0
  38. package/dist/viewer/server.js.map +1 -0
  39. package/dist/wda/device-discovery.d.ts +12 -0
  40. package/dist/wda/device-discovery.js +91 -0
  41. package/dist/wda/device-discovery.js.map +1 -0
  42. package/dist/wda/wda-client.d.ts +38 -0
  43. package/dist/wda/wda-client.js +314 -0
  44. package/dist/wda/wda-client.js.map +1 -0
  45. package/dist/wda/wda-manager.d.ts +29 -0
  46. package/dist/wda/wda-manager.js +263 -0
  47. package/dist/wda/wda-manager.js.map +1 -0
  48. package/dist/wda/wda-scan.d.ts +3 -0
  49. package/dist/wda/wda-scan.js +41 -0
  50. package/dist/wda/wda-scan.js.map +1 -0
  51. package/package.json +40 -0
  52. package/src/idb/ax-scan/Makefile +30 -0
  53. 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
+ [![Website](https://img.shields.io/badge/blitz.dev-website-black)](https://blitz.dev/)
7
+ [![Discord](https://img.shields.io/badge/discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/wJQ6dA95S6)
8
+ [![npm](https://img.shields.io/npm/v/@blitzdev/iphone-mcp?label=npm&color=blue)](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
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { type DeviceClient } from './types.js';
2
+ export declare function getDeviceClient(udid?: string): Promise<DeviceClient>;
@@ -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