Open-source project
shaobeichen/dsh-pocket avatar
shaobeichen/dsh-pocket

DSH Pocket: access your desktop DeepSeek Harness from a phone by QR code

把 DeepSeek Harness 装进你的口袋:电脑上跑 dsh web,手机扫码即同步访问(局域网 + 公网,实时同屏)Put 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 mirroring)

1,179 stars58 forksJavaScriptGPL-2.0

At a glance

What is it?
DSH Pocket is a dsh plugin that puts a QR code in front of your desktop DeepSeek Harness, over LAN or a cloudflared tunnel. It is a thin remote-access layer with a hard dependency on dsh web staying up.
Who is it for?
Adopt DSH Pocket if you already run dsh web on a machine that stays awake and you want to check on an agent from a phone without SSH or a remote desktop. Skip it if the host machine sleeps, if you cannot leave dsh web running, or if exposing a code-executing harness to the public internet is out of policy for your network.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem DSH Pocket solves: a desktop harness with no remote hands

DeepSeek Harness runs on a computer. Its web interface is served by dsh web, and the README frames the plugin around a specific situation: the agent is working on the desktop machine while you are somewhere else, commuting, in a dorm, or away from the office, and you want to see progress, send a task, or approve something. The README lists three motivations directly: checking on a running agent from a phone, asking the desktop agent to look something up or write code when there is no remote desktop and no SSH, and operating the harness from outside the room.

The intended user is therefore someone who already has DeepSeek Harness installed and running locally, not someone looking for a hosted agent service. The README states there is no account and no server to set up, and the package is a single npm module with a settings page rather than a core plus adapter split. That framing matters: DSH Pocket does not run an agent itself. It is a transport and access layer bolted onto a dsh web instance that must already be alive.

How the QR code, tunnel and password layer fit together

The mechanism is a plugin loaded into dsh web. According to package.json, the package declares a dsh bundle patch at cordis.patch.yml and a web client injection list that includes @deepseek-ai/dsh-client-connection, @deepseek-ai/dsh-client-ui-slots, @deepseek-ai/dsh-client-ui-layout, @deepseek-ai/dsh-client-locale and @deepseek-ai/dsh-session-log-export. In practice that means the plugin adds a settings entry, labeled 手机访问 (phone access) in the README, alongside the general settings and model pages, and wires its client UI into the existing dsh web layout.

Real-time mirroring is described as WebSocket passthrough: the README says streaming output is forwarded whole, so what scrolls on the desktop scrolls on the phone, and input works in both directions. A heartbeat is included to keep routers and phone power-saving from silently dropping the connection, with automatic reconnect.

Access control has two separate layers. LAN access has its own 8-digit password, on by default, and a toggle that can disable it so a phone on the same network connects directly. Public access always requires a password, and by default that password is regenerated each time public access is turned on, invalidating the old link. Both can be replaced with a fixed 8-digit password made of letters or digits. Login attempts are rate limited: the README states five consecutive wrong entries from one IP lock it for 60 seconds, and a global failure threshold briefly locks everything to frustrate distributed scanning. Payloads are compressed, with the README citing a long session shrinking from 17MB to about 1MB using brotli quality 6.

Installing the plugin and opening the phone view

The README assumes DeepSeek Harness is already present. If the dsh command is missing, it gives a global install and a version check:

sh
npm install -g @deepseek-ai/dsh     # 全局安装;验证:dsh --version
# 不想全局装?每次命令前加 npx:npx @deepseek-ai/dsh <命令>

The README notes that npx @deepseek-ai/dsh can be used instead of a global install. The plugin itself is added to the web profile and then dsh web is restarted:

sh
# 1. 装插件(一个包全都有)
dsh plugin --profile web add dsh-pocket -w

# 2. 重启 dsh web
npx @deepseek-ai/dsh web

After the restart, the README says to open Settings and look for the phone access entry in the left sidebar. From that page, the LAN QR code is available immediately; scanning it on a phone connected to the same Wi-Fi opens the same interface, and the phone is asked for the LAN password shown in the LAN block, which can be refreshed or replaced with a custom 8-digit value. For access from outside, the same page has a button to enable public access. The README states a disclaimer dialog appears every time, and must be acknowledged before the tunnel starts. The first run downloads cloudflared, and the README says macOS and Linux use the Tsinghua mirror. A public QR code then appears, and the phone enters the 8-digit public password shown in the public block.

Upgrades use a separate command, and the README warns that --latest is required across major versions because a ^0.x range will not move to 1.x:

sh
dsh plugin --profile web update dsh-pocket --latest -w

The password is not the only thing standing between the internet and your shell

The README is blunt about the risk: DSH can execute code on your computer. That sentence should govern how you deploy this. A LAN QR code plus its 8-digit password is described as the key, and the README explicitly says not to send the LAN QR code, URL or password to anyone. Disabling the LAN password is offered for people who find it tedious, and the README notes the trade-off: any device on the same network can then connect without a password. On a home network that may be acceptable. On a shared office, campus or guest network it is not, and the README itself points at compliance review for company or sensitive networks before enabling public access.

The public path is a different category of exposure. Once the cloudflared tunnel is up, a harness that can run code is reachable from the internet, protected by an 8-digit password and a rate limiter. The default rotation of the public password on each enable is a real mitigation: a leaked link dies when you cycle it. Choosing a custom fixed password removes that property, and the README says so plainly, recommending you manage it deliberately. In named tunnel mode the password does not rotate at all, because the address is fixed. If you take that route, the password becomes the only rotating element you control, and you should treat it as a long-lived credential.

