DSH Plugins Marketplace

DSH Plugins

Plugins

/

Development & Infrastructure

/

dsh-phone-bridge

c

dsh-phone-bridge

Manifest valid★ 1

DSH plugin: talk to your DeepSeek Harness from your phone. Send text and photos, read replies as they stream — across any network via your own Tailscale tailnet. 用手机跟电脑上的 DSH 对话,不同 Wi-Fi 也能用。

UI (client)hasBundlePatch

phone-bridge

📱 phone-bridge

v1.1.2

用手机跟电脑上的 DSH 对话:发文字、拍照、传图,回复实时回显。不同 Wi-Fi 也能用。

GitHub stars MIT license awesome · DSH plugin DSH
Node.js JavaScript Android

English | 中文

Official Web and the official desktop app are both supported. Official dsh web uses profile web. The official desktop EXE (DeepSeek Harness 0.2.0-rc.2) uses profile desktop. Install and Apply them separately.

No public server, no third-party relay. The phone and the PC meet on a private WireGuard network that you create with your own Tailscale account. Nothing is exposed to the public internet.

Node.js ≥18. Android 7.0 (API 24) or newer for the native app; any modern browser also works.

⬇️ Download

Releases → v1.1.2

FileGoes onSize
phone-bridge-1.1.2.apkphone249 KB
phone-bridge-plugin-1.1.2.zipPC (DSH plugin)5 MB

Three steps:

# 1. Install the plugin on the PC, then restart DSH
dsh plugin --profile desktop add github:chs-1108/dsh-phone-bridge

# 2. Install Tailscale on both sides and sign in
#    PC https://tailscale.com/download   phone: Play Store

# 3. Install the APK, open it, scan the QR in DSH -> Settings -> Phone Sync
adb install -r phone-bridge-1.1.2.apk

The APK is a generic build with no baked-in address: every user scans their own PC's QR code and connects to their own PC.

Contents


What this is

phone-bridge is a plugin for the official DeepSeek Harness that puts your DSH session in your pocket. The phone opens a small web app (or a native Android shell), sends text and photos into a real DSH session, and reads the Agent's reply as it streams back.

Phone (WebView / browser)
   │  HTTP over Tailscale — encrypted WireGuard, peer to peer
   ▼
DSH webServer  ──▶  /phone-bridge prefix route  ──▶  sessionController  ──▶  model

It consumes only DSH's public webServer and sessionController services. No core patches, no forked host.

Highlights

  • Works across networks — the phone does not need to share a Wi-Fi with the PC. Both sides join a Tailscale tailnet, each gets a stable 100.x.y.z address, and the URL never changes when you switch between Wi-Fi and cellular.
  • Real session, not a side channel — messages land in a normal DSH session. Pin the bridge to any session with /api/prefs, or let it create one lazily and reuse it.
  • Streaming replies — the plugin subscribes to sessionController.follow({assistantStream: true}) and the phone polls incremental results, so long answers appear while they are being written.
  • Photos and camera — the native Android shell wires onShowFileChooser into a system chooser with a camera entry, writes the capture through MediaStore, and hands the WebView a readable URI. Text and up to 8 images per message.
  • Camera-free fallback — no APK needed. A plain browser works: open the URL, send text, attach images.
  • One-click deployment — setup-phone-bridge.ps1 installs Tailscale, patches the listen address, registers the plugin, builds the APK, and pushes both apps to a USB-attached phone. It needs your Tailscale account and nothing else.
  • No Gradle — the APK builds straight from aapt2 + d8 + zipalign + apksigner in about ten seconds.

Requirements

DSH0.2.0 or newer, desktop EXE or dsh web
Node.js≥ 18
Host OSWindows 10/11 (the deploy script is PowerShell)
PhoneAndroid 7.0+ for the APK, or any modern browser
AccountYour own free Tailscale account

Optional, only for building the APK: JDK 17 and Android SDK build-tools 34.0.0. Optional, only for pushing to a phone over USB: adb.

Fastest way: double-click

Download the repository, then double-click install.cmd. A window opens; follow it.

Only two things need you:

  1. Sign in to Tailscale - a browser opens, use your own account
  2. Plug in the phone by USB - tap Allow when it asks for debugging authorisation

