Mobile Development 25 min read

DeepSeek Harness on Mobile: Building a Cross-Platform Client with Kuikly

The author built DSH Mobile, a Kotlin Multiplatform app using Tencent's Kuikly framework, connecting to DeepSeek Harness via its Host protocol (HTTP RPC + dual WebSockets) with SSH/QR-code relay, native bridging, and robust reconnection logic, enabling on-the-go interaction with long-running AI agent tasks.

Tencent TDS Service
Tencent TDS Service
Tencent TDS Service
DeepSeek Harness on Mobile: Building a Cross-Platform Client with Kuikly

Problem: Long-Running AI Tasks Stall When Away from Desktop

DeepSeek Harness (DSH) tasks often run for minutes and pause for human approvals, questions, or confirmations. If the user leaves the computer, the task stalls. The goal was not to write code on a phone, but to handle these short, frequent interactions — check progress, approve commands, answer agent queries — while commuting, in meetings, or queuing.

Solution Overview: DSH Mobile

DSH Mobile is a cross-platform native app (Android, iOS, HarmonyOS) built with Kuikly (Kotlin Multiplatform). It connects directly to the DSH Host protocol running on the computer (port 3080) via HTTP RPC and two WebSocket event streams. The agent loop, tool execution, and plugins remain on the desktop; the phone handles connection, interaction, and rendering.

~13,000 lines of Kotlin in commonMain are shared across platforms. Each platform host adds ~3,000–4,000 lines for system capability integration and build configuration.

Why Kuikly

Kuikly was chosen for development speed. Its component marketplace provides ready-made capabilities (Markdown rendering, WebView, SQLite, camera, etc.) that work across all three targets without per-platform reimplementation. The KuiklyUI-AI rules and Skills (DSL, components, networking, state, coroutines, multi-platform resources) integrate with AI coding assistants (CodeBuddy, Cursor, Claude Code), letting agents generate boilerplate, protocol models, state machines, and repetitive pages while the developer focuses on interaction, platform differences, and real-device testing. KuiklyUI-AI repository: https://github.com/Tencent-TDS/KuiklyUI-AI

Component Marketplace: Markdown and WebView

KuiklyMarkdown

(v1.0.6-2.1.21): Handles streaming Markdown with code blocks, lists, links, and syntax highlighting. Parses via intellij-markdown, outputs Block list, provides streaming render state. The app only manages DSH-specific logic: stable blocks stay static, tail updates at 16 ms frame intervals, unclosed code fences are auto-closed in a parse copy. KuiklyWebview (v1.0.1-2.0.21): Opens Markdown links and external pages in-app. Shared Kotlin code sets URL and listens to load-start, progress, finish, fail events; refresh/back logic shared. Avoids wrapping Android WebView, iOS WKWebView, and HarmonyOS Web component separately.

implementation("com.tencent.kuiklybase:KuiklyMarkdown:1.0.6-2.1.21")
implementation("com.tencent.kuiklybase:KuiklyWebview:1.0.1-2.0.21")

Native Bridging: Platform Differences Pushed to the Edge

Cross-platform pain points are system capabilities: WebSocket, QR scanning, SSH, database. DSH Mobile defines unified Module interfaces in commonMain (connect, send, receive, disconnect). Each platform implements its own backend:

WebSocket: OkHttp (Android), NSURLSession (iOS), NetworkKit (HarmonyOS) — all behind DshWebSocketModule.

SSH tunneling, QR pairing: same pattern.

Platform differences are confined to the bottom layer; chat UI, event handling, business state know nothing about the OS. As DSH protocol evolves (still in developer preview), only the shared layer needs updates, instantly propagating to all three targets.

Native bridging architecture diagram
Native bridging architecture diagram

Direct Host Protocol: No Middleware

DSH Mobile uses the official Host protocol (same as the web frontend). DSH (built on Cordis plugin runtime) exposes three relevant layers: core/session, agent-loop, tools — session, agent loop, tool execution, produce events. host/apiproxy — assembles RPC method table and two downstream event streams. client/connection — binds to localhost:3080, serves HTTP /api/..., WebSocket /api/events.mux and /api/events.host.

The app connects to the outermost layer, no need to understand internal plugin structure.

HTTP RPC: One Call per Action

