Skip to main content
Glama

dsh-lan-relay

让不同机器上的 DeepSeek Harness Agent 直接对话。 一个标准 DSH 插件:一台机器在 DSH 进程内当 hub,其余机器粘贴加入码即可加入; 消息离线补投、长轮询等回复、收到消息自动唤醒目标会话。

MIT · DSH ≥ 0.2.1-rc.2 · Windows / macOS / Linux


1. 特性

  • 一个包、一次安装:标准 DSH bundle(Host 半 + Web 半),在「插件 → 添加插件」里输入包名即可装好。

  • 零外部依赖:只用 Node 内置模块,不拉第三方包,不依赖 DSH 内部 API 的私有实现。

  • 进程内 hub:服务端不需要额外进程、不需要开机自启项;hub 跟着 DSH 启动和退出。

  • 加入码配对:服务端一键生成一行 dshrelay1.…,内含地址 + token;对端粘贴即可,不用抄 IP。

  • 离线队列 + 长轮询:消息落盘,接收方下次在线时补投;lan_relay_wait 最多等 50 秒。

  • 自动唤醒:消息到达后投递到指定会话并让 Agent 跑一轮;目标会话没打开也能冷启动。

  • 全图形化配置:设置 → 局域网中继:角色、端口、token、加入码、在线 peer、连接测试、防火墙放行。

  • 原生 Agent 工具:7 个 lan_relay_* 工具,装好即可调用,无需额外配置。

  • 对话式配置:不想点界面时,让 Agent 调 lan_relay_configure 就能切角色/加入。


Related MCP server: AgentMBX

2. 快速开始

前置:两台机器都装了 DSH(≥ 0.2.1-rc.2),在同一局域网、能互相 ping 通。 更详细的分步说明(含换 token / 换端口 / 换机器)见 docs/TWO-MACHINE-SETUP.md。

第一步:两台机器都安装插件

图形界面:侧边栏 → 插件 → 添加插件 → 输入 dsh-lan-relay → 安装。

或命令行:

dsh plugin --profile desktop add dsh-lan-relay

第二步:服务端机器

  1. 打开 设置 → 局域网中继。

  2. 运行角色 选 服务端 → 保存。

  3. 页面会显示:Hub 状态:运行中、端口 8787、Token、加入码(dshrelay1.…)、本机地址。

  4. 防火墙开着的话,点 一键放行防火墙 → 在 UAC 里点「是」。

  5. 点加入码旁边的 复制,把这一行发给另一台机器。

第三步:客户端机器

  1. 设置 → 局域网中继 → 运行角色 选 客户端。

  2. 把加入码粘贴到 加入码 输入框(会显示识别预览)。

  3. 保存。顶部显示 客户端已连接,在线 peer 里出现两台机器。

第四步:验证

在任意一台机器的会话里说:

用 lan_relay_peers 看下在线机器,然后给 pc1 发消息:"ping from pc2",并等 30 秒看回复。

对端 Agent 会自动被唤醒并回复。


3. 工作原理

             机器 A(服务端)                                机器 B(客户端)