Everything else is automatic: install Tailscale, change the listen address, register the plugin, create the pairing key, detect the port, build the APK, push and install it, grant the camera permission, run the health check.

Details in 安装说明.md (Chinese). Prefer a terminal? install-gui.ps1 -Console. Prefer the command line? Use the steps below.

Download and install

Everything lives on one page: Releases → v1.1.2

FileGoes onSize
phone-bridge-1.1.2.apkthe phone249 KB
phone-bridge-plugin-1.1.2.zipthe PC (DSH plugin)0.9 MB

On the PC

# From GitHub
dsh plugin --profile desktop add github:chs-1108/dsh-phone-bridge

# Or from the downloaded zip
dsh plugin --profile desktop add "D:\path\to\phone-bridge-plugin-1.1.2.zip"

Restart DSH, then open Settings → Phone Sync. A QR code means it worked.

⚠️ You must change the listen address, or the phone cannot connect

DSH's web server binds 127.0.0.1 by default — it is meant for the local browser only, so requests from the phone over Tailscale are refused outright.

Automatic (recommended)

Open Settings → Phone Sync. If a red block reports the server is listening on loopback only, click Fix it for me:

🔴 DSH listens on loopback only
   The web server accepts local connections only, so requests from the phone
   never arrive.
   [ Fix it for me ]   edits the config; DSH must restart after

The plugin locates the current profile's cordis.patch.yml, changes host, and leaves a timestamped backup beside it. Then fully quit DSH and reopen it.

Manual

Edit the profile's cordis.patch.yml:

Windows: %USERPROFILE%\.dsh\profiles\desktop\cordis.patch.yml
macOS/Linux: ~/.dsh/profiles/desktop/cordis.patch.yml

Add this (if a webserver entry already exists, change only host):

- id: webserver
  name: '@deepseek-ai/dsh-host-webserver'
  inject: [webStartup]
  config:
    host: '0.0.0.0'
    port: !!js ctx.webStartup.port ?? 3080
    compression: gzip
    compressionLevel: 1
    compressionThresholdBytes: 1024

name is @deepseek-ai/dsh-host-webserver or @deepseek-ai/dsh-web-server depending on the DSH version. The automatic fix reuses whatever the file already says.

Verify

Fully quit DSH and reopen it (closing the window is not enough), then:

netstat -ano | findstr LISTENING | findstr 19387
You seeMeaning
0.0.0.0:19387 or [::]:19387✅ the phone can reach it
127.0.0.1:19387❌ local only, the phone will always fail

From v1.1.2 the plugin detects this itself and offers the repair inline, so you never have to guess.

curl http://127.0.0.1:19387/phone-bridge/health
# {"ok":true,"name":"phone-bridge","version":1}

On the phone

Install Tailscale on both sides and sign in (same account, or share the devices with each other). PC builds are at tailscale.com/download; the phone app is on the Play Store.

adb install -r phone-bridge-1.1.2.apk

No cable? Copy the file over and tap it. Opening the app shows the pairing screen.

Pairing

  1. On the PC: DSH → Settings → Phone Sync — there is a QR code
  2. On the phone: tap Scan the QR code on your PC
  3. Tap Connect — from then on the app opens straight into the chat

The QR code is generated on demand: it encodes this PC's Tailscale address plus a random token, recomputed every time the page loads. Nothing to configure.

