DSH Plugins Marketplace

DSH Plugins

Plugins

/

Tools & Capabilities

/

dsh-go-plugin-adb

J

dsh-go-plugin-adb

Manifest valid

ADB plugin for Android phones: opens an adb shell for itself inside the phone—no root, no PC required, works even with WiFi off. The AI assistant uses it to install apps, view logs, take screenshots, and run shell commands. / Android adb plugin that gives an AI agent a real adb shell from inside the phone — no root, no PC.

hasBundlePatch

dsh-go-plugin-adb

在手机内部给 Agent 一个真实的 adb shell。不是"电脑连手机",是"Agent 住在这台手机里,连自己"。

English | 中文

项目值
版本2026.1105.1908(年.月日.时分,看到这个号就知道是哪天哪一刻发的版)
验证环境nubia REDMAGIC NX809J / Android 16 (SDK 36) / adb 34.0.4
工具数6
需要 root不需要
测试稳定性 10/10 · 工具定义 6/6

一、这是什么

DSH Go 跑在手机上的 proot Ubuntu 里。这个插件让它能用 adb 命令操作它自己所在的这台手机:

  • 装包、卸载包、看当前装了哪些包
  • 看 logcat
  • 执行任意 shell 命令(uid 2000)
  • 截图、读系统状态
  • 查系统状态(电量、显示、窗口、进程)

它解决的问题:以前要操作手机,得用电脑插数据线连 adb,或者用无障碍去点屏幕。这个插件让 Agent 直接在自己身体里开一个 shell。


二、端口仍是 5555,但连的是回环地址

需要说清一点:端口仍然是 5555,这个插件没有换端口。区别在于"连哪个地址"——常规做法连的是局域网 IP,这里连的是回环 127.0.0.1。

adb tcpip 之后 adbd 会监听整个网络栈(不只是回环),所以本机连回环也能用。但 tcpip 会重启 adbd、踢掉 Shizuku 等其它客户端——插件不自动做这一步,见第五节的说明。

Agent 连 127.0.0.1:5555,流量走回环网卡,所以:

  • ✅ 关 WiFi、开飞行模式都不断
  • ✅ 不依赖路由器、不依赖同一局域网
  • ⚠️ 但同一局域网内的其他机器也能连到这个端口(仍然需要你这台机器的 adb 私钥才能进)

不用时执行 adb usb 或关掉无线调试就收回了。


三、前提条件

先说清三件事,不然后面每一步都会疑惑:

疑问答案
这些命令在哪跑?全部在手机内部的 proot Ubuntu 里跑(DSH Go 提供的终端)。不是电脑。
192.168.1.100 是谁的 IP?手机自己的局域网 IP。因为 adb 客户端和 adbd 在同一台设备上,所以配对时填手机上显示的那个 IP。
从 GitHub 克隆下来要构建吗?不用。纯 ESM 的 JS,没有构建步骤、没有 npm install。package.json 里的 peerDependencies 是可选的,缺了插件会走内置回退。
  1. 一部 Android 手机,开了开发者选项
  2. 无线调试可用(用于一次性配对)
  3. 首次配对时手机要连着 WiFi——配对走局域网。配对成功之后就不需要了,关 WiFi 也能用(见第二节)
  4. proot 环境能装 adb 客户端:
apt-get update && apt-get install -y android-tools-adb

装完验证:

adb version
# Android Debug Bridge version 1.0.41

注意:DSH Go 升级运行时镜像时,apt 装的东西会全部丢失,需要重装一次 adb。这是实测过的坑。


四、安装

4.1 包从哪来

dsh plugin add 接受两种目标:

方式 A:本地目录(从 GitHub 克隆下来的人用这个)

git clone https://github.com/JMINN0/dsh-go-plugin-adb.git
cd dsh-go-plugin-adb
dsh plugin --profile web add .

注意 add 后面那个 . 表示"当前目录"。必须先进到仓库目录再执行,否则会报找不到包。

方式 B:已发布的包名(如果这个包已经发到 npm registry)

dsh plugin --profile web add dsh-go-plugin-adb

该选哪个? 这个包目前没有发布到 npm registry,只存在于 GitHub 仓库。所以:

  • 从 GitHub 来的人 → 用方式 A(clone + add .)
  • 报 package not found → 说明你用了方式 B,改回方式 A