DSH registers callable capabilities in an RPC method map (52 methods in dsh-v0.1.1-rc.2). Sending a message calls session.prompt via POST /api/session.prompt. Session list, history, workspace, model, Goal, settings all share the same RPC channel. Method signatures come from TypeScript; the registry maps names to implementations. The mobile client implements only needed methods. Full map at rpc-map.ts (https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.1-rc.2/packages/host/apiproxy/src/api/rpc-map.ts). Pin to a verified tag; master may break compatibility.

Two WebSocket Streams, Separate Concerns

/api/events.mux

: per-session events — model output, tool calls, approvals, questions, message queue, background jobs. /api/events.host: global host events — session add/remove, run state, workspace changes, host-level errors.

Separation lets the chat page consume mux while workspace/list rely on host. Two details need special handling: session/queue and session/jobs push full snapshots, not deltas. They don’t enter session log; on reconnect the app overwrites local state with the latest snapshot. session/projection.value and host/remote-event.args are wide types at the carrier layer. Structure defined by business packages; app must preserve unknown fields and degrade gracefully on parse failure instead of breaking the whole stream.

Reconnection: Replay Events, Then Re-align History

Mobile networks drop (lock screen, background, tunnel, Wi-Fi/cellular switch). Reconnection sequence:

Re-establish SSH or Relay tunnel.

Use last received sequence number to fetch missing session/event messages.

Request session.history to re-align chat log.

Overwrite queue and jobs with latest snapshots.

Each connection carries a generation ID; stale RPC responses from a dead connection are discarded. If the agent kept running on the desktop, the app re-subscribes to the ongoing task — it does not re-send the user’s prompt. Reconnection restores observation and control, not re-execution. The state machine lives in shared code, so all three platforms follow identical recovery rules; platform code only forwards low-level connection events.

Two Remote Connection Methods

SSH Tunnel (Direct)

Phone creates local port forwarding, mapping a loopback port to the desktop’s 127.0.0.1:3080. HTTP RPC and both WebSockets traverse the tunnel. Authentication happens at SSH layer; DSH still sees only loopback requests. Simplest when SSH host/keys already configured.

QR-Code Relay (Zero-Config)

