# Connecting iOS Client to OpenHuman Desktop Core: Transport Strategies

> Explore OpenHuman's iOS client transport strategies: LanHttpTransport, TunnelTransport, and CloudHttpTransport. Connect your iOS app to the desktop core seamlessly.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: how-to-guide
- Published: 2026-08-29

---

**OpenHuman iOS clients communicate with the Rust-based desktop core through three distinct transport strategies—LanHttpTransport for direct local network access, TunnelTransport for encrypted remote connections, and CloudHttpTransport for cloud-proxied reachability—all orchestrated by the TransportManager singleton.**

The `tinyhumansai/openhuman` repository provides a cross-platform architecture where the desktop core exposes an HTTP RPC interface, requiring specific transport implementations to bridge iOS clients running outside the host process. Understanding these transport strategies is essential for developers configuring connectivity across local networks, encrypted tunnels, or cloud backends.

## Transport Architecture Overview

The OpenHuman desktop core runs as a Rust process within a Tauri shell, exposing its functionality via an HTTP RPC server at `http://127.0.0.1:<port>/rpc`. According to the implementation in [`app/src-tauri/src/core_rpc.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_rpc.rs), this endpoint requires **bearer token authentication** using an in-memory token generated at startup. The iOS client never communicates directly with the Tauri UI layer; instead, it targets this RPC endpoint through abstraction layers defined in `app/src/services/transport/`.

## Available Transport Strategies

OpenHuman implements three transport classes to accommodate different network topologies and security requirements.

### LanHttpTransport for Local Networks

The **LanHttpTransport** class in [`app/src/services/transport/LanHttpTransport.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/LanHttpTransport.ts) provides the lowest-latency path by sending unencrypted HTTP requests directly to the core's local RPC endpoint.

This strategy requires the iOS device to share the same local area network as the desktop host. The transport retrieves the authentication bearer token by invoking the Tauri command `core_rpc_token`, which is implemented in the Rust module [`app/src-tauri/src/core_rpc.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_rpc.rs). Use this transport when both devices operate on trusted local infrastructure and minimal overhead is critical.

### TunnelTransport for Encrypted Remote Access

When operating outside the local network, the **TunnelTransport** class in [`app/src/services/transport/TunnelTransport.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/TunnelTransport.ts) establishes a persistent encrypted channel to the core.

This implementation uses **XChaCha20-Poly1305** encryption over a TCP or WebSocket connection to a remote tunnel server, with the endpoint URL configured via the `VITE_TUNNEL_URL` environment variable. All JSON-RPC payloads undergo end-to-end encryption before reaching the core's HTTP RPC interface, ensuring confidentiality even across untrusted networks. The tunnel server implementation resides in the separate `tinyhumansai/backend` repository.

### CloudHttpTransport for Cloud-Proxied Connectivity