4.1.1 如果 add 失败的常见原因

报错原因解法
package not found / 找不到包用了包名但没发布到 registry改用方式 A
找不到 package.json没 cd 进仓库目录cd 进去后 add .
ERR_MODULE_NOT_FOUND目录不完整(比如只拷了部分文件)重新 clone

4.2 --profile web 是什么意思

DSH 可以有多套 profile(配置档)。手机本机引擎用的那套就叫 web。

  • 不加 --profile 会装到默认 profile,手机 App 不会加载它
  • 必须写 --profile web,工具才会出现在你的手机上

如果你的环境只有一个 profile:先用 dsh plugin --help 看默认值是不是 web。是就照写;不是就仍然写 --profile web——因为手机 App 引擎加载的就是 web 这一套,装到别处不会生效。

4.3 装完要重启引擎

安装只改配置,不重载代码。必须重启一次引擎:

路径:App 内 → 设置 → 引擎 → 重启引擎

(命令行方式因版本而异,最稳的是用 App 里的按钮。)

重启后工具列表里会多出 6 个 adb_*。不重启就看不到工具,这一条最容易漏。

4.4 验证装好了

# ① 配置里有没有
python3 -c "
import json
d=json.load(open('$HOME/.dsh/profiles/web/package.json'))
print([b for b in d['dsh']['profile']['bundles'] if 'adb' in b])"
# 期望输出:['dsh-go-plugin-adb']

# ② 引擎有没有加载成功(没有 apply failed 就是好的)
grep -i "apply failed" ~/.dsh/dsh-app/diagnostics.md 2>/dev/null | grep adb || echo "没有加载错误 ✅"

两项都对、并且重启过引擎,工具才会出现。

4.5 最后一关:真的调一次工具(这才叫装好了)

前面几步都只证明"配置对了",证明不了"工具能用"。 必须真调一次:

在 DSH Go 的对话里直接说:

用 adb_devices 看看现在连着哪些设备

Agent 会调用 adb_devices,期望返回:

127.0.0.1:5555  device

看到这行才算真的装好了。 如果 Agent 说"没有这个工具",回到 4.3 确认重启过引擎;如果返回 连不上,已试过端口,回到第五节重新配对。

工具怎么触发? 这些工具是给 Agent 用的,不是给人敲的。你正常说话,Agent 自己决定调用哪个。你也可以直接点名:"用 adb_shell 执行 getprop ro.product.model"。

工具列表在哪看? 重启引擎后,DSH Go 的对话里 Agent 就能调用了。部分版本的界面上能看到可用工具清单,具体位置因版本而异——但只要能调成功,就不需要去界面上找。


五、一次性配对(只有第一次要)

这是 adb 的标准流程,不是插件特有的:

顺序很重要,跳步会报 no devices/emulators found。

# 1. 手机:开发者选项 → 无线调试 → 使用配对码配对设备
#    屏幕会显示两个东西:
#      - 配对用的 IP:端口(如 192.168.1.100:37123)
#      - 6 位配对码
#    另外「无线调试」主页面还有一个「IP 地址和端口」(如 192.168.1.100:41000),
#    这个和配对端口**不是同一个**,两个都要记下来。

# 2. 配对(用配对端口)
adb pair 192.168.1.100:37123
# 提示 Enter pairing code: 时输入 6 位码
# 成功会显示 Successfully paired to ...

# 3. 连上无线调试端口(这个端口每次开无线调试都会变,看手机上显示的)
adb connect 192.168.1.100:41000
# 成功显示 connected to 192.168.1.100:41000

# 4. 验证拿到 shell
adb -s 192.168.1.100:41000 shell id
# uid=2000(shell) ...

# 5. 连回环(插件默认走这条,WiFi 断了也不影响)
adb connect 127.0.0.1:5555
adb -s 127.0.0.1:5555 shell id

⚠️ 不要用 adb tcpip 5555 去"固定端口"

早期文档教过这一步,现在明确不要做。实测证明:

执行 adb tcpip 5555 之前:adbd=20723、shizuku_server=23040、GKD 用户服务=23080
执行之后(8 秒):        adbd=20469(重启了)、shizuku_server 没了、GKD 用户服务没了
TLS 端口从 44197 变成 33271

