Chuyển đến nội dung chính

harness-relay-mcp

Đã xác minh

harness-relay-mcp · v0.2.17 · MIT

Delegate and monitor DeepSeek Harness work from any MCP agent.

Cài đặt

dsh plugin add harness-relay-mcp

Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.

Mã nguồn

Thẻ

Tác giả

Readme

Harness Relay MCP

English | 简体中文

让外部 Agent 委派并持续监控 DeepSeek Harness 任务。

让任何支持 MCP 的 Agent 向 DeepSeek Harness 委派长时间任务,并持续监控直至完成。

Harness Relay MCP 将 MCP 客户端直接连接到 DeepSeek Harness 原生会话与事件模型。推荐形态是安装为 Harness 树外内部 bundle;它不包装 CLI、不修改 Harness 源码,也不接管 Harness 进程。

MCP Agent
   │
   ├─ start_run ── Provider / 模型 / 推理强度 / preset / 权限
   │
   ├─ status_run / wait_run / steer_run / cancel_run
   │
   └─ 持久结果 + 原生 Harness Web 会话链接

定位:Harness 控制平面,而不是模型包装器

Harness Relay MCP 是独立的第三方项目,并非由 DeepSeek AI 开发、背书或提供支持。

这不是 DeepSeek 模型包装器,而是 DeepSeek Harness 的 MCP 控制平面。

请区分三种完全不同的接入方向:

  • DeepSeek Harness 官方仓库当前记录的是 mcp-client,用途是让 Harness 消费外部 MCP Server;这与把 Harness 暴露为可由 MCP 控制的工作 Agent 方向相反。
  • 简单 DeepSeek MCP Server 直接调用模型 API 并返回模型输出,不会进入 Harness 原生会话、插件、工作区、权限和事件生命周期。
  • Harness Relay MCP 连接现有的官方 Harness Host,把该 Host 的原生能力提供给外部 MCP Agent。

截至 2026-08-20,官方 dsh 启动器源码只提供 profile 启动和插件管理,没有记录可对外控制 Harness 的 dsh mcp Server 命令。DeepSeek Harness 仍处于开发者预览阶段,依赖本对比前应重新核对官方仓库。

对比核验日期:2026-08-20。

能力 当前官方 Harness 简单 DeepSeek MCP Harness Relay MCP
主要方向 Harness 消费 MCP 工具 MCP 客户端调用 DeepSeek 模型 MCP 客户端控制运行中的 Harness Host
原生 Harness 会话和事件 内部原生存在,但没有通过文档化 MCP Server 对外提供 不支持 支持
Harness 插件、工具和沙箱 Harness 内部原生能力 不支持 由 Harness 原生执行
Provider/模型/推理强度/preset Harness UI 和 API 内可用 通常只有少量固定模型参数 从 Host 发现并选择
原生权限 preset Harness 内部行为 没有工作区权限体系 read-only、workspace-write、danger-full-access
长任务生命周期 在 Harness 内操作 通常一次请求返回一次结果 启动、查询、等待、纠偏、回复、取消、重新打开
持久监控和恢复 Harness 保存会话历史 通常没有 Relay 运行标识、幂等、对账和重启恢复
Harness Web 会话链接 原生 UI 没有 返回并可验证
安装与维护 只使用 Harness 时最低 MCP 方案中最简单 组件更多,需要持续适配 Harness

如何选择

  • 只需要分类、提取、总结或快速第二意见,而且模型文本输出已经足够时,使用简单 DeepSeek MCP Server。
  • 任务必须在 DeepSeek Harness 内运行,并需要已登记工作区、工具、插件、Provider 目录、原生权限、持久会话、长任务监控、故障恢复或 Web 查看时,使用 Harness Relay MCP。
  • 不要仅为替代一次普通 Chat Completions 请求而安装 Relay;额外的 Host、状态、认证和 proxy 层不会在这种场景中产生足够的控制面价值。

