← 返回列表
⚠ 装前注意
通过 MCP 操作 DeepSeek Harnessdsh:在 dsh 进程内启动一个 MCP…
基本兼容但装前注意:未发布到 npm registry,仅可从源码安装 · 最近上游提交 2026/9/23 · 已提供中文文档
通过 MCP 操作 DeepSeek Harness (dsh):向任何 MCP 客户端暴露会话、任务执行和工作区管理。
综合分
30
GitHub 分
30
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add Leawind/dsh-ops-mcp未发布到 npm registry,仅可从源码安装,改用 GitHub 源安装
信任档位:已验证本站已于 1 天前真实安装成功
- 是什么
- dsh 原生插件 · chat
- 装得上吗
- 本站已真实安装成功(非静态推断)
- 安全吗
- 本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
- 还在维护吗
- 活跃:最近一次提交在 3 天前
档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →
🟢实装验证通过· 2026/9/24
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/23(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查⚠ 装前注意
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-ops-mcp(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
未发布到 npm registry,仅可从源码安装
验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/23 08:33:58
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-agent-presets@deepseek-ai/dsh-llm@deepseek-ai/dsh-session@deepseek-ai/dsh-tools用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
由 DeepSeek 最新模型翻译生成dsh-ops-mcp
通过 MCP 操作 DeepSeek Harness(dsh):在 dsh 进程内启动一个 MCP server,把会话执行、任务队列、工作区管理能力暴露出来,任何 MCP 客户端都能调用。
npm version
license
📖 English · 中文(当前页)
它解决什么问题
dsh 自带完整的 agent 运行时——模型路由、工具沙箱、预设、会话持久化——但它是一个 Cordis 应用,外部程序无法直接调用。dsh-ops-mcp 把它「由内向外」翻转:插件在 dsh 进程内启动 MCP server(StreamableHTTP),通过 ctx.agents / ctx.agentPresets / ctx.tools 桥接运行中的 harness。
你的 MCP 客户端是指挥官,dsh 是执行者。 适配的客户端包括且不限于:Claude Code、Codex CLI、Cursor、另一个 dsh 实例(经官方 dsh-mcp-client 挂接)、任何自动化脚本。
MCP 客户端(Claude Code / Codex / 另一个 dsh / …)
│ agent_run / task_inbox / task_result / model_list / select_model (HTTP + Bearer)
▼
dsh-ops-mcp(MCP server, 127.0.0.1:8090)
│ ctx.agents.create → 挂载 preset
▼
dsh agent —— 完整工具集:bash、fs、todo、web…
工具
| 工具 | 用途 |
|---|---|
| echo | 验证 MCP 连通性 |
| dsh_list_tools | 列出 dsh 全局工具注册表(name + description;模型工具在 preset 作用域,通常为空) |
| model_list | 列出当前可路由的 provider、模型 id、推理档与缺省选择(选模型前先查这里) |
| agent_run | 同步执行任务,返回结构化结果;sessionId 续接会话;provider/model/reasoningEffort 指定本次模型;detail 分级控制返回体积 |
| task_inbox | 把结构化任务(任务+上下文+cwd+模型)推入异步队列,返回 taskId |
| task_result | 取回队列任务结果;detail=status 轻量轮询,不重复注入 payload |
| select_model | 切换已存在会话使用的模型(官方 sessionController.selectModel 路径) |
| attach_session | 把会话归组到其 cwd 对应的工作区 |
| rename_session | 给已有会话改名 |
模型选择
优先级:单次调用参数 > 插件 config(provider+model) > 宿主默认选择(ctx.agentDefaultModel.currentSelection(),与 Web UI 建会话同源)。只给一边时用低优先级来源补另一边;补齐不了会明确报错,而不是留个空模型(否则 persona 里的 {{model}} 变量无值,整个 turn 在组装期失败)。
推理强度(reasoningEffort)与模型同源:调用参数 > 插件 config > 宿主默认选择里的档位。但若调用方或插件 config 已显式钉住 provider+model,就不再继承宿主那个"为别的模型选的"档位(宿主对不支持的显式 effort 直接拒绝,不做 clamp/别名,继承反而会把本来能跑的部署弄挂)。
三条改模型的路径:
| 想要什么 | 怎么做 |
|---|---|
| 这次任务换个模型跑 | agent_run / task_inbox 带 provider+model(可加 reasoningEffort) |
| 同一个会话中途换模型、保留历史 | select_model(官方 sessionController.selectModel:校验 + 写一条持久通知,在下一个 step 生效;历史不丢) |
| 整台部署固定用一个模型 | 插件 config 里成对配 provider+model,并设 allowModelOverride: false 锁死调用方覆盖 |
两个来源语义要分清:
- 常驻会话池按 cwd + 模型三元组 分组。同一目录下用 A 模型跑任务 1、B 模型跑任务 2,是两个独立会话(上下文不串联),这样"哪个会话在用哪个模型"始终可预期;想在一个会话里换模型就用 select_model。
- 结果里新增 model: {provider, model, reasoningEffort?},调用方不用猜这次是谁答的。
model_list 的 source 说明目录口径:sessionController = 官方口径(与 Web UI 模型选择器同一数据源,含 default / routableProviders / 各 provider 的加载失败与推理档);llm = 回退口径(llm.listProviders() + 逐个 listModels(),用于没有 sessionController 的部署,如 headless,不含推理档元数据)。同时回报插件自身的模型配置与 allowModelOverride,调用方一眼能看出"我能不能自己选"。
结果分级(token 预算)——本插件的存在意义是省调用方(operator)的上下文:dsh 内部执行细节不进调用方上下文,读回按 detail 投影:
- summary(默认,~数百 token):changes/verification/leftovers 三行总结 + 回答尾部(总结 JSON 在末尾)+ 工具名列表 + error
- normal(~2k token):上述 + 截断的工具调用参数与结果
- full(最坏数万 token,排查用):完整原文
- task_result 另有 status 档:轮询只返回 {taskId, status, error?},完成后再取一次 summary——避免轮询把结果 payload 重复灌进上下文
续接同一 sessionId 时,executor 已记得此前内容,context 建议只发增量。
每个任务结果都是结构化的:sessionId / model / assistantText / toolCalls / toolResults / changes / verification / leftovers——调用方可以直接写回自己的记忆系统或工单。
会话按 cwd + 模型 复用(LRU,默认 8 个),避免每次调用都重新加载项目上下文。
安装与运行
插件以包形式装进 dsh 的 profile 目录(loader 从那里解析插件名;在仓库根直接 --patch 是找不到本地包的——见 E2E 记录 发现 1):
git clone https://github.com/Leawind/dsh-ops-mcp.git
cd dsh-ops-mcp
npm install && npm run build
npm pack # 产出 dsh-ops-mcp-.tgz
装进 profile(Windows 注意: 用 tarball, pnpm 对 file:D:/... 形式会拼坏路径)
pnpm -C ~/.dsh/profiles/ add -w
export DEEPSEEK_API_KEY=... # 模型凭证(或用 ~/.dsh 里已保存的)
dsh --profile --patch ./cordis.yml --no-open --port 3081
MCP server 监听 127.0.0.1:8090(StreamableHTTP)。任意 MCP 客户端指向 http://127.0.0.1:8090/mcp 即可。
客户端配置示例
通用(任何支持 streamable-http 的 MCP 客户端):
{
"mcpServers": {
"dsh": {
"url": "http://127.0.0.1:8090/mcp",
"headers": { "Authorization": "Bearer " }
}
}
}
让另一个 dsh 操作这个 dsh(对端 profile 的 cordis.patch.yml,走官方 dsh-mcp-client):
- id: mcp-dsh-ops
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: dsh
transport: streamable-http
url: http://127.0.0.1:8090/mcp
headers:
Authorization: 'Bearer '
cordis.yml(patch 格式)
- insert:
- id: dsh-ops-mcp
name: 'dsh-ops-mcp'
config:
http: true
port: 8090
host: 127.0.0.1 # 默认仅本机; 暴露前必须加认证
authToken: 'your-secret-token' # Bearer token 认证(常数时间比较)
workspaceRoots: ['/workspace'] # cwd 白名单(跨平台分隔符/大小写安全)
allowedHosts: ['my-box.lan'] # Host 头白名单追加项(防 DNS rebinding)
preset: 'standard' # 挂载的 agent preset
model: '' # 空 = 跟随 dsh 用户/默认设置
provider: '' # 与 model 成对; 空 = 跟随宿主默认
reasoningEffort: '' # 默认推理强度(空 = 适配器默认)
allowModelOverride: true # false = 锁死模型, 拒绝调用方的覆盖
| 字段 | 默认值 | 含义 |
|---|---|---|
| host / port | 127.0.0.1 / 8090 | MCP server 监听地址;监听失败(如端口被占)会让插件启动显式失败 |
| authToken | — | Bearer token;设置后所有请求强制校验(常数时间比较) |
| workspaceRoots | — | cwd 白名单;agent 只能在列出的目录(含子目录)下干活 |
| allowedHosts | — | Host 头白名单追加项;默认放行绑定地址与 loopback 别名,其余 403 |
| provider / model | 跟随宿主用户设置(agentDefaultModel) | 生成 agent 的模型选择;需成对配置,只配一边会用宿主默认补全另一边 |
| reasoningEffort | 适配器默认 | 默认推理强度(适配器定义的 id,见 model_list 的 reasoningEfforts) |
| allowModelOverride | true | 是否允许调用方(agent_run/task_inbox/select_model)覆盖模型;false = 部署锁死,覆盖请求被明确拒绝 |
| preset | standard | 挂载的 agent preset |
| defaultDetail | summary | agent_run/task_result 的默认详略级别(单次调用可用 detail 覆盖) |
| reattachOrphans | false | 启动时把未分组会话补挂到工作区(批量写用户数据,默认关;attach_session 工具随时可用) |
| maxQueue / taskTtlMs / maxAgents | 100 / 10 分钟 / 8 | 队列容量、结果保留时长、会话池 LRU 上限 |
每个任务结果都是结构化的:sessionId / model / changes / verification / leftovers / error / toolCallCount …(按 detail 分级投影);error 承接 turn 的非正常收场(模型调用失败/取消/blocked),不会再出现"成功"的空结果。
零宿主副本
插件运行时对 @deepseek-ai/ 零依赖:所有 dsh 能力都经注入的宿主服务
(ctx.agents / ctx.tools / ctx.agentPresets …)访问;类型只在编译期做声明合并
(import type,构建后擦除),@deepseek-ai/ 全部是 devDependencies。
因此插件自带的新旧依赖副本永远不会与宿主进程内的私有 Symbol/类标识错位——
上游 0.1.x 时代 scopeOf 副本不匹配导致 agent 静默失去全部工具的根因就此消除。
事件读取走公开 API session.snapshotEvents(),消息构造用与宿主 createUserMessage
逐字段一致的本地实现。
安全
⚠️ 这个插件暴露的是本机执行能力(等价于远程代码执行)。默认只监听 127.0.0.1。启用时务必:
1. 配置 authToken——防本机其他进程与 DNS rebinding 攻击(常数时间比较);
2. 配置 workspaceRoots——限定 agent 可操作的目录;
3. 不要绑定 0.0.0.0 或暴露到局域网/公网,除非前面有反代 + TLS + 认证。
内置防护:Host 头白名单(默认绑定地址 + loopback 别名,防 DNS rebinding,缺失 Host 400);
HTTP 入口只服务 /mcp,其余路径 404。
源码来源
本项目的初始源码复制自 chushixixin/dsh-harness-mcp-server(MIT,感谢 @chushixixin),随后作为独立项目演进:不保留 git fork 关系,也不计划向上游贡献。主要改造方向:
- 去 Hermes 化:面向任意 MCP 客户端(Claude Code / Codex / Cursor / 另一个 dsh / 自动化脚本);
- 贴合当前版本 dsh:见下方 Roadmap;
- 独立命名与仓库:dsh-ops-mcp。
Roadmap / 已知限制(对 dsh 0.1.5-rc.2)
0.2.0 Roadmap 的兼容性问题已在 0.3.0 处理;0.3.1 完成真机 E2E 验证(全绿,见 docs/e2e-0.1.5-rc.2.zh.md),并修复 E2E 发现的问题:{{model}} 提示词变量(模型选择现经 agentDefaultModel 补全)、turn 失败透出、池会话 flush、存量捞回默认关闭、安装流程文档修正。
0.5.0 补齐模型选择面:model_list(官方目录 / llm 回退)、agent_run+task_inbox 的按调用覆盖、select_model(会话内换模型)、reasoningEffort、allowModelOverride 门禁、结果自报 model、会话池按 cwd + 模型 分组。
仍然存在的限制:
- [ ] 任务队列在进程内存中,进程重启丢失(后续可持久化)。
- [ ] agent_run / task_inbox 无服务端超时与取消——卡死的 agent 会占住该 cwd 的串行锁,后续同目录任务排队等待;调用方需自带 MCP 层超时。队列也还不能列举/取消。
- [ ] 只读查询面还不完整:没有 session_list(列会话、读历史、查某会话当前模型),只有 attach_session / rename_session / select_model。
- [ ] preset 仍是部署级配置(一个 MCP server 实例一种 persona),不能按调用指定。
- [ ] spawn 出的会话里工具调用走宿主 approval 策略(ask 下敏感操作可能弹窗或 fail-closed;本次 E2E 的只读操作未受影响)。
- [ ] dsh_list_tools 只列宿主全局注册表;按 agent 作用域列出实际可用工具需要宿主侧 API(ScopeKey 私有符号,零副本原则下拿不到)。
- [ ] select_model 依赖 web profile 的 sessionController;该服务缺席时(如 headless)只有目录回退与按调用覆盖可用,工具会明确报不可用。
- [ ] dsh 未来版本升级时,devDeps 里的 @deepseek-ai/* 类型版本需同步(仅影响编译期,运行时零依赖不受影响)。
开发
npm install
npm run build # 独立构建(纯 tsc), 产出 lib/
npm run smoke # 端口 8099/8098/8096/8095 假 ctx 冒烟(57 项, 真实 MCP 协议往返) + 端口冲突专项
真机 E2E(需要本机 dsh 与模型凭证,会花少量 token):按 docs/e2e-0.1.5-rc.2.zh.md 的方式起一个独立 profile,然后 E2E_WITH_AGENT=1 node e2e.mjs。
License
MIT —— 见 LICENSE(保留上游版权声明)。