@ebowwa/mcp-ios-devices 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.
@@ -0,0 +1,58 @@
1
+ /**
2
+ * App Management Tools
3
+ * Install, uninstall, and manage apps on iOS devices
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { DeviceCtl } from '@ebowwa/ios-devices';
9
+
10
+ const deviceCtl = new DeviceCtl();
11
+
12
+ registerTool({
13
+ name: 'ios_list_apps',
14
+ description: 'List all installed apps on a device',
15
+ inputSchema: z.object({
16
+ deviceId: z.string().describe('Device UDID'),
17
+ }),
18
+ handler: async ({ deviceId }) => {
19
+ return deviceCtl.listApps(deviceId);
20
+ },
21
+ });
22
+
23
+ registerTool({
24
+ name: 'ios_install_app',
25
+ description: 'Install an app (.app or .ipa) on the device',
26
+ inputSchema: z.object({
27
+ deviceId: z.string().describe('Device UDID'),
28
+ appPath: z.string().describe('Path to .app or .ipa file'),
29
+ }),
30
+ handler: async ({ deviceId, appPath }) => {
31
+ return deviceCtl.installApp(deviceId, appPath);
32
+ },
33
+ });
34
+
35
+ registerTool({
36
+ name: 'ios_uninstall_app',
37
+ description: 'Uninstall an app from the device',
38
+ inputSchema: z.object({
39
+ deviceId: z.string().describe('Device UDID'),
40
+ bundleId: z.string().describe('App bundle identifier'),
41
+ }),
42
+ handler: async ({ deviceId, bundleId }) => {
43
+ return deviceCtl.uninstallApp(deviceId, bundleId);
44
+ },
45
+ });
46
+
47
+ registerTool({
48
+ name: 'ios_get_app_icon',
49
+ description: 'Get the icon for an app',
50
+ inputSchema: z.object({
51
+ deviceId: z.string().describe('Device UDID'),
52
+ bundleId: z.string().describe('App bundle identifier'),
53
+ outputPath: z.string().optional().describe('Path to save icon'),
54
+ }),
55
+ handler: async ({ deviceId, bundleId, outputPath }) => {
56
+ return deviceCtl.getAppIcon(deviceId, bundleId, outputPath);
57
+ },
58
+ });
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Backup & Restore Tools
3
+ * Create and restore device backups
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { LibIMobileDevice } from '@ebowwa/ios-devices';
9
+
10
+ registerTool({
11
+ name: 'ios_create_backup',
12
+ description: 'Create a backup of the device',
13
+ inputSchema: z.object({
14
+ deviceId: z.string().describe('Device UDID'),
15
+ directory: z.string().describe('Directory for backup'),
16
+ encrypt: z.boolean().optional().describe('Encrypt backup'),
17
+ password: z.string().optional().describe('Password for encrypted backup'),
18
+ }),
19
+ handler: async ({ deviceId, directory, encrypt, password }) => {
20
+ const lib = new LibIMobileDevice({ udid: deviceId });
21
+ return lib.createBackup(directory, encrypt, password);
22
+ },
23
+ });
24
+
25
+ registerTool({
26
+ name: 'ios_restore_backup',
27
+ description: 'Restore a backup to the device',
28
+ inputSchema: z.object({
29
+ deviceId: z.string().describe('Device UDID'),
30
+ directory: z.string().describe('Backup directory'),
31
+ password: z.string().optional().describe('Password for encrypted backup'),
32
+ }),
33
+ handler: async ({ deviceId, directory, password }) => {
34
+ const lib = new LibIMobileDevice({ udid: deviceId });
35
+ return lib.restoreBackup(directory, password);
36
+ },
37
+ });
38
+
39
+ registerTool({
40
+ name: 'ios_list_backups',
41
+ description: 'List available backups',
42
+ inputSchema: z.object({}),
43
+ handler: async () => {
44
+ const lib = new LibIMobileDevice();
45
+ return lib.listBackups();
46
+ },
47
+ });
48
+
49
+ registerTool({
50
+ name: 'ios_get_backup_info',
51
+ description: 'Get information about a backup',
52
+ inputSchema: z.object({
53
+ directory: z.string().describe('Backup directory'),
54
+ }),
55
+ handler: async ({ directory }) => {
56
+ const lib = new LibIMobileDevice();
57
+ return lib.getBackupInfo(directory);
58
+ },
59
+ });
60
+
61
+ registerTool({
62
+ name: 'ios_unpack_backup',
63
+ description: 'Unpack a backup to a directory',
64
+ inputSchema: z.object({
65
+ directory: z.string().describe('Backup directory'),
66
+ }),
67
+ handler: async ({ directory }) => {
68
+ const lib = new LibIMobileDevice();
69
+ return lib.unpackBackup(directory);
70
+ },
71
+ });
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Device Management Tools
3
+ * Physical iOS device control via devicectl and libimobiledevice
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { DeviceCtl, LibIMobileDevice } from '@ebowwa/ios-devices';
9
+
10
+ const deviceCtl = new DeviceCtl();
11
+
12
+ // ============================================================================
13
+ // Device Listing & Info
14
+ // ============================================================================
15
+
16
+ registerTool({
17
+ name: 'ios_list_devices',
18
+ description: 'List all connected iOS devices',
19
+ inputSchema: z.object({}),
20
+ handler: async () => {
21
+ return deviceCtl.listDevices();
22
+ },
23
+ });
24
+
25
+ registerTool({
26
+ name: 'ios_device_info',
27
+ description: 'Get detailed information about a specific device',
28
+ inputSchema: z.object({
29
+ deviceId: z.string().describe('Device UDID, name, or ECID'),
30
+ }),
31
+ handler: async ({ deviceId }) => {
32
+ return deviceCtl.getDeviceInfo(deviceId);
33
+ },
34
+ });
35
+
36
+ registerTool({
37
+ name: 'ios_device_lock_state',
38
+ description: 'Get the lock state of a device (locked/unlocked)',
39
+ inputSchema: z.object({
40
+ deviceId: z.string().describe('Device UDID'),
41
+ }),
42
+ handler: async ({ deviceId }) => {
43
+ return deviceCtl.getLockState(deviceId);
44
+ },
45
+ });
46
+
47
+ registerTool({
48
+ name: 'ios_device_displays',
49
+ description: 'Get display information for a device',
50
+ inputSchema: z.object({
51
+ deviceId: z.string().describe('Device UDID'),
52
+ }),
53
+ handler: async ({ deviceId }) => {
54
+ return deviceCtl.getDisplays(deviceId);
55
+ },
56
+ });
57
+
58
+ // ============================================================================
59
+ // Pairing
60
+ // ============================================================================
61
+
62
+ registerTool({
63
+ name: 'ios_pair_device',
64
+ description: 'Pair with an iOS device',
65
+ inputSchema: z.object({
66
+ deviceId: z.string().describe('Device UDID'),
67
+ }),
68
+ handler: async ({ deviceId }) => {
69
+ return deviceCtl.pair(deviceId);
70
+ },
71
+ });
72
+
73
+ registerTool({
74
+ name: 'ios_unpair_device',
75
+ description: 'Unpair from an iOS device',
76
+ inputSchema: z.object({
77
+ deviceId: z.string().describe('Device UDID'),
78
+ }),
79
+ handler: async ({ deviceId }) => {
80
+ return deviceCtl.unpair(deviceId);
81
+ },
82
+ });
83
+
84
+ // ============================================================================
85
+ // Device Control
86
+ // ============================================================================
87
+
88
+ registerTool({
89
+ name: 'ios_reboot_device',
90
+ description: 'Reboot an iOS device',
91
+ inputSchema: z.object({
92
+ deviceId: z.string().describe('Device UDID'),
93
+ }),
94
+ handler: async ({ deviceId }) => {
95
+ return deviceCtl.reboot(deviceId);
96
+ },
97
+ });
98
+
99
+ registerTool({
100
+ name: 'ios_set_orientation',
101
+ description: 'Set device orientation',
102
+ inputSchema: z.object({
103
+ deviceId: z.string().describe('Device UDID'),
104
+ orientation: z.enum(['portrait', 'landscape', 'portrait-upside-down', 'landscape-left', 'landscape-right']),
105
+ }),
106
+ handler: async ({ deviceId, orientation }) => {
107
+ return deviceCtl.setOrientation(deviceId, orientation);
108
+ },
109
+ });
110
+
111
+ registerTool({
112
+ name: 'ios_respring',
113
+ description: 'Respring the device (restart SpringBoard UI)',
114
+ inputSchema: z.object({
115
+ deviceId: z.string().describe('Device UDID'),
116
+ }),
117
+ handler: async ({ deviceId }) => {
118
+ return deviceCtl.respring(deviceId);
119
+ },
120
+ });
121
+
122
+ // ============================================================================
123
+ // LibIMobileDevice Tools (Additional)
124
+ // ============================================================================
125
+
126
+ registerTool({
127
+ name: 'ios_get_device_name',
128
+ description: 'Get or set the device name',
129
+ inputSchema: z.object({
130
+ deviceId: z.string().describe('Device UDID'),
131
+ newName: z.string().optional().describe('New name (omit to get current name)'),
132
+ }),
133
+ handler: async ({ deviceId, newName }) => {
134
+ const lib = new LibIMobileDevice({ udid: deviceId });
135
+ if (newName) {
136
+ return lib.setDeviceName(newName);
137
+ }
138
+ return lib.getDeviceName();
139
+ },
140
+ });
141
+
142
+ registerTool({
143
+ name: 'ios_get_device_date',
144
+ description: 'Get the current date/time from the device',
145
+ inputSchema: z.object({
146
+ deviceId: z.string().describe('Device UDID'),
147
+ }),
148
+ handler: async ({ deviceId }) => {
149
+ const lib = new LibIMobileDevice({ udid: deviceId });
150
+ return lib.getDeviceDate();
151
+ },
152
+ });
153
+
154
+ registerTool({
155
+ name: 'ios_shutdown_device',
156
+ description: 'Shutdown the device',
157
+ inputSchema: z.object({
158
+ deviceId: z.string().describe('Device UDID'),
159
+ }),
160
+ handler: async ({ deviceId }) => {
161
+ const lib = new LibIMobileDevice({ udid: deviceId });
162
+ return lib.shutdown();
163
+ },
164
+ });
165
+
166
+ registerTool({
167
+ name: 'ios_restart_device',
168
+ description: 'Restart the device',
169
+ inputSchema: z.object({
170
+ deviceId: z.string().describe('Device UDID'),
171
+ }),
172
+ handler: async ({ deviceId }) => {
173
+ const lib = new LibIMobileDevice({ udid: deviceId });
174
+ return lib.restart();
175
+ },
176
+ });
177
+
178
+ registerTool({
179
+ name: 'ios_sleep_device',
180
+ description: 'Put the device to sleep',
181
+ inputSchema: z.object({
182
+ deviceId: z.string().describe('Device UDID'),
183
+ }),
184
+ handler: async ({ deviceId }) => {
185
+ const lib = new LibIMobileDevice({ udid: deviceId });
186
+ return lib.sleep();
187
+ },
188
+ });
189
+
190
+ registerTool({
191
+ name: 'ios_enter_recovery',
192
+ description: 'Put device into recovery mode',
193
+ inputSchema: z.object({
194
+ deviceId: z.string().describe('Device UDID'),
195
+ }),
196
+ handler: async ({ deviceId }) => {
197
+ const lib = new LibIMobileDevice({ udid: deviceId });
198
+ return lib.enterRecovery();
199
+ },
200
+ });
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Diagnostics Tools
3
+ * Device diagnostics and information
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { LibIMobileDevice } from '@ebowwa/ios-devices';
9
+
10
+ registerTool({
11
+ name: 'ios_get_diagnostics',
12
+ description: 'Get device diagnostics (WiFi, Battery, NAND, etc.)',
13
+ inputSchema: z.object({
14
+ deviceId: z.string().describe('Device UDID'),
15
+ type: z.enum(['All', 'WiFi', 'GasGauge', 'NAND', 'Battery', 'HDMI']).default('All'),
16
+ }),
17
+ handler: async ({ deviceId, type }) => {
18
+ const lib = new LibIMobileDevice({ udid: deviceId });
19
+ return lib.getDiagnostics(type);
20
+ },
21
+ });
22
+
23
+ registerTool({
24
+ name: 'ios_get_ioreg',
25
+ description: 'Get IO Registry information',
26
+ inputSchema: z.object({
27
+ deviceId: z.string().describe('Device UDID'),
28
+ plane: z.enum(['IODeviceTree', 'IOPower', 'IOService']).optional(),
29
+ }),
30
+ handler: async ({ deviceId, plane }) => {
31
+ const lib = new LibIMobileDevice({ udid: deviceId });
32
+ return lib.getIORegistry(plane);
33
+ },
34
+ });
35
+
36
+ registerTool({
37
+ name: 'ios_get_mobilegestalt',
38
+ description: 'Get MobileGestalt values from device',
39
+ inputSchema: z.object({
40
+ deviceId: z.string().describe('Device UDID'),
41
+ keys: z.array(z.string()).describe('Keys to query'),
42
+ }),
43
+ handler: async ({ deviceId, keys }) => {
44
+ const lib = new LibIMobileDevice({ udid: deviceId });
45
+ return lib.getMobileGestalt(...keys);
46
+ },
47
+ });
48
+
49
+ registerTool({
50
+ name: 'ios_mount_image',
51
+ description: 'Mount developer disk image on device',
52
+ inputSchema: z.object({
53
+ deviceId: z.string().describe('Device UDID'),
54
+ imagePath: z.string().describe('Path to developer disk image'),
55
+ signaturePath: z.string().optional().describe('Path to signature file'),
56
+ }),
57
+ handler: async ({ deviceId, imagePath, signaturePath }) => {
58
+ const lib = new LibIMobileDevice({ udid: deviceId });
59
+ return lib.mountImage(imagePath, signaturePath);
60
+ },
61
+ });
62
+
63
+ registerTool({
64
+ name: 'ios_start_debug_server',
65
+ description: 'Start debug server proxy for remote debugging',
66
+ inputSchema: z.object({
67
+ deviceId: z.string().describe('Device UDID'),
68
+ port: z.number().default(6666).describe('Port for debug server'),
69
+ }),
70
+ handler: async ({ deviceId, port }) => {
71
+ const lib = new LibIMobileDevice({ udid: deviceId });
72
+ return lib.startDebugServerProxy(port);
73
+ },
74
+ });
75
+
76
+ registerTool({
77
+ name: 'ios_start_bluetooth_logger',
78
+ description: 'Start Bluetooth packet logging',
79
+ inputSchema: z.object({
80
+ deviceId: z.string().describe('Device UDID'),
81
+ outputPath: z.string().optional().describe('Output file path'),
82
+ }),
83
+ handler: async ({ deviceId, outputPath }) => {
84
+ const lib = new LibIMobileDevice({ udid: deviceId });
85
+ return lib.startBluetoothLogging(outputPath);
86
+ },
87
+ });
@@ -0,0 +1,60 @@
1
+ /**
2
+ * File System Tools
3
+ * Access files on iOS devices via AFC
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { DeviceCtl, LibIMobileDevice } from '@ebowwa/ios-devices';
9
+
10
+ const deviceCtl = new DeviceCtl();
11
+
12
+ registerTool({
13
+ name: 'ios_list_files',
14
+ description: 'List files in a directory on the device',
15
+ inputSchema: z.object({
16
+ deviceId: z.string().describe('Device UDID'),
17
+ path: z.string().describe('Directory path to list'),
18
+ }),
19
+ handler: async ({ deviceId, path }) => {
20
+ return deviceCtl.listFiles(deviceId, path);
21
+ },
22
+ });
23
+
24
+ registerTool({
25
+ name: 'ios_copy_to_device',
26
+ description: 'Copy a file to the device',
27
+ inputSchema: z.object({
28
+ deviceId: z.string().describe('Device UDID'),
29
+ source: z.string().describe('Local source path'),
30
+ destination: z.string().describe('Device destination path'),
31
+ }),
32
+ handler: async ({ deviceId, source, destination }) => {
33
+ return deviceCtl.copyToDevice(deviceId, source, destination);
34
+ },
35
+ });
36
+
37
+ registerTool({
38
+ name: 'ios_copy_from_device',
39
+ description: 'Copy a file from the device',
40
+ inputSchema: z.object({
41
+ deviceId: z.string().describe('Device UDID'),
42
+ source: z.string().describe('Device source path'),
43
+ destination: z.string().describe('Local destination path'),
44
+ }),
45
+ handler: async ({ deviceId, source, destination }) => {
46
+ return deviceCtl.copyFromDevice(deviceId, source, destination);
47
+ },
48
+ });
49
+
50
+ registerTool({
51
+ name: 'ios_start_afc_shell',
52
+ description: 'Start an AFC shell for file system access',
53
+ inputSchema: z.object({
54
+ deviceId: z.string().describe('Device UDID'),
55
+ }),
56
+ handler: async ({ deviceId }) => {
57
+ const lib = new LibIMobileDevice({ udid: deviceId });
58
+ return lib.startAFCShell();
59
+ },
60
+ });
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Location Tools
3
+ * Simulate GPS location on devices
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { LibIMobileDevice } from '@ebowwa/ios-devices';
9
+
10
+ registerTool({
11
+ name: 'ios_set_location',
12
+ description: 'Set simulated GPS location on device',
13
+ inputSchema: z.object({
14
+ deviceId: z.string().describe('Device UDID'),
15
+ latitude: z.number().min(-90).max(90).describe('Latitude'),
16
+ longitude: z.number().min(-180).max(180).describe('Longitude'),
17
+ }),
18
+ handler: async ({ deviceId, latitude, longitude }) => {
19
+ const lib = new LibIMobileDevice({ udid: deviceId });
20
+ return lib.setLocation(latitude, longitude);
21
+ },
22
+ });
23
+
24
+ registerTool({
25
+ name: 'ios_reset_location',
26
+ description: 'Reset simulated GPS location (stop simulation)',
27
+ inputSchema: z.object({
28
+ deviceId: z.string().describe('Device UDID'),
29
+ }),
30
+ handler: async ({ deviceId }) => {
31
+ const lib = new LibIMobileDevice({ udid: deviceId });
32
+ return lib.resetLocation();
33
+ },
34
+ });
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Logging & Diagnostics Tools
3
+ * Collect logs and diagnostic information from iOS devices
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { LibIMobileDevice, DeviceCtl } from '@ebowwa/ios-devices';
9
+
10
+ registerTool({
11
+ name: 'ios_stream_syslog',
12
+ description: 'Stream syslog from device (real-time logs)',
13
+ inputSchema: z.object({
14
+ deviceId: z.string().describe('Device UDID'),
15
+ match: z.string().optional().describe('Only include logs matching pattern'),
16
+ exclude: z.string().optional().describe('Exclude logs matching pattern'),
17
+ process: z.string().optional().describe('Filter by process name'),
18
+ kernel: z.boolean().optional().describe('Include kernel logs only'),
19
+ }),
20
+ handler: async ({ deviceId, match, exclude, process, kernel }) => {
21
+ const lib = new LibIMobileDevice({ udid: deviceId });
22
+ return lib.streamSyslog({ match, exclude, process, kernel });
23
+ },
24
+ });
25
+
26
+ registerTool({
27
+ name: 'ios_get_syslog_archive',
28
+ description: 'Download syslog archive from device',
29
+ inputSchema: z.object({
30
+ deviceId: z.string().describe('Device UDID'),
31
+ outputPath: z.string().describe('Path to save archive'),
32
+ }),
33
+ handler: async ({ deviceId, outputPath }) => {
34
+ const lib = new LibIMobileDevice({ udid: deviceId });
35
+ return lib.getSyslogArchive(outputPath);
36
+ },
37
+ });
38
+
39
+ registerTool({
40
+ name: 'ios_collect_diagnostics',
41
+ description: 'Collect diagnostic information from device',
42
+ inputSchema: z.object({
43
+ deviceId: z.string().optional().describe('Device UDID (omit for all devices)'),
44
+ archiveDestination: z.string().optional().describe('Path for diagnostic archive'),
45
+ }),
46
+ handler: async ({ deviceId, archiveDestination }) => {
47
+ const deviceCtl = new DeviceCtl();
48
+ return deviceCtl.collectDiagnostics({ devices: deviceId, archiveDestination });
49
+ },
50
+ });
51
+
52
+ registerTool({
53
+ name: 'ios_download_crash_reports',
54
+ description: 'Download crash reports from device',
55
+ inputSchema: z.object({
56
+ deviceId: z.string().describe('Device UDID'),
57
+ outputDirectory: z.string().describe('Directory to save crash reports'),
58
+ extract: z.boolean().optional().describe('Extract crash reports'),
59
+ keep: z.boolean().optional().describe('Keep reports on device'),
60
+ }),
61
+ handler: async ({ deviceId, outputDirectory, extract, keep }) => {
62
+ const lib = new LibIMobileDevice({ udid: deviceId });
63
+ return lib.downloadCrashReports(outputDirectory, { extract, keep });
64
+ },
65
+ });
66
+
67
+ registerTool({
68
+ name: 'ios_get_diagnostics',
69
+ description: 'Get diagnostics information (WiFi, Battery, NAND, etc.)',
70
+ inputSchema: z.object({
71
+ deviceId: z.string().describe('Device UDID'),
72
+ type: z.enum(['All', 'WiFi', 'GasGauge', 'NAND', 'Battery', 'HDMI']).optional().default('All'),
73
+ }),
74
+ handler: async ({ deviceId, type }) => {
75
+ const lib = new LibIMobileDevice({ udid: deviceId });
76
+ return lib.getDiagnostics(type);
77
+ },
78
+ });
79
+
80
+ registerTool({
81
+ name: 'ios_get_ioreg',
82
+ description: 'Get IO Registry information',
83
+ inputSchema: z.object({
84
+ deviceId: z.string().describe('Device UDID'),
85
+ plane: z.enum(['IODeviceTree', 'IOPower', 'IOService']).optional(),
86
+ }),
87
+ handler: async ({ deviceId, plane }) => {
88
+ const lib = new LibIMobileDevice({ udid: deviceId });
89
+ return lib.getIORegistry(plane);
90
+ },
91
+ });
92
+
93
+ registerTool({
94
+ name: 'ios_get_mobilegestalt',
95
+ description: 'Get MobileGestalt values from device',
96
+ inputSchema: z.object({
97
+ deviceId: z.string().describe('Device UDID'),
98
+ keys: z.array(z.string()).describe('Keys to query'),
99
+ }),
100
+ handler: async ({ deviceId, keys }) => {
101
+ const lib = new LibIMobileDevice({ udid: deviceId });
102
+ return lib.getMobileGestalt(...keys);
103
+ },
104
+ });
105
+
106
+ registerTool({
107
+ name: 'ios_start_bluetooth_logger',
108
+ description: 'Start Bluetooth packet logging',
109
+ inputSchema: z.object({
110
+ deviceId: z.string().describe('Device UDID'),
111
+ outputPath: z.string().optional().describe('Path to save logs'),
112
+ }),
113
+ handler: async ({ deviceId, outputPath }) => {
114
+ const lib = new LibIMobileDevice({ udid: deviceId });
115
+ return lib.startBluetoothLogging(outputPath);
116
+ },
117
+ });