主要能力

  • 使用 Harness 原生会话和持久事件,不解析 CLI 输出。
  • 完整异步生命周期:启动、查询、等待、纠偏、回复、取消和重新打开。
  • 在首条任务提示词前选择 Provider、模型、推理强度、Agent preset 和原生权限。
  • 直接支持 Harness 的 read-only、workspace-write、danger-full-access 三档权限。
  • 支持有序文本和内联图片提示词,并对 base64 和大小进行有界校验。
  • 持久保存运行标识,MCP Server 重启后可恢复监控。
  • 返回稳定的 Harness Web 会话链接;随附 Skill 会在分享前验证页面确实可见。
  • 兼容 Codex、Claude Code、OpenCode、Cursor 及其他符合标准的 MCP 客户端。
  • 内部 bundle 使用 Harness 0.1.2 的直接 Typert Gateway 和原生权限服务;外部 Agent 通过认证 HTTP 或无状态 stdio proxy 调用。
  • 保留独立 dsh-relay 模式用于旧版 Harness 和显式回滚。

运行要求

  • Node.js ^22.19 或 >=24。
  • 内部模式要求 DeepSeek Harness >=0.1.3-alpha.2 <0.2.0、web profile,并只允许 127.0.0.1 绑定。该最低版本已包含上游 Windows 后台子进程修复,模型调用 rg 等普通命令时不会再弹出短暂控制台窗口。Relay 0.2.6 及更早版本依赖已移除的 rc.7 ApiProxy 接口,无法在此 Harness 版本线加载。
  • 独立兼容模式要求已在本机回环 HTTP 地址运行的 DeepSeek Harness Web Host。
  • 目标工作区必须已在 Harness 中登记,或属于明确配置的允许根目录。

默认 Host 地址:

http://127.0.0.1:3080/

安装

安装为 Harness 内部 bundle(推荐)

使用 Harness 官方 profile 命令从 npm 安装已发布包,检查组合后的配置,再启动该 profile:

dsh plugin --profile web add harness-relay-mcp
dsh --profile web --dump-config
dsh --profile web

离线安装或需要锁定本地文件时,可下载 Release tarball,并将第一条命令中的 harness-relay-mcp 替换为本地 .tgz 路径。

配置输出应包含 id: harness-relay-mcp 和 name: 'harness-relay-mcp'。因此 Harness 插件列表显示为无斜杆的 harness-relay-mcp。如果 dsh web 已在运行,安装或升级后需要重启该 Host 才会加载新 bundle。启动后,bundle 会继续在兼容路径 $DSH_HOME/plugins/dsh-relay/web/relay-endpoint.json 发布不含密钥的端点描述;Bearer token 单独保存在 Host 专属状态目录。

卸载不会取消已提交的 Harness 任务:

dsh plugin --profile web remove harness-relay-mcp

不要把 Relay 再配置进同一 Harness 的 MCP client,否则会形成 Harness → Relay → Harness 递归。

安装 Codex 插件

Codex 插件是外部调用层,不能替代前面的 Harness 内部 bundle。先确认 dsh --profile web 已加载 harness-relay-mcp,再从本仓库 Marketplace 安装 Codex 插件:

codex plugin marketplace add tonytanglab/deepseek-harness-relay-mcp
codex plugin add deepseek-harness-relay@harness-relay
codex plugin list

第一条命令登记本项目的 GitHub Marketplace;第二条命令从 npm 获取同版本插件包,并为 Codex 加载 .mcp.json 与 delegate-to-deepseek-harness Skill。Codex 侧只启动无业务状态的 dist/dsh-relay-proxy.mjs,它通过端点描述连接已经运行的 Harness 内部 bundle;这个流程不会修改 DeepSeek Harness 源码、web profile 的内部 bundle 配置或 cordis.patch.yml。

若更新后原生工具消失,且 Codex 报 connection closed: initialize response,先检查任务引用的缓存目录是否仍包含 dist/dsh-relay-proxy.mjs。新缓存目录存在不代表运行中的宿主已切换。使用桌面应用对应的 Codex CLI 从已确认的 Marketplace 重装;如果新任务仍引用已移除的缓存,保存进行中的工作后重启应用。必须验证原生 doctor 和工具目录后再宣称恢复,不得改用临时 Relay 客户端。

