Manages DSH skills and MCP servers from the web settings: skill cards with hot enable/disable, workspace scopes, groups, batch migration and drag-and-drop import, plus stdio/HTTP MCP CRUD with connection tests, secret redaction and the unified dsh-panel CLI.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-skill-mcp-panel
# from a prebuilt release tarball
dsh plugin --profile web add "https://github.com/Fishquito7/dsh-skill-mcp-panel/releases/download/v2.0.2/dsh-skill-mcp-panel-2.0.2.tgz"
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:Fishquito7/dsh-skill-mcp-panel
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
dsh-skill-mcp-panel
Manage DSH skills and MCP servers right from the DSH web sidebar, plus the unified dsh-panel CLI
A DSH plugin that brings skill and MCP server management into the DSH web home sidebar — click Skill/MCP in the left column and the center main area switches to a full panel (not a modal, not a tab in the Settings dialog), and changes take effect immediately. The package also ships the unified dsh-panel command: everything the panels can do, plus cross-profile upgrades.
- 🗂️ Skill management — list and preview installed skills, search, workspace split and group filters, expand a card to read the full content, hot enable/disable and delete, plus
.md/.zip/ skill-folder adding and batch migration - 🔌 MCP server management — visually maintain the MCP managed block in the profile's
cordis.patch.yml, with Stdio / HTTP transports, connection tests, and hot reload through DSH HMR after saving - 🧩 Full panels, not modals — the same slot mechanism as the host's built-in Plugins page; clicking the left column swaps the center main area, and each panel carries a “← Back to session” arrow
- ⌨️ The
dsh-panelCLI —dsh-panel skill …anddsh-panel mcp …expose everything the two panels can do - 📦 Works out of the box — both the npm package and the Release tarball ship prebuilt artifacts
Profile note: the
mcpsub-commands require an explicit--profile <name>, and the name must already exist — a typo is rejected rather than creating a profile. Theskillsub-commands are not split per profile (skills live under the user root / workspace), so they need no--profile.dsh-panel updatewithout--profileupdates every profile that has the plugin installed (desktopis owned by the desktop app and is skipped automatically).
Contents: Screenshots · Install · Features · CLI · How it works · Development · Uninstall · Changelog · Links · License
Screenshots
The panels live in the home sidebar, right below Plugins (moved there from the Settings dialog in v2.1.0). Clicking Skills/MCP swaps the center main area to that panel, and each panel's top-left “← Back to session” arrow returns you to the session you were reading.
Install
Install the package (its bundle layer auto-mounts it — no config editing). Pick either:
Option 1: GitHub Release tarball (recommended — always the latest)
dsh plugin --profile web add https://github.com/Fishquito7/dsh-skill-mcp-panel/releases/latest/download/dsh-skill-mcp-panel.tgzThis is the version-less stable link: every release uploads both the
dsh-skill-mcp-panel.tgzalias (always pointing at the latest build) and a versioneddsh-skill-mcp-panel-<version>.tgz, so this command never needs editing. To pin a specific version, swaplatest/download/dsh-skill-mcp-panel.tgzfordownload/v<version>/dsh-skill-mcp-panel-<version>.tgz.Option 2: npm (prebuilt, same channel as the plugin marketplace)
dsh plugin --profile web add dsh-skill-mcp-panelBoth install prebuilt artifacts — no local build needed. Installing from git also works (git-hosted dependencies are blocked from running their prepare build scripts by default; if you see
git-hosted plugins build on install..., add the key pnpm printed underallowBuildsin the profile'spnpm-workspace.yamland re-run):dsh plugin --profile web add github:Fishquito7/dsh-skill-mcp-panelRestart the gateway
dsh-restartThen refresh the page: right below Plugins the left column lists a single merged Skill/MCP row — clicking it swaps the center main area to the panel, and tabs inside the panel switch between Skills and MCP.
Features
The panel works exactly like the host's built-in Plugins page: a single Skill/MCP row in the left column swaps the center main area to the panel — no Settings tab, no dialog. Tabs inside the panel switch between Skills and MCP and remember the page you left; ← Back to session takes you back to where you were.
Skills panel
- List and cards — search by name and expand a card for the full content; split by workspace (global / each workspace) and filter by group or by origin
- Enable, disable, delete — the switch is hot (it renames
SKILL.mdon disk) and delete is undoable; skills shipped by plugins can be hidden with one checkbox - Add — use "+" or drop files, archives or skill folders straight onto the page:
.md,.zipand whole folders all work, and a folder holding several skills imports in one go; invalid items and same-name items within the target scope are skipped with a reason - Migrate — copy or move skills in bulk to several workspaces; one failure never aborts the rest
- Groups — create, rename and delete groups and batch-check members; groups live only in the plugin's own display config, skill directories are never touched
MCP panel
- Server management — Stdio and HTTP transports: add, edit, enable/disable, delete and test connections; saving is hot-reloaded by DSH HMR, no gateway restart. Only the panel's own managed block is edited — everything else in
cordis.patch.yml(including rows inside the block that are not ours) is preserved byte for byte - Secrets —
env/headersare redacted in the UI and in RPC, an omitted key keeps its old value, and${NAME}in a value reads that environment variable - Disable individual tools — turn tools off by name; a disabled tool disappears from the model-facing tool list instead of being merely refused at call time, so the context saving is real
- OAuth sign-in — one click for a remote
streamable-httpserver that supports it (authorization-server discovery, dynamic client registration, authorization code + PKCE); the token is written back into that row and hot-reloaded, and it can be disconnected at any time
DSH version compatibility
Only DSH 0.2.x is supported (peer declaration >=0.2.0-rc.1 <0.3.0-0). DSH checks that declaration at install time and again at profile startup, refusing to load and printing the exact-version exemption when it does not match — no silent breakage. The upper bound is <0.3.0-0 because the check runs with includePrerelease, so <0.3.0 would let 0.3.0-rc.1 through.
If you really need it on an older host, grant the exemption the host prints:
dsh plugin --profile web allow-version dsh-skill-mcp-panel@2.3.1 --dsh-version <host-version> --accept-risk
CLI
The unified parent command is dsh-panel.
Global shim: at startup the host writes
dsh-panelinto the npm global bin directory. On Windows that is three files —dsh-panel.cmd(CMD),dsh-panel.ps1(PowerShell) and an extension-lessdsh-panelsh script (what Git Bash / MSYS2 / Cygwin look for; without it bash sayscommand not found, which is what v2.1.5 fixed); on macOS / Linux it is a single executabledsh-panel. All of them point at the plugin copy of whichever profile started last.
The mcp sub-commands require an explicit --profile <name>, and the name must already exist (a profile is a directory with a package.json under $DSH_HOME/profiles/<name>). A typo exits with code 2 — it will not silently create a profile the way dsh plugin does. The skill sub-commands do not need it: skills live under the user root / workspace and are not split per profile. dsh-panel update without --profile updates every profile that has the plugin installed.
Profile overview
dsh-panel profiles # installed version / bundle mount / install spec for every profile
The first line is the current dsh-panel entry point and its version. That matters: dsh-panel is a single global shim, written by whichever profile booted last (src/global-shim.ts), so it has no necessary relationship to any row in that table.
Skill sub-commands
dsh-panel skill --help
dsh-panel skill list # list skills (with scope: global / workspace)
dsh-panel skill add <path> # add to global (.md file, bundle dir, or .zip archive)
dsh-panel skill add <path> --workspace D:\projA # add directly into a workspace
dsh-panel skill scope <name> --global # migrate one skill to global
dsh-panel skill scope <name> --workspace D:\projA # migrate one skill into a workspace (--copy to copy)
dsh-panel skill migrate <name...|--all> --from <global|path> --to <global|path> [--copy] [--yes]
dsh-panel skill disable <name> # disable
dsh-panel skill enable <name> # enable
dsh-panel skill delete <name> # delete (asks for confirmation)
Skill files are shared globally (~/.dsh/skills and <workspace>/.dsh/skills) and are not split per profile, so the skill sub-commands need no --profile. Passing it optionally confirms that profile exists and warns you when it has not mounted this plugin in dsh.profile.bundles (such a profile simply will not show the panels).
MCP sub-commands
dsh-panel mcp list --profile web
dsh-panel mcp add --name <serverName> --stdio --command <cmd> [--args <arg> ...] [--env KEY=VALUE ...] [--cwd <path>] --profile web
dsh-panel mcp add --name <serverName> --http --url <url> [--header KEY=VALUE ...] --profile web
dsh-panel mcp enable|disable <serverName> --profile web
dsh-panel mcp remove <serverName> [--yes] --profile web
dsh-panel mcp test <serverName> --profile web
Write ${NAME} in a value to read that environment variable (it is formatted into a !!js expression in cordis.patch.yml, evaluated by DSH at load time); a !!js prefix passes a raw JS expression through:
dsh-panel mcp add --name github --stdio --command npx --args -y --args @modelcontextprotocol/server-github \
--env 'GITHUB_TOKEN=${GITHUB_TOKEN}' --profile web
dsh-panel mcp add --name web --http --url https://example.com/mcp \
--header 'Authorization=Bearer ${MCP_TOKEN}' --profile web
# advanced: a raw JS expression, stored inside a !!js tag
dsh-panel mcp add --name web2 --http --url https://example.com/mcp \
--header 'Authorization=!!js `Bearer ${process.env.MCP_TOKEN}`' --profile web
dsh-panel mcp add --name github --stdio --command npx --args -y --args @modelcontextprotocol/server-github \
--env 'GITHUB_TOKEN=!!js process.env.GITHUB_TOKEN' --profile web
dsh-panel mcp add --name web --http --url https://example.com/mcp \
--header 'Authorization=!!js `Bearer ${process.env.MCP_TOKEN}`' --profile web
MCP configuration is written to the managed block in the target profile's cordis.patch.yml and hot-reloaded while the gateway is online. The block is delimited by # >>> dsh-skill-mcp-panel:mcp:begin / # <<< ...end — do not edit inside it.
Updating the plugin
dsh-panel update # update every profile that has the plugin installed
dsh-panel update --yes # same, without prompting
dsh-panel update --profile web # update only web
dsh-panel mcp update # same as dsh-panel update
- The comparison baseline is the version each profile has installed in its own
node_modules, not the version of whichever CLI copy happens to be running. - Updates stay on the channel that profile was installed from: a tarball install updates from the versioned
tarball URL, an npm install updates from npm pinned to that version, and a git (or unknown) install keeps
using
github:Fishquito7/dsh-skill-mcp-panel#v<version>. - Profiles already on the latest version are skipped, never reinstalled.
desktopis owned exclusively by the DSH desktop app — the host rejectsdsh plugin --profile desktop; it is skipped with an explanation during an automatic sweep, and exits with code 2 when named explicitly.- After an update: client bundles hot-swap (just refresh the page); server-side changes need that profile's gateway restarted.
The CLI only scans the cwd-anchored project roots and the user roots; add --cwd <workspace-path> to manage a different workspace's skills. If a skill name exists in several scopes, enable/disable/delete require --global/--project/--workspace to pick which copy to operate on.
add is not in that set: as long as the target scope has no skill of that name, adding one that already exists elsewhere succeeds and only prints a notice (v2.1.7).
How it works
Skills
Every action in the page or via dsh-panel skill ends up as a change to the skill files on disk (SKILL.md), and DSH's own file watcher notices immediately — that is why enable/disable, add/delete and migration are all hot, with no gateway restart.
- A skill's entity lives directly in its workspace's skill folder: global =
~/.dsh/skills, workspace =<workspace>/.dsh/skills— no hidden store, no junctions: after uninstalling the plugin the skills are plain files DSH keeps discovering - Disable = rename
SKILL.mdtoSKILL.md.disabled; enable = rename it back - Changing where a skill lives = physically copying/moving the files into the target folder (validated first, rolled back on failure)
- Deployment-bundled skills are read-only: they cannot be disabled or deleted
MCP
The plugin writes MCP server configuration into the managed block in the profile's cordis.patch.yml; the actual connection and tool registration are done by the official DSH plugin @deepseek-ai/dsh-mcp-client, loaded automatically through DSH HMR.
Development
The source is TypeScript under src/; the compiled lib/*.js is committed with the repo (so git installs keep working).
After editing the source, run pnpm build: tsc compiles to lib/ and strips the extra module marker from the browser bundle.
When publishing, npm pack rebuilds automatically through prepack — no manual compile step.
Uninstall
dsh plugin --profile web remove dsh-skill-mcp-panel
Changelog
Only version notes that change how you use the plugin; see Releases for the full history.
v2.3.1 — fixes #51: the per-tool disabling panel would not open (
remote[method] is not a function). The cause is blunt: the browser bundle carries its own Remote method list, and the client only knows methods mounted from that list — v2.2.0 addedlistTools/getToolFilter/setToolFilterplus the OAuth trio to the host-side list only, so clicking “Tools” always threw. The card's OAuth sign-in / disconnect buttons had the same root cause and are fixed too. A newtest-client-contribution.mjscompares both lists in both directions so this cannot slip againv2.3.0 — DSH
0.2.xonly (peer raised to>=0.2.0-rc.1 <0.3.0-0; every 0.1.x compatibility branch is gone: icons no longer fall back to the pixel-suffixed names, and the strict codec dropped itsschemafield); DSH0.2.1support: the protocol dependency is pinned to@deepseek-ai/dsh-typert-protocol@^0.2.1-rc.1and its peer@deepseek-ai/cordisis now declared explicitly (the old^0.1.0-rc.6installed a pre-0.2 protocol into the profile, which DSH 0.2.1 rejected with “strict definition withdrawn” and took both pages down; a missingcordispeer broke even the import — issue #48); the two pure helpers we used fromdsh-home-paths/dsh-subprocessare inlined so their peer chains disappear; MCP cards gain OAuth sign-in / sign-in again / disconnect buttons (the CLI capability, now in the panel: open the authorization page, poll until done)v2.2.0 — frontend rebuilt to the new design (three columns: workspaces, groups, content; batch select + migrate; undoable deletes); #46 fixed: foreign rows inside the managed block are preserved (a save used to roll back every dsh-market update, see ADR-0003); MCP gains per-tool disabling (a real context saving, see ADR-0005) and OAuth sign-in (
dsh-panel mcp oauth); the skills page gains grouping by origin and a scrollable workspace rail (#42);dsh-panel skill addnarrows its name check to the target scope (ADR-0002)v2.1.7 — the name-conflict test in “Adding skills” is narrowed to the target scope: it used to reject an add whenever the same name existed anywhere on the machine (another workspace, the global root), now only a same name inside the target scope is skipped; a same name in another scope is added and reported as a notice (
dsh-panel skill addbehaves the same). See ADR-0002: DSH resolves duplicate names by root rank, a workspace's discovery roots are resolved from the session cwd (other workspaces are not on that chain), and every other row-level operation already keys on (name + scope)v2.1.6 — the add flow is fixed: the folder picker no longer drops the selected folder’s own name (until now, picking any valid bundle was answered with a bogus “missing a top-level SKILL.md”); all three entry points (files / folder·ZIP / drag & drop) classify through one rule — a selection that directly contains
SKILL.mdis a single skill bundle (top-level dependency.mdfiles plusreferences/,scripts/are payload and are no longer validated as skills), otherwise every skill found inside is discovered recursively and flattened to the first level of the skill root, so a folder holding several skills imports in one go (ZIP included); invalid, duplicate and conflicting items are skipped with a reason, and only a total failure is an error.dsh-panel skill addmatches the panelv2.1.5 — the sidebar’s Skills and MCP rows merge into one “Skill/MCP” row (with a new merged-entry icon) plus tabs inside the panel (the tab you left is remembered); a new “show plugin skills” switch; MCP environment variables accept the intuitive
${NAME}form (the panel/CLI formats them into!!js, and they read back as${NAME}instead of being flattened into a literal), a new “How it works” note on the MCP page, and grey examples on empty fields; an extension-less bash shim on Windows;dsh-panel updatestays on each profile’s original install channel (tarball / npm / git) and the README install guide uses the version-less stable tarball linkv2.1.3 — DSH
0.2.0support (peer upper bound raised to<0.3.0-0, without which the host denies the whole row at profile startup); an illegal MCP server name no longer answers with a bare gateway errorv2.1.2 —
mcpsub-commands require an explicit--profile, a typo is rejected instead of creating a profile;dsh-panel updateupdates every profile; newdsh-panel profilesv2.1.1 — DSH
0.1.7support for the host's renamed icon exports, so the Skills page renders againv2.1.0 — the panels moved from the Settings dialog to the home sidebar, each with a “← Back to session” arrow
v2.0.0 — the MCP panel
Links
- npm package: dsh-skill-mcp-panel
- Releases: github.com/Fishquito7/dsh-skill-mcp-panel/releases
- Issues: github.com/Fishquito7/dsh-skill-mcp-panel/issues
- Chinese docs: README.md
License
MIT
Links
More in this category
yjh051108/dsh-routing-suite★ 6997
One repository, three parts: a runtime injector for DSH plugin packages (inject, hot-reload, unload, promote a dev staging tool to the front, route self-heal, plus a settings-page plugin manager that lists, unloads and drags folders in to internalize), a task-aware reasoning-mode router agent preset (router-standard / router-spec / router-react), and a graded two-level task protocol whose six tools (commit_star, lock_stage, revise_do, edit_plan, mark_task, redteam_verdict) pin task state to disk. The injector implementation ships in-tree, so the install carries its own behaviour rather than a dependency list.
strukto-ai/mirage#dsh★ 3696
Swaps the filesystem and bash providers for a mirage virtual workspace: file tools and shell commands run over mounted resources (RAM, S3, Redis, Slack, Gmail, Notion, Postgres) instead of the host disk, with per-mount read/write/exec modes, per-command sandbox routing (monty, pyodide, quickjs in process; docker, e2b, daytona remote), and installed CLIs (git, gh, slack, linear, ntn, gws, or one you register) as head words in the virtual terminal.
first-fluke/oh-my-agent#dsh★ 1344
Runs project OMA checks before and after tool execution and when a turn tries to finish. Installs its OMA CLI dependency and initializes unconfigured projects on first use. Requires Node.js 22+; initial setup needs network access and project write access.
hust-open-atom-club/oh-dsh★ 322
Community distribution: TUI, desktop, and Web UI as one bundle with layered installation.
weijiafu14/pi2dsh★ 217
Pi Host ABI compatibility engine: after one install, unmodified Pi extensions from npm mount as native DSH plugins with `dsh plugin add <pi-package>`. Verified end to end on stock DSH with pi-mcp-adapter (full MCP manager: OAuth, resources, prompts, MCP Apps, elicitation, sampling), @tintinweb/pi-subagents, pi-code, pi-hermes-memory and pi-background-tasks; `pi2dsh inspect` reports a package's compatibility before installing.
MichengAI/dsh-skills-manager★ 194
Manages local DeepSeek Harness skills in Settings and shows shared Agent skills as read-only.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.