原因:adb tcpip 会重启 adbd,而 adbd 是多个客户端共享的资源——Shizuku 在 adb 模式下本身就是 adbd 的一个客户端(走无线调试 TLS 端口,用自己的密钥上线)。重启 adbd 等于把别人踢下线。

对照组:adb kill-server + start-server 不会动 adbd,Shizuku 三个进程的 PID 全部原样。

所以插件自己也不做这件事:ensure() 里永远不调 tcpip,只"搭车"——用当前可用的连接,或者扫回环端口找出 adbd 现在挂在哪个端口上。

手机重启后怎么恢复

adb tcpip 的设置不是持久的,重启就丢。但不需要再执行它:

  1. 手机 → 开发者选项 → 确认「无线调试」开着
  2. 插件会自己扫端口找回连接(扫 127.0.0.1:30000-50000,约 6 秒)
  3. 扫不到的话,读出无线调试页面上「IP 地址和端口」那个号,adb connect <IP>:<端口>

常见失败对照

报错原因解法
failed to authenticate密钥不匹配手机上撤销 USB 调试授权,重新配对
connection refused(多个端口)手机重启过,无线调试被关了重开无线调试,让插件扫端口
no devices/emulators found没有已连接设备先用手机上的 IP:端口 连一次

配对成功后密钥存在 ~/.android/adbkey,以后不用再配对,包括重装 adb 之后。


六、六个工具

adb_devices

列出当前连接的设备。无参数。

adb_devices
→ 127.0.0.1:5555  device

adb_shell

执行 shell 命令。最常用的一个。没有拦截、没有白名单、没有二次确认。

参数类型必填说明
commandstring✅要执行的命令,可含管道、重定向、&&、$()
timeoutMsinteger超时毫秒,1000–600000,默认 60000
adb_shell { command: "getprop ro.build.version.release" }   → 16
adb_shell { command: "pm list packages | grep tencent" }
adb_shell { command: "dumpsys battery | grep -E 'level|status'" }
adb_shell { command: "echo 中文也可以" }

实际边界:

边界说明
超时默认 60 秒,最长 600 秒
输出上限32MB,超出返回失败但前 32MB 仍在
编码按 UTF-8 解码,二进制内容(直接 cat 图片)会损坏
stdin不支持,交互式命令(top、vi)用不了
退出码非 0不算工具失败,输出照常返回,附带退出码说明

安全提示见第九点五节——它能卸包、删盘、重启、改设置,没有任何确认。

adb_install

安装 APK。

参数类型必填说明
pathstring✅设备上的绝对路径,如 /sdcard/app.apk
reinstallboolean加 -r 保留数据,默认 true
downgradeboolean加 -d 允许降级,默认 false
adb_install { path: "/sdcard/Download/app.apk" }
→ { text: "安装成功:<路径>" }  或失败原因(如 INSTALL_FAILED_UPDATE_INCOMPATIBLE)

path 用哪种路径:用设备上的路径(/sdcard/...),不是 proot 里的路径。proot 的 /root/xxx 设备看不到,要先 push 过去。

reinstall: false 且已装同包:会安装失败(包已存在)。这种场景一般用默认的 reinstall: true 覆盖。

签名不一致:失败。要么先用 pm uninstall 卸载旧的(数据会丢),要么用同一密钥重新签名。

adb_logcat

读日志尾部,不会留长驻进程。

参数类型说明
linesinteger取多少行,默认 200,最大 20000
filterstring过滤规则,支持正则(走 grep -E)。简单单词也是合法的正则
// 单关键词
adb_logcat { filter: "FATAL", lines: 100 }
// 正则:多个关键词或起来
adb_logcat { filter: "AndroidRuntime|FATAL|ANR", lines: 200 }

返回值是纯文本尾部。匹配不到时返回 (最近 N 行里没有匹配 "X" 的内容),这是正常结果不是错误。

adb_screencap

截图并保存。两个参数都是可选的,adb_screencap {} 也合法(会用默认路径截主屏)。

参数类型必填说明
outPathstring设备侧路径,默认 /sdcard/dsh-screencap.png
localPathstring同时拉回到 proot 的本地路径,如 /tmp/shot.png
// 截主屏到默认位置
adb_screencap {}