如果 personal Marketplace 指向本地源码目录,Codex 安装器只复制现有文件,不会运行 TypeScript/esbuild 构建。每次拉取源码后必须先在该目录执行 pnpm run prepare:codex-local;命令会构建并校验三套 dist 产物的内嵌版本及 proxy 的完整工具目录,然后才能生成 cachebuster 并执行 codex plugin add。否则可能出现 manifest 和安装记录显示新版、实际 MCP 进程仍运行旧 bundle 的假升级。正式使用优先采用上面的仓库 Marketplace/npm 安装路径。

Codex 内置 MCP 的生成规范(不要写错入口)

Windows 偶发控制台弹窗还需检查 Harness 本体:启用原生 Job 子进程管理时,Node runner 必须设置 windowsHide: true,原生 CreateProcessW/CreateProcessAsUserW 目标必须使用 CREATE_NO_WINDOW。仅更新 Relay 或修复 Harness 的普通 spawn 回退入口不足以覆盖这条路径;更新 Harness 后须重启实际 Host,并验证控制台可见性及输出、退出和清理行为。

Codex 插件 manifest 必须同时引用 Skill 和包内 MCP 声明:

{
  "skills": "./skills/",
  "mcpServers": "./.mcp.json"
}

随插件发布的 .mcp.json 必须使用下面的相对入口:

{
  "mcpServers": {
    "harness-relay-mcp": {
      "command": "node",
      "args": ["./dist/dsh-relay-proxy.mjs"],
      "cwd": "."
    }
  }
}

cwd: "." 由 Codex 解析到当前已安装插件的版本根目录。不要写开发机绝对路径或 %USERPROFILE%\.codex\plugins\cache\... 版本缓存路径;不要在 Codex 用户 config.toml 再注册第二份同名 MCP。最重要的是,Codex 只能启动 dsh-relay-proxy.mjs:不能指向 dsh-relay-harness.mjs(Harness 内部 bundle),不能指向会另建独立控制面的 dsh-relay.mjs,也不能由 Agent 手工启动第二个 Harness Web。proxy 通过 $DSH_HOME/plugins/dsh-relay/web/relay-endpoint.json 发现 authority;从 0.2.8 起,只有旧 owner 可证明已死亡且回环端口确认空闲时,proxy 才会复用上一任 embedded Host 发布的精确启动契约安全拉起 Harness。端口已占用或无法探测时仍安全失败。客户端配置不保存 bearer token。

安装后新建 Codex 任务,正确调用链是:

doctor → list_workspaces → list_capabilities
  → start_review(分析/审核,只读)或 start_run(明确要求实施时使用 workspace-write)
  → wait_run(循环到终态)→ 读取 assistantText → 主进程复核

上述操作只能直接调用已安装插件暴露的原生 MCP 工具;严禁生成临时 .tmp/harness-*-call.mjs,也不得通过 node、PowerShell、Python 或其它 shell 调用、轮询 Relay,否则会绕过托管后台传输,并可能在 Windows 弹出可见控制台。若原生工具不可用,应修复或重装插件并新建 Codex 任务,不能回退到 shell 客户端。

用户明确指定 Harness/模型审核当前或命名的已注册工作区,即授权 Harness 在该范围内自行读取。主任务只通过内置 MCP 传递工作区、文件/目录位置、审查或实施范围、验收条件以及路由/权限元数据;Harness 必须在已授权工作区内自行读取。无论使用 read-only 还是 workspace-write,都禁止把源码正文、diff、文件转储、源码编码或仓库归档嵌入 task、文本 content、steer_run 或 reply_run 参数,也不应误报为“Codex 上传源码”。写权限只改变 Harness 可执行的操作,不改变源码传递边界。这项授权不包含凭据、秘密或无关路径。只有用户明确要求 Harness 修改、修复、实现或重构时,才调用 start_run 并选择 permissionPreset: "workspace-write";单纯“调用 Harness”仍默认 start_review。

安装后重启 Codex,并新建一个 Codex 任务,让新任务加载 MCP Server 和 Skill。可在新任务中要求:

调用 Harness Relay 的 doctor 和 list_workspaces,只做只读检查,确认 Harness Host、Relay 端点和工作区是否可用。

升级仓库 Marketplace 与 Codex 插件时:

codex plugin marketplace upgrade harness-relay
codex plugin add deepseek-harness-relay@harness-relay

然后再次重启 Codex 并新建任务。不要把 Relay 配置为同一个 Harness 的 MCP client;Codex 插件应连接 Relay proxy,而 Harness 仍通过 dsh plugin --profile web add harness-relay-mcp 管理内部 bundle。Codex Marketplace 的官方格式与命令参见 OpenAI 插件打包文档。

让 AI 分析并协助安装

尚未安装插件的用户可以把下面提示词直接交给具备终端权限的 Codex。AI 应先只读检查环境、说明将发生的改动并获得用户确认,再执行安装;不得修改 DeepSeek Harness 产品源码或把 Relay 配回 Harness MCP client:

请阅读 https://github.com/tonytanglab/deepseek-harness-relay-mcp/blob/main/README.zh-CN.md 的“安装”章节,协助我安装 Harness Relay MCP。
先只读检查操作系统、Node.js 版本、dsh、Codex CLI、Harness web profile 和 127.0.0.1:3080,不要修改任何文件。
列出检测结果、缺失依赖、拟执行命令和影响范围,获得我确认后再操作。
Harness 侧只能使用 dsh plugin --profile web add harness-relay-mcp 安装内部 bundle,不修改 DeepSeek Harness 源码,不把 Relay 添加为 Harness MCP client。
Codex 侧使用仓库 Marketplace tonytanglab/deepseek-harness-relay-mcp,安装 deepseek-harness-relay@harness-relay。
Codex 插件 manifest 必须引用包内 .mcp.json;.mcp.json 只能以 cwd "." 启动 node ./dist/dsh-relay-proxy.mjs。不要指向 dsh-relay-harness.mjs 或 dsh-relay.mjs,不要在用户 config.toml 重复注册 MCP,也不要由 Agent 手工启动第二个 Harness Web;旧 owner 已死亡时交给 proxy 执行受控单实例恢复。
当我明确指定 Harness/模型审核或修改当前或命名的已注册工作区时,Harness 在该范围内自行读取;Codex 只传 workspace、文件/目录位置、审查或实施范围、验收条件、模型、权限和幂等信息。read-only 与 workspace-write 都禁止把源码正文、diff、文件转储、源码编码或仓库归档放入 task/content/steer_run/reply_run 参数。若我明确要求 Harness 修改代码,使用 start_run + workspace-write;普通审核使用 start_review。
安装后验证 dsh --profile web --dump-config、codex plugin list,并提醒我重启 Codex、新建任务后运行 doctor 与 list_workspaces。遇到错误时停止并报告原始错误,不扩大权限、不删除现有配置。

本地开发

pnpm install
pnpm run build

内部 bundle 启动后,让 MCP 客户端启动通用 stdio proxy:

{
  "mcpServers": {
    "harness-relay-mcp": {
      "command": "node",
      "args": ["C:/Users/you/plugins/deepseek-harness-relay-mcp/dist/dsh-relay-proxy.mjs"],
      "env": {
        "DSH_RELAY_CLIENT_PRINCIPAL_ID": "cursor:project"
      }
    }
  }
}

proxy 默认读取 $DSH_HOME/plugins/dsh-relay/web/relay-endpoint.json;未设置 DSH_HOME 时统一回退到用户目录下的 .dsh,空白 DSH_PROFILE 回退到 web。自定义状态目录时显式设置 DSH_RELAY_ENDPOINT_DESCRIPTOR。客户端配置不保存 token。harness-relay-mcp 包根入口是 Harness bundle,同时提供 harness-relay-mcp、harness-relay-mcp-proxy 命令;旧 dsh-relay 命令作为兼容别名保留。

0.2.3 起,内部 bundle 会在 endpoint 同目录原子发布不含凭证的 relay-status.json。stdio proxy 先启动本地 MCP;tools/list 与本地 doctor 不等待远端连接或 Harness 自动恢复。proxy 从 embedded Relay 的同一组注册定义生成完整产品工具目录,因此恢复期间 Codex 仍能发现 list_capabilities、start_review、wait_run 和其他原生工具。当 endpoint 缺失、状态失败、owner epoch 不匹配、token 不可读或 POST 返回 401/404/405/503 时,除 doctor 外的调用在路由恢复前统一返回 RELAY_ROUTE_UNAVAILABLE。Host 恢复后,同一个 proxy 会重新连接并发送 tools/list_changed,让客户端刷新远端元数据变化。