Manual address/port/key entry is mobile-unfriendly. The author built dsh-scan-remote plugin (https://github.com/yukiykchen/dsh-scan-remote). After install, DSH Settings shows a Remote Access page with a QR code. Phone scans, pairs. Both desktop plugin and app connect to a Relay server, which forwards traffic via sealed-tunnel-v1. DSH still listens only on 127.0.0.1:3080; the plugin accesses DSH locally and connects to Relay; the app connects to the same Relay. Relay never touches port 3080; desktop never exposes DSH to LAN/public. Master key stays in URL fragment (not sent to Relay). Tunnel data is sealed before forwarding.

Phone as Decision-Node Entry Point

DSH Mobile suits short, lightweight, high-frequency interactions: view streaming replies and tool status, approve/deny commands, answer agent questions, check background jobs/Goal progress/session state during fragmented time. Long prompts, large diffs, deep reasoning remain better on desktop — the app is a remote control panel, not a full mobile IDE.

Industry trend: Cursor iOS (cloud agent + remote control), ChatGPT mobile (continue Mac Codex tasks), Claude Code Remote Control (resume local sessions). All address the same shift: coding delegated to agents, humans provide intent, judgment, and review at decision nodes — not necessarily at a desk. References: Cursor iOS blog (https://cursor.com/blog/ios-mobile-app), ChatGPT desktop version notes (https://help.openai.com/zh-hans-cn/articles/6825453-chatgpt-%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E), Claude Code Remote Control docs (https://docs.anthropic.com/en/docs/claude-code/remote-control).

Next steps for DSH Mobile: add input capabilities (image upload, voice via session.prompt ’s content array), notifications (need desktop cooperation to signal when human input required), stabilize connection/reconnection first. Shared layer already holds streaming Markdown, tool cards, disconnection state machine, session model — future Agent hosts only need protocol adapters, not UI rewrites.

Quick Start

Launch DSH and Relay

Start Relay.

Install QR plugin and start DSH.

Install DSH Mobile on phone.

Scan Remote Access QR code in DSH Settings.

Phone and computer must share a trusted Wi-Fi/hotspot.

# Terminal 1: start local Relay
git clone https://github.com/yukiykchen/dsh-scan-remote.git
cd dsh-scan-remote/relay
cp .env.example .env
npm ci
npm run build
HOST=0.0.0.0 PORT=8787 npm start
HOST=0.0.0.0

opens port 8787 on all interfaces — use only on trusted networks, check firewall.

# Terminal 2: install plugin and start DSH
npx @deepseek-ai/dsh plugin --profile web add \
  "github:yukiykchen/dsh-scan-remote#v0.0.1"

export PUBLIC_RELAY_URL=http://192.168.1.10:8787
npx @deepseek-ai/dsh web
PUBLIC_RELAY_URL

must be the computer’s current LAN address (written into QR code, reachable from phone). After DSH starts, open Settings → Remote Access.

Remote Access QR code page
Remote Access QR code page

Download and Install App

Android: APK from releases page (https://github.com/yukiykchen/deepseek-harness-mobile/releases).

iOS: Open iosApp/iosApp.xcworkspace in Xcode, configure developer signing, install on device.

HarmonyOS: Open ohosApp in DevEco Studio, build yourself.

Repo: deepseek-harness-mobile (https://github.com/yukiykchen/deepseek-harness-mobile).

If QR scan times out, check: (1) phone can reach http://<computer-lan-ip>:8787/health; (2) PUBLIC_RELAY_URL matches current computer IP; (3) Relay actually listens on a phone-reachable interface, firewall allows 8787. When computer changes Wi-Fi/hotspot, IP changes — update PUBLIC_RELAY_URL, restart DSH, re-scan.

Cloud Deployment: Agent Independent of Personal Computer

DSH Mobile can pair with DeepSeek Harness deployed on Tencent Cloud Lighthouse (lightweight application server). Agent loop, tools, plugins, workspace run continuously in the cloud; phone still only connects, interacts, renders. Long tasks no longer require the personal computer to stay on. User can view streaming output, tool status, handle approvals, add context, confirm next steps from phone. Tencent Cloud Lighthouse: https://cloud.tencent.com/product/lighthouse

Development Entry Points

New Host method: add definition in DshHostProtocol.kt, reuse existing RPC channel — no native changes unless new system capability needed.

New native capability: define Module in commonMain, implement per platform. Android exports from KuiklyRenderActivity, iOS in KuiklyExpand/Modules, HarmonyOS in kuikly/modules.

New page: create class with @Page annotation; KSP generates routing.

New DSH event on mobile: write a DSH plugin listening to the event, forward via host/remote-event. Event must be allowlisted on Host side; app must tolerate wide-type parameters.

Registering new official RPC methods or replacing the transport layer requires changes to DSH core — contribute upstream.

Related Repositories

Kuikly Framework: https://github.com/Tencent-TDS/KuiklyUI

Kuikly Component Repositories: https://github.com/orgs/Kuikly-contrib/repositories

DSH Mobile: https://github.com/yukiykchen/deepseek-harness-mobile

QR Plugin & Relay: https://github.com/yukiykchen/dsh-scan-remote

KuiklyUI AI Rules & Skills: https://github.com/Tencent-TDS/KuiklyUI-AI

Tencent Cloud Lighthouse: https://cloud.tencent.com/product/lighthouse

DSH RPC Method Table: https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.1-rc.2/packages/host/apiproxy/src/api/rpc-map.ts

DSH Downstream Event Definitions: https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.1-rc.2/packages/host/apiproxy/src/api/events.ts

DSH remains in developer preview; protocol and package structure may change breaking. Method counts, paths, event names in this article correspond to dsh-v0.1.1-rc.2. Lock to a verified version and track upstream incrementally.

About Kuikly

Kuikly is Tencent’s open-source high-performance cross-platform framework based on Kotlin Multiplatform, covering Android, iOS, HarmonyOS, H5, WeChat Mini Program, and Mac, serving 500M+ daily active users. Now open source: GitHub repo (https://github.com/Tencent-TDS/KuiklyUI) | Official docs (https://kuikly.tds.qq.com/Introduction/arch.html?utm_source=artical20).

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

WebSocketAI agentKotlin MultiplatformSSH TunnelingKuiklyDeepSeek HarnessCross-platform Mobile DevelopmentNative Bridging
Tencent TDS Service
Written by

Tencent TDS Service

TDS Service offers client and web front‑end developers and operators an intelligent low‑code platform, cross‑platform development framework, universal release platform, runtime container engine, monitoring and analysis platform, and a security‑privacy compliance suite.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.