The session model is another constraint. The README states that phone login is bound to the dsh web process: while it keeps running, the phone does not need to re-enter the password, and after a restart or update it does. That is convenient and also means every dsh web restart is a moment when you need the password at hand. The README does not document a way to revoke a single phone session independently of cycling the password or restarting the process.

Where DSH Pocket is the wrong tool

The first failure mode is a sleeping or off host. Nothing in the README suggests the plugin keeps the desktop harness alive; it attaches to a running dsh web. If the machine suspends, the phone view goes with it. This is not a remote desktop replacement for a laptop that travels with you, and it is not a way to reach an agent on a computer that is shut down.

The second is the file browsing entry. The README states that the mobile file browser requires the host to provide an explorer panel from dsh-web-ui, and that when the official DSH does not include it, the entry hides itself rather than appearing and doing nothing. So a feature you may expect from the screenshots is conditional on your host build, not guaranteed by the plugin.

The third is address selection in unusual networks. The README notes that automatic detection can fail to pick a reachable address under Tailscale or VPN setups, and offers a LAN address dropdown for manual selection. If your machine has multiple interfaces, expect to use it.

Finally, the tunnel choice has a cost. Quick tunnels give a random prefix that changes on every restart. Named tunnels give a stable hostname but require a Cloudflare account, your own domain, and a public hostname pointed at http://127.0.0.1:3081, and they drop automatic password rotation. If you want a fixed address, you are accepting a fixed credential too.

Compared with just forwarding a port or running SSH

The obvious alternative is to skip the plugin and expose dsh web yourself, either with an SSH tunnel or a reverse proxy plus a VPN. The difference in approach is where the access logic lives. With a manual tunnel you get a raw port on the network and you supply your own authentication, TLS and session handling, or you rely on the VPN to gate everything. DSH Pocket instead ships the access layer inside the harness: it generates the QR codes, holds the LAN and public passwords, enforces the five-attempts-per-IP lockout, rotates the public password by default, and re-establishes the tunnel after a DSH restart, which the README lists as automatic tunnel recovery.

That is a meaningful difference for a phone-first workflow, because typing a long URL and managing certificates on a phone is unpleasant, and the QR code removes that step. It is also a difference in trust surface: you are adding a plugin with GPL-2.0 licensing into a harness that executes code, and you are depending on its password handling rather than on a VPN you already operate. If your organization already runs a VPN with device posture checks, the plugin's 8-digit password is weaker than what you have, and layering it on top adds a second path into the same harness. If you have no VPN and no wish to build one, the plugin is the shorter route to the same outcome.

Licence, maintenance and what an upgrade costs you

The package is GPL-2.0, per package.json and the LICENSE file. The README's badge markup still carries an MIT alt text on a GPL-2.0 badge, which is a documentation inconsistency rather than a licensing one; the package.json license field and the LICENSE file are the authoritative pair. GPL-2.0 matters if you plan to redistribute a modified version or bundle it into a product, and the README says nothing about commercial support or exceptions. That is a question for your own counsel, not something the repository answers.

Maintenance looks current rather than dormant: the last push was on 2026-09-10, and the release list shows v2.10.6, v2.10.5 and v2.10.4 all tagged on 2026-09-10, with semantic-release configured in the repository. The cadence of patch releases on a single day suggests active iteration, and the repository is not archived. That said, version numbers in the 2.10.x range with several builds in one day can also mean rapid fixes; if you pin a version, read the CHANGELOG before moving.

Upgrade cost is low but not zero. The update command is one line, and the README flags that --latest is required to cross major versions. The real cost is the restart: dsh web has to come back up, which invalidates phone sessions, and any open public tunnel is re-established by the plugin's recovery logic. Plan upgrades for a moment when you are at the keyboard, not while you are relying on the phone.

Runtime requirements are worth checking before install. package.json sets engines.node to >=22 and declares a peer dependency on @deepseek-ai/cordis ^4.0.1. The plugin's own dependencies are small: qrcode and qrcode-terminal, with ws and esbuild in devDependencies.

Editorial conclusion

Adopt DSH Pocket if you already run dsh web on a machine that stays awake and you want to check on an agent from a phone without SSH or a remote desktop. Skip it if the host machine sleeps, if you cannot leave dsh web running, or if exposing a code-executing harness to the public internet is out of policy for your network. Before relying on it, verify the LAN QR code resolves on your phone, confirm the LAN password toggle behaves the way you want, and read the disclaimer flow for public access. The most important thing to check first is that your dsh web process stays running: the README states that restarting or updating dsh web forces every phone to enter its password again.

Frequently asked questions

What does DSH mean in DSH Pocket?

DSH is the short name for DeepSeek Harness, the desktop agent tool this plugin attaches to. The package name dsh-pocket and the command dsh plugin both use that abbreviation.

How do I install DSH Pocket into dsh web?

The README gives two steps: run dsh plugin --profile web add dsh-pocket -w, then restart with npx @deepseek-ai/dsh web. The phone access entry appears in Settings afterwards.

Does DSH Pocket work when I am away from my home network?

Yes, through the public access option on the phone access page. The README states it opens a cloudflared tunnel and produces a public QR code that works on 4G or any network, protected by an 8-digit password.

Why does my phone ask for the password again after a DSH Pocket update?

The README states that phone login is bound to the dsh web process on the computer. As long as it keeps running you do not re-enter the password, and after a restart or update you enter it once more.

Can I get a fixed public address instead of a changing one?

The README describes an optional named tunnel mode using a Cloudflare Tunnel Token and your own domain, with the public hostname pointed at http://127.0.0.1:3081. In that mode the public password does not rotate automatically.

Official sources

  1. Issues
  2. License: GPL-2.0
  3. README
  4. Releases
  5. shaobeichen/dsh-pocket on GitHub
Community notes

Community notes