快速开始

先读取 Harness 原生工作区注册表,不要把 Host 进程目录当成授权清单:

{
  "tool": "list_workspaces",
  "arguments": {}
}

然后读取 Host 实际能力,不要猜测路由名称:

{
  "tool": "list_capabilities",
  "arguments": {}
}

然后使用 Kimi K3/MAX 发起只读审查:

{
  "tool": "start_review",
  "arguments": {
    "workspace": "D:/work/project",
    "task": "读取 README.zh-CN.md、skills/delegate-to-deepseek-harness 与 src/mcp-server;审查任务契约和权限边界,只返回可复现的发现。",
    "provider": "kimi-coding",
    "model": "k3",
    "reasoningEffort": "max",
    "agentPreset": "standard",
    "idempotencyKey": "review-2026-08-19-001"
  }
}

保存返回的 runId、sessionId 和 webUrl,并持续调用 wait_run 直到终态。单次最多等待 30 秒;超时且 status: running 只是切片。若 hostPollContract.hostMustCallWaitRunAgain 为 true,必须立刻再调 wait_run。给出 webUrl 不等于完成:

{
  "tool": "wait_run",
  "arguments": {
    "runId": "<run-id>",
    "timeoutMs": 30000
  }
}

活动运行需要补充或纠正时调用 steer_run。运行进入终态后,通过 reply_run 在同一个原生 Harness 会话中继续对话。

同时省略 sessionId 和 sessionMode 时,会在所选 Harness 工作区内创建新会话。需要延续现有项目对话时,先调用 list_workspace_sessions 并传入其中空闲的 sessionId,或者传入 sessionMode: "latest-idle",复用最新的非空、空闲、未归档会话。显式 sessionId 不能与 sessionMode 同时使用。

运行生命周期

start_run
   │
   ├─ 预留会话
   ├─ 选择模型和原生权限 preset
   ├─ 持久化 runId + prompt rpcId
   ├─ 提交 session.prompt
   └─ 与持久历史对账

running ── status/wait/steer/cancel ──> succeeded | incomplete | failed | cancelled | needs_attention
   │
   └─ 终态 ── reply_run ──> 同一会话中的新运行

promptAdmission 表示提示词接纳状态:

值 含义
pending 运行标识已经持久化,但提示词提交尚未完成。
accepted Harness 已接纳提示词,或已观察到其持久消息。
unknown 传输响应不可用;应按 rpcId 对账,不能重复提交任务。
rejected Harness 未接纳或未持久化提示词。

start_run 参数

参数 是否必需 说明
workspace 是 Relay 策略允许的绝对工作区路径。
task 两种提示词形式选一 仅包含文件/目录位置、审查或实施范围与验收条件的纯文本任务;禁止源码正文、diff、文件转储、源码编码或仓库归档;与 content 互斥。
content 两种提示词形式选一 同样遵循仅位置/范围契约的有序文本/图片块;图片只用于任务本身要求的非工作区证据,不能替代 Harness 自行读取工作区源码;与 task 互斥。
sessionId 否 复用所选工作区内的空闲会话。
sessionMode 否 fresh 或 latest-idle;默认为 fresh,不能与 sessionId 同时使用。
provider 与 model 同时提供 list_capabilities 返回的准确 Provider ID。
model 与 provider 同时提供 list_capabilities 返回的准确模型 ID。
reasoningEffort 否 适配器支持的强度,例如 low、high 或 max。
agentPreset 否 Harness Agent preset,只能在创建新会话时选择。
permissionPreset 否 原生权限 preset,默认为 read-only。
confirmedDangerousPermission 完全访问时必需 使用 danger-full-access 前必须显式设为 true。
idempotencyKey 建议提供 调用方稳定键;相同请求重试时返回原操作,不会重复提交。
openBrowser 否 默认保持 false;仅当用户明确要求打开原生会话 URL 时设为 true。