You can also type the two values by hand: the pairing address (http://100.x.y.z:19387/phone-bridge) and the pairing token shown on the same settings page.

Re-pairing with another PC

In the app: Settings → Clear pairing (scan again). That returns to the pairing screen; scan the new PC's code.

Using it

Type in the box at the bottom (or tap Camera / Gallery to send a photo), then send. The reply streams back. Sessions at the top switches the target session; Settings toggles whether the reasoning stream is included.

Without the APK

Open the pairing address in the phone's browser instead. Same features; photos go through the standard file picker.

Install (other ways)

The standard way — dsh plugin

DSH ships a plugin subcommand that forwards its arguments to pnpm inside the profile directory. That is the supported install path for every third-party plugin, this one included:

# Desktop app (DeepSeek Harness 0.2.0-rc.2)
dsh plugin --profile desktop add github:chs-1108/dsh-phone-bridge

# Official web build
dsh plugin --profile web add github:chs-1108/dsh-phone-bridge

Add it from a local clone instead, if you already have one:

dsh plugin --profile desktop add /path/to/dsh-phone-bridge

Then append the bundle name to dsh.profile.bundles in the profile's package.json, and restart DSH:

{
  "dsh": {
    "profile": {
      "bundles": [
        "@deepseek-ai/dsh-base",
        "@deepseek-ai/dsh-web-app",
        "dsh-phone-bridge"
      ]
    }
  }
}

Confirm it loaded:

curl http://127.0.0.1:19387/phone-bridge/health
# {"ok":true,"name":"phone-bridge","version":1}

One-click deploy

Once the plugin is in, setup-phone-bridge.ps1 does the rest of the environment — Tailscale, the listen address, the APK, and the phone over USB. On the PC, in an elevated PowerShell:

Set-ExecutionPolicy -Scope Process Bypass -Force
.\setup-phone-bridge.ps1

It walks nine steps and stops to ask you only twice:

  1. Sign in to your Tailscale account (a browser opens).
  2. Confirm restarting DSH so the plugin loads.

Connect the phone by USB with USB debugging enabled beforehand if you want the script to install the Tailscale and phone-bridge APKs for you. It also pre-grants the camera permissions.

When it finishes you get a URL like:

http://100.x.y.z:19387/phone-bridge/?token=<48 hex chars>

Open it on the phone, or launch the installed DSH 手机同步 app — it is already paired.

?token= is a query parameter on purpose. A #fragment never reaches the server, so #t=... would fail authorization.

Script options

.\setup-phone-bridge.ps1 -SkipPhone       # PC side only
.\setup-phone-bridge.ps1 -SkipApk         # reuse the last APK build
.\setup-phone-bridge.ps1 -SkipTailscale   # already installed and signed in
.\setup-phone-bridge.ps1 -SkipRestart     # restart DSH yourself later
.\setup-phone-bridge.ps1 -Port 19387      # pin the port

Manual install

If dsh plugin is not available in your build, wire it up by hand:

1. Put the plugin where DSH can find it

git clone https://github.com/chs-1108/dsh-phone-bridge.git
mkdir -p ~/.dsh/phone-bridge
cp -r dsh-phone-bridge/{index.js,client.js,package.json,cordis.patch.yml,web,vendor} ~/.dsh/phone-bridge/

2. Register it in the profile

Link the package into the profile's node_modules and add a row to cordis.patch.yml:

- id: phone-bridge
  name: dsh-phone-bridge

3. Make the webServer reachable

The server listens on 127.0.0.1 by default, so the phone cannot reach it. Override the host in the same cordis.patch.yml (profile patch is the highest-precedence layer):

- id: webserver
  name: '@deepseek-ai/dsh-web-server'
  config:
    host: '0.0.0.0'
    port: !!js ctx.webStartup.port ?? 3080
    compression: gzip
    compressionLevel: 1
    compressionThresholdBytes: 1024
  inject: [webStartup]

4. Restart DSH, then read the token

cat ~/.dsh/phone-bridge/state.json

The phone side

Just install phone-bridge-1.1.2.apk from the release - no build step needed.

It opens on the pairing screen; scan the QR or type the two values. The pairing is stored on the phone, so later launches go straight to the chat.

The app runs a foreground service (partial wake lock plus a low-priority notification), so the screen going off or the app going to the background does not drop the connection. Tailscale runs as a background service on both sides too, so closing a window never drops the link and a reboot reconnects on its own.

Building the APK yourself

Needs JDK 17 and the Android SDK (build-tools 34, platform 34):

$env:PHONE_BRIDGE_JAVA_HOME = "C:\path\to\jdk-17"
$env:PHONE_BRIDGE_SDK       = "C:\path\to\Android\Sdk"
$env:PHONE_BRIDGE_BUILD_TOOLS = "34.0.0"
pwsh -File build-apk.ps1
# -> apk-out/phone-bridge.apk

With no arguments you get the generic build: each user scans their own PC's code. That is the one to publish.

Baked-in build (self-use only)

To skip scanning while debugging, compile the address in:

.\build-apk.ps1 -BaseUrl "http://100.x.y.z:19387/phone-bridge" -Token "<your token>"

It opens straight into the chat, but it only ever connects to that one PC, so do not publish it. Clearing the pairing from inside the app still works and is not undone by the baked-in values.

How it works

PieceRole
index.jsHost half. Registers a prefix route on webServer, drives sessionController.prompt() and .follow(), mints the token.
client.jsClient half. Injects the settings panel into the DSH web UI.
web/app.htmlThe single-page app the phone loads. No framework, ~16 KB.
apk/Native Android shell: SetupActivity, MainActivity (WebView + file chooser + camera), ScanActivity (zxing), CaptureProvider.
setup-phone-bridge.ps1Nine-step deployment for both ends.
build-apk.ps1Gradle-free APK build.

Authorization is either loopback (the PC talking to itself) or a 48-hex-character token compared in constant time. Sessions are resolved lazily: if the stored sessionId still exists it is reused, otherwise a new one is created and persisted.

The capture path deliberately writes into the shared MediaStore rather than a private ContentProvider. Every camera app can already write there, which removes the cross-process URI grant that silently fails on several OEM ROMs.

Full detail, including the nine capture bugs and why each fix was needed, is in IMPLEMENTATION.md. Deployment walkthrough and troubleshooting: SETUP.md.

Privacy

This plugin ships no server address, token, or account. Values are injected at build time by build-apk.ps1 from -BaseUrl / -Token, and the committed BuildDefaults.java and network_security_config.xml stay blank apart from loopback.

Traffic stays inside your own tailnet, end-to-end encrypted, with nothing proxied through a third party. The plugin opens no additional outbound connections.

Treat the token like a password: anyone holding it can talk to your DSH. Rotate it by deleting token from ~/.dsh/phone-bridge/state.json and restarting.

Troubleshooting

SymptomCauseFix
{"ok":false,"error":"unauthorized"}Token not transmittedUse ?token=, never #t=
Phone cannot connectServer bound to loopbackSet host: '0.0.0.0' in cordis.patch.yml, restart
web boot: 1 entry did not activateClient registration id ≠ package nameMust be dsh-phone-bridge
Capture saves but the photo never appearsProvider unreachable by the camera appUse the MediaStore path in MainActivity
adb devices shows unauthorizedDebugging prompt not acceptedUnlock the phone, tap Allow
APK install fails on signatureDifferent signing keyadb uninstall com.dsh.phonebridge first

Check the plugin is alive:

curl http://127.0.0.1:19387/phone-bridge/health
# {"ok":true,"name":"phone-bridge","version":1}

Development

node test/loader-import.mjs   # client half registers under the package name
node test/composition.mjs     # host half composes
node test/host.smoke.mjs      # route and auth smoke tests

Rebuild the distributable:

.\build-zip.ps1

License

MIT — see LICENSE.

Comments

Loading…

From the same category

awesome-dsh-plugin

by awesome-dsh-plugin

A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表

Development & Infrastructure

★ 19.2k

CC0-1.0

Python

Oct 17, 2026

Index only — not installable

by 0xsline

DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.

Development & Infrastructure

★ 1.2k

CC0-1.0

Python

Oct 16, 2026

Index only — not installable

by pax-beehive

Open-source CLI, schemas, resolver, and DSH agent tools for DSH Plugin Hub

Development & Infrastructure

★ 391

MIT

TypeScript

Oct 6, 2026

Index only — not installable

by xiajiajun516

DeepSeek Harness (DSH) backup & restore plugin — export, import, migrate and sync your complete DSH configuration, plugins, MCP servers, skills and workspace. One-click migration to another machine.

Development & InfrastructureManifest valid

★ 201

MIT

TypeScript

Oct 17, 2026

dsh plugin --profile web add dsh-config-manager

by yjh051108

推荐组件(非必须):DeepSeek Harness 运行时注入器;已随 dsh-routing-suite 单仓库化保留,本仓库继续维护/发布。

Development & InfrastructureManifest valid

★ 167

TypeScript

Oct 16, 2026

dsh plugin --profile web add @dsh-external/dsh-super-injector

by jigjoy-ai

A CLI that turns a goal into a pull request - and a sandbox for testing concurrent AI coding agents on the Mozaik runtime.

Development & Infrastructure

★ 124

MIT

TypeScript

Oct 13, 2026

Index only — not installable