The **CloudHttpTransport** class in [`app/src/services/transport/CloudHttpTransport.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/CloudHttpTransport.ts) routes requests through the OpenHuman cloud backend at `https://api.tinyhumans.ai`.

This strategy sends authenticated HTTPS requests to the cloud API, which then proxies the RPC calls to the desktop core if the host is online. CloudHttpTransport provides the most reliable connectivity for users behind NATs or restrictive firewalls, though it introduces an additional network hop compared to direct local or tunneled connections.

## Transport Selection and Configuration

The iOS client selects its transport strategy at runtime through the **TransportManager** singleton defined in [`app/src/services/transport/TransportManager.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/TransportManager.ts).

Configuration occurs via environment variables, typically stored in `app/.env.local` (see the template in `app/.env.example`). Set `VITE_TRANSPORT` to one of three values:

- `lan` — Instantiates LanHttpTransport for local network access
- `tunnel` — Instantiates TunnelTransport for encrypted remote access
- `cloud` — Instantiates CloudHttpTransport for cloud-proxied access

The TransportManager exposes a `getTransport()` method that returns the configured implementation, ensuring consistent RPC client initialization throughout the iOS application lifecycle.

## iOS Implementation Examples

The following examples demonstrate how to initialize transports and execute RPC calls from the iOS client.

### Initializing the Default Transport

```typescript
import { TransportManager } from './services/transport/TransportManager';

// Transport selection is determined by VITE_TRANSPORT at build time
const transport = TransportManager.getTransport();
const rpcClient = transport.getRpcClient();

```

### Executing RPC Calls

```typescript
async function runCoreTurn(prompt: string) {
  const transport = TransportManager.getTransport();
  const rpc = transport.getRpcClient();
  
  const result = await rpc.call('core.runTurn', {
    prompt,
    // Additional model parameters can be supplied here
  });
  
  return result;
}

```

### Establishing a Tunnel Connection

When `VITE_TRANSPORT` is set to `tunnel`, explicitly initialize the encrypted channel:

```typescript
import { TunnelTransport } from './services/transport/TunnelTransport';

async function initSecureTunnel() {
  const tunnel = new TunnelTransport({
    url: process.env.VITE_TUNNEL_URL!,
    // The tunnel server exchanges initial tokens for session tokens
  });
  
  await tunnel.connect(); // Establishes XChaCha20-Poly1305 encrypted channel
  return tunnel.getRpcClient();
}

```

## Summary

- OpenHuman iOS clients connect to the desktop core via HTTP RPC, not directly to the Tauri UI layer.
- **LanHttpTransport** ([`app/src/services/transport/LanHttpTransport.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/LanHttpTransport.ts)) offers direct local network access with minimal latency but requires LAN proximity.
- **TunnelTransport** ([`app/src/services/transport/TunnelTransport.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/TunnelTransport.ts)) provides end-to-end XChaCha20-Poly1305encryption for remote access through a dedicated tunnel server.
- **CloudHttpTransport** ([`app/src/services/transport/CloudHttpTransport.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/CloudHttpTransport.ts)) proxies requests through the OpenHuman cloud API, ensuring connectivity through NATs and firewalls.
- The **TransportManager** ([`app/src/services/transport/TransportManager.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/TransportManager.ts)) singleton orchestrates transport selection based on the `VITE_TRANSPORT` environment variable.
- Bearer token authentication is handled uniformly across all transports, with tokens sourced from the Rust core via `core_rpc_token` in [`app/src-tauri/src/core_rpc.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_rpc.rs).

## Frequently Asked Questions

### How does the iOS client authenticate with the OpenHuman desktop core?

The iOS client authenticates using a bearer token generated by the Rust core at startup. For LanHttpTransport, the client retrieves this token by calling the Tauri command `core_rpc_token` defined in [`app/src-tauri/src/core_rpc.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_rpc.rs). Tunnel and cloud transports handle authentication through their respective handshake protocols, attaching the token to every JSON-RPC request header.

### What is the difference between TunnelTransport and CloudHttpTransport?

**TunnelTransport** ([`app/src/services/transport/TunnelTransport.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/TunnelTransport.ts)) creates an encrypted end-to-end tunnel using XChaCha20-Poly1305, sending traffic directly to your specific desktop instance through a relay. **CloudHttpTransport** ([`app/src/services/transport/CloudHttpTransport.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/services/transport/CloudHttpTransport.ts)) sends HTTPS requests to the centralized OpenHuman API (`api.tinyhumans.ai`), which then forwards requests to your desktop. Use TunnelTransport when you need end-to-end encryption without intermediary inspection; use CloudHttpTransport when you need maximum connectivity reliability behind restrictive networks.

### Can the iOS client switch transports at runtime?

No, the transport strategy is determined at build time by the `VITE_TRANSPORT` environment variable and instantiated as a singleton by TransportManager. While the application code could theoretically reinitialize TransportManager, the standard iOS build bundles a single transport configuration. To switch strategies, you must rebuild the client with a different `VITE_TRANSPORT` value.

### Which transport offers the lowest latency for local network usage?

**LanHttpTransport** provides the lowest latency for iOS clients on the same local network as the desktop core. By sending unencrypted HTTP directly to `http://127.0.0.1:<port>/rpc` without tunnel encryption or cloud proxy overhead, it minimizes round-trip time. However, it requires the iOS device to reach the desktop's local port, making it unsuitable for remote connections.