图片提示词

使用不带 data: URL 前缀的规范 base64:

{
  "workspace": "D:/work/project",
  "content": [
    { "type": "text", "text": "审查这张截图。" },
    {
      "type": "image",
      "mediaType": "image/png",
      "data": "<canonical-base64>",
      "name": "screen.png"
    }
  ]
}

支持 PNG、JPEG、WebP 和 GIF。图片字节会发送给 Harness,但不会保留在 Relay 运行快照或状态文件中。

原生权限 preset

Preset 适用场景
read-only 审查、诊断、研究、比较和规划;任务参数只传位置与范围。
workspace-write 仅在授权工作区和写路径内实施修改;仍只传位置与范围,不传源码正文。
danger-full-access Harness 完全访问;仅在调用方明确授权时使用。

在 embedded 模式下,DSH Relay 会在需要时激活目标 Session,直接调用原生权限服务,并在提交首条任务提示词前确认最终 preset。提示词中的文字声明不会被当作权限边界;权限 preset 也不会放宽仅位置/范围的任务传递契约。

start_review、start_run 和 reply_run 可携带结构化范围声明:reviewTargets 是审核对象,contextReadScope 是可按需检索和读取的支持材料范围,excludedPaths 是排除路径,writeScope 是写入范围。审核计划文件时,目标文件不等于读取白名单;除非用户明确要求只读该文件,否则可把授权仓库或相关子树列入 contextReadScope。这些字段会进入 Harness 提示并随 reply_run 继承,但它们不是逐路径文件系统强制策略。Harness 的原生权限控制读写模式;所选模型仍可能经其配置的提供商处理读取内容,Relay 使用回环地址不代表全部模型处理均在本地。

start_review 强制要求精确的 provider、精确的 model 和 authorizationBasis: explicit-user-request。用户明确要求 Harness 或点名 Harness 模型审查已识别的工作区或文件,即已授权所选目的地处理范围内的读取内容;调用方不得仅因模型提供商在外部处理内容而再次索要确认。该标记为 Codex 审批记录既有选择,不扩大工作区、上下文、权限、处理目的地或允许的外部操作。start_run 与 reply_run 为兼容非审查流程仍保留可选标记。

MCP 工具

工具 用途
doctor 检查 Relay 包、Host 连接、工作区策略和持久状态。
setup_plan 生成经过验证且不写入磁盘的客户端配置补丁。
setup_doctor 将 setup 计划和调用方提供的探针结果转换为机器可读报告。
start_service 将授权工作区附加到 Harness;必要时 proxy 会先执行受控 Host 恢复。
open_service 打开 Host 根地址。
list_services 列出已恢复的工作区附加记录。
list_workspaces 列出用于路由的 Harness 原生工作区注册表。
list_workspace_sessions 列出指定已登记工作区的直接会话,不读取对话内容。
stop_service 只移除 Relay 附加状态,不停止 Harness。
list_capabilities 列出 Provider/模型/推理强度、Agent preset 和原生权限模式。
start_run 创建或复用会话并提交受跟踪任务。
start_review 固定使用 Harness 原生 read-only 权限提交审查任务,并区分审核目标与支持材料读取范围。
steer_run 向活动运行插入纠偏指令。
get_run 读取并对账运行;推荐使用的运行状态入口。
get_run_summary 将运行投影为稳定的状态、模型、权限、耗时和下一步字段。
status_run 已弃用的兼容别名;请迁移到 get_run,计划在 0.3.0 删除。
open_run 打开原生 Harness Web 会话链接。
wait_run 最长等待 30 秒以获取运行进展。超时只是切片;若 hostPollContract.hostMustCallWaitRunAgain 为 true,必须立刻再调 wait_run。运行仍为 running 时不得结束宿主回合。
list_runs 对账并列出已持久化运行。
get_operation 读取一条持久化的 start、reply、steer 或 cancel 幂等操作。
reconcile_operation 根据 Harness 持久事件解析不确定操作,且不重复提交请求。
reconcile_permissions 重试恢复已过期或中断的 Harness 原生权限租约。
reply_run 在已完成会话中创建新的受跟踪运行。
cancel_run 请求 Harness 原生取消。
read_notifications 从指定游标开始重放当前进程的有界通知投影。