// 截到指定位置,并拉回 proot
adb_screencap { outPath: "/sdcard/a.png", localPath: "/tmp/a.png" }
→ { text: "已保存:/sdcard/a.png(拉回 /tmp/a.png)" }

注意:截的是主屏。要截虚拟屏上的内容,那是 dsh-go-plugin-screen 的事,不是这个插件。

adb_reconnect

强制重建连接:杀本地 adb server、重启、把无线调试端口迁移到 5555、验证 uid 2000。无参数。

手机重启后、或者 adb_devices 显示 offline 时用。


七、能做什么、不能做什么

能做(都是实测过的):

pm list packages / pm path / pm install / pm uninstall
am start / am force-stop / am broadcast
logcat / dumpsys / getprop / settings
screencap / input / cmd window / cmd notification

⚠️ cmd package 的 uninstall / clear 会卸包清数据,其余子命令(list packages 等)只是查询。都不需要确认。

关于 pull / push:这六个工具里没有专门的 pull/push 工具。要传文件用 adb_shell 执行设备侧的 cp、mkdir 等;从 proot 往设备传文件,用插件外的 adb push(也就是在 proot 命令行里直接敲,不走插件工具)。这是文档早期版本的一个错误表述,已更正。

不能做:

限制原因
读 /data/data、/data/appSELinux 拦着,uid 2000 进不去
run-as 别的 App只对 debuggable 的包有效
需要 root 的命令没有 root
跨用户访问只能操作当前用户

八、稳定性与兼容性

完整的测试报告在 STABILITY.md,摘要:

稳定性 10/10,逐条解释(ensure 是插件内部的"确保连接可用"动作,不是工具名):

测试含义
连续 ensure ×30反复请求连接 30 次,平均 33ms,最慢 56ms
连续 shell ×30连续执行 30 条命令,全部成功
kill-server ×5 自愈手动杀掉 adb server 5 次,插件都能重新拉起来
disconnect ×3 自愈手动断开连接 3 次,都能自动重连
状态文件损坏能回落state.json 写坏了不影响使用,会退回默认端口
错端口能回落状态文件里记的端口不通时,自动试 5555
并发 ensure ×3三个请求同时要连接,不会互相踩
超时不挂死命令卡住会返回错误,不会让整个插件吊死
adb 缺失时不退进程没装 adb 时返回可读错误,不会把引擎进程带崩
状态文件不可写不崩磁盘只读时仍然能工作

兼容性:

已验证未验证
Android 16Android 11–15、Android 10 及更早
adb 34.0.4adb 1.0.39 以下
nubia NX809J三星、小米、Pixel 等其他厂商 adbd
Linux prootWindows / macOS 主机

端口自动协商:插件按这个顺序尝试 state.port(上次成功的端口)→ 5555 → 6555 → 7555 → 8555 → 9555。

候选里没有 5556、5557 这些紧邻的端口,是因为 5554–5585 是 Android 模拟器的固定占用段(这台设备上就有一个 emulator-5554),继续往上加会撞。所以第二个候选直接跳到 6555。这些端口由 adbd 在 adb tcpip <port> 时监听(但插件不会自动执行,见第五节)。

端口记在哪:~/.dsh/plugin-adb/state.json,内容形如:

{ "port": 5555, "lastOkAt": 1793871234567 }

想知道当前用的哪个端口,直接读这个文件:

cat ~/.dsh/plugin-adb/state.json

九、返回值契约(实测结果,不是承诺)

所有工具都返回 { text: string },不抛异常。下面是实测的返回值,不是设计意图。

adb_shell

情况实际返回 text
正常有输出命令的 stdout
成功无输出(无输出)
超时命令超时(2000ms 内没结束)。要更长时间就调大 timeoutMs。 + 命令原文
退出码非 0命令失败(退出码 1) + 命令原文(如果 stderr 有内容,会附在 [stderr] 行后)
命令失败输出 + 退出码说明
连接失败连不上,已试过端口:... + 三步配对指引

怎么判断成功:text 里含 命令超时 / 命令失败 / 连不上 就是失败。

adb_devices

返回形如:

adb devices:
127.0.0.1:5555	device

