good-boy4069/dsh-mobile-remote
DeepSeek 微信远程控制插件:通过微信驱动您的 dsh 代理——双向文件传输、主动通知、多会话切换(iLink)
项目介绍Project Overview
dsh-mobile-remote 是 DSH 插件,扫码绑定微信机器人后,可在微信里发命令、派任务、收结果、切换会话,并支持双向文件传输与主动通知。适合在手机上跨网络远程操控 dsh 代理。注意:消息经腾讯 iLink 服务器传输,非端到端加密;全权限模式无人工确认,仅应绑定本人微信。
dsh-mobile-remote is a DSH plugin that binds a WeChat bot via QR code, letting you send commands, assign tasks, receive results, switch sessions, transfer files both ways, and get proactive notifications from WeChat over any network. Use it to control a dsh agent remotely from a phone. Caveat: messages pass through Tencent iLink servers and are not end-to-end encrypted; full-permission mode has no human confirmation, so bind only your own WeChat account.
请帮我了解并安装插件:【dsh-mobile-remote】【https://github.com/good-boy4069/dsh-mobile-remote】
把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.
或使用命令行安装(适合开发者)Or use CLI install (for developers)
命令行安装CLI Install
npx @deepseek-ai/dsh plugin --profile web add dsh-mobile-remote
把 good-boy4069/dsh-mobile-remote 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
dsh-mobile-remote
Your phone's WeChat becomes the remote control for your DeepSeek Harness agent.
Scan a QR code to bind a WeChat bot, then drive your dsh agent from WeChat over any network (4G / any WiFi): send commands, assign tasks, receive results, browse directories with /ls — plus two-way file transfer, proactive notifications, and multi-session switching.
- Full-permission mode: the agent can use every tool without confirmation (a
strictescape hatch is reserved viapermissionMode) - Voice messages: never stored or transcribed; replies「无法识别语音消息」(voice message not recognized)
- Messages transit Tencent iLink servers (WeChat has no third-party API) — not end-to-end encrypted; see "Risks & Boundaries"
Why this plugin
Compared with other dsh WeChat bridges (dsh-weixin, dsh-chatnode-wechat, dsh-im-bridge, …):
- Protocol fidelity: every wire detail was verified line-by-line against Tencent's official openclaw-weixin SDK v2.4.6 (notes and reference sources in
docs/) — outboundaes_keyencoding, the two separate media-type numbering schemes, and the CDN upload/download flows all match the official SDK. Both inbound AES key encodings (base64 of raw bytes / base64 of hex) are supported, with explicit errors on bad keys (no silent truncation) - Two-way file transfer: inbound images/files/videos are downloaded, decrypted and saved automatically (stable naming to prevent crash-replay duplicates + plaintext MD5 verification + 100 MB cap); outbound via the
/sendcommand or a[[send-file:path]]line in the model's reply — both share a single allowlist path check (symlink escapes, out-of-root paths and directories are rejected) - Proactive notifications: a
weixin_sendmodel tool (text + file) plus completion notifications for unbound sessions (rule-based dedup against double-send). Expired session tokens (-14) return an exact message, the health panel degrades and prompts a re-scan, and re-scanning while running hot-rotates credentials without a restart - Multi-session remote control:
/sessionslisting +/switchwith number/title dual semantics; when a session is taken over by another chat, the previous chat is notified — no cross-window output mixing - Reliability engineering (rare among peers): an exactly-once processing pipeline (queue + cursor atomically persisted), an at-least-once delivery outbox with crash recovery, a global processing limiter (8) + download semaphore (3) + backpressure throttling, drain re-entrancy mutexes and cursor identity checks, redundant credential persistence; 182 automated tests green, strict typecheck, and a zero-value-import gate for host packages
- Observability: a
/healthendpoint (allowlisted fields, no internal identifiers), a three-state status bar on the login page (running / missing credential / stopped + reason), and agateway.logfile log (1 MB rotation, 0600) - Clear security boundaries: the allowlist is the only usage boundary, the login page is loopback-only, error texts never leak keys or paths, and
weixin_sendfile sending is constrained by the same path allowlist as/send
Install
# 1. Install the plugin into the web profile
npx @deepseek-ai/dsh plugin --profile web add dsh-mobile-remote
# 2. Start (or restart) dsh web
dsh web
QR login
- With
dsh webrunning, openhttp://127.0.0.1:3080/mobile-remote-weixin/loginin a browser on this machine - Scan the QR code with WeChat and confirm (if WeChat shows a numeric code, enter it on the page)
- Once confirmed, message the bot from WeChat
The login page shows a gateway status bar (green = running / yellow = missing credential / red = stopped + reason); GET /mobile-remote-weixin/health returns a health snapshot (loopback-only, no internal identifiers).
Commands
| Command | Effect |
|---|---|
/status |
Session state + session id + workspace |
/new |
Unbind current session; next message starts a new one |
/stop |
Stop the running task |
/reply <text> |
Follow up on the current task |
/sessions |
Last 10 sessions (current binding marked ⭐) |
/switch <number-or-title> |
Switch session: pure digits resolve by /sessions number first, fall back to title match |
/切换聊天窗口:<title> |
Always match by title (use this for titles that are pure digits) |
/send <file-path> |
Send a file from the workspace/inbox to WeChat |
/ls [path] |
List a computer directory |
/workspace |
Show the current workspace |
/help |
Show the command list again |
File transfer
- Inbound: images/files/videos sent from WeChat are downloaded, decrypted and saved to
<workspace>/.wechat-inbox/<date>/(name = original + message hash, stable naming prevents crash-replay duplicates;maxMediaBytescap, 100 MiB default). The model sees a[received file] <absolute path>hint and can continue with vision tools. - Outbound:
/send <path>sends directly; the agent can also put a single[[send-file:path]]line in its final reply (the line itself is never shown to the user). Paths must be inside the workspace or the inbox directory (one shared check; symlink escapes and out-of-root paths are rejected). - Voice messages stay rejected: not downloaded, not stored.
Proactive notifications
weixin_sendtool: agents in WeChat sessions can push text/files to WeChat (to the bound chat window; falls back tonotifyChatIdwhen unbound). Disable withenableWeixinSendTool: false.- Completion notifications: configure
notifyChatId+notifyOnTurnEnd: true, and when a task finishes in a session not bound to WeChat, a✅ Task complete: session「title」push goes to the notification target (bound sessions are never double-notified; deduped when the tool already pushed this turn).
Configuration (all optional)
Environment variables:
| Variable | Default | Meaning |
|---|---|---|
WEIXIN_BOT_TOKEN |
none | Login token (auto-saved after QR login; normally not needed) |
WEIXIN_ALLOWED_USERS |
the scanner | Allowed user ids, comma-separated |
WEIXIN_ALLOWED_GROUPS |
empty | Allowed group ids (groups need user+group match) |
WEIXIN_BOT_API_BASE |
https://ilinkai.weixin.qq.com |
iLink gateway |
WEIXIN_CDN_BASE |
https://novac2c.cdn.weixin.qq.com/c2c |
Media CDN |
WEIXIN_MAX_MESSAGE_CHARS |
3500 | Reply chunk length |
WEIXIN_MAX_MEDIA_BYTES |
100 MiB | Media size cap |
WEIXIN_PERMISSION_MODE |
full |
full = full permission; strict = reserved escape hatch |
WEIXIN_DSH_WORKSPACE |
auto | Default workspace for new WeChat sessions (this var > explicit config > dsh current workspace > process cwd) |
cordis config keys:
| Key | Default | Meaning |
|---|---|---|
inboxDir |
'' (=workspace/.wechat-inbox) | Inbox directory; out-of-root values fall back with a warning |
enableWeixinSendTool |
true |
Master switch for the weixin_send tool |
notifyChatId |
'' | Notification target / tool fallback (Web sessions can also push once set) |
notifyOnTurnEnd |
false |
Push completion notifications for unbound sessions |
logDir |
'' (=state dir) | Gateway log directory (gateway.log, 1 MB rotation) |
statePath |
~/.dsh/mobile-remote-weixin/gateway-state.json |
Gateway state file |
Health & logs
- Health snapshot (
/health): running state, poll activity, consecutive error count, binding counts, backlog, credential presence, start-failure reason — allowlisted fields only, never chat/session ids or progress. - File log:
gateway.log(append-only, 0600, 1 MB single-generation rotation, silent degradation on write failure), tee'd to the dsh logger.
Risks & boundaries (please read)
- Full-permission mode: no human in the loop; the allowlist is the only boundary — only add your own WeChat account.
weixin_sendoutbound surface: the tool is visible to in-scope agents; injected inbound messages could convince the model to push workspace text/files to WeChat.filePathis constrained by the same allowlist as/send, but text content is not path-checked — do not use in untrusted groups.- Privacy: messages transit Tencent iLink servers (not end-to-end encrypted); decrypted media lands in the workspace
.wechat-inbox. - Account coexistence: driving the same WeChat account with another iLink client (e.g. OpenClaw) will steal messages — disable one of them.
- Credentials: the token is stored locally (credentials service + managed fallback file, 0600); a leak equals account control.
- Platform risk: iLink is an undocumented bot API that may drift; rule-breaking use risks a ban — at your own risk.
Limitations & not-supported (honest disclosure)
- No voice recognition: voice messages always get「无法识别语音消息」(not downloaded/transcribed/stored) — a deliberate design decision
- No multimodal pipeline: images/files are only saved to disk with a path hint for the model; the plugin does not parse content (pair with a vision tool such as
vision_analyze) - No scheduled tasks: no cron-style "do X every day"
- No remote approval buttons: full-permission mode means no human-in-the-loop confirmations and no approve/reject interaction in WeChat;
strictmode is a reserved escape hatch (approval flow not implemented) - Depends on an undocumented protocol: iLink may drift and break features; misuse risks a ban
- Single account binding: one credential set per dsh instance; multiple WeChat accounts need multiple profile instances (no built-in multi-instance management)
- No content-level file dedup: resending the same file in different messages lands duplicate copies (only crash replays of the same message are deduplicated)
- Chinese-only commands and copy: slash commands, help text and prompts are Chinese; no English/i18n
- No graphical settings panel: all configuration is via environment variables / cordis patch (the login page only offers QR scan, a status bar and the health endpoint)
- Requirements: Node ≥ 22.12, a dsh web profile, and a WeChat account that can scan-bind an iLink bot
Development
npm install
npm run typecheck
npm test
npm run build
License
MIT
nexu-io/open-design
freestylefly/awesome-gpt-image-2
anywhere-labs/dsh-desktop
walkinglabs/learn-harness-engineering
awesome-dsh-plugin/awesome-dsh-plugin
MemTensor/MemOS