客户端配置与监控投影

setup_plan 支持 Codex、Claude Code、Cursor,以及显式标记版本的 OpenCode V2 配置结构。它接收已经解析的 Node 与 Relay 入口绝对路径,只返回结构化最小补丁,绝不直接编辑客户端配置。启动器平台必须与配置平台一致;pnpm.exe、pnpm.cmd 等包管理器 shim 不能充当 Node 运行时。

setup_doctor 同样无副作用。文件系统、Broker、Host、工作区、模型和权限事实必须由获得授权的调用方提供;未提供的探针会标记为 skipped,不会猜测结果。

get_run_summary 消费 Relay 权威运行快照并输出版本化监控投影。read_notifications 重放当前 MCP Server 进程保留的通知,并在游标缺口时返回明确的重同步元数据。原生运行通知 transport 尚未启用,因此通知缓冲为空属于正常情况,客户端必须自动降级到 get_run_summary、wait_run 或 get_run 轮询。

持久化与故障恢复

默认状态文件:

%LOCALAPPDATA%/dsh-relay/state.json

状态会经过 schema 校验、带所有者校验的跨进程锁和原子替换,并在支持的平台上使用限制性文件权限;旧写入者不能回退已停止服务、终态运行、待处理状态、操作或权限租约。损坏文件会被隔离而不是覆盖。默认不持久化提示词文本和图片字节。Relay 重启后会恢复运行与操作标识,并与 Harness 原生历史重新对账。对账得到的 Assistant 文本会按当前 turn 的事件顺序保留,不再只返回最后一条 Assistant 消息。活动运行在配置时间内没有持久进展时会进入 needs_attention 并给出 attentionReason: run_stalled;后续一旦出现新进展会自动恢复为 running。

embedded Host 还会发布不含凭据的启动契约,仅记录绝对 Node/dsh 入口、源码启动所需的官方 Node loader 参数、profile、工作目录和 Relay 运行路径。构建后的 lib/bin.js 入口继续使用普通 Node;apps/cli/src/bin.ts 入口必须保留精确的 tsx ESM loader 向量,raw Node 源码启动器会被拒绝。遇到 OWNER_DEAD 或 Host 已正常停止时,stdio proxy 会先获取跨进程启动锁并复查状态,再确认已记录的回环端口为空闲、校验启动器结构和文件,最后用隐藏窗口和 --no-open 拉起 Harness。并发客户端只会收敛到一次启动;启动器缺失或无效、owner 状态未知、端口占用以及启动失败都会继续以明确诊断安全失败。

多个本地 MCP Server 进程可以共享一个状态文件;写入会按稳定标识串行化并合并。遗留锁会安全失败,而不会仅因时间过长就被删除。需要运行隔离时,再为不同客户端配置独立的 DSH_RELAY_STATE_FILE。

会话链接

每个运行都会返回如下原生 URL:

http://127.0.0.1:3080/?sessionId=<session-id>

HTTP 200 只能证明 Host 已响应,不能证明超长实时对话已经完成浏览器渲染。随附 Skill 默认保持 Harness 无弹窗运行并直接分享可点击的会话链接;仅当用户明确要求打开或显示页面时才调用 open_run 并验证可见的工作区和会话。Harness 成功选择会话后可能把地址栏规范化回 Host 根地址,但选中的会话仍然保持不变。

配置