回环目标 127.0.0.1:5555: 已就绪(NX809J)
记住的端口: 5555 · 上次成功: 1793888292386 · 重连次数: 0

没设备时:第一段是 (没有任何设备),后面仍会给出端口状态。

adb_logcat

情况实际返回
有匹配匹配到的日志行
无匹配(最近 20 行里没有匹配 "XXX" 的内容)——这是正常结果,不是错误
filter 含非法字符filter 含不支持的字符:... + 允许的字符集说明

filter 走 grep -E,支持正则:"AndroidRuntime|FATAL|ANR"、"zygote|init" 都可以。

adb_install

情况实际返回
成功安装成功:<设备路径>
失败Failure [INSTALL_FAILED_xxx: 原因]

常见失败码:INSTALL_FAILED_UPDATE_INCOMPATIBLE(签名不一致)、INSTALL_FAILED_VERSION_DOWNGRADE(需 downgrade: true)、INSTALL_FAILED_INSUFFICIENT_STORAGE(空间不足)。

adb_screencap

成功返回两行:

截图已保存:/sdcard/dsh-ct.png
-rw-rw---- 1 u0_a490 media_rw 1575442 2026-11-05 22:18 /sdcard/dsh-ct.png

带 localPath 时多一行 已拉到本地:/tmp/xxx.png。失败返回 截图失败:<原因>。

adb_reconnect

返回重建过程与结果,成功包含 uid 2000 的验证行。


九点五、权限与风险(重要,请先读这段)

这个插件不拦截任何命令。 它的定位就是给手机提权——尽可能多地提供能力,而不是当沙箱。

adb_shell 能执行设备上 uid 2000 能执行的一切:

pm install / pm uninstall / pm clear         装包、卸包、清数据
am start / am force-stop / am broadcast      起应用、杀应用
input tap / input text / input swipe         模拟点击和输入
settings put / settings get                  改系统设置
rm / mv / cp / chmod                         读写文件
screencap / screenrecord                     截图、录屏
dumpsys / logcat / getprop                   读系统状态
sh / su / busybox / 各种 shell 语法          执行任意脚本

没有二次确认,没有白名单,没有危险命令拦截。

所以这些事它真的能做成

  • pm uninstall <包名> 把应用卸了,数据一起没
  • rm -rf /sdcard 把内部存储清空
  • reboot 重启手机,正在做的事全断
  • settings put 改错设置可能让系统行为异常
  • input 在你没注意的时候点了什么东西

用之前请知道

  1. 备份重要数据。这个工具没有撤销。
  2. AI 也会误读指令。说"清理一下缓存"和"删除下载目录"是两件事,它可能理解成后者。
  3. 卸载任何应用前,先用 aapt 读 APK 的真实中文名——包名不可信。踩过事故:com.xiaoji.egggame.redmagic 看着像游戏,实际是红魔跑 PC 游戏的「盖世游戏」组件,卸了用户的核心功能就没了。
  4. 不要把它交给不可信的模型或第三方。拿到这个工具等于拿到你手机的一大半控制权。

做不到的事(不是权限问题,是系统限制)

限制原因
读 /data/data、/data/appSELinux 挡着 uid 2000
run-as 非 debuggable 应用系统限制
真正需要 root 的操作没有 root

十、卸载与回滚

出问题想退回原状,两步:

# 1. 从 profile 移除
dsh plugin --profile web remove dsh-go-plugin-adb

# 2. 重启引擎(App:设置 → 引擎 → 重启)

验证已移除:

python3 -c "
import json
d=json.load(open('$HOME/.dsh/profiles/web/package.json'))
print([b for b in d['dsh']['profile']['bundles'] if 'adb' in b])"
# 期望输出:[]

注意:卸载插件不会撤销已经做的系统改动。比如之前 adb tcpip 5555 开的端口还在,要收回执行:

adb usb          # 切回 USB 模式(如果连着线)
# 或者手机里关掉无线调试

想完全清理:卸载后删掉状态文件 ~/.dsh/plugin-adb/state.json,里面只存端口和上次成功时间。


十一、排错

装完工具没出现

# 1. 检查 bundles 列表
python3 -c "
import json;d=json.load(open('$HOME/.dsh/profiles/web/package.json'))
print(d['dsh']['profile']['bundles'])" | grep adb