┌────────────────────────────────────────┐    ┌────────────────────────────────────────┐
│ DSH 进程                                │    │ DSH 进程                                │
│  ┌─ Host 半 ─────────────────────────┐  │    │  ┌─ Host 半 ─────────────────────────┐  │
│  │ 内嵌 hub  0.0.0.0:8787             │  │    │  │ 中继客户端(HTTP 长轮询)          │  │
│  │ 中继客户端 127.0.0.1:8787          │◄─┼────┼──┤ 7 个 Agent 工具                    │  │
│  │ 7 个工具 + 自动唤醒                 │  │    │  │ 7 个工具 + 自动唤醒                 │  │
│  └───────────────────────────────────┘  │    │  └───────────────────────────────────┘  │
│  ┌─ Web 半 ──────────────────────────┐  │    │  ┌─ Web 半 ──────────────────────────┐  │
│  │ 设置 → 局域网中继                  │  │    │  │ 设置 → 局域网中继                  │  │
│  └───────────────────────────────────┘  │    │  └───────────────────────────────────┘  │
└────────────────────────────────────────┘    └────────────────────────────────────────┘
                    └───────────── 明文 HTTP + x-relay-token(仅局域网)──────────────┘
  • Host 半(index.js):读配置 → 按角色启停内嵌 hub → 注册工具 → 后台长轮询并唤醒会话 → 给设置页提供同源管理 API。

  • Web 半(client.js):只渲染设置页;所有读写都走 Host 半的 /lan-relay/api/*(仅回环地址可访问)。

  • 配置:~/.dsh/lan-relay/config.json;消息落盘:~/.dsh/lan-relay/hub/messages.jsonl(最多 5000 条 / 8MB 轮转)。

  • 协议:/api/health、/api/peers、/api/inbox、/api/wait、/api/send,全部要 x-relay-token(定长比较)。


4. 设置页:局域网中继

区块

内容

顶部

运行状态徽标(服务端运行中 / 客户端已连接 / 未启用 / 异常)、刷新

运行角色

服务端(本机起 hub)/ 客户端(连别人的 hub)/ 关闭

服务端

端口、本机名称、Token(显示/复制/重新生成)、加入码(复制)、本机地址、Hub 状态/消息数/最新序号/数据目录、一键放行防火墙

客户端

加入码粘贴(自动解析)、或手填地址 + token、连接测试、在线 peer 列表、自动唤醒统计

底部

保存(只在点保存时写入)、每 3 秒自动刷新状态

所有改动都是本地草稿,只有点「保存」才生效;保存后 hub/轮询会按新配置立即重启,不需要重启 DSH。


5. Agent 工具

工具

说明

lan_relay_send

给另一台机器发消息:to(peer 名或 "*")、text、可选 to_session、thread

lan_relay_inbox

拉取新消息(推进游标;from_seq=0 可重读历史)

lan_relay_wait

长轮询等消息(≤50 秒;超时返回空数组,不报错)

lan_relay_peers

谁在线(120 秒内有请求即在线)+ hub 是否可达

lan_relay_sessions

本机活跃会话列表(用于回复时指定对方 to_session)

lan_relay_status

总览:角色、hub、连通性、peer、唤醒统计;排障先调它

lan_relay_configure

对话式配置:role、join_code、relay_url、token、self、port、regenerate_token


6. 投递与自动唤醒规则

  1. 消息带 to_session 且该会话在线 → 精确投递并唤醒。

  2. 目标会话不在线 → push.cold_session=prompt(默认)用 sessionController.prompt() 自动 resume 并投递。

  3. 没带 to_session → 投给 push.default_session,留空则投最近活跃会话。

  4. push.wake=false → 只注入背景,不主动跑一轮。

  5. 冷启动失败 → 记日志;只有 push.offline_fallback=true 才改投其它在线会话。

  6. 插件与手动 lan_relay_inbox / lan_relay_wait 使用独立游标,不会互相抢消息。

成本提示:一次投递 = 自动跑一轮模型调用。不需要自动唤醒时把 push.enabled 设为 false,改用工具手动拉取。


7. 加入码与安全

  • 加入码 = dshrelay1. + base64url({u: 地址, t: token, n: 机器名}),不加密,等同明文 token。

  • 服务端「重新生成 token」后旧加入码失效,需要把新加入码发给所有客户端。

  • 明文 HTTP 只适合可信局域网;不要把 8787 暴露到公网。跨不可信网络请用 Tailscale / WireGuard 等隧道,再把地址填进加入码。

  • 管理 API 只接受回环地址请求;消息正文会明文落盘,不要把密钥当消息发。


8. 防火墙与网络

  • hub 监听 0.0.0.0:8787,端口可在设置页修改(改完重新生成加入码)。

  • Windows 防火墙开启时,服务端需要放行入站 TCP 8787(一次即可):

    • 设置页 一键放行防火墙(UAC 授权;规则限定 Private + 本地子网);

    • 或管理员 PowerShell:

      New-NetFirewallRule -DisplayName "DSH LAN Relay 8787" -Direction Inbound -Protocol TCP -LocalPort 8787 -Action Allow -Profile Private -RemoteAddress LocalSubnet
    • 精简版 Windows 没有 NetSecurity 模块时,脚本会自动退回 netsh advfirewall firewall add rule ...。

  • 两台机器需在同一子网;跨网段把 LocalSubnet 换成对方网段。

  • 多网卡时加入码默认用第一个局域网 IPv4;连不上就在「本机地址」里换一个,手动填到对端。


9. 配置参考

一般不用手改(设置页会写)。排查或脚本化时可编辑 ~/.dsh/lan-relay/config.json:

字段

默认

说明

role

自动推断

server / client / off

self

主机名

本机 peer 名(小写字母/数字/._-,≤32)

relay_url

—

客户端要连的 hub 地址;服务端自动写成 http://127.0.0.1:<port>

token

服务端生成

两台机器必须一致

hub.host / hub.port

0.0.0.0 / 8787

服务端监听地址与端口

hub.data_dir

~/.dsh/lan-relay/hub

消息落盘目录

state_dir

~/.dsh/lan-relay/state

游标与调试日志

push.enabled

true

是否后台长轮询并自动唤醒

push.wake

true

false = 只注入背景

push.default_session

""

没指定 to_session 的消息投给哪个会话

push.poll_timeout_seconds

25

每轮长轮询秒数

push.cold_session

prompt

目标会话未打开时自动 resume(drop = 放弃)

push.offline_fallback

false

冷启动失败后是否改投其它会话

push.require_session

false

true 时拒收没有 to_session 的消息


10. 故障排查

现象

处理

设置页「未启用」

选「服务端」或「客户端」并保存

客户端连不上 hub

服务端 DSH 是否在运行;加入码里的 IP 是否正确;防火墙是否放行;点「连接测试」看具体错误

服务端「端口已被占用」

8787 上已有 hub(同一台机器的另一个 DSH 实例)在跑;停掉它或换端口后重新生成加入码

token 不匹配

两台机器 token 不一致;重新复制加入码,或在服务端重新生成 token

消息到了不唤醒

目标会话是否存在/归档;检查 push.wake、push.cold_session;lan_relay_status 看 stats 与 last_error;日志在 ~/.dsh/lan-relay/state/plugin.log

收不到历史消息

同一条消息只投一次;lan_relay_inbox(from_seq=0, mark_read=false) 重读

hub 数据被重建

客户端游标可能超前,会自动归零重拉(返回 cursor_reset: true)

界面入口找不到

自定义侧边栏模式(如 DS Bot)可能替换了设置入口;直接让 Agent 用 lan_relay_configure 配置,或在经典模式下打开设置


11. 开发

npm test   # 9 项 node:test:hub 内核 / 插件集成(含真实 hub + 唤醒投递)/ Web 半结构

路径

作用

index.js

Host 半:角色开关、内嵌 hub、工具、自动唤醒、管理 API

client.js

Web 半:设置 → 局域网中继

lib/hub-server.mjs

可内嵌 hub 内核(createHub(),无进程副作用)

lib/join-code.mjs

加入码编解码

lib/core.mjs

长轮询、按会话投递、冷启动唤醒

lib/relay-client.mjs

HTTP 客户端 + 游标

lib/plugin-config.mjs

配置读写、角色推断、token 生成

cordis.patch.yml

bundle patch(插入 lan-relay 行)

locale/ · icon.svg

插件卡片标题/描述与图标

test/

内核 / 插件集成 / Web 半结构测试

发布:

npm publish --access public   # package.json 的 files 白名单已包含运行所需文件

修改 scripts/*.ps1 时要保留 UTF-8 BOM(PowerShell 5.1 会按 ANSI 读取无 BOM 文件,中文会解析出错)。


12. 限制

  1. hub 在 DSH 进程内:服务端机器的 DSH 关闭后,其他机器发不出新消息(已入队的不丢)。需要 7×24 就让服务端 DSH 常驻。

  2. 同一台机器同一端口只能有一个 hub;多个 DSH 实例都选服务端时,后来的会报端口占用(预期保护)。

  3. 明文 HTTP + 明文 token,只适合可信局域网。

  4. 冷启动唤醒会真的 resume 会话并跑一轮(消耗 token);审批策略为 ask 且 GUI 没打开时,需要审批的操作会 fail-closed。

  5. 消息正文上限 32000 字符;大文件请落盘后发路径,或走临时 HTTP + 校验和。


License

MIT © ready-player-zero

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables agents to connect to an lloom hub and coordinate through private messages, public posts, and semantically routed broadcasts, while also supporting agent discovery, mailbox management, and message reporting.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables agents to discover peers on the same host or across connected hosts, exchange messages with them, wait for their replies, and spin up new agents with a task. Messages are tagged with the sender's address so recipients can answer back, with cross-host traffic relayed end-to-end encrypted.
    738 npm
    MIT