A Node.js library for interacting with iOS devices through Appium using remote XPC services. This library enables communication with iOS devices through various services like system logs and network tunneling.
This library provides functionality for:
npm install appium-ios-remotexpc
ConnectionType: Network (USB entries use ConnectionType: USB). This library connects through usbmuxd the same way for both; the tunnel path is unchanged (lockdown → CoreDeviceProxy → TUN/TAP → Remote XPC).Controls the logging verbosity of the library.
infosilly - Most verbose, logs everythingverbose - Very detailed logsdebug - Detailed debugging informationinfo - General informational messages (default)warn - Warning messageserror - Error messages only# Set log level to debug for verbose output
APPIUM_IOS_REMOTEXPC_LOG_LEVEL=debug npm test
# Set log level to error for minimal output
APPIUM_IOS_REMOTEXPC_LOG_LEVEL=error node your-script.js
This is particularly useful for debugging issues or reducing log noise in production environments.
The following diagram illustrates the high-level flow of how the tunnel is created:

The appium-ios-tuntap (previously tuntap-bridge) module plays a crucial role in establishing network connectivity:
Technical Details: - Platform Support: Works on both macOS and Linux - IPv6 Support: Creates IPv6 tunnels for modern iOS communication - Packet Handling: Manages packet routing between virtual interface and device - Automatic Cleanup: Properly closes tunnels and cleans up interfaces
Security Considerations: - Requires root/sudo access for TUN/TAP interface creation - Uses TLS for secure communication with iOS devices
import {
createLockdownServiceByUDID,
rsdSessionLockKey,
startCoreDeviceProxyTcp,
TunnelManager,
} from 'appium-ios-remotexpc';
// Create lockdown service
const { lockdownService, device } = await createLockdownServiceByUDID(udid);
// Start CoreDeviceProxy (raw TCP; TLS handled in native forwarder)
const { socket, cert, key } = await startCoreDeviceProxyTcp(
lockdownService,
device.DeviceID,
device.Properties.SerialNumber,
);
// Create tunnel using tuntap
const tunnel = await TunnelManager.getTunnel(socket, { cert, key });
console.log(`Tunnel created at ${tunnel.Address} with RSD port ${tunnel.RsdPort}`);
// Discover RSD services (serialized per tunnel; closed before return)
await TunnelManager.runSerializedRsdSession(
rsdSessionLockKey(tunnel.Address, tunnel.RsdPort),
async () => {
const remoteXPC = await TunnelManager.connectRemoteXPCUnlocked(
tunnel.Address,
tunnel.RsdPort,
);
try {
console.log(remoteXPC.getServices());
} finally {
await remoteXPC.close();
}
},
);
usbmuxd (the multiplexer daemon, e.g. on macOS) does not only list USB devices: once a device is paired with the host and wireless sync / lockdown-over-WiFi is enabled, the same daemon’s device list includes that device as attached over WiFi. In plist responses from ListDevices, those rows carry ConnectionType: Network (and a distinct DeviceID from any USB listing for the same physical device).
There is no separate “WiFi API” in this library: call createUsbmux() → listDevices() (or any other client that queries usbmuxd) and use the returned DeviceID and UDID with createLockdownServiceByUDID and the tunnel steps in the previous section—identical to USB.
Typical host-side setup:
ConnectionType: Network—for example by logging the result of listDevices() from this library, or by checking another usbmuxd client’s device list while the device is on the same network and not on USB.For an end-to-end tunnel smoke test with the tunnel registry HTTP API, use npm run tunnel-creation or npm run test:tunnel-creation (see scripts/test-tunnel-creation.ts), usually with sudo for TUN/TAP.
Apple TV and tvOS devices over WiFi are supported. The following symbols are part of the public API and are intended for external use (e.g. by the Appium XCUITest driver):
import {
AppleTVPairingService,
UserInputService,
AppleTVTunnelService,
} from 'appium-ios-remotexpc';
const userInput = new UserInputService();
const pairing = new AppleTVPairingService(userInput);
const result = await pairing.discoverAndPair('Living Room');
For step-by-step pairing instructions, see the Apple TV Pairing Instructions.
# Clone the repository
git clone https://github.com/yourusername/appium-ios-remotexpc.git
cd appium-ios-remotexpc
# Install dependencies
npm install
# Build the project
npm run build
This project uses GitHub Actions for continuous integration and Dependabot for dependency management:
All pull requests must pass these checks before merging. The workflows are defined in the .github/workflows directory.
npm run build - Clean and build the projectnpm run lint - Run ESLintnpm run format - Run prettiernpm run lint:fix - Run ESLint with auto-fixnpm test - Run tests (requires sudo privileges for tunneling)CLI helpers under scripts/ are ESM (.mjs) and load the library via the package entrypoint. Run npm run build before using them so appium-ios-remotexpc resolves to build/.
npm run tunnel-creation / npm run test:tunnel-creation — Create USB tunnels and start the tunnel registry HTTP API (requires sudo)npm run test:tunnel-creation:lsof — Same as above with --keep-open (for inspecting open sockets)npm run pair-appletv — Pair an Apple TV over WiFi for Remote XPC (requires sudo)npm run start-appletv-tunnel — Start an Apple TV WiFi tunnel and tunnel registry (requires sudo)Pass --help after -- to any of these npm scripts to see CLI flags (for example: npm run pair-appletv -- --help).
/scripts - Optional CLI helpers (ESM .mjs) for tunnels and Apple TV pairing; use via npm run entries under Scripts/src - Source code/lib - Core libraries/lockdown - Device lockdown protocol/pair-record - Pairing record handling/plist - Property list processing/remote-xpc - XPC connection handling/tunnel - Tunneling implementation with tuntap integration/usbmux - usbmuxd client (USB and WiFi-listed devices)/services - Service implementations/ios/diagnostic-service - Device diagnostics/syslog-service - System log access/tunnel-service - Network tunneling# Run all tests
npm test
Note: Integration tests require:
- Physical iOS devices connected (USB and/or WiFi if the device is paired and visible to usbmux as Network)
- Sudo privileges for tunnel creation
- Device trust established
Apache-2.0
Contributions are welcome! Please feel free to submit a Pull Request.
This project is under active development. APIs may change without notice.
$ claude mcp add appium-ios-remotexpc \
-- python -m otcore.mcp_server <graph>