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

技能与 MCP 面板 re-ITRT/dsh-skill-mcp-panel

DeepSeek Harnessv2.1.5
re-ITRT35 天前有提交已提供中文文档扫描:含敏感能力

管理 DeepSeek Harness 的技能列表和 MCP 服务器,以侧边栏面板挂载,主题完全取自宿主自身的设计 token。

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

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

自动兼容检查有告警:npm 同名包「dsh-skill-mcp-panel」归属 fishquito7/dsh-skill-mcp-panel,装到的可能不是本插件。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add re-ITRT/dsh-skill-mcp-panel
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · market
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 35 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

npm 同名包「dsh-skill-mcp-panel」归属 fishquito7/dsh-skill-mcp-panel,装到的可能不是本插件

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-skill-mcp-panel @ 2.1.5
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/6 14:16:51

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

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

读写/删除本地文件发起外部网络请求
查看扫描证据(共 19 处,展示前 15 条)
  • 读取本地文件
    lib/index.js:233
    const parsed = JSON.parse(await readFile(overlayPath(ctx), 'utf8'))
  • 写入本地文件
    lib/index.js:248
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    lib/index.js:250
    await writeFile(temporary, `${JSON.stringify({ version: OVERLAY_VERSION, disabled }, null, 2)}\n`, 'utf8')
  • 写入本地文件
    lib/index.js:251
    await rename(temporary, path)
  • 删除本地文件
    lib/index.js:675
    await rm(target.path, { recursive: target.kind === 'directory', force: false })
  • 写入本地文件
    lib/index.js:688
    await mkdir(entryDir, { recursive: true })
  • 写入本地文件
    lib/index.js:689
    await rename(target.path, join(entryDir, 'payload'))
  • 写入本地文件
    lib/index.js:690
    await writeFile(
  • 删除本地文件递归
    lib/index.js:742
    await rm(entryDir, { recursive: true, force: true })
  • 读取本地文件
    lib/index.js:775
    ids = await readdir(root)
  • 读取本地文件
    lib/index.js:807
    await stat(path)
  • 读取本地文件
    lib/index.js:1761
    return await readFile(path, 'utf8')
  • 发起网络请求
    lib/client.js:408
    const response = await fetch(path, init);
  • 发起网络请求
    lib/client.js:551
    const response = await fetch(API.openPath, {
  • 发起网络请求
    lib/client.js:655
    const response = await fetch(API.openApps, { headers: { accept: "application/json" }, cache: "no-store" });
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 管理技能列表
  • 管理MCP服务器
  • 侧边栏面板挂载

README

由 DeepSeek 最新模型翻译生成
dsh-skill-mcp-panel · 技能与 MCP 面板 DeepSeek Harness 的技能列表与 MCP 服务器管理面板,挂在侧边栏,主题完全继承宿主自身的设计 token。 License: MIT Tests Dependencies 侧边栏一个入口——技能与 MCP——打开一整页,里面是两个紧凑列表:当前部署对外提供的全部 Agent 技能,以及全部已配置的 MCP 服务器。每行只有一行:名字、一句说明、一个开关,以及原地展开的 详情。MCP 行还能编辑、新建、删除;两个列表都能打开该对象所在的目录。 页面里没有自己的主题代码。所有颜色、圆角、字体、焦点环都取自宿主的 --dsw- token,字号也跟随宿主,所以它会自动跟着部署主题(浅色/深色/第三方主题)以及设置 → 外观 → 字号大小 走。
展开完整文档(README 剩余 1 节)
dsh-skill-mcp-panel · 技能与 MCP 面板

DeepSeek Harness 的技能列表与 MCP 服务器管理面板,挂在侧边栏,主题完全继承宿主自身的设计 token。

License: MIT
Tests
Dependencies

侧边栏一个入口——技能与 MCP——打开一整页,里面是两个紧凑列表:当前部署对外提供的全部 Agent 技能,以及全部已配置的 MCP 服务器。每行只有一行:名字、一句说明、一个开关,以及原地展开的 详情。MCP 行还能编辑、新建、删除;两个列表都能打开该对象所在的目录。

页面里没有自己的主题代码。所有颜色、圆角、字体、焦点环都取自宿主的 --dsw- token,字号也跟随宿主,所以它会自动跟着部署主题(浅色/深色/第三方主题)以及设置 → 外观 → 字号大小 走。

排版

dsh-client-ui-layout 把正文字号作为内联变量写到 body 上,并由它派生出一个增量:

--dsh-content-font-size: 14px; / 12–17,就是用户设置的那个值 / --dsh-content-font-delta: calc(var(--dsh-content-font-size, 14px) - 14px);

本页每一个尺寸都按会话区自己的写法表达——px + var(--smp-delta),其中 --smp-delta 是 --dsh-content-font-delta 的别名。没有任何写死的 px,并且有测试守着这一点,所以面板会和旁边的对话正文一起长缩。

两个列表

技能

当前会话构成下可见的技能目录,所以项目级和 preset 级的技能会和内置技能并列出现。

| 控件 | 行为 |
| 名字 | /名字 标识 + 发现来源;调用策略只在非默认时才加标签 |
| 说明 | 截断到一行,完整文本留在 tooltip |
| 开关 | 启用/停用该技能 |
| 详情 | provider、来源、路径、用完整句子写清的调用策略、完整正文,以及 打开目录 / 删除 |

技能的调用策略由两个互相独立的标记决定,默认都开:

| 标记 | 含义 |
| modelInvocable | 技能在模型的技能目录里,Agent 可以自己决定加载 |
| userInvocable | 技能在输入框的 / 菜单里,你可以打 /名字 手动调用 |

因为几乎所有技能两个都是开的,到处打标签等于没信息。所以行内只标非默认的情况,详情面板则用一整句话说明,而不是丢两个词让你猜。

开关是怎么实现的

"停用"由本插件维护,不是去改文件。DSH 没有 per-skill 开关:技能存在是因为某个 provider 列出了它,而调用策略由 provider 自己决定——官方 Office provider 把两个标记硬编码了、根本不读 frontmatter,所以改文件对它永远无效。

对所有 provider 都有效的杠杆是 registry 自己的去重规则:同一层内,rank 最小的候选赢下这个名字。所以本插件注册一个 provider,把每个被停用的技能用 rank: 0、
invocation: { modelInvocable: false, userInvocable: false } 重新声明一遍。这样它会从模型目录
和 / 菜单里消失,但在本页面仍然可见——连同原来的说明、provider 和正文——随时可以开回来。

集合存在一个 JSON 文件里:/storages/skill-mcp-panel.json,每次变更都会让 registry 的目录缓存失效。

删除技能

删除是真的删文件,不是另一种"停用"。目录型技能删的是整个 // 目录,所以它的 references/、scripts/ 一起走;其它情况只删那一个文件。确认框会在动手之前告诉你会走哪种模式。

| 技能来源 | 模式 | 行为 |
| 你自己的——project-dsh、project-agents、user-dsh、user-agents、custom | 永久删除 | 直接删掉,什么都不留 |
| 官方/包内的——bundled 及其它 | 移入回收站 | 文件离开原目录,但被移到回收站并列在 已删除 里,点 恢复 放回原位 |

这个区分依据 registry 自带的 source 字段——它本来就记录了谁拥有这个文件。你自己的技能是你的,删就删。官方技能不一样:删了会毁掉升级自带的文件,而且重装时会被悄悄还原;何况开关对 Office 技能本来就无解。把这一类存起来,能让唯一有效的杠杆保持可逆。

被移走的技能落在 /storages/skill-mcp-panel.trash//,带一个记着原路径的 manifest.json。恢复时会拒绝覆盖已经重新出现的路径;trash id 会被校验成单个路径段,所以回收站之外的东西都寻址不到。

删除永远是两步:操作行被替换成一个写着技能名的确认块,只有确认块里的"删除"才会请求宿主。

MCP 服务器

每个已配置的服务器一行。

| 控件 | 行为 |
| 命名空间 | mcp____,附状态、传输、工具数量的标签 |
| 目标 | 命令 …参数 那一行,或端点 URL |
| 开关 | 写 profile patch 里这一行的 disabled,和部署自己的插件列表完全一致 |
| 详情 | entry id、插件名、传输、脱敏后的配置、全部已注册工具,然后是 打开目录、编辑、删除 |
| 新建服务器 | 用新建表单替换列表,所以空状态和表单永远不会同时出现 |
| 删除 | 从 profile patch 移除这一行,然后等 Loader 真的卸载 |

新建/编辑表单

固定两列网格:服务器名和传输占第一行,然后是传输自己的字段——命令和工作目录,或者跨两列的地址——参数和环境变量并排、各三行。常见情况下用不到的东西(超时、启动失败即报错)收在一个更多选项 折叠里。

格式提示只放在控件的 placeholder 里,绝不写成控件下面的说明文字,所以没有字段会长出第二行,列也始终对齐。表单打开时会替换列表,这样标题栏就不可能提供一个"它自己就是"的按钮。编辑时才按需读取部署自己的表单投影,这是本页除技能正文之外唯一的单项读取。

打开目录

打开目录会揭开技能自己的目录,或 MCP 行所在的、装着 cordis.patch.yml 的 profile 目录。
它复用部署自身的能力,而不是重新实现平台启动:页面先问 GET /open-in-app/apps 这台宿主解析出的是哪个文件管理器(explorer、finder、filemanager),再向 POST /open-in-app/open 发 {app, path}。当目录里解析不到文件管理器时——比如通过 SSH 启动——这个控件干脆不出现。

目录永远来自宿主返回的 payload,宿主用 dirname 从自己已经解析过的路径推导。页面从不自己编路径。

新鲜度

没有任何轮询,也没有刷新按钮。列表在挂载时读一次(每次打开面板都会挂载),窗口重新获得焦点时再读一次(节流到每四秒最多一次),以及页面自己每次写入之后再读一次。所有会改动的控件都会自己重读列表,所以页面永远不会展示一个部署已经离开的状态。

安装

dsh plugin --profile desktop add

或者在 Agent 会话里用 plugin_manager,action: install_bundle,target 用本目录的绝对路径。

改宿主代码需要重启进程。 部署从 dsh.client 组合浏览器半边并热重载它的 bundle,所以 UI 改动刷新页面即可;而 Node 半边只被 import 进进程的 ESM 缓存一次,新的 lib/index.js 只有在应用重启后才生效。

发布到 npm

本仓库是这个插件的家;npm 是可选的第二个分发渠道。发布用 npm run publish:npm,之所以要专门写个脚本,是因为这个名字有两件事很容易搞错。

裸名字已经被占了。 npm 上的 dsh-skill-mcp-panel 属于另一个无关的 DSH 插件—— Fishquito7/dsh-skill-mcp-panel,它做的事基本一样、功能更多,而且还在活跃维护。不带 scope 发布会被 403 拒掉;而另起一个相近到让人混淆的名字,比不发还糟。所以脚本用当前登录者自己的 scope 发布,这样任何人都撞不到。

镜像不能接受发布。 ~/.npmrc 里的 registry= 常常是只读镜像,所以脚本永远显式打到 registry.npmjs.org。

npm login --registry=https://registry.npmjs.org/ # 只需一次;网站登录不算
npm run publish:npm

在 npmjs.com 网站登录和命令行登录不是一回事:npm 把浏览器会话和命令行分开,token 必须落到 ~/.npmrc 里。脚本发现没有 token 时会直接把这一点打印出来。

包名只在发布期间被替换,发布结束后会被还原——即使发布失败也还原——所以仓库始终保留自己的名字。
prepublishOnly 会跑测试作为门禁;再次发布前需要先升版本(npm version patch)。

目录结构

| 路径 | 作用 |
| package.json | 声明 dsh.bundle.patch 和 dsh.client 浏览器半边 |
| cordis.patch.yml | 把 Node 半边插进 profile 的 bundle patch |
| lib/index.js | Node 半边:/skill-mcp 读写接口 |
| lib/client.js | 浏览器半边:sidebar.panellist 入口和 main 页面 |
| test/host.test.mjs | Node 半边测试,跑在假宿主上,用真实 YAML 校验写入 |
| test/client.test.mjs | 浏览器半边渲染测试,跑在一个极小的、懂 hook 的渲染器上 |

没有构建步骤。 lib/ 既是源代码也是发布产物;浏览器半边是用模块表格式
(window.__ModuleLoader__.load({ id, factory }))手写的,所以不需要打包器,pnpm 也不用跑任何
依赖构建脚本。运行时零依赖。

测试

npm test

Node 自带测试运行器,83 个测试,零依赖。宿主套件在假宿主上下文上跑真实的 route handler,而这个假宿主的 config editor 用一个真实的 YAML 解析器去解析 profile patch——所以每个产出的文档都是被"写它的代码之外"的解析器校验过的。渲染套件用一个极小的、懂 hook 的渲染器渲染浏览器半边,并对渲染结果断言。

如果机器上没有任何 YAML 解析器,宿主套件照样能跑,只是不再用独立解析器校验产出文档。可以用 DSH_YAML_MODULE 指向一个来恢复这层校验。

宿主接口

所有接口都在一个前缀路由下。每个请求先过部署自己的信任闸门
ctx.connection.requestRejection()——和每一个官方宿主路由(包括 /open-in-app)用的是同一套
Host/Origin 加浏览器身份校验。没有 connection 服务的组合会退回到 Sec-Fetch-Site/Origin 检查。

| 路由 | 方法 | 用途 |
| /skill-mcp/state | GET | 合并快照;?bodies=0 跳过正文预览,?session= 指定技能读取的作用域 |
| /skill-mcp/skill | GET | 单个技能的完整定义,只用来补全正文 |
| /skill-mcp/skill/enabled | POST | { name, enabled }——写启用状态 overlay |
| /skill-mcp/skill/delete | POST | { name }——永久删除自己的技能,或把官方技能移入回收站 |
| /skill-mcp/skill/restore | POST | { trashId }——把移入回收站的技能放回去 |
| /skill-mcp/mcp/server | GET | 单个服务器的表单投影,由编辑表单按需读取 |
| /skill-mcp/mcp/save | POST | { entryId, config }——经 ctx.configEditor.edit() 持久化 |
| /skill-mcp/mcp/create | POST | { config }——向 profile patch 追加一行 |
| /skill-mcp/mcp/enabled | POST | { entryId, enabled }——写这一行的 disabled |
| /skill-mcp/mcp/delete | POST | { entryId }——从 profile patch 移除这一行 |

只有详情页的正文补全和编辑表单走单项路由;列表 payload 已经带了其它一切,所以展开一行永远不可能出现空面板。

Node 半边要求 webServer、connection、skills、tools,并通过 ctx.get(...) 读取可选的 agents、agentPresets、configEditor、hmr。技能读取的作用域按以下顺序解析:?session= 指定的会话、最新的存活根 Agent(带它的工作区 cwd)、默认 Agent preset 的常驻作用域、最后只有全局层;解析结果由 skills.scopeSource 报告。

写入为什么是安全的

- 配置编辑走 ctx.configEditor.edit():它会拿运行中的插件校验新值、调和 Loader,失败时回滚。
- 新建行、disabled 标记、删除行都是对 profile 自己的 patch 文件做文本补丁,经 ctx.hmr.runExclusive 串行化并原子写入。然后轮询 Loader:如果这一行六秒内没有挂载、标记没有生效、或者删掉的行仍然挂着,就把先前的文件内容还原,并带着原因失败。
- 技能启用状态只写本插件自己的 overlay 文档,并让 registry 的目录缓存失效。不改任何技能文件。
- 技能删除绝不跟随页面给的路径;由宿主自己解析技能、用自己的规则推导目标,并把 trash id 校验成单个路径段。
- 凭据永不进入浏览器。 列表和详情 payload 会把所有形如凭据的值替换成 keep 标记;表单把这些字段显示为空,保存空标记会还原已存储的值。全新的服务器没有东西可还原,所以空的凭据字段会被直接丢掉。

许可

MIT
预览分享卡片长什么样 ↓re-ITRT/dsh-skill-mcp-panel
分享 · DeepSeek Harness Hub
re-ITRT/dsh-skill-mcp-panel

管理 DeepSeek Harness 的技能列表和 MCP 服务器,以侧边栏面板挂载,主题完全取自宿主自身的设计 token。

回到顶部