Connecting iOS Client to OpenHuman Desktop Core: Transport Strategies

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, 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 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. 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 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 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.

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

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

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:

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

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. 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) 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) 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →