🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

能力管理器 easun-zhu/dsh-cap-manager

DeepSeek Harness
easun-zhu2 天前有提交已提供中文文档扫描:含敏感能力

统一管理 MCP 服务、技能与 Claude 插件

30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add easun-zhu/dsh-cap-manager
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么[目录]—
dsh 原生插件 · market
暂无时间戳·判据 →
装得上吗[实装验证]—
本站尚未做安装检查
暂无时间戳·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 2 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 68 处,展示前 58 条)
  • 发起网络请求
    src/cc-market.ts:75
    response = await fetch(url, { redirect: 'follow', signal: AbortSignal.timeout(timeoutMs) })
  • 写入本地文件
    src/cc-market.ts:118
    await mkdir(dirname(this.cachePath), { recursive: true }).catch(() => undefined)
  • 写入本地文件
    src/cc-market.ts:119
    await fsWriteFile(this.cachePath, JSON.stringify(cache, null, 2), 'utf8').catch(() => undefined)
  • 读取本地文件
    src/cc-market.ts:144
    const parsed = JSON.parse(await fsReadFile(this.cachePath, 'utf8')) as MarketCache
  • 删除本地文件递归
    src/cc-store.ts:280
    await rm(join(this.options.baseDir, 'store', existing.name), { recursive: true, force: true }).catch(() => undefined)
  • 读取本地文件
    src/cc-store.ts:335
    const parsed = JSON.parse(await readFile(join(this.options.baseDir, REGISTRY_FILENAME), 'utf8')) as Registry
  • 删除本地文件递归
    src/cc-store.ts:362
    await rm(join(this.options.baseDir, 'store', previous.name), { recursive: true, force: true }).catch(() => undefined)
  • 删除本地文件递归
    src/cc-store.ts:364
    await rm(join(this.options.baseDir, 'store', previous.name, previous.version), { recursive: true, force: true }).catch(() => undefined)
  • 删除本地文件递归
    src/cc-store.ts:373
    await rm(temp, { recursive: true, force: true })
  • 写入本地文件
    src/cc-store.ts:374
    await mkdir(temp, { recursive: true })
  • 写入本地文件
    src/cc-store.ts:378
    if (dirname(destination) !== temp) await mkdir(dirname(destination), { recursive: true })
  • 写入本地文件
    src/cc-store.ts:379
    await writeFile(destination, bytes, { mode: 0o600 })
  • 删除本地文件递归
    src/cc-store.ts:381
    await rm(target, { recursive: true, force: true })
  • 写入本地文件
    src/cc-store.ts:382
    await rename(temp, target)
  • 删除本地文件递归
    src/cc-store.ts:384
    await rm(temp, { recursive: true, force: true }).catch(() => undefined)
  • 读取本地文件
    src/cc-store.ts:486
    entries = await readdir(skillsDir, { withFileTypes: true })
  • 读取本地文件
    src/cc-store.ts:495
    found.push({ skillName: entry.name, path, directory: dirname(path), file: await readFile(path, 'utf8') })
  • 读取本地文件
    src/cc-store.ts:501
    found.push({ skillName: entry.name.replace(/ md$/, ''), path, directory: skillsDir, file: await readFile(path, 'utf8') })
  • 读取本地文件
    src/cc-store.ts:535
    const raw = await readFile(locator.file, 'utf8').catch(() => undefined)
  • 读取本地文件
    src/cc-store.ts:567
    const text = await readFile(join(root, candidate), 'utf8').catch(() => undefined)
  • 写入本地文件
    src/cc-store.ts:689
    await copyFile(file, `${file}.cap-bak-${stamp}`)
  • 发起网络请求
    src/client/files.ts:56
    const response = await fetch(parsed.href)
  • 读取本地文件
    src/patch-writer.ts:45
    return await readFile(file, 'utf8')
  • 写入本地文件
    src/patch-writer.ts:89
    await copyFile(file, `${file}${BACKUP_PREFIX}${stamp}`)
  • 读取本地文件
    src/patch-writer.ts:91
    const backups = (await readdir(dirname(file)))
  • 删除本地文件
    src/patch-writer.ts:95
    await unlink(join(dirname(file), name)).catch(() => undefined)
  • 写入本地文件
    src/patch-writer.ts:110
    await mkdir(dirname(file), { recursive: true })
  • 读取本地文件
    src/project-config.ts:56
    text = await readFile(file, 'utf8')
  • 读取本地文件
    src/project-config.ts:226
    return await readFile(file, 'utf8')
  • 写入本地文件
    src/project-config.ts:236
    await copyFile(file, `${file}${BACKUP_PREFIX}${stamp}`)
  • 读取本地文件
    src/project-config.ts:238
    const backups = (await readdir(dirname(file)))
  • 删除本地文件
    src/project-config.ts:242
    await unlink(join(dirname(file), name)).catch(() => undefined)
  • 写入本地文件
    src/project-config.ts:259
    await mkdir(dirname(file), { recursive: true })
  • 读取本地文件
    src/project-mounter.ts:277
    return await realpath(path)
  • 读取本地文件
    src/project-mounter.ts:300
    await access(path)
  • 读取本地文件
    src/scopes.ts:32
    if (patchFile === undefined || !existsSync(patchFile)) return new Set()
  • 读取本地文件
    src/service.ts:536
    const names = await readdir(dirname(target)).catch(() => [] as string[])
  • 读取本地文件
    src/service.ts:542
    const size = await stat(file).then(info => info.size, () => 0)
  • 读取本地文件
    src/service.ts:556
    const data = await readFile(hit.file)
  • 删除本地文件
    src/service.ts:566
    await unlink(hit.file)
  • 读取本地文件
    src/service.ts:919
    await access(path)
  • 读取本地文件
    src/skills-store.ts:111
    entries = await readdir(root.path, { withFileTypes: true })
  • 写入本地文件
    src/skills-store.ts:209
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    src/skills-store.ts:240
    await mkdir(trashBase, { recursive: true })
  • 删除本地文件递归
    src/skills-store.ts:242
    await rm(target, { recursive: true, force: true }).catch(() => undefined)
  • 写入本地文件
    src/skills-store.ts:243
    await mkdir(target, { recursive: true })
  • 写入本地文件
    src/skills-store.ts:244
    await rename(source, join(target, basename(source)))
  • 读取本地文件
    src/skills-store.ts:275
    entries = await readdir(trashBase, { withFileTypes: true })
  • 写入本地文件
    src/skills-store.ts:313
    await mkdir(dirname(meta.originalPath), { recursive: true })
  • 写入本地文件
    src/skills-store.ts:314
    await rename(join(path, basename(meta.originalPath)), meta.originalPath)
  • 删除本地文件递归
    src/skills-store.ts:315
    await rm(path, { recursive: true, force: true })
  • 删除本地文件递归
    src/skills-store.ts:325
    await rm(path, { recursive: true, force: true })
  • 读取本地文件
    src/skills-store.ts:340
    const raw = await readFile(join(path, 'trash-meta.json'), 'utf8')
  • 删除本地文件递归
    src/skills-store.ts:463
    await rm(target, { recursive: true, force: true })
  • 读取本地文件
    src/skills-store.ts:501
    return { name, files: [{ path: `${name}.md`, base64: (await readFile(file)).toString('base64') }] }
  • 读取本地文件
    src/skills-store.ts:508
    const entries = await readdir(join(dir, relative), { withFileTypes: true })
  • 读取本地文件
    src/skills-store.ts:516
    const bytes = await readFile(join(dir, child))
  • 删除本地文件
    src/skills-store.ts:689
    await rm(join(dirname(file), name)).catch(() => undefined)
