dsh-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-bridgestart a dsh session named api-review to audit src/api.ts"
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-bridge
让 MCP 客户端(Codex、Claude Desktop、Cursor 等任何标准 MCP client)驱动本机 DeepSeek Harness 的 dsh web 会话:创建或接管命名会话、下发任务清单、异步轮询、按轮取回可审计的执行结果。
dsh web 自带一个本机 /api,但没有 MCP 接口;dsh 也不需要在 Codex 里装插件。这个仓库补的就是中间那一层:一个 stdio MCP server,把 /api 翻译成 9 个 agent 好用的工具。
验证环境:@deepseek-ai/dsh@0.2.1-rc.2、Windows 11、Node 24。接口约定与被版本升级打断后的重建步骤见 docs/API-CONTRACT.md。
为什么需要它
把 dsh 当成第二个执行工位而不是自己的子上下文:它不共享你的对话历史,只看到你写给它的那段任务文本;它是异步的,"已接受"不等于"已完成";它改的是它自己工作区里的文件。所以这个桥接把三件事固化成接口:
书面交接:任务必须以清单形式下发(目标 / 边界 / 验收标准 / 交付物)。
可复核的完成判据:只有
state:"completed"算完成,见 docs/ORCHESTRATION.md。边界约束:可选模型集合由配置预先限定,越权请求在下发之前就被拒绝。
Related MCP server: dsh-orchestrator
安装
要求 Node >= 18.14(headers.getSetCookie())。
git clone <this-repo>
cd dsh-bridge
npm install
npm test # 离线契约测试:无需 dsh、无网络、不消耗任何额度接到 MCP 客户端
以 Codex 为例,写入 ~/.codex/config.toml:
[mcp_servers.dsh]
command = 'node'
args = ['/absolute/path/to/dsh-bridge/bridge.mjs']
startup_timeout_sec = 60 # 桥接可能会自己拉起 dsh web,冷启动约 10s
tool_timeout_sec = 45 # 与 dsh_wait 的 maxSeconds 对齐
[mcp_servers.dsh.env]
DSH_PORT = '3080'
DSH_BRIDGE_STATE = '/absolute/path/to/dsh-bridge/.state'Claude Desktop 等设备上同一段配置的 JSON 形式(mcpServers.dsh.command/args/env)即可。
改完 bridge.mjs 要重启客户端:MCP 子进程加载的是启动时的代码,编辑不会热更新。
先让 dsh web 跑起来
桥接需要一次性启动 token,而它只出现在 dsh web 的 stdout,不落进 dsh 自己的任何文件。两种做法:
# A. 人工启动,并把 stdout 落到桥接读得到的位置(生命周期自己掌握)
powershell -File start-dsh-web.ps1
# B. 什么都不做:端口空闲时桥接会自己启动实例,stdout 写到同一个捕获文件DSH_BRIDGE_STATE 目录下的 dsh-web.out 是唯一的 token 来源,.state/ 已在 .gitignore 里。
拓扑上建议只跑一个 dsh web 实例:两个实例并发写同一个 ~/.dsh/storages/workspace.json 的行为未经验证。
一轮标准动作
dsh_models # 需要指定模型时先看它:只列被策略允许的选项
dsh_sessions {cwd} # 该工作区已有哪些会话
dsh_launch {alias, cwd, task} # 新阶段 → 新别名,立即返回句柄
或 dsh_send {alias, task} # 同一阶段追加一轮(复用同一会话)
dsh_wait {alias, maxSeconds: 45} # 反复调用直到落定
dsh_result {alias} # 验收载荷:助手文本 + 产生它的工具调用 + 落盘文件
dsh_status {alias} # 模型、token 用量、上下文压力、待答问题
dsh_cancel {alias} # 取消在跑的一轮
dsh_adopt {alias, sessionId, cwd} # 接管 web UI 里已经开着的会话state 只有四个取值:
值 | 含义 | 该怎么处理 |
| 本轮 | 可以验收,仍建议抽查产物 |
| 本轮以错误结束,真因在 | 原文上报,不要静默换模型重跑 |
| 还在跑 | 继续 |
| 任务已被接受,但本轮没有记录任何 turn | 按"未验证"处理,不能报完成 |
两个反复出现的陷阱已经做进实现里:session/prompt 返回的 accepted:true 只是受理;session/list.running 由 true 变 false 不区分成败。
工具参考
工具 | 参数 | 说明 |
| — | 实时模型目录 ∩ 允许清单,含 default / routableProviders / failures。不发模型请求 |
|
| 建会话(默认落进该路径对应的侧边栏分栏)、pin 模型、下发首轮。 |
|
| 同一会话的下一轮 |
|
| 接管已存在的会话;不能改它所在的分栏 |
|
| 盯到本轮落定或时间窗结束 |
|
| 立即快照,含 token 用量与上下文压力 |
|
| 本轮验收载荷(默认只看本轮) |
|
| 列出桥接拥有的别名;给了 |
|
| 请求取消,返回 |
别名规则:^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$,会话 id 是 dsh-<alias>。cwd 必须是存在的绝对路径;Windows 上桥接会把正斜杠统一成反斜杠,因为 dsh 逐字登记路径,C:/x 与 C:\x 会被当成两个工作区。
模型策略
模型可选集合由配置预先约束,桥接是唯一同时看得见"调用方要什么"和"dsh 允许什么"的位置。
变量 | 默认 | 说明 |
| 空=不限制 | 文法 |
| 空 | 调用方不传 |
| 空 | 与上一行配套的推理强度 |
行为要点:
校验是纯预检:别名、路径、模型、推理强度任何一项不合规,请求在发出任何
/api调用之前就被拒绝 —— 不冷启动 dsh、不建会话、不写账本。缺省值与允许清单冲突时,错误信息会标明冲突来自
DSH_DEFAULT_MODEL/DSH_DEFAULT_EFFORT,而不是让人误以为是调用方写错。模型目录在 dsh 启动后异步加载。桥接在 pin 之前会等目标 provider 出现(这个等待不消耗额度),因此自启动路径不会因为目录尚未加载完成而空耗一轮。
dsh 的目录条目不声明各模型支持哪些推理强度,所以强度合法性只能由 dsh 判定(非法值报
session/model-unavailable)。
其余环境变量
变量 | 默认 | 说明 |
|
|
|
|
| 会话账本、token 捕获、审计日志,以及 dsh 子进程的 cwd( |
| 空 | 指向"已由别处捕获的 dsh web stdout",进入 attach 模式,不再自己启动实例 |
|
| 单次 |
|
| 轮询间隔 |
|
|
|
|
| 等待 provider 进入模型目录的上限 |
|
| 实例启动等待上限 |
|
| 审计日志滚动阈值(保留一份 |
| 空 |
|
| 空 |
|
| 自动探测 | 覆盖 node.exe 与 |
|
| 版本闸门,不一致时预检报警 |
会话账本
DSH_BRIDGE_STATE/sessions.json 记录每个别名的会话 id、工作区、分栏、每轮的 requestId 与基线序号。它是"下发过一次"的可审计记录,也是跨进程共享的:一个客户端会话会拉起很多短生命周期的桥接进程,因此写入走 O_EXCL 锁 + 临时文件 rename,持久化失败会抛出错误而不是静默。
账本按
DSH_BRIDGE_STATE隔离:不同目录的别名互不可见。只存句柄,不存执行结果 —— 审计载荷一律回 dsh 重新读取。
一个别名一个归属:并发写提供原子性,不提供跨进程的合并语义,同一别名不要并行发两轮。
侧边栏分栏
分栏由 workspace 的 sessionIds 成员关系决定,与 cwd 是两套独立机制:用 cwd 建的会话落在 Ungrouped,用 workspaceId 建的会进对应项目分栏且 cwd 不变。workspace/create {path} 是幂等的,因此兼作 path → workspaceId 的解析器,桥接据此自动分栏。
分栏只能在创建时决定:把已存在的会话移进 workspace 会被 dsh 拒绝(the session is not accounted)。dsh_adopt 因此只能接管,不能改组。
运维命令
node launch.mjs resolve # 解析到哪个 node / dsh 入口 / 版本
node launch.mjs check # 预检:不启动进程,验证版本一致与 profile 能否组合
node launch.mjs doctor # 体检:解析 → 组合 → 端口 → token → 鉴权 → modelCatalog,并给出 broken 结论
node launch.mjs start # 已在跑就 attach;没跑就预检后自启并捕获 stdout
node launch.mjs stop # 只停 instance.json 里记录的 pid,不杀不属于自己的进程测试与验证
npm test # 离线:契约 + MCP 子进程,20 个用例,零额度
node tests/live-check.mjs # 对着活实例只读复验,不建会话、不消耗额度
node tools/probe-api.mjs # 重新推导各端点的 args 形状(--mutate 才会建会话)
node tools/probe-acp.mjs # ACP 面是否仍可用(--prompt 才会下发)
node tools/read-session-log.mjs <session.v4.jsonl.zstd> # 多帧 zstd 会话日志解码live-check 有三个显式开启的、有代价的步骤,被跳过的步骤不计入通过:
--adopt:接管DSH_TEST_WS里一个空闲会话。不创建任何东西。--create:两个并发dryRun启动,验证共享账本在并发下的合并。会留下会话,而 API 删不掉它们(session/delete未转发),只能在 dsh 界面归档。--dispatch:真实一轮任务,消耗模型额度,需要DSH_TEST_WS指向一个可随便写的目录。
代码注释里的 MEASURED: 标记表示该行为由实际执行验证过,而不是从文档推断。
.github/workflows/ci.yml 在 Linux 与 Windows、Node 20 与 22 上跑同一套离线用例,所以贡献者本地不需要 dsh 也能验证改动。
安全说明
捕获文件里的启动 token 换来的 cookie 是 owner 权限,dsh 对 owner 不做逐方法鉴权 —— 读到该文件等于读到那台机器上的 dsh。文件权限
600,目录已 gitignore。桥接只访问
127.0.0.1,不外发数据;审计日志记录端点名与 HTTP 状态,不记录 token。/api没有向后兼容承诺,因此每次 dsh 升级后先跑npm test,再看docs/API-CONTRACT.md末节的重建步骤。把外派任务交给另一个 agent 意味着它会在它的工作区里改文件。下发前确认
cwd是可写的沙箱目录,验收时按docs/ORCHESTRATION.md抽查产物。
故障排查
现象 | 原因 | 处理 |
| 端口上那个实例的 stdout 没被捕获到桥接能读的位置(不是 token 过期) | 用 |
| token 属于另一个实例(它被重启过),或端口不对 |
|
| profile patch 里有新版本拒绝的配置键 |
|
| 端口已被占用 | 查占用进程并停掉旧实例 |
| 该 profile 没有这个 provider,或目录尚未加载完 |
|
会话不在预期的侧边栏分栏 | 分栏在创建时决定,接管无法更改 | 用 |
客户端的 MCP 面板看不到工具列表 | 部分客户端不展示 tools | 调一次 |
版本支持策略
launch.mjs(进程与凭据)+ lib/api-contract.mjs(线上格式)是两条唯一路径,bridge.mjs 只做传输与工具。升级 dsh 时最多坏这两处,而 tests/contract.test.mjs 会第一时间变红。
支持的 dsh 版本记录在 launch.mjs 的 DSH_TESTED_VERSION。如果你的版本不同且 /api 应答异常,先跑 docs/API-CONTRACT.md 末节的命令重新推导契约,再决定是否需要改 lib/api-contract.mjs。
贡献方式
改动接口形状时,先让
tests/contract.test.mjs反映实测结果,再改实现。任何新增断言必须来自实际执行;注释里用
MEASURED:标注,并避免写入与某台机器绑定的路径、进程号或账户名。测试用例若拉起子进程,必须在
finally里关闭 —— 否则断言失败会变成挂起,而不是失败。提交前确认
.state/、node_modules/、任何*.out/*.ndjson捕获都没进入暂存区(git status看一眼,git diff --cached再核一遍)。
许可
MIT,见 LICENSE。
This server cannot be deployed
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server exposing the Backtest360 engine API as tools for AI agents.
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
Related MCP Servers
- AlicenseAqualityBmaintenanceAn MCP bridge that exposes DeepSeek Harness (DSH) web UI's cordis RPC API as stdio tools, enabling any MCP client to manage workspaces, create/resume sessions, send messages, and fetch session stats.51MIT
- 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.138MIT
- AlicenseNot gradedqualityCmaintenanceTurns DeepSeek Harness into an MCP server with tools for session management, agent execution, resources, and OAuth, plus browser automation and GitHub/GitLab integration.67 npm20MIT
- AlicenseNot gradedqualityBmaintenanceMCP server bridging ChatGPT to DeepSeek Harness, exposing 13 tools for task submission, status tracking, result retrieval, project/session management, and human-in-the-loop approvals.2MIT