dsh-plugin-subagent-bridge
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dsh-plugin-subagent-bridgespawn a DSH worker in my repo to fix the failing tests, then wait for its answer"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
dsh-plugin-subagent-bridge
在 DeepSeek Harness 宿主内部提供本机回环 MCP 端点,让另一个智能体(如 Codex)把任务派给 DSH 会话并取回结果。
插件运行在宿主进程内,直接使用公开的 sessionController 服务 —— 不需要读取 ~/.dsh/.credentials.yaml,也不需要伪造 cookie。
创建项目(workspace)
DSH 的侧边栏分组是"项目(workspace)",和会话的工作目录是两回事:新建会话默认落在「未分组」,除非它所在的目录已经是一个项目。
dsh_task / dsh_spawn 的 workspace 参数把这一步也接管了:
// 目录不是项目 → 用它创建项目(标题取目录名),会话直接归到项目下
dsh_task({ prompt: "…", cwd: "/repo/clawer", workspace: true })
// 用指定标题创建
dsh_spawn({ task_name: "w1", message: "…", cwd: "/repo/clawer", workspace: "Clawer" })
// 不传 → 只复用已有项目;目录没有项目就保持未分组(和以前一样)
dsh_task({ prompt: "…", cwd: "/repo/clawer" })行为细节:
目录不存在时先递归创建,再做项目登记(登记要求目录已存在);
目录已经是项目 → 直接复用,不改标题(底层
create对同一路径返回已有记录);返回结果里带上
workspace: { id, title, path },方便确认落在哪个项目;项目操作失败不影响派发本身(分组是外观,不因此让任务失败)。
Related MCP server: subagent-harness-mcp
指定模型
dsh_task、dsh_spawn、dsh_followup 都可以带 model,让 worker 跑在指定模型上:
dsh_task({ prompt: "…", model: "zai-coding-cn/glm-5.3", reasoningEffort: "max" })
dsh_spawn({ task_name: "review", message: "…", model: "opencode-go/deepseek-v4.1-flash" })
dsh_followup({ worker: "review", message: "…", model: "deepseek-account/deepseek-flash" })写法是
provider/model;只写模型名时沿用当前默认 provider(model: "glm-5.3");reasoningEffort可选,取值随模型(low/medium/high/max等);不传
model就完全不动会话,行为和以前一致;实测(Host 侧
sessionController.selectModel):请求头里的 provider/model 确实变成指定的那组,且不会改写 profile 的默认模型。
实现上就是在建好会话、发第一个 prompt 之前调一次 selectModel,所以 worker 的第一轮就已经在新模型上跑。
工具
工具 | 作用 |
| 同步派活:开会话、投递、阻塞到这一轮结束,只返回最终回答(最后一条 assistant 消息) |
| 异步派活:立刻返回 |
| 给已有 worker 再派一轮(复用它的上下文) |
| 关闭 worker,释放并发名额(不删除会话) |
| 列出本桥开的 worker 及其实时状态 |
| 一次等多批 worker: |
| 向指定会话投递一条用户消息并开始一轮;返回 |
| 长轮询读进度:返回该会话在 |
| 列出会话元数据(id、标题、工作目录、是否运行、最后活动时间) |
反向:DSH → Codex
插件同时给本部署的 Agent 注册了一个工具:
工具 | 参数 | 返回 |
|
|
|
它执行 codex exec [resume <id>] --json -o <临时文件>,从事件流取 thread.started、从 -o 文件取最终消息;工具结果里会带 [codex thread <id> · 12s],把那个 id 传给 resume 就能继续同一个 Codex 线程(实测能记住上一轮的回复)。
注意:resume 时 sandbox 与 cwd 不生效 —— codex exec resume 子命令本身不接受 -s / -C,线程沿用它原来的设置。
边界(v0 硬约束):
dsh_list_sessions只返回元数据,不含任何消息内容。dsh_read_result只对本桥派发过的会话生效;从未派发过的会话一律拒绝。
安装
# 本地目录安装
git clone https://github.com/Dogtiti/dsh-plugin-subagent-bridgePlugins → 添加 → 选该目录。
启动后插件在 127.0.0.1:47821 监听,并写入端点文件(权限 0700/0600):
{
"url": "http://127.0.0.1:47821/mcp/<token>",
"port": 47821,
"token": "<token>",
"pid": 12345,
"startedAt": "2026-10-22T12:30:00.000Z"
}路径:~/.dsh/bridge/endpoint.json
接到 Codex
codex mcp add dsh-bridge --url "$(node -p "require(process.env.HOME+'/.dsh/bridge/endpoint.json').url")"验证:
codex mcp list
codex mcp get dsh-bridgeCodex 的桌面 App 与 CLI 共用 ~/.codex/config.toml,所以两端都会看到这条。
token 存在 URL 路径里(能力 URL),因此不需要在 Codex 侧配置环境变量 —— 桌面 App 从 Finder 启动时拿不到自定义环境变量。若你更想用 bearer,也可以
--bearer-token-env-var指向环境变量,插件同时支持Authorization: Bearer <token>。
移除:
codex mcp remove dsh-bridge配置
- insert:
- id: subagent-bridge
name: 'dsh-plugin-subagent-bridge'
config:
port: 47821键 | 默认 | 说明 |
|
| 总开关;关闭后不监听、不写端点文件 |
|
| 回环监听端口;固定端口是为了让 Codex 侧那条 URL 在重启后依然有效 |
|
| 端点与令牌的落盘位置 |
|
| 单次 |
|
|
|
|
| worker 注册表与重基线的落盘位置(0600) |
|
| 跨工具委派层数上限(1 = 只允许一层,和 Codex / DSH 的默认 |
|
| 滚动窗口内允许的派发次数(spawn / task / dispatch / followup / codex_dispatch 合计) |
|
| 上述窗口长度 |
|
| 每个工作目录的 worker 上限( |
|
| 全局兜底上限,防止多个项目一起把机器压满 |
|
| 记录超过这个时间没更新就不再占名额(过期自动释放,无需手动清理) |
|
|
|
|
|
|
|
| Codex 可执行文件;含 |
|
|
|
|
| 单次 |
端口被占用时插件不会静默换端口:端到端文件里会写入 error 字段,并在宿主日志打印 subagent-bridge: could not start on port …。
防环护栏
两个 agent 都接了同一个桥时,存在真实的环路:DSH worker → codex_dispatch → 那次 Codex 运行也能看到 dsh-bridge → 又 dsh_spawn → …。两边各自进程内的深度规则都管不到这条链(Codex 的 agent_max_depth 只数自己的 spawn_agent,DSH 的 maxDepth 只看 delegationDepth,而桥建的 worker 是顶层会话,深度恒为 0)。
所以桥自带两道:
① 深度(maxHops,默认 1)
每次都计算这次派发会产生的深度:
max(当前在飞的链路深度, 调用方深度) + 1;调用方是桥建的 worker 时按其深度 1 起算;
codex_dispatch运行期间会把链路标记为"在飞",嵌套回来的调用继承该深度;超限直接报错,措辞可执行:
codex_dispatch would create delegation depth 2, but maxHops is 1. Carry the work out directly instead of delegating again.
默认 1 的含义:Codex 可以派给 DSH,但 DSH 不能再用桥派回去 —— 与两个产品各自的 maxDepth: 1 语义对齐。
② 速率(dispatchPerMinute,默认 10 / 60s)
拦截广度型失控(一次开很多 worker)和客户端紧循环重试,与提示词无关,是纯兜底:
rate limit: 10 dispatches per 60s reached; retry in 23s名额怎么算
worker 名额按工作目录分桶,调用方不用传任何 owner:
每个
cwd默认 4 个(maxWorkersPerRoot);全局默认 12 个(
maxWorkers),跨项目兜底;完成但没
dsh_close的仍占名额(与 Codex 一致);记录 24 小时没更新就自动不再占名额(
workerTtlMs),不需要手动清理;阻塞式
dsh_task不计入名额,只登记。
为什么不是"每个会话 4 个":MCP 端点是共享的,请求里没有会话或线程身份(Codex 的 CODEX_THREAD_ID 只存在于 shell 环境)。cwd 是唯一由调用方稳定提供、且语义上对应"一个项目"的维度。
跨重启
worker 注册表(task_name / sessionId / 终态结果)和每轮的时间基线都落在 ~/.dsh/bridge/workers.json:
派发、完成、关闭都会更新它;
重启后
dsh_list_workers仍能看到之前的 worker;已经结束的 worker,
dsh_wait直接返回缓存里的最终回答(不必重新打开会话);重启时还在跑的 worker,会话未打开时状态是
offline(结果未知,去 DSH 侧边栏打开那个会话即可查看);dsh_followup会给 worker 开新一轮,同时清掉缓存的旧回答;文件最多保留 200 条,超出时先淘汰最旧的 已关闭 worker。
安全模型
只监听
127.0.0.1,不对外暴露。请求必须携带令牌:路径
/mcp/<token>,或Authorization: Bearer <token>;比较使用定长时间比较。令牌首次启动时生成并持久化(重启后复用),因此能力 URL 稳定。
能力等价于「向指定会话投递消息」:本机任意进程只要能读到端点文件就能派活。文件权限 0600、目录 0700;不要把它复制到共享位置。
DSH 侧的权限策略不受影响:派发进去的消息仍按会话自身的 sandbox / 审批策略执行。
实现
Codex / 任意 MCP 客户端
│ POST /mcp/<token> JSON-RPC(stateless,单次 JSON 响应)
▼
dsh-plugin-subagent-bridge(宿主进程内)
· node:http 监听 127.0.0.1:47821
· initialize / tools/list / tools/call / ping
· sessionController.prompt({sessionId, requestId, mode, content})
· sessions.get(id).snapshotEvents() 读回助手文本协议实现为 streamable HTTP 的无状态子集:每个 POST 返回一段 application/json,不做服务端推送,因此取结果用长轮询——dsh_read_result 在服务端等,客户端一次调用即可拿到答案;客户端断开时服务端立即停止等待。
配套 skill
skills/ 下有两份可直接安装的 skill,把"什么时候该派活、怎么派、怎么收尾"写成模型能读的规则:
Skill | 装给谁 | 作用 |
| Codex | 让 Codex 把任务当 subagent 派给 DSH( |
| DSH | 让 DSH 的 agent 在需要独立视角/复核时派给 Codex( |
# Codex 侧
mkdir -p ~/.codex/skills && cp -R skills/deepseek-worker ~/.codex/skills/
# DSH 侧
mkdir -p ~/.dsh/skills && cp -R skills/delegate-to-codex ~/.dsh/skills/两份都是标准 SKILL.md:YAML frontmatter(name + description)+ 正文。触发靠 description——模型平时只看到名字和描述,判断相关了才读正文,所以描述里写满了中英触发语和"不要用"的边界。改完立刻生效,不用重启:Codex 下一次会话、DSH 下一轮就能看到。
兼容性
DSH
^0.2.1-0(engines.dsh)。MCP 协议版本:
2025-06-18、2025-03-26、2024-11-05(按客户端请求回显,未知版本回落到最新)。依赖宿主公开服务
sessionController(list/prompt)与sessions.get();两者不可用时工具会返回明确错误。
开发
node --test "test/*.test.mjs"58 项:握手与版本协商、通知处理、工具清单、未知方法与未知工具、参数校验、元数据列表不含消息内容、派发调用形状、拒绝与错误透出、结果读取的时间基线、未派发会话的拒绝、长轮询(文本晚到即返回 / 超时 / 调用方取消)、真实 HTTP 往返(含 404/405/202 与 bearer 分支)、codex exec 事件解析、二进制解析、成功/失败/超时三种运行结果、resume 的参数分叉、工具结果的 lossless JSON 约束、只回最终回答(多步叙述被丢弃)、dsh_wait 的任一完成 / 超时 / 错误 / 未派发四种状态、dsh_spawn 立即返回与注册、fork_turns=all 走 fork、并发上限与 dsh_close 释放名额、dsh_followup 的重基线与最终回答切换、注册表落盘与重启后复原、冷会话下的缓存回答与 offline 状态、注册表 200 条上限的淘汰顺序、maxHops 拒绝回派而放行首层、在飞链路阻塞嵌套派发、速率突发的拒绝与窗口过期、followup 计入同一预算、握手版本号取自 package.json(不再硬编码)、新建的 worker 会按 cwd 自动归入对应工作区(不再落到「未分组」)、阻塞式 dsh_task 不占 spawn 名额(重启后也不占)、按 cwd 分桶的每项目预算与全局上限、过期记录到期释放名额、超时返回 running: true 与续等指引、阻塞时长被夹到 240 秒以内。
test/persistence.test.mjs 单独覆盖持久化:文件权限 0600、缺失/损坏/畸形记录、spawn 返回时文件已落盘、完成即缓存、followup 清缓存、close 后重启仍为 closed、冷会话走缓存或 offline、并发写不串。
相关插件
插件 | 说明 |
预测下一条指令并显示为占位文字, | |
输入框中按 | |
dsh-plugin-subagent-bridge(本仓库) | 让 Codex 通过本机 MCP 把 DSH 当 subagent 用(spawn / wait / followup),反向也能把任务派给 Codex |
在模型选择器旁显示供应商套餐额度余量(目前 GLM Coding Plan),点开是明细浮层 | |
在模型名旁显示供应商品牌 logo(24 个厂商,支持前缀匹配) |
许可
MIT © Dogtiti
This server cannot be deployed
Maintenance
Related MCP Connectors
A paid remote MCP for OpenAI Codex agent coordination MCP, built to return verdicts, receipts, usage
Hosted MCP server for task-first delegation to remote workstations and workers.
Enable secure connectivity between Sentry issues and debugging data, and LLM clients, using a Model Context Protocol (MCP) server.
Coordinate and verify OpenCode workers over MCP Streamable HTTP.
Related MCP Servers
- AlicenseAqualityAmaintenanceA local STDIO MCP server that bridges Codex to the official DeepSeek Harness (DSH) Web Host, enabling supervised DSH collaboration through session management, delegation, and monitoring tools.1311MIT
- AlicenseNot gradedqualityAmaintenanceA local MCP server that enables Codex and other MCP clients to orchestrate native external coding-agent harnesses through a normalized lifecycle, with guarded execution and deterministic testing.73 PyPIMIT
- FlicenseAqualityCmaintenanceEnables MCP clients like Codex CLI and Claude Code to delegate tasks to a local DeepSeek Harness (dsh), with native Web transport for visible progress, model selection, and persistent long-running jobs, plus an ACP-compatible transport.6-
- AlicenseNot gradedqualityAmaintenanceExposes a running DeepSeek Harness as an MCP endpoint so any other agent or script can create workspaces and sessions, hand coding tasks to the DSH agent, read and write files, run shell commands, and invoke permitted harness tools under the same sandbox, transcript, and permission policy as the DSH UI.156 npm6MIT