# 2. 检查引擎日志里的 apply failed
grep -i "apply failed" ~/.dsh/dsh-app/diagnostics.md | grep adb

# 3. 重启引擎

device not found — 按顺序试,别跳步:

# 1. 先直连
adb connect 127.0.0.1:5555
adb devices

# 2. 还不行 → 读插件记的端口,换那个再试
cat ~/.dsh/plugin-adb/state.json
adb connect 127.0.0.1:<state.json 里的 port>

# 3. 还是不行 → 多半手机重启过,adbd 换端口了。
#    手机:开发者选项 → 确认「无线调试」开着
#    a) 插件会自己扫端口找回(127.0.0.1:30000-50000,约 6 秒)
#    b) 扫不到就读无线调试页面上的「IP 地址和端口」,直接连:
#       adb connect <那个 IP:端口>
#    注意:不要用 adb tcpip 去「固定端口」——它会重启 adbd,
#    把 Shizuku 等其它客户端踢下线(已实测)。

为什么 adb_reconnect 救不了重启后的场景:它内部也是"先有连接才能迁移端口"。手机重启后必须走上上面第 3 条的人工链。adb_reconnect 只适合"连接还在但不稳定"(forward 残留、socket 卡住)。

unauthorized

密钥丢了。重新走一遍第五节的配对流程。

adb: command not found

apt-get update && apt-get install -y android-tools-adb

十二、原理

Agent (proot Ubuntu)
   ↓ adb -s 127.0.0.1:5555 shell ...
adb client (uid 2000)
   ↓ 回环 TCP 127.0.0.1:5555
adbd (手机系统)
   ↓
Android 系统服务(pm / am / dumpsys / input / screencap ...)

没有使用任何私有接口,全部走标准 adb 协议。所以 adb 能做的事它都能做,adb 做不了的它也做不了。


十三、许可

MIT。见 LICENSE。

Versions

Latest versionPublishedSize
2026.1105.1908——

Comments

Loading…

Similar plugins

dsh-plugin-android-use

by HuanLinOTO

让模型通过 adb 操作安卓手机的 DSH 插件(截图、UI 树、点击、滑动、输入文本、按键、打开应用) | DSH plugin exposing adb-based tools that let the model operate an Android phone (screenshot, UI dump, tap, swipe, input text, press keys, open ap

Manifest valid

★ 4

↓ 266/wk

TypeScript

Oct 18, 2026

dsh plugin --profile web add @huanlin/dsh-plugin-android-use

by Void-LifeStream

DeepSeek Harness plugin: treat a real Android phone as a device the agent can inspect and tidy up over adb. No root required.

Tools & CapabilitiesManifest valid

★ 0

MIT

JavaScript

Oct 16, 2026

dsh plugin --profile web add dsh-phone

by Void-LifeStream

DeepSeek Harness plugin: treat a real Android phone as a device the agent can inspect and tidy up over adb — free up storage, find what is eating the disk, clear caches, uninstall, screenshot. No root

Tools & CapabilitiesManifest valid

★ 0

MIT

JavaScript

Oct 21, 2026

dsh plugin --profile web add dsh-phone-butler

by ZSeven-W

DeepSeek Harness plugin for Android — build, run, and interact with a live emulator or USB device stream inside a conversation, driven entirely through adb.

Tools & CapabilitiesManifest valid

★ 348

↓ 882/wk

MIT

TypeScript

Nov 10, 2026

dsh plugin --profile web add @zseven-w/dsh-android

by kunjinkao-os

Android Mobile GUI Agent plugin for DeepSeek Harness with ADB control, iterative verification, approvals, and a Web mobile view

UI & ExperienceManifest valid

★ 12

MIT

JavaScript

Aug 20, 2026

dsh plugin --profile web add dsh-mobile-gui-agent

by guzhou079-arch

DeepSeek Harness plugin — let an agent drive an Android phone on a virtual display, so your own screen stays untouched. · 让 AI 在安卓手机的「虚拟屏」上干活,手机照常用。

Tools & CapabilitiesDevelopment & InfrastructureManifest valid

★ 0

LGPL-3.0

JavaScript

Oct 17, 2026

dsh plugin --profile web add dsh-plugin-android-vscreen