前言¶
DeepSeek Harness(DSH)将每个对话复用到一个 plumb serve 连接上。DSH 的 MCP 客户端不发送身份:没有按对话的会话 ID,也没有按调用的 _meta。Plumb 的隔离层(代理工作区分片、读取跟踪、邮件寻址)依赖于声明的身份,因此未识别的对话可以强制锁定彼此的工作区。通常的缓解措施是在 ~/.dsh/AGENTS.md 中添加指令,但这仅适用于主对话。DSH 子代理在进程内运行,拥有独立的系统提示词且没有父上下文,因此在结构上是匿名的。
dsh-plumb-identity 插件通过为每个 DSH 对话、工作区和子代理提供稳定的 plumb 会话身份来解决这个问题。它在传输层强制执行此身份,而不是依赖指令。
安装与启用¶
此插件依赖运行中的 plumb 守护进程(plumb serve 可作为名为 plumb 的 MCP 服务器访问)。
推荐方式:配置文件包安装¶
插件默认安装即包含 dsh.bundle 补丁,会自动挂载并应用默认配置。需在 web 和 headless 两个 profile 下安装:
dsh plugin --profile web add dsh-plumb-identity
dsh plugin --profile headless add dsh-plumb-identity
安装后需重启 dsh 进程,因为运行中的进程不会重新读取补丁层。
替代方式:手动补丁¶
若未安装 bundle,需手动向 ~/.dsh/cordis.patch.yml 追加补丁行:
- insert:
- id: dsh-plumb-identity
name: dsh-plumb-identity
config:
serverName: plumb
开发调试¶
若指向本地 checkout,需先移除或禁用 bundle 挂载,避免重复 loader entry id:
- insert:
- id: dsh-plumb-identity
name: 'file:///absolute/path/to/dsh-plumb-identity/dsh-plumb-identity.mjs'
config: { serverName: plumb, logEvents: true }
核心功能¶
- 稳定的会话身份:为每个 DSH 对话、工作区和子代理提供稳定的 plumb 会话 ID。
- 传输层强制执行:在 MCP 传输层强制执行身份,而非依赖指令。
- 主动声明:主动发送
session_start请求,并在tools/call中添加_meta标记。 - 失败开放:SDK 缺失或声明被拒时,保持失败开放,不会中断工具调用。
- 配置灵活:支持通过配置项调整行为,或使用 bundle 一键安装。
配置项¶
所有配置均为可选。插件默认使用 plumb 作为 MCP 服务器名称。
| 字段 | 默认值 | 说明 |
|---|---|---|
serverName |
plumb |
需要保护的 MCP 服务器名称(工具调用需匹配 mcp__<serverName>__*) |
idPrefix |
dsh |
生成的 ID 的第一段 |
purpose |
dsh |
对话的 session_start purpose 标签 |
subagentPurpose |
dsh-subagent |
当会话头部显示 parentSession/delegationDepth 时的 purpose 标签 |
detail |
brief |
主动 session_start 的数据包大小 |
excludeEnv |
["PAUTA_RUN_ID"] |
当任一环境变量被设置时,完全排除该环境 |
connectMarker |
plumb |
匹配 stdio 命令以识别 plumb 连接的子串 |
logEvents |
false |
是否在每次调用时输出 stamp/capture 的调试行 |
sdkPath |
DSH profile tree | MCP SDK 的绝对路径(client/index.js),用于非标准安装 |
注意事项¶
- 依赖版本:需要 DSH 0.1.1-rc.2+ 和 plumb 0.17.x。
- 安装冲突:安装 bundle 和手动
insert会产生冲突(重复 loader entry id)。若需切换方式,需先移除另一方式添加的条目。 - 环境排除:将
excludeEnv设置为['PAUTA_RUN_ID']时会完全排除该环境。被排除的环境不会挂载任何插件,其 plumb 调用将没有任何身份,可能导致工作区 pin 冲突。