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

能力库 kaine380/dsh-mcp-unified-panel

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

统一管理 MCP 服务器与技能,支持浏览器授权

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · market
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
数据截至 2026/11/05·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/05·判据 →
还在维护吗[仓库]—
更新放缓:最近一次提交在 32 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

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

验证判据与等级说明 →

可信度证据

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

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

可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 92 处,展示前 81 条)
  • 读取本地文件
    lib/index.js:548
    const info = await stat(resolvePath(path)).catch(() => undefined);
  • 读取本地文件
    lib/index.js:619
    const scopedRaw = await readFile(entry.file, "utf8");
  • 读取本地文件
    lib/index.js:631
    const raw = await readFile(located.entry.file, "utf8");
  • 写入本地文件
    lib/index.js:664
    await rename(entry.file, target);
  • 写入本地文件
    lib/index.js:694
    await rename(skill.path, target);
  • 删除本地文件递归
    lib/index.js:704
    await rm(dirname(entry.file), { recursive: true, force: true });
  • 删除本地文件
    lib/index.js:706
    await rm(entry.file, { force: true });
  • 删除本地文件递归
    lib/index.js:730
    await rm(dirname(skill.path), { recursive: true, force: true });
  • 删除本地文件
    lib/index.js:732
    await rm(skill.path, { force: true });
  • 写入本地文件
    lib/index.js:967
    await mkdir(dirname(filePath), { recursive: true });
  • 写入本地文件
    lib/index.js:968
    await writeFile(filePath, write.data);
  • 写入本地文件
    lib/index.js:971
    await rename(staging, target);
  • 写入本地文件
    lib/index.js:975
    await rename(stagedFile, target);
  • 删除本地文件递归
    lib/index.js:976
    await rm(staging, { recursive: true, force: true }).catch(() => { });
  • 删除本地文件递归
    lib/index.js:982
    await rm(stagingBase, { recursive: true, force: true }).catch(() => { });
  • 读取本地文件
    lib/skill-files.js:34
    await access(path);
  • 读取本地文件
    lib/skill-files.js:225
    items = await readdir(dir, { withFileTypes: true });
  • 读取本地文件
    lib/skill-files.js:235
    || (item.isSymbolicLink() && (await stat(full).catch(() => undefined))?.isDirectory() === true);
  • 读取本地文件
    lib/skill-files.js:243
    const parsed = parseFrontmatter(await readFile(file, "utf8").catch(() => ""));
  • 读取本地文件
    lib/skill-files.js:265
    const parsed = parseFrontmatter(await readFile(full, "utf8").catch(() => ""));
  • 读取本地文件
    lib/skill-files.js:269
    const parsed = parseFrontmatter(await readFile(full, "utf8"));
  • 读取本地文件
    lib/scope.js:45
    const info = await stat(absolute).catch(() => undefined);
  • 读取本地文件
    lib/scope.js:75
    const raw = readFileSync(join(dshHome, "storages", "workspace.json"), "utf8");
  • 删除本地文件递归
    lib/scope.js:105
    await rm(path, { recursive: true, force: true });
  • 写入本地文件
    lib/scope.js:142
    await mkdir(targetRoot, { recursive: true });
  • 写入本地文件
    lib/scope.js:146
    await rename(sourceDir, target);
  • 写入本地文件
    lib/scope.js:160
    await rename(staging, target);
  • 写入本地文件
    lib/scope.js:163
    await mkdir(staging, { recursive: true });
  • 写入本地文件
    lib/scope.js:166
    await rename(stagedFile, target);
  • 删除本地文件递归
    lib/scope.js:167
    await rm(staging, { recursive: true, force: true }).catch(() => { });
  • 删除本地文件递归
    lib/scope.js:171
    await rm(staging, { recursive: true, force: true }).catch(() => { });
  • 删除本地文件递归
    lib/scope.js:181
    await rm(target, { recursive: true, force: true }).catch(() => { });
  • 读取本地文件
    lib/groups.js:37
    const parsed = JSON.parse(await readFile(groupsFile(dshHome), "utf8"));
  • 写入本地文件
    lib/groups.js:62
    await mkdir(groupsRoot(dshHome), { recursive: true });
  • 写入本地文件
    lib/groups.js:65
    await writeFile(tmp, JSON.stringify({ version: GROUPS_VERSION, groups }, void 0, 2) + "\n", "utf8");
  • 写入本地文件
    lib/groups.js:66
    await rename(tmp, target);
  • 读取本地文件
    lib/version.js:17
    const pkg = JSON.parse(readFileSync(fileURLToPath(new URL("../package.json", import.meta.url)), "utf8"));
  • 读取密钥环境变量
    lib/version.js:37
    const token = process.env.GITHUB_TOKEN?.trim() || process.env.GH_TOKEN?.trim();
  • 发起网络请求
    lib/version.js:38
    const response = await fetch(RELEASES_LATEST_URL, {
  • 执行外部命令固定命令
    lib/global-shim.js:22
    return execFileSync("npm", ["prefix", "-g"], { encoding: "utf8", windowsHide: true }).trim();
  • 读取本地文件
    lib/global-shim.js:29
    const old = existsSync(path) ? readFileSync(path, "utf8") : undefined;
  • 读取本地文件
    lib/global-shim.js:29
    const old = existsSync(path) ? readFileSync(path, "utf8") : undefined;
  • 写入本地文件
    lib/global-shim.js:32
    writeFileSync(path, content, mode !== undefined ? { mode } : "utf8");
  • 写入本地文件
    lib/global-shim.js:34
    chmodSync(path, mode);
  • 写入本地文件
    lib/global-shim.js:74
    mkdirSync(binDir, { recursive: true });
  • 读取本地文件
    lib/provider.js:81
    const raw = await readFile(candidate.locator.path, { encoding: "utf8", signal: options.signal });
  • 执行外部命令来自配置/变量
    lib/oauth-client/oauth.js:329
    const child = spawn(command.file, command.args, { stdio: 'ignore' });
  • 读取本地文件
    lib/cli-skill.js:84
    return Buffer.from((await readFile(fullPath, "utf8")).replace(/^ FEFF/, "").replace(/ /g, "\n").replace(/ /g, "\n"), "utf8");
  • 读取本地文件
    lib/cli-skill.js:91
    const items = await readdir(dir, { withFileTypes: true });
  • 读取本地文件
    lib/cli-skill.js:102
    const target = await stat(full).catch(() => undefined);
  • 读取本地文件
    lib/cli-skill.js:121
    const info = await stat(source).catch(() => undefined);
  • 读取本地文件
    lib/cli-skill.js:133
    const validation = validateFrontmatter(await readFile(skillMd, "utf8"));
  • 读取本地文件
    lib/cli-skill.js:144
    const validation = validateFrontmatter(await readFile(source, "utf8"));
  • 写入本地文件
    lib/cli-skill.js:181
    await mkdir(destRoot, { recursive: true });
  • 写入本地文件
    lib/cli-skill.js:187
    await mkdir(dirname(dest), { recursive: true });
  • 写入本地文件
    lib/cli-skill.js:189
    await writeFile(dest, await readNormalizedMd(file.full));
  • 写入本地文件
    lib/cli-skill.js:191
    await copyFile(file.full, dest);
  • 写入本地文件
    lib/cli-skill.js:193
    await rename(staging, target);
  • 写入本地文件
    lib/cli-skill.js:196
    await mkdir(staging, { recursive: true });
  • 删除本地文件递归
    lib/cli-skill.js:200
    await rm(staging, { recursive: true, force: true }).catch(() => { });
  • 删除本地文件递归
    lib/cli-skill.js:204
    await rm(staging, { recursive: true, force: true }).catch(() => { });
  • 删除本地文件递归
    lib/cli-skill.js:272
    await rm(tmpBase, { recursive: true, force: true }).catch(() => { });
  • 执行外部命令固定命令
    lib/cli-skill.js:311
    const child = spawn("dsh", ["plugin", "--profile", profile, "add", spec], {
  • 删除本地文件递归
    lib/cli-skill.js:717
    await rm(dirname(entry.file), { recursive: true, force: true });
  • 删除本地文件
    lib/cli-skill.js:719
    await rm(entry.file, { force: true });
  • 读取本地文件
    lib/cli-mcp.js:344
    const data = JSON.parse(await readFile(resolve(path), "utf8"));
  • 读取本地文件
    lib/profiles.js:37
    return JSON.parse(readFileSync(path, "utf8"));
  • 读取本地文件
    lib/profiles.js:78
    entries = readdirSync(root, { withFileTypes: true });
  • 读取本地文件
    lib/profiles.js:89
    if (!existsSync(join(root, entry.name, "package.json")))
  • 读取本地文件
    lib/profiles.js:103
    if (!existsSync(join(profilesRoot(home), name, "package.json")))
  • 读取本地文件
    lib/patch-editor.js:56
    return await readFile(path, "utf8");
  • 写入本地文件
    lib/patch-editor.js:216
    await writeFile(temp, content, "utf8");
  • 写入本地文件
    lib/patch-editor.js:218
    await rename(temp, path);
  • 删除本地文件
    lib/patch-editor.js:223
    await rm(path, { force: true });
  • 写入本地文件
    lib/patch-editor.js:224
    await rename(temp, path);
  • 删除本地文件
    lib/patch-editor.js:228
    await rm(temp, { force: true }).catch(() => { });
  • 读取本地文件
    lib/patch-editor.js:247
    const info = await stat(lockPath);
  • 删除本地文件
    lib/patch-editor.js:249
    await rm(lockPath, { force: true }).catch(() => { });
  • 删除本地文件
    lib/patch-editor.js:265
    await rm(lockPath, { force: true }).catch(() => { });
  • 发起网络请求
    lib/oauth-client/tools.js:31
    return client.request({ method: 'tools/list', ...cursor === undefined ? {} : { params: { cursor } } }, ListToolsResultSchema);
  • 发起网络请求
    lib/oauth-client/tools.js:35
    return client.request({ method: 'tools/call', params: { name: rawName, arguments: args } }, RawCallToolResultSchema, {
扫描于 2026/11/5(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-home-paths@deepseek-ai/dsh-subprocess@deepseek-ai/dsh-typert-protocol@deepseek-ai/schemastery@deepseek-ai/dsh
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 统一管理MCP服务器
  • 管理技能
  • 内置OAuth2.1授权

能力库(Unified MCP & Skill Hub):DeepSeek Harness 的一站式 MCP 与技能管理器,支持按功能识别行,内置 OAuth 2.1 客户端驱动。

README

由 DeepSeek 最新模型翻译生成
dsh-mcp-unified-panel 能力库 (Unified MCP & Skill Hub) DeepSeek Harness 一站式能力管理中心 —— 全功能 MCP 服务器管理、官方/第三方特征识别、原生 OAuth 2.1 浏览器授权、技能热管理。 中文 · English 🇨🇳 中文 📖 为什么需要它(解决的痛点) 在 DeepSeek Harness 生态中,管理 MCP 与技能一直面临三大痛点: 1. 官方 MCP 客户端不支持 OAuth 2.1 鉴权:官方 @deepseek-ai/dsh-mcp-client 仅支持 stdio 与静态 Token 请求头,无法完成类似 Cloudflare、GitHub Copilot 等现代 MCP 所需的 OAuth 2.1 + PKCE 浏览器交互授权。 2. 上游面板包名白名单封杀第三方:上游面板在 4 处核心逻辑中写死了 @deepseek-ai/dsh-mcp-client 包名白名单,导致所有第三方客户端挂载的行被整行丢弃,用户不仅在界面上看不到,更无法进行可视化启停与管理。
展开完整文档(README 剩余 1 节)
dsh-mcp-unified-panel

能力库 (Unified MCP & Skill Hub)

DeepSeek Harness 一站式能力管理中心 —— 全功能 MCP 服务器管理、官方/第三方特征识别、原生 OAuth 2.1 浏览器授权、技能热管理。

中文 · English

🇨🇳 中文

📖 为什么需要它(解决的痛点)

在 DeepSeek Harness 生态中,管理 MCP 与技能一直面临三大痛点:

1. 官方 MCP 客户端不支持 OAuth 2.1 鉴权:官方 @deepseek-ai/dsh-mcp-client 仅支持 stdio 与静态 Token 请求头,无法完成类似 Cloudflare、GitHub Copilot 等现代 MCP 所需的 OAuth 2.1 + PKCE 浏览器交互授权。
2. 上游面板包名白名单封杀第三方:上游面板在 4 处核心逻辑中写死了 @deepseek-ai/dsh-mcp-client 包名白名单,导致所有第三方客户端挂载的行被整行丢弃,用户不仅在界面上看不到,更无法进行可视化启停与管理。
3. 插件碎片化与设置页割裂:为了同时实现 MCP 运维、第三方支持与技能管理,用户不得不同时安装 dsh-skill-mcp-panel、dsh-plugin-manager、dsh-oauth-mcp-client 多个插件。不同插件各说各话,并在设置页留下一堆失效或多余的 Tab,极易产生并发写入冲突。

🌟 核心特性与能力

dsh-mcp-unified-panel 以 dsh-skill-mcp-panel@2.1.5 为底座,并深度融合 @dsh-external/dsh-oauth-mcp-client 的底层鉴权驱动,打造出真正的 All-in-One 开箱即用能力管理方案:

- 🚀 All-in-One 架构,零外部依赖:内置完整的 OAuth 2.1 客户端驱动(子路径导出 dsh-mcp-unified-panel/oauth-client)。用户只需安装本插件一个包,即可获得全量功能,设置面板干干净净。
- 🔍 特征识别替代包名白名单:采用结构化判据(id + config.serverName + 通讯协议特征),智能识别官方与第三方(如 OAuth)MCP 行。所有有效行全部同屏可见,并支持一键启停。
- ⚡ 原生 OAuth 2.1 浏览器授权:支持直接在面板通过「+ 添加 OAuth MCP」一键新增连接,自动派生 credentialRef 并触发系统默认浏览器完成 PKCE 授权,自动落盘凭证。
- 🛡️ YAML 字节保留与安全隔离:
- 官方外部行原地安全更新与启停,严格校验字段,!!js 动态表达式(如 Bearer Token 环境变量)百分之百无损往返。
- 第三方行严格隔离,只允许翻动 disabled 开关与一键卸载,绝不套用官方重写 Schema,杜绝破坏用户私有客户端配置。
- 🎨 精简现代的界面交互:
- 左侧侧边栏入口统一为「能力库」。
- 卡片右上角集成 ⚙️ 编辑、⚡ 连通性测试(真实检测并列出激活工具)、🗑️ 卸载图标(带防误触二次确认)。
- 采用 DSH 官方 @deepseek-ai/dsh-client-ui-primitives 原生组件,Switch 开关与 Checkbox 复选框质感与官方完全一致。
- 📦 完整的技能管理能力:保留了上游全部成熟的技能目录浏览、启用/停用、删除、新建导入、多工作区迁移与分组功能。

📦 安装指南

方式一:DSH 插件市场安装(推荐)

在 DSH 插件市场中搜索 dsh-mcp-unified-panel 或 能力库,点击安装即可。

方式二:命令行安装

在你使用的 profile 下安装(以 desktop profile 为例):
dsh plugin --profile desktop add dsh-mcp-unified-panel

安装后重启 DSH 桌面端即可在侧边栏看到「能力库」入口。

🛠️ 命令行支持 (CLI)

插件内置统一的 CLI 工具 dsh-mcp-unified:

查看所有 MCP 服务器状态(含官方受管、外部行、第三方 OAuth) dsh-mcp-unified mcp list --profile desktop

启停任一 MCP 服务器(支持官方与第三方) dsh-mcp-unified mcp enable <serverName> --profile desktop dsh-mcp-unified mcp disable <serverName> --profile desktop

新增 OAuth MCP 连接并触发鉴权 dsh-mcp-unified mcp oauth-add --name cloudflare-api --url https://mcp.cloudflare.com/mcp --profile desktop

卸载指定 OAuth MCP 连接 dsh-mcp-unified mcp oauth-remove <serverName> --profile desktop

🙏 致敬与开源底座

本项目站在巨人的肩膀上:
- 感谢 dsh-skill-mcp-panel 提供的强大侧边栏面板与技能管理框架。
- 感谢 @dsh-external/dsh-oauth-mcp-client 提供的优雅的 MCP OAuth 2.1 协议实现。

🌐 English

📖 动机与问题陈述

在 DeepSeek Harness 生态中,管理 Model Context Protocol(MCP)服务器和 Agent Skills 长期受制于几个关键限制:

1. 官方客户端不支持 OAuth 2.1:官方 @deepseek-ai/dsh-mcp-client 只支持 stdio 和静态 HTTP headers,无法处理 Cloudflare、GitHub Copilot 等服务要求的现代 OAuth 2.1 + PKCE 浏览器授权。
2. 上游白名单排除第三方客户端:上游面板在四个传播点把 @deepseek-ai/dsh-mcp-client 硬编码进白名单,第三方和基于 OAuth 的线路在 UI 里被完全丢弃。
3. 插件碎片化与冗余:用户以前得同时应付 dsh-skill-mcp-panel、dsh-plugin-manager 和 dsh-oauth-mcp-client,导致配置冲突、UI 杂乱、设置标签页孤立。

🌟 核心特性

dsh-mcp-unified-panel 基于 dsh-skill-mcp-panel@2.1.5 构建,由 @dsh-external/dsh-oauth-mcp-client 的 OAuth 引擎驱动,带来真正统一、All-in-One 的体验:

- 🚀 All-in-One 独立架构:内置完整的 OAuth MCP 客户端驱动(dsh-mcp-unified-panel/oauth-client)。你只装这一个包就能获得全部功能,无需额外依赖。
- 🔍 基于特性的识别:用结构化特性检测取代死板的包白名单。官方和第三方 MCP 服务器并排可见、可控。
- ⚡ 交互式 OAuth 2.1 认证:一键添加 OAuth MCP 端点。自动协调 PKCE 循环,打开默认浏览器授权,并安全持久化 token。
- 🛡️ 字节级保真的 YAML 安全:
- 官方 MCP 原地更新,同时保证 !!js 表达式(如 Bearer 环境变量)原样保留。
- 第三方行安全隔离:只允许开关和卸载,绝不用官方 schema 覆盖第三方定义。
- 🎨 干净统一的原生 UI:
- 侧边栏入口简洁标注为 「能力库」。
- 卡片右上角有 ⚙️ 编辑、⚡ 实时测试(探测并列出活跃工具)、🗑️ 卸载(带确认)。
- 开关和复选框使用原生 @deepseek-ai/dsh-client-ui-primitives 组件,外观与手感 100% 一致。
- 📦 完整技能管理套件:继承 Agent Skills 的完整目录检查、工作区迁移和分组功能。

📦 安装

Install into your target profile (e.g., desktop):
dsh plugin --profile desktop add dsh-mcp-unified-panel

安装后重启 DeepSeek Harness,面板即可在侧边栏激活。

📄 许可证

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

统一管理 MCP 服务器与技能,支持浏览器授权

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