dsh-pocket
Manifest valid★ 2.5kPut DeepSeek Harness in your pocket: run dsh web on your computer and access it synchronously by scanning a QR code on your phone (LAN + public network, real-time screen sync)
DSH Pocket
Take your DeepSeek Harness anywhere: one package, one settings page — scan a QR code on your phone to see the same screen as your computer in real time, even when you're out and about.
⭐ 顺手留颗 Star,作者能高兴一整天 · 行,给你一颗 Star
What is this
You're away from your computer but still want to use the DeepSeek Harness running on it.
- On your commute, an agent is running a task on your computer; you want to check on your phone how far it's gotten and what the results are
- Out and about, you suddenly want your computer's agent to look up something or write code, but you have no remote desktop or SSH
- Your computer is at the dorm/office, you're out — you want to "control your DeepSeek Harness" anytime: send tasks, view output, approve actions
That's exactly what DSH Pocket does: install it, scan a QR code on your phone, and you can view and control the DeepSeek Harness interface on your computer in real time — even when you're away.
The actual effect — the phone's screen is the computer's screen, in real time:
✨ Features
| Feature | Description |
|---|---|
| 📶 LAN QR code | Works out of the box: Settings → Mobile Access opens a LAN QR code right away — put your phone on the same WiFi and scan to start (auto-detects your machine's LAN IP; in WSL, automatically picks up the Windows physical NIC IP) |
| 🚪 LAN toggle | One-click enable/disable LAN access from the settings page (a confirmation prompt appears when toggling): when off, the LAN QR code/link is immediately invalidated — only the public network remains available |
| 🌐 Public QR (you're away) | Click "Enable public access" → cloudflared tunnel → a public QR code is generated, reachable on 4G or any network |
| 🏷️ Fixed public domain | Optional "named tunnel" mode: enter a Cloudflare Tunnel Token + your own domain, and your public address is fixed and stable (won't change on restart; see below) |
| 🔐 Access password | Public links use an 8-character random password by default (refreshed every time public access is enabled; you can set a fixed custom password — once customized it stops refreshing); LAN has a separate default 8-character random password (on by default, can be turned off with one click in settings — when off, LAN QR scans connect directly) |
| 🔑 Custom password | Public and LAN passwords can both be set to your own fixed 8–64 character password (upper/lowercase letters or digits) in settings (public stops auto-refreshing once customized) |
| 🧘 Session persistence | After entering the password once on your phone, it's remembered long-term (login state is bound to the dsh web process on your computer: as long as it isn't restarted, no re-entry needed on the phone; re-entry required once after dsh web restart/update) |
| ⚡ Real-time sync | Streaming output is fully proxied over WebSocket — while your computer is printing, your phone scrolls in sync, with bidirectional control; built-in heartbeat keep-alive (prevents silent disconnects from router NAT / power-save, with automatic reconnection on drop) |
| 📱 Mobile adaptation | Narrow screens automatically get a drawer layout (ported from dsh-web-mobile, MIT): side drawer, full-width sessions, status-bar safe area, touch optimizations |
| 🧭 Optional right sidebar | Mobile shows the native right sidebar entry; regular phones can disable it in settings to stay compact, while foldables in expanded mode can comfortably use both the terminal bottom bar and the right sidebar |
| 📁 File browser | The mobile "File browser" entry requires the host to provide an explorer panel (dsh-web-ui component); when the official DSH has none, the entry auto-hides — no "clicks do nothing" |
| 🗜️ Transfer compression | Large JSON responses are automatically gzip/brotli-compressed (long sessions 17MB → ~1MB, brotli quality 6: fast and bandwidth-efficient), loading faster and using less data on mobile |
| 🔁 Automatic tunnel recovery | After DSH restarts, any previously running public tunnel is automatically re-established — no manual re-launch needed |
| 🧩 Zero-dependency install | One npm package, one settings page — no separate core/adapter to install; no account, no server |
🚀 How to Use
Where's the entry point: after installation and restarting dsh web, open Settings — you'll see a 「Mobile Access」 entry in the left sidebar (at the same level as "General Settings" and "Models"):
Prerequisite: DeepSeek Harness must be installed on your computer. If the terminal says dsh: command not found (dsh command not found), install it first:
npm install -g @deepseek-ai/dsh # 全局安装;验证:dsh --version
# 不想全局装?每次命令前加 npx:npx @deepseek-ai/dsh <命令>
# 1. 装插件(一个包全都有)
dsh plugin --profile web add dsh-pocket -w
# 2. 重启 dsh web
npx @deepseek-ai/dsh web
LAN (same WiFi)
Settings → Mobile Access → scan the "📶 LAN" QR code on your phone → open the link and enter the LAN password (shown in the LAN section of the settings page; click "Refresh" to generate a new one, or click "Custom" to set your own fixed 8–64 character password — upper/lowercase letters or digits) → you land on the DSH on your computer, in real-time sync.
The 「LAN access」 switch defaults to on: toggle off/on with one click (prompted on switch) — off invalidates the LAN QR/link at once (phone can't open it), public access unaffected; flip back "on" to restore.
The LAN password is on by default (security first). If it's just you and re-entering is a bother, switch "LAN access password" to off in the settings LAN section — after that, scanning the LAN QR connects directly, no password (only devices on the same LAN can access; public access always requires a password, unaffected).
After a single phone login, no re-entry for a long time: as long as dsh web on your computer doesn't restart, reopening the phone needs no input (one re-entry needed after dsh web restart/update).
Advanced: auto-detection may fail to pick a reachable address in Tailscale/VPN and similar setups. Manually select a detected IP from the "LAN address" dropdown; normally no change needed.
Public (you're away)
On the same page, click "Enable public access" → a security disclaimer pops up first; you can only proceed after checking "I acknowledge" (on corporate/classified networks, confirm compliance first) → wait for the tunnel to establish (first time downloads cloudflared; macOS/Linux use the Tsinghua mirror, instant) → scan the "🌐 Public" QR on your phone → open the link and enter the access password (shown in the settings public section; default is an 8-char random password refreshed on each enable, or click "Custom" to set a fixed 8–64 char password — letters or digits; no more refreshes after customization) → reachable even away (4G/work network).
Update to a new version:
dsh plugin --profile web update dsh-pocket --latest -w(when crossing major versions--latestis required — the^0.xrange won't auto-bump to 1.x).
Fixed public domain (named tunnel, optional)
The default "quick tunnel" public address changes on every restart (random prefix). If you want a stable public address, you can use a Cloudflare named tunnel (requires a Cloudflare account + your own domain):
- In Cloudflare Zero Trust → Networks → Tunnels, create a Tunnel and copy its Tunnel Token
- In that Tunnel's Public Hostname, point your domain (e.g.
pocket.example.com) Service tohttp://127.0.0.1:3081 - Back in the public section of the settings page: switch the mode to "Named tunnel", paste the Tunnel Token, fill in the fixed domain, and save
- Click "Enable public access" → your public address is pinned to your domain and no longer changes on restart
Note: in named-tunnel mode the public password is not auto-rotated (the address is fixed, so the password persists across restarts); we recommend managing it actively via "Custom password". The Tunnel Token is stored locally only ($DSH_HOME/dsh-pocket/settings.json, readable only on this machine) and is never echoed back on the settings page.
⚠️ Security (required reading)
- DSH can run code on your computer. The LAN QR/URL + a dedicated 8-char password is the key (password on by default, can be off — then LAN scans connect directly, only same-network devices can access). Don't share the LAN QR, URL, or password with anyone
- Read and check the disclaimer before enabling public access (prompted each time; server-enforced, no bypass): public = exposing a code-running DSH to the internet. Use strong passwords, turn off when done, avoid classified networks
- Public is protected by an 8-char random password by default: links are random, the password refreshes on each enable by default, old links invalidate instantly — a leak is useless, just change password/re-enable; a custom password can be 8–64 chars of letters or digits and stops auto-refreshing
- Phone login state is bound to the dsh web process on the computer: if dsh web keeps running, no re-entry; after restart/update, one re-entry is needed
- Login rate-limiting (brute-force protection): 5 consecutive wrong passwords from the same IP locks it for 60s; when global failures exceed the threshold, a short global lock applies (blocks distributed scanning via IP rotation); the counter resets on a correct password
- The public URL is random from cloudflared, changes on every restart (old links auto-expire, effectively rotating); in named-tunnel fixed-domain mode the address is stable and the password doesn't auto-rotate — manage it with a custom password
- Public detection is fail-closed (issue #66): apart from loopback and LAN private addresses, every unknown domain (including fixed domains from your own tunnels/reverse proxies pointing at the local port) is treated as public and requires the public password — there's no "switch domain to dodge the password" hole
- LAN mode isn't exposed to the public internet; only same-network devices can reach it
- For personal use; the public password is stored locally at
$DSH_HOME/dsh-pocket/token(auto-refreshed on each enable by default, not refreshed once customized), the LAN password at$DSH_HOME/dsh-pocket/token-lan(manual refresh on the settings page), and toggle/custom flags at$DSH_HOME/dsh-pocket/settings.json - CLI mode (running
dsh-pocketfrom the command line) also has a password (before the issue #90 fix, this path was unauthenticated): an 8-char password is randomly generated by default, printed to the terminal and embedded in the QR (scanning UX unchanged); manual URL entry requires it, local access is password-free.--pin <值>orDSH_POCKET_PIN=<值>to customize (min 6 chars);--no-authdisables it — not recommended — that's a code-running DSH exposed to anyone who can reach that port
💻 DSH Desktop
- In the desktop edition, dsh-pocket's QR-code-while-screen-is-on feature works normally; updates/restarts are managed by the desktop app (those two items are auto-disabled within the plugin)
- ⚠️ Desktop advanced mode currently doesn't support mobile access (that mode disables the web layout, so the phone can't get the layout service and shows a blank screen) — switch back to compatibility mode and restart; in advanced mode, the phone will show a clear notice
🩹 FAQ (pitfalls to avoid)
| Symptom | Cause & Solution |
|---|---|
dsh: command not found / DSH undefined error | dsh CLI not installed: run npm install -g @deepseek-ai/dsh, or prefix the command with npx @deepseek-ai/dsh |
ERR_PNPM_ADDING_TO_ROOT | pnpm 9 workspace root restriction: add -w (--workspace-root) to the end of install/update commands |
| Installed/updated but no UI change | Must restart dsh web for changes to take effect; the running process still loads old code |
listen EADDRINUSE ... :3081 | An old dsh-pocket process is still holding the port: macOS/Linux lsof -ti :3081 | xargs kill -9; Windows netstat -ano | findstr :3081 (find the LISTENING PID) → taskkill /PID <PID> /F, then retry |
| Want to change the port (issue #70) | Plugin mode: write "proxyPort": 3082 in $DSH_HOME/dsh-pocket/settings.json then restart dsh web. CLI mode: dsh-pocket --port 3082. A port conflict reports EADDRINUSE — kill the old process or use a different port |
| Want a temporary password for a guest | Not supported yet: the "temporary access PIN" feature from issue #69 was removed in 2.6.x (it would crash on revoke). To share access now: send the main password or a ?token=<主密码> link, then refresh on the settings page when done |
| cloudflared won't install on a Linux server (issue #45) | When all CDN mirrors (GitHub/ghproxy/gh.ddlc/gh-proxy) are unreachable on a remote Linux in China/enterprise networks: manually install cloudflared on the server (e.g. apt install cloudflared, dnf install cloudflared, or download the tgz and extract anywhere), then add "cloudflaredPath": "/path/to/cloudflared" to $DSH_HOME/dsh-pocket/settings.json, restart dsh web — the plugin calls it directly, no auto-download |
| Stuck on 0.x, won't upgrade | The ^0.x range disallows 1.x: use --latest for updates (dsh plugin --profile web update dsh-pocket --latest -w) |
Public error 1033 | See "Public tunnel FAQs" below — usually caused by a local proxy/VPN (Clash in TUN mode, etc.) killing the tunnel |
| After clicking "Restart dsh web", the page says the process is running in the background | The self-restart spawns a detached background process (no terminal attached) — the standard way to update in-page; to stop it: macOS/Linux lsof -ti :3080 | xargs kill -9; Windows netstat -ano | findstr :3080 → taskkill /PID <PID> /F (logs at $DSH_HOME as dsh-pocket-restart-*.log) |
⚠️ Public Tunnel FAQ (Must Read)
Symptom: After clicking "Enable Public Access", opening the public URL on your phone shows error 1033 (Tunnel error).
Most common cause: a proxy/VPN is running on this machine (Clash, Surge, v2ray, sing-box, etc., especially in TUN mode).
These tools take over all traffic and often break cloudflared's tunnel edge connections
(*.argotunnel.com, Cloudflare edge IPs), so the tunnel registers successfully but the data plane can't connect.
Fixes (from lightest to heaviest, try in order):
- First, disable only the proxy's TUN mode — no need to quit the proxy software. In most cases this step alone is enough:
- Clash: turn off the "TUN Mode" switch in settings (or right-click the menu bar icon → uncheck TUN Mode)
- Surge: turn off "Enhanced Mode"; v2ray/sing-box: turn off "Virtual NIC / route hijacking"
- Then go back to the settings page and click "Enable Public Access" again
- If that still doesn't work, fully quit the proxy software (not just close the UI: for Clash, right-click the menu bar icon → Quit; if a background service is installed, stop it in the service manager and confirm the process is gone with
ps aux | grep clash), then retry - Add direct-connection rules to your proxy so it lets tunnel domains and Cloudflare edge IPs through (Clash rules example):
- DOMAIN-SUFFIX,argotunnel.com,DIRECT - DOMAIN-SUFFIX,trycloudflare.com,DIRECT - IP-CIDR,198.41.192.0/24,DIRECT,no-resolve - If the network truly isn't working, switch to LAN mode: turn on your phone's hotspot → connect your computer to the phone hotspot → scan the LAN QR code, with exactly the same effect (still works when you're out and about)
其他可能:企业防火墙/校园网拦截出站;此时请让 IT 放行或改用热点。
"Downloading cloudflared" fails or gets stuck on first launch:
- macOS/Linux: prefer the Tsinghua mirror (measured ~3MB/s, done in seconds); on failure it automatically falls back to the official GitHub + accelerator sources.
- Windows: no Tsinghua mirror (Homebrew doesn't support Windows); it uses the official direct download (about 50MB, single-threaded downloads are slow, which is normal — just wait a few minutes; you can also use a proxy to speed it up).
- If everything fails, the settings page will show a message. Fallback options (pick any one):
- Manually install the command-line cloudflared and then retry (once installed, dsh-pocket just uses the one in PATH and no longer downloads it):
- macOS:
brew install cloudflared; Linux:sudo apt install cloudflaredor download from the official site - Windows:
winget install cloudflaredor download from the official site - Any platform:
npm i -g cloudflared
- macOS:
- Enable a proxy (system proxy/Clash, etc.) and click "Enable Public Access" again
- Manually download the binary and place it in the
$DSH_HOME/dsh-pocket/bin/directory ($DSH_HOMEis usually~/.dsh, on Windows it's%USERPROFILE%\.dsh; the file name can becloudflared(add.exeon Windows) or the release asset name — the plugin accepts both)
🗂 Architecture (Single Package)
| File | Description |
|---|---|
lib/index.js | Plugin entry point: auto-start proxy + register RPC + access password management (public 8-digit, changes each time it's enabled; LAN has an independent 8-digit one, manually refreshable/toggleable) + LAN access master switch + desktop environment adaptation |
lib/settings.mjs | Settings persistence: LAN access master switch (on by default) + LAN password switch (on by default), stored in $DSH_HOME/dsh-pocket/settings.json |
lib/service.mjs | Service: proxy lifecycle (port auto-adaptation), public tunnel (auto-recovery), status snapshot (including QR code) |
lib/proxy.mjs | Header-rewriting reverse proxy: Host/Origin → loopback, HTTP + WebSocket passthrough + polyfill injection + gzip/brotli compression + per-Host access token authentication (always verified for public; per switch for LAN) + block LAN Host when LAN is off |
lib/tunnel.mjs | cloudflared: multi-mirror download (Tsinghua first)/adaptive multi-threading/launch/parse public URL (HTTP/2) |
lib/web-rpc.js | loopback RPC: status / tunnel.start / tunnel.stop / lan.setEnabled / version / update / restart |
client/ | Settings page "Access from Phone" + mobile adaptation (port of dsh-web-mobile) |
bin/dsh-pocket.mjs | CLI: LAN/public mode, prints URL + QR code |
🛠 Development
npm install
node client/build.mjs # 改 client/ 后重新打包
npm test # 代理 / 认证 / 压缩 / 隧道 / 服务 / RPC / 设置(109 测试)
Want to test changes locally first? No release needed: point the plugin to your local repo via a symbolic link, then restart dsh web and you'll be running the local code. Full steps (including how to switch back to the official npm version) are in LOCAL-DEV.md.
🤝 Acknowledgments
- Mobile adaptation ported from mexiaosqwq/dsh-web-mobile (MIT)
- Public tunnel powered by cloudflared
📄 License
GPL-2.0 — free software license: you may freely use, modify, and distribute it, but any modified version must also be released under GPL and retain the copyright notice; commercial use is permitted under the same terms.
Note: the mobile adaptation part is ported from dsh-web-mobile (MIT license, compatible with GPL), and its copyright notice is kept in
client/mobile/LICENSE.dsh-web-mobile.
Any issues? Feedback welcome: if you hit a bug, have an idea, or want to request a feature, please let us know on GitHub Issues 🙏
Compatibility
Versions
| Latest version | Published | Size |
|---|---|---|
| 2.6.3 | — | — |
| 2.6.0 | — | — |
| 2.2.0 | — | — |
| 2.1.1 | — | — |
| 2.5.1 | — | — |
| 2.3.0 | — | — |
| 2.6.2 | — | — |
| 2.10.5 | — | — |
| 2.9.1 | — | — |
| 2.10.0 | — | — |
| 2.5.0 | — | — |
| 2.10.6 | — | — |
| 2.0.0 | — | — |
| 2.10.2 | — | — |
| 2.10.4 | — | — |
| 2.1.3 | — | — |
| 1.16.1 | — | — |
| 2.4.0 | — | — |
| 2.1.4 | — | — |
| 2.1.2 | — | — |
Comments
Loading…
Similar plugins
by summer1238
手机平板远程 DeepSeek Harness:扫码即可继续使用电脑上的 DSH,无需远程桌面 / SSH / 公网 IP,支持一次性配对、Github授权加密登录,独立设备授权与随时撤销,实现远程连接很简单,但安全才是我们所想要的。
★ 139
↓ 116/wk
MIT
TypeScript
Aug 21, 2026
dsh plugin --profile agent add dsh-remote-web-gatewayby donoteatme
Browser-first, LAN-only access to the current DeepSeek Harness Web UI with one-time QR pairing, revocable devices, event-driven diagnostics, and a slot-preserving mobile layout; no companion app, clou
★ 1
↓ 588/wk
MIT
TypeScript
Sep 12, 2026
dsh plugin --profile web add dsh-local-linkby daha1216
把 DeepSeek Harness 装进口袋:手机扫码同步操控电脑端 DSH(局域网/公网直连 + 移动端抽屉布局),基于上游 v2.10.3 安全加固版
★ 0
↓ 4.4k/wk
GPL-2.0
JavaScript
Oct 17, 2026
dsh plugin --profile web add dsh-pocketby winlin926
把电脑上的 DeepSeek Harness 会话漫游到手机:浏览器扫码即用,AI-HUB App 共用同一地址和配对码。
★ 1
MIT
TypeScript
Oct 24, 2026
dsh plugin --profile web add dsh-roamby RestRegular
Pocket for DeepSeek Harness: mobile web access to sessions, live output, tool calls, questions and approvals.
★ 1
MIT
JavaScript
Oct 23, 2026
dsh plugin --profile web add @restregular/dsh-pocketby kinderao
Phone and remote access to the DSH Web UI: scan a LAN QR code, or reach your PC from anywhere through a self-hosted relay server you run yourself instead of a cloudflared tunnel. Per-device credential
★ 4
↓ 121/wk
GPL-2.0
JavaScript
Sep 17, 2026
dsh plugin --profile web add dsh-pocket-relay