扫描于 2026/11/4(0 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-app-boot@deepseek-ai/dsh-atomic-write@deepseek-ai/dsh-client-ui-primitives@deepseek-ai/dsh-home-paths@deepseek-ai/dsh-mcp-client@deepseek-ai/dsh-plugin-market-index@deepseek-ai/dsh-typert-protocol
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
dsh-cap-manager 在 DeepSeek Harness Web UI 中一个面板统一管理 MCP 服务、技能与 Claude Code 插件。 一款 DeepSeek Harness(dsh)插件:在 Web UI 侧边栏增加 MCP 与技能 面板: - 🔌 MCP 服务 —— 按全局 / Profile / 项目三作用域分组的卡片,实时显示连接状态与工具数。新增、编辑、开关、删除即时生效;支持从 Claude / Cursor / Cline / Roo / VS Code 导入 mcpServers JSON,也支持导出。 - 🧠 技能 —— 项目与用户全部可写技能根汇成一份可搜索列表。就地编辑、导入 .zip 压缩包或 URL、一键导出、回收站恢复、.cap-bak 备份历史。 - 🧩 Claude Code 插件 —— 在 dsh 里浏览 Anthropic 官方 claude-plugins-official 市场(315+ 个插件):安装、更新、卸载、开关。插件技能经原生 skill provider 实时供给;manifest 里的 mcpServers 挂载为实时 MCP 连接。 完整设计与兼容性说明见 DESIGN.md。当前版本:v1.2.0 (MCP 页新增只读的 Claude Code 插件服务分组)。
展开完整文档(README 剩余 1 节)
dsh-cap-manager

在 DeepSeek Harness Web UI 中一个面板统一管理 MCP 服务、技能与 Claude Code 插件。

一款 DeepSeek Harness(dsh)插件:在 Web UI 侧边栏增加 MCP 与技能 面板:

- 🔌 MCP 服务 —— 按全局 / Profile / 项目三作用域分组的卡片,实时显示连接状态与工具数。新增、编辑、开关、删除即时生效;支持从 Claude / Cursor / Cline / Roo / VS Code 导入 mcpServers JSON,也支持导出。
- 🧠 技能 —— 项目与用户全部可写技能根汇成一份可搜索列表。就地编辑、导入 .zip 压缩包或 URL、一键导出、回收站恢复、.cap-bak 备份历史。
- 🧩 Claude Code 插件 —— 在 dsh 里浏览 Anthropic 官方 claude-plugins-official 市场(315+ 个插件):安装、更新、卸载、开关。插件技能经原生 skill provider 实时供给;manifest 里的 mcpServers 挂载为实时 MCP 连接。

完整设计与兼容性说明见 DESIGN.md。当前版本:v1.2.0 (MCP 页新增只读的 Claude Code 插件服务分组)。

🖼️ 截图

面板以 MCP 与技能 出现在侧边栏。下图是 MCP 页 —— 项目 / 全局 / Profile 三个作用域分组,每张卡片带实时状态、工具数与启停开关(已停用的行保留配置但不挂载)。

技能页 —— 项目 / 全局分组 + 只读插件提供分组插件页 —— 已安装卡片 + 官方市场(315+)

深色模式自动跟随宿主主题

📦 安装

前置:DeepSeek Harness ≥ 0.2.1-rc.2(全局安装 dsh,或全部通过 npx -y @deepseek-ai/dsh 运行)。

免编译 —— 从 npm 安装:

dsh plugin --profile web add dsh-cap-manager

若 pnpm 的发布冷却期拒绝解析刚发的版本,可显式固定版本:
dsh plugin --profile web add dsh-cap-manager@1.2.0。

或安装 Release tarball(效果相同,不依赖 npm):

浏览器 Web UI
dsh plugin --profile web add https://github.com/easun-zhu/dsh-cap-manager/releases/download/v1.2.0/dsh-cap-manager-1.2.0.tgz
桌面客户端
dsh plugin --profile desktop add https://github.com/easun-zhu/dsh-cap-manager/releases/download/v1.2.0/dsh-cap-manager-1.2.0.tgz

web / desktop 换成你自己的 profile 名即可;重启 dsh,然后在左侧边栏打开 MCP 与技能。(github: git 简写等于从源码装 —— 仓库不含编译产物 lib/,优先用 npm 或 tarball。)

从本地目录安装:

pnpm install && pnpm build # 产出 lib/index.js + lib/client.js
dsh plugin --profile web add /absolute/path/to/dsh-cap-manager
dsh --profile web # 重启以加载插件

可选:通过插件市场安装

把下面这个已托管的索引 URL 添加到 dsh 的发现页(或 plugin-market 的 indexes 配置),即可一键安装:

https://easun-zhu.github.io/dsh-cap-manager/market/index.json

索引声明了 engines.dsh >= 0.2.1-rc.2,安装源为 npm。自托管:把 market/index.json 复制到任意 http(s) 位置即可。可随时用上游校验器验证:

node --experimental-strip-types test/m5-smoke.ts # 含 market/index.json 校验

🔌 MCP 服务

每个项目可携带 .dsh/mcp.yml(手改或面板管理):

mcpServers:
projmini:
enabled: true # false = 保留配置,不挂载 transport: stdio command: node
args: [./scripts/mcp.mjs]
env:
TOKEN: !!js process.env.MY_TOKEN # 挂载期求值

- 文件是唯一事实源:项目存在活动会话(或被面板项目选择器选中)时,其 enabled 的服务被挂载;外部修改即时生效(watcher + 差异挂载)。
- serverName 跨所有层唯一 —— 冲突在挂载前即被拒绝。
- URL 导入(⇩):按 URL 直接抓取 mcpServers JSON 文档或技能 .zip。抓取由浏览器执行,目标需发送 CORS 头(GitHub raw 与多数静态托管都支持);载荷随后进入与粘贴文本 / 本地文件完全相同的预览 / 解包管线。
- 新增表单内置模板下拉(filesystem、memory、sequential-thinking、fetch、github、 puppeteer),一键填充起步配置。

🔁 导入与导出

- 导入(MCP 页 → ⇩):粘贴、选文件或 URL 抓取 mcpServers JSON —— 容忍 VS Code 的 JSONC 方言(注释、尾逗号),sse 条目映射为 streamable-http 并警告,非法键自动 slug 化并标记。${VAR} / ${env:VAR} 引用转为 !!js process.env.VAR 表达式(嵌入时为反引号模板);VS Code 的 ${input:…} 占位渲染凭据表单,应用时替换。
预览列出每条转换、改名与失败;应用复用常规写入路径(共享校验、HMR 实时生效)。
- 导出(MCP 页 → ⇧):全部受管行 + 选中项目文件合并为标准 {"mcpServers": …} 文档;!!js 表达式还原为 ${VAR}。已停用行跳过(标准格式无停用位)。密钥以明文导出 —— UI 明示。
- 技能导入(技能页 → ⇩):.zip(允许多一层包装目录 —— 按 SKILL.md 位置识别技能根)、文件夹、散 .md 或 zip URL;上限 10 MB / 200 文件,拒绝 zip-slip 路径,丢弃 macOS 垃圾文件。文件逐字节原样落盘;同名默认跳过,勾选覆盖才替换。
- 技能导出(卡片上的 ⇧):目录技能下载为 .zip(含资源),文件技能为 .md。
- 回收站与备份(♻):已删技能列出原路径并可一键恢复;受管文件旁的每份 .cap-bak-(patch、项目 mcp.yml、SKILL.md —— 每文件保留 5 份)可恢复到目标或删除。

🧠 技能

技能页扫描四个可写根(<project>/.dsh/skills、<project>/.agents/skills、 ~/.dsh/skills、~/.agents/skills),按 provider 自身规则处理,同名冲突按 rank 顺序裁决(项目胜过用户);被遮蔽条目与无法解析的文件以角标显式呈现而不是消失。
编辑原子写 SKILL.md(保留未知 frontmatter 键与注释,开关统一为 true/false);删除把目录移入 ~/.dsh/cap-manager/trash/(trash-meta.json 记录来源),同名遮蔽浮出时给出警告。

🧩 Claude Code 插件

面板第三个 tab 管理来自 Anthropic 官方 claude-plugins-official 市场的 Claude Code 插件 —— 唯一内置源。

| 市场 | 315+ 个插件,宿主 10 分钟缓存,刷新按钮强制重拉,支持搜索 |
| 安装 | 下载 pin 住的 GitHub tarball(codeload),严格 tar 解包器落盘(逃逸路径拒绝、符号链接跳过),存入 ~/.dsh/cap-manager/plugins/store/<名称>/<版本>/ |
| 技能 | 插件的 skills//SKILL.md 经 ctx.skills provider 实时供给 —— 启用即出现在技能页的只读插件组(rank 排在你自己的技能之后,同名时用户技能优先) |
| MCP 服务 | manifest 声明的 mcpServers 挂载为实时连接 —— 与项目级服务同一套转换与 diff/挂载纪律,含跨层 serverName 预检;同时出现在 MCP 服务页的只读「Claude Code 插件」分组(实时状态、工具数、来源插件),随插件开关启停 |
| 开关 | 技能 + MCP 一起即时启停 |
| 精确更新 | 点「刷新市场」顺带取 marketplace 仓库的 HEAD commit sha,每个已装插件(外部 git 源比对条目 sha,仓库内源比对 HEAD sha)都得到精确的"有更新"判定;sha-pin 源显示更新角标。点「更新」先下载并逐字节内容比对:相同只采纳新 pin 不重装,不同才重装 |
| 卸载 | 卸挂载、删 store 目录、清登记(registry.json 原子写 + .cap-bak 历史) |
| 超时 | 所有网络调用限时(索引 20 s / tarball 120 s);刷新失败自动回退缓存 |

dsh 没有对应机制的内容(commands/、agents/、hooks/)保留在磁盘,并在已安装
卡片上如实标注"未接入"。

🛠️ 开发

- pnpm typecheck —— 对 src/ 跑 tsc
- pnpm build —— 宿主半(esbuild ESM,包全部 external)+ 浏览器半(esbuild CJS, window.__ModuleLoader__.load 注册契约,构建期断言)
- 冒烟测试:node --experimental-strip-types test/m4-smoke.ts(转换器)、 test/m5-smoke.ts(模板 + 市场索引)、test/m6-smoke.ts(tar 解包、子树下载、 manifest 转换)
- harness 各包是 peerDependencies;运行期 profile 链接到正在运行的 dsh 的副本,绝不打包。

从源码检出运行

deepseek-harness 源码检出必须先完成一次 pnpm run build:artifacts 才能服务 Web 客户端:启动会扫描所有声明 dsh.client 的包,缺 lib/client.js 即失败。只构建过服务端产出的检出会在启动时报 ENOENT .../lib/client.js。

⚠️ 绝不要把 --from-default-profile 指向已存在的 profile:它会重置该 profile 的 package.json、patch 和 node_modules —— 清空已装插件。启动一律用 --profile;--from-default-profile 只作一次性初始化。

📁 目录结构

| 路径 | 职责 |
| src/index.ts | 宿主半入口(挂载 CapabilityManagerService) |
| src/service.ts | capabilityManager Typert Remote 服务(patch + 项目 + 技能路由) |
| src/scopes.ts | 适配层:profile patch 组合 + 作用域归属 |
| src/config-view.ts | 原始行配置 ↔ 脱敏视图,!!js 标签化(共用) |
| src/patch-writer.ts | 保注释编辑 cordis.patch.yml 各层 |
| src/project-config.ts | <project>/.dsh/mcp.yml 解析(含 !!js 求值)+ 写入 |
| src/project-mounter.ts | 会话跟随 + watcher + 差异挂载项目服务 |
| src/skills-store.ts | 技能根扫描、frontmatter 读写、回收站(+元数据)、压缩包导入/打包 |
| src/import-mcp.ts | mcpServers JSON → wire 配置转换 + 导出反演 |
| src/cc-market.ts | claude-plugins-official 目录缓存 + 安全 tar.gz 解包器 |
| src/cc-store.ts | 插件 registry、技能 provider(rank 550)、MCP 挂载 |
| src/status-tracker.ts | 适配层:fiber 状态(数字 FiberState)+ mcp__ 工具计数 |
| src/client/index.ts | 浏览器半入口(locale + remote $mount + slots) |
| src/client/CapabilitiesPage.tsx | 面板(卡片、tab、搜索、项目选择器) |
| src/client/McpEditor.tsx | MCP 表单编辑器(模板 + 目录预填) |
| src/client/SkillEditor.tsx | 技能表单 + Markdown 正文编辑器 |
| src/client/ImportWizard.tsx | mcpServers JSON 导入向导(粘贴/文件/URL) |
| src/client/SkillImport.tsx | zip/文件夹/.md/URL 技能导入 |
| src/client/catalog.ts | 模板下拉起步数据 |
| src/client/CcPluginsPanel.tsx | Claude Code 插件市场 + 已安装卡片 |
| src/client/TrashPanel.tsx | 回收站恢复 + .cap-bak 备份浏览 |
| src/client/files.ts | base64/zip 编解码(fflate)、下载、URL 抓取 |
| market/index.json | plugin-market format-1 索引(发现页用) |
| test/ | node 冒烟检查(m4 转换器、m5 模板 + 市场索引、m6 tar/manifest) |

📤 发布(维护者)

1. 把 package.json(repository、homepage)与 market/index.json(homepage、 repository.url)中的 OWNER 占位替换为真实 GitHub 用户名;补上 LICENSE 文件(包声明 MIT)。
2. pnpm typecheck && pnpm build && node --experimental-strip-types test/m4-smoke.ts &&
node --experimental-strip-types test/m5-smoke.ts —— 全部通过。
3. npm publish(包内容为 lib/ + cordis.patch.yml;harness 各包保持 peerDependencies)。
4. 给仓库加上 dsh-plugin GitHub topic(社区发现惯例, awesome-deepseek-harness 按此收录)。
5. 托管 market/index.json(GitHub Pages 或 raw URL)并分享该 URL;每次发版更新 publishTimestamp / 增加版本条目。

📄 许可

MIT · 完整设计文档:DESIGN.md。
预览分享卡片长什么样 ↓easun-zhu/dsh-cap-manager
分享 · DeepSeek Harness Hub
easun-zhu/dsh-cap-manager

统一管理 MCP 服务、技能与 Claude 插件

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部