环境变量 默认值 用途
DSH_RELAY_HOST_URL http://127.0.0.1:3080/ 本机回环 Harness Host 地址。
DSH_RELAY_AUTO_START true owner 与端口安全检查通过后,允许 stdio proxy 重启上一任 Harness Web 启动器。
DSH_RELAY_AUTO_START_TIMEOUT_MS 120000 等待受控 Host 恢复发布 ready Relay 端点的最长时间。
DSH_RELAY_ALLOWED_WORKSPACE_ROOTS Harness 工作区目录 操作系统分隔的额外授权绝对根目录列表;未配置时只接受 Harness 已登记工作区。
DSH_RELAY_STATE_FILE %LOCALAPPDATA%/dsh-relay/state.json Relay 持久状态位置。
DSH_RELAY_PERSIST_PROMPT_TEXT false 明确接受本地留存时持久化提示词摘要。
DSH_RELAY_CLIENT_PRINCIPAL_ID local-user 与幂等键共同使用的稳定本地调用方标识。
DSH_RELAY_PERMISSION_LEASE_MS 86400000 复用会话权限租约的记录时限。
DSH_RELAY_RPC_TIMEOUT_MS 30000 Host RPC 超时。
DSH_RELAY_POLL_INTERVAL_MS 750 活动运行轮询间隔。
DSH_RELAY_MAX_HISTORY_PAGES 100 单次对账最多读取的持久历史页数。
DSH_RELAY_RUN_STALL_MS 300000 活动运行无进展多久后标记为 needs_attention;恢复进展时自动回到运行态。
DSH_RELAY_MAX_TASK_CHARACTERS 100000 单条提示词的最大文本字符数。
DSH_RELAY_MAX_ASSISTANT_TEXT_BYTES 256000 返回的 Assistant 文本尾部最大字节数。
DSH_RELAY_MAX_IMAGE_BYTES 5242880 单张图片最大解码字节数。
DSH_RELAY_MAX_IMAGES 20 每条消息最大图片数。
DSH_RELAY_MAX_MESSAGE_IMAGE_BYTES 104857600 每条消息中图片的最大解码总字节数。

只接受本机回环 HTTP Host。工作区路径会先经过文件系统解析,再执行包含关系检查。

安全模型

  • Harness Relay MCP 不读取或存储 Harness 凭据。
  • 现有 Harness Host 仍然是模型、权限、会话、附件和任务执行的权威来源。
  • 默认权限 preset 为 read-only。
  • 未配置显式 roots 时,以 Harness 工作区注册表作为路由授权真源;配置 roots 后仍执行更严格的本地边界。
  • stop_service 不会停止 Harness,也不会删除会话。
  • Harness 输出属于证据;最终复核和高风险决策仍由调用方 Agent 负责。
  • Relay 无法保证 Codex 或其他 MCP 客户端是否请求批准或触发 auto-review;这仍由客户端、客户端策略和具体操作共同决定。

与 Harness 插件标准的边界

Harness Relay MCP 采用双层兼容结构:harness-relay-mcp 包根入口是遵循 Harness/Cordis 标准的树外内部 bundle,导出 Config/apply(ctx) 并通过 dsh.bundle 与 cordis.patch.yml 安装。0.2.9 绑定 0.1.2 Host 服务(typertGateway、Session/Workspace/Settings controllers、Agent Presets、WebServer 和 Permission Presets),将 session.follow/page 与 workspace.follow 转换为 Relay 语义网关;已移除的 rc.8 mux stream 不可用时,仍以持久历史轮询作为权威对账路径。外部 Agent 通过认证 HTTP 或无业务状态的 proxy 使用同一内部 authority,standalone 入口只作为兼容和回滚路径。整个方案不复制或修改 Harness 产品源码。

参见 DeepSeek Harness 官方文档:创建 Harness 插件和发布 bundle。

开发与验证

version.json 是唯一可编辑版本源。构建会先同步 npm 与 Codex 清单,再生成自包含 MCP bundle。

pnpm run test
pnpm run build
pnpm run test:mcp
pnpm run check:package
pnpm pack --dry-run

prepack 会执行严格 TypeScript 检查、构建 bundle,并验证显式发布白名单。敏感目录、运行时产物、敏感文件和符号链接会被拒绝;展开后的默认总字节上限为 8 MiB。发布自动化可通过 DSH_RELAY_PACKAGE_MAX_BYTES 调整门限,但提高上限应经过审查,不能用于掩盖异常包体增长。test:mcp 每次都会先重新构建,再启动 stdio 冒烟测试。

标识

使用位置 名称
产品名 Harness Relay MCP
仓库名 deepseek-harness-relay-mcp
Codex 插件 ID deepseek-harness-relay
npm 包 harness-relay-mcp
MCP Server ID harness-relay-mcp
Skill delegate-to-deepseek-harness

许可证

MIT