DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
W

dsh-webim

Webim

Remote web entry for DeepSeek Harness: reuse the same DSH web UI from your phone or another network, with a rotatable token link and QR code in Settings, a built-in Cloudflare quick tunnel, a phone layout, per-feature switches, and an HTTP/WebSocket bridge to the local Harness.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:shimiei/dsh-webim#48b6a579ca8d5920ea489030e08a6b2521d310e5
READMECompatibilityVersions
Cloudflare 隧道模式:隧道运行中,二维码指向隧道地址公网直连模式:保存自己的公网 IP 或域名手机上的设置页:单列布局,二维码与入口卡片浅色主题下的同一块面板

Compatibility and provenance

Webim is published as dsh-webim and currently resolves to version 1.6.2. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
10/26/2026

Versions

1.6.2stable
10/26/2026
1.6.1stable
10/26/2026
1.6.0stable
10/25/2026
Show 3 more versionsCollapse versions
1.5.3stable
10/25/2026
1.5.2stable
10/25/2026
1.5.1stable
10/24/2026

Related plugins

Loading related plugins…

Latest
1.6.2
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
10/26/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in integrations-communication.

Acp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseDs Botds-botDS Bot: a team of long-lived Bots for DeepSeek Harness, with Main Bots, Bot-to-Bot messages and group chatsFree Searchdsh-free-searchFree web search for DeepSeek Harness: 27 engines (Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl/Parallel/You.com keyless; Zhihu global/site via MCP and Perplexity/SerpBase/DeepSeek (official + native tools/search)/Baidu/Kimi/Aliyun/DoubaAb Wechat Scrapedsh-ab-wechat-scrape--- description: "The out-of-tree wechat_scrape tool: retrieves WeChat official-account articles, filters promotional blocks, and saves each as a Markdown file, for maintainers of this machine's dsh profiles." kind: "package-reference" ---

README

dsh-webim:把本地 DeepSeek Harness 带到手机与异地浏览器

不改 DeepSeek Harness 的一行代码,就把这台机器的 DSH 变成手机、平板、异地浏览器都能打开的网站。
复用同一套 DSH 前端 · token 扫码即进 · 内置 Cloudflare 隧道 · 手机层单独适配 · 零运行时依赖


这是什么

DeepSeek Harness(DSH)默认只监听 127.0.0.1 的随机端口,同一个 Wi-Fi 下的手机都连不上,更别说人在外面。

dsh-webim 是一个 DSH 插件:它在 0.0.0.0:3081 起一个反向代理,把本机 Harness 的 HTTP 与 WebSocket 原样桥接出去,并在 DSH 的设置页里长出一块**「远程接入」**面板,负责入口地址、二维码、令牌、隧道和一堆运行时开关。

它不修改 DSH 本体:前端还是那套前端,工作区、会话、插件全都在,只是多了一个经过 token 校验的入口。远程浏览器拿到的是 DSH 自己的 UI,实际驱动的是这台机器上的 Harness 进程——本地绝对路径(工作区、file:// 引用、会话存储)永远留在服务端。

能力说明
同一套前端反向代理透传 HTTP + Upgrade(/api/remote.mux 实时流),不劫持、不改写 DSH 的页面
扫码即进设置页内联 SVG 二维码(自研编码器,无外部图片请求,绕开 CSP img-src),扫完直接落到 DSH
令牌可轮换32 字节 base64url token,一次刷新即硬切:旧链接、旧二维码、已登录会话一起失效
三种接入方式仅局域网 / 公网直连(自己的 IP 或域名)/ Cloudflare 快速隧道;一次只开一种,也能让隧道与公网并存
内置隧道自动下载并拉起 cloudflared quick tunnel,几秒后拿到 https://xxx.trycloudflare.com,不用配端口映射
固定隧道也可以跑自己的域名:填域名 + Zero Trust 令牌,域名永不变;令牌被拒会直接报错并停止重连,不会反复重启
自检面板里点「自检」,由本机真的去访问 https://你的域名/__webim/ping,把「隧道在跑」和「域名真能打开」分开:解析没建、1033、Access 拦截、回源 502 各有各的话术
手机层窄屏抽屉、输入框不再被键盘顶飞、设置页单列,interactive-widget=resizes-content
运行时开关总开关 / 局域网 / 公网 / 移动端 / 隧道 / 文件查看 / 路径转链接 / 浮动入口,全都不用重启
主题自适应浅色/深色跟随 Harness 本身:浮标、面板、提示条、手机抽屉、文件浏览页全部同步,没有一块"深色孤岛"
远程安全令牌门 + 会话绑定浏览器 + 失败限流与封禁 + 上游 Cookie 由本机 .credentials.yaml 铸造,凭据不出机器
零依赖只用 Node 标准库:QR 编码器、PNG 编码器、代理、二维码都是自己写的

截图

取自真实运行中的面板,所有 IP、域名、令牌与二维码都已替换成文档占位值(RFC 5737 / example.com)。

Cloudflare 隧道模式:隧道运行中,二维码指向隧道地址 公网直连模式:保存自己的公网 IP 或域名

手机上的设置页:单列布局,二维码与入口卡片 浅色主题下的同一块面板
手机端(390pt):单列、入口卡片与二维码,扫码即进 · 右为浅色主题

三种接入方式

设置页只有一块分段控件,选完即生效(内部就是三个布尔开关的组合):

方式实际写入效果
仅局域网{lan: true, public: false, tunnel: false}只出 http://<本机 IP>:3081/?token=…,同一 Wi-Fi 可用,不暴露到公网
公网直连{lan: true, public: true, tunnel: false}先列你保存的公网 IP / 域名(自己做端口映射或反代),再列局域网地址
Cloudflare 隧道{lan: true, public: false, tunnel: true}卡片里再选临时隧道(https://xxx.trycloudflare.com,每次启动都变)或固定隧道(自己的域名,地址不变);公网地址默认不参与,需要时勾「同时列出公网直连地址」

三个开关各自独立,也各有含义:

开关关掉之后
总开关监听彻底停掉:3081 无监听、隧道一起停、入口列表清空;桌面端不受影响
局域网可访问监听从 0.0.0.0 重绑到 127.0.0.1,同网段设备连不上,隧道照旧(它连的是本机回环)
公网入口不再展示保存的公网地址,隧道不受影响(v1.5.1 起两者解耦)

二维码永远跟随被点选的那张入口卡,不是"排在第一个的那个";指向消失时自动回落到列表第一项,不会留死链。

快速开始

要求:Windows / macOS / Linux,Node ≥ 18,已安装并能正常打开 DeepSeek Harness。

git clone https://github.com/<you>/dsh-webim.git
cd dsh-webim

# 装进 DSH 的 desktop profile(建链接 + 写 patch,幂等)
node scripts/install.mjs

然后重启 / 刷新 DSH 窗口,打开 设置 → 远程接入:

  1. 顶栏确认「入口运行中」,记住 host:port(默认 0.0.0.0:3081);
  2. 选一种接入方式(想最省事就选 Cloudflare 隧道,等几秒拿到 https 域名);
  3. 点入口卡片选中它,扫右侧二维码,或直接复制链接。

想手动安装也可以:在 <profile>/node_modules/ 下指向本仓库建一个链接,把 dsh-webim 加进 profile 的 dsh.profile.bundles,再在 cordis.patch.yml 里加一段配置(见下一节)。

不用插件也能跑(调试用)

node bin/serve.mjs --host 0.0.0.0 --port 3081

它和插件共用 lib/gateway.js,只是没有设置页,参数从命令行来。

配置

配置写在 profile 的 cordis.patch.yml(用户覆盖层),或直接改插件自带 cordis.patch.yml 的默认值:

- id: dsh-webim
  config:
    enabled: true             # 插件是否加载(与「是否监听」是两件事)
    host: "0.0.0.0"           # 监听地址;0.0.0.0 = 所有网卡
    port: 3081
    password: ""              # 口令门;留空 = 只认 token 链接
    accessToken: ""           # 固定 token;留空 = 自动生成,可在设置页刷新
    publicUrl: ""             # 公网 IP / 域名(含端口),如 http://1.2.3.4:3081
    sessionDays: 30
    sessionBind: 'ua'        # 'ua' = 会话只对扫码那台浏览器有效;'off' = 拿到 cookie 就能进
    maxFailures: 8            # 同一 IP 失败多少次锁定
    failureWindowMinutes: 10
    blockMinutes: 15
    allowedRoots: []          # 远程文件查看允许的根;空 = 所有盘符
    deniedPaths: []           # 额外拒绝路径(默认已拒绝 $DSH_HOME 里的凭据)
    linkifyPaths: true
    logRequests: false
    tunnelBinary: ""          # 指定现成的 cloudflared;留空 = 用下面自动下载的那份
    tunnelAutoInstall: true   # false = 不自动下载 cloudflared
    tunnelMode: "quick"       # "quick" = 临时隧道;"named" = 固定隧道(自己的域名)
    tunnelHostname: ""        # 固定隧道的域名,如 dsh.example.com
    features:                 # 只提供首启默认值,运行时以 features.json 为准
      enabled: true
      lan: true
      public: true
      mobileUi: true
      tunnel: false
      fileBrowser: true
      linkifyPaths: true
      pill: true

运行时状态都在 $DSH_HOME/webim/:token.json、public-url.txt、qr-target.txt、features.json、tunnel.json、plugin.log(插件日志,排障用)、cloudflared/。删掉对应文件即回到默认。

固定隧道多两个文件:tunnel-named.json(域名 + 模式)和 tunnel-token.txt(连接令牌,权限 0600)。令牌单独存文件、不进配置,避免误贴进 issue 或提交到仓库;面板里只显示"已保存",status() 也只回 hasToken。

如果域名外面还套了 Cloudflare Access(Zero Trust 应用),把 Access 服务令牌放进 access-client-id.txt 与 access-client-secret.txt,「自检」会带 CF-Access-Client-Id / CF-Access-Client-Secret 去访问。服务令牌只解决"机器过 Access 登录页",不能建 DNS / 隧道——那是 API Token 的活。

固定隧道怎么配

  1. Cloudflare Zero Trust → Networks → Tunnels → 创建(或选定)一条隧道,复制它的连接令牌;
  2. 在同一条隧道里加一条 Public Hostname:dsh.你的域名.com → HTTP → 127.0.0.1:3081(这一步会顺带建好 CNAME,域名必须托管在同一个 Cloudflare 账号下);
  3. 设置页 → 对外入口 → Cloudflare 隧道 → 切到固定隧道,填域名、粘贴令牌,保存。

面板随后显示 https://dsh.你的域名.com,进程异常退出会按 2s → 4s → … → 30s 退避自动重连,最多 5 次;令牌被 Cloudflare 拒绝(Tunnel not found / Unauthorized)时不再重试,直接把原因写在面板上——这种错重连一万次也没用。

命令行等价做法(需要 cloudflared tunnel login 生成的证书):

cloudflared tunnel route dns <隧道ID> dsh.你的域名.com
cloudflared tunnel run --token <令牌>

工作原理

请求路径:手机 → Cloudflare 隧道 → dsh-webim 网关 → 本机 Harness

几条关键设计:

  • 只在入口校验:token 或口令任一通过即铸造 DSH 自己的 dsh-auth-* Cookie,之后由上游继续认这个 Cookie;网关不缓存任何会话内容。
  • WebSocket 桥接:Upgrade 直接接到上游,/api/remote.mux 的实时流不断。
  • 隧道与监听解耦:隧道连的是本机回环,所以关掉局域网、甚至只绑 127.0.0.1,隧道仍然可用。
  • 设置页 RPC 先回包再干活:切模式会重绑端口,导致"回包跟着旧连接一起死";因此面板先就地更新,再后台轮询等状态回来。
  • QR 自研:Byte 模式、版本 1–20、L/M/Q/H、8 种掩码,输出内联 SVG;tests/qr.test.mjs 与 Python qrcode 做了矩阵对照。

目录结构

lib/           网关、代理、安全、文件、隧道、二维码、入口地址推导
assets/        注入到 DSH 前端的小补丁(移动端抽屉、状态胶囊、路径点击)
client.js      设置页(React,走 DSH 的 slot 与设计 token)
bin/serve.mjs  独立模式入口
scripts/       安装 / 卸载
tests/         86 个测试(安全、网关、token、插件、客户端契约、二维码、隧道)
tools/         无依赖调试工具(CDP 探针、截图脱敏、banner / 架构图合成)
docs/          banner、图标、README 截图

开发与测试

node --test tests/*.test.mjs

当前 86 个用例全部通过(约 1.7 秒):安全 10、网关 16、token-only 6、token 10、host 插件 7、client 契约 12、二维码 11、功能开关 4、隧道 5、入口地址过滤 1。

界面另有几个零依赖探针(需先手动起 headless Edge 并打开调试端口):

node tools/probe-remote.mjs <debug-port> <入口链接> out.png --eval-file tools/eval-ui-report.mjs
node tools/make-shots.mjs    <debug-port> <入口链接> docs/shots   # 生成脱敏截图
python tools/make-banner.py                                      # 重新合成 banner 与图标
python tools/make-arch.py                                        # 重新绘制架构图

改完代码要让它生效:node scripts/install.mjs 触发宿主热重载;只改 cordis.patch.yml 里的注释不算变化,得动一个值(例如 sessionDays 30 ↔ 31)。

安全须知

远程入口意味着别人拿到链接就等于坐在你的 DSH 前面,请至少做到:

  1. 别用弱口令:口令门默认关闭,走 token;要开口令就给个像样的。
  2. 公网优先用 HTTPS:Cloudflare 隧道 天然 https;自己做端口映射时建议反代加证书,并透传 X-Forwarded-Proto: https(网关据此给 Cookie 加 Secure)。
  3. 令牌会随刷新硬切:刷新后旧链接、旧二维码、已登录浏览器全部失效,这是设计。
  4. 会话绑定浏览器:cookie 里带 User-Agent 指纹(sessionBind: 'ua',默认),换设备/换浏览器复制 cookie 一律 401;手机在 Wi-Fi 与蜂窝间切换不受影响。想回到"拿到 cookie 就能进"的老行为,把它设成 'off'。
  5. 文件查看有白名单:默认拒绝 $DSH_HOME 里的凭据与状态目录,可用 allowedRoots / deniedPaths 收紧。
  6. 不用就关总开关:3081 会真的停掉,隧道一起停。

常见问题

现象处理
设置了但手机连不上确认防火墙放行 TCP 3081;Get-NetTCPConnection -LocalPort 3081 应有监听;路由器/云主机安全组也要放行
隧道一直起不来首次要下 ~55 MB 的 cloudflared(看 $DSH_HOME/webim/cloudflared/);企业网络挡 github.com / *.trycloudflare.com 时会失败;可用 tunnelBinary 指定现成二进制
固定隧道报 Tunnel not found / Unauthorized令牌和隧道对不上:多半复制了别的隧道(或别的账号)的令牌,或这条隧道已被删除。回 Zero Trust → Networks → Tunnels → 该隧道 → 复制令牌,粘回面板保存
固定隧道「运行中」但域名打不开只配了令牌、没配 Public Hostname:同一隧道下加 你的域名 → HTTP → 127.0.0.1:3081(会顺带建 CNAME)。域名不在同一个 Cloudflare 账号时,CNAME 自己指到 <隧道ID>.cfargotunnel.com
点了隧道按钮没反应v1.5.1 起有转圈 + 计时 + 占位卡片;若 30 秒没域名,看 $DSH_HOME/webim/plugin.log(含 cloudflared 最后几行输出)
切换模式后页面卡一下预期行为:重绑端口会打断当前页面连接,面板每 1.2 秒自动重连,3–5 秒恢复
二维码扫出来不是我想的那个二维码跟随被点选的卡片;点一下想要的那张,下方会写「扫码目标 · …」
刷新令牌后自己也进不去设计如此:会话签名把 token 当盐,轮换后旧会话全部失效,重新扫码即可
端口被占(EADDRINUSE)已有旧网关在跑;插件用 Symbol.for('dsh-webim.gateway.v1') 注册表在 bind 前关掉上一代,/__webim/ping 的 instance.tokenId 可看是谁在应答

已知限制

  • 隧道用的是 quick tunnel(免账号),域名每次启动都变,Cloudflare 也不保证可用性;长期使用请换 named tunnel + 自己的域名。
  • 网关到本机 Harness 之间是明文回环 HTTP,本机进程可读;跨机安全靠外层 https。
  • 只桥接 HTTP/WS,不做协议改写,所以 DSH 前端的所有能力都取决于上游本身。
  • 移动端适配是"补丁式"的:DSH 大版本换 DOM 结构时,assets/client.css 里的选择器可能需要跟进。

License

MIT。与 DeepSeek / DeepSeek Harness 官方无关,属于第三方插件。