# dsh-mcp-manager
A visual MCP manager β installed or not, connected or not, at a glance
Server list Add / Remove Enable / Disable Connection status Connectivity test zh / en
DeepSeek Harness DSH Desktop
Manage every MCP server in DeepSeek Harness from Settings β MCP,
no more hand-editing cordis.patch.yml β every change applies live (HMR hot reload).
[](https://www.npmjs.com/package/@js2hou/dsh-mcp-manager)
[](LICENSE)
[](https://github.com/anywhere-labs/deepseek-harness-desktop)
[](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin)
[](https://github.com/AwesomeHou/dsh-plugin-marketplace)
[](https://github.com/imsai-sh/awesome-deepseek-harness-plugins)
[](https://github.com/hikariming/dshfind)
## β¨ Features
- **π Server list** β every installed/enabled MCP server (`@deepseek-ai/dsh-mcp-client` instance): `serverName`, transport (`stdio` / `streamable-http`), URL / command, enabled state, loader phase, registered tool count
- **β Add / β Remove** β validated form for stdio and streamable-http servers (env / headers / args / timeout / failOnStartupError), duplicate id/serverName rejected; one-click removal
- **π Enable / Disable** β toggle anytime; tools hot-connect / hot-disconnect
- **πΆ Connection status** β live status pill per server (Connected Β· N tools / Failed / Loading / Disabled) plus an independent **Test** probe (`initialize` + `tools/list`) reporting latency and tool count
- **βοΈ Edit** β the edit form opens in place of the card being edited; save applies immediately
- **π Localized** β UI copy follows the DSH language (zh / en) in real time
- **πΎ Persistent** β every mutation is written to the profile's `cordis.patch.yml` and survives restarts; the footer shows the file path
## π Install
Listed on **[dsh-market](https://github.com/dsh-market/dsh-market)** and **[dsh-plugin-marketplace](https://github.com/AwesomeHou/dsh-plugin-marketplace)**.
**Prerequisites**: DSH installed and running (`dsh web` works).
### Option 1 Β· AI agent install
> Tell your agent: "Please install the dsh-mcp-manager plugin from https://github.com/Js2Hou/dsh-mcp-manager"
### Option 2 Β· Plugin marketplace (recommended)
Pick one of the marketplaces:
- **[DSH Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop) (community desktop build)**: built-in plugin market β pick the **DSH 1024Store** or **dshfind** source and search for `js2hou/dsh-mcp-manager` (several plugins share that name β pick the one by **Js2Hou**);
- **[dsh-market](https://github.com/dsh-market/dsh-market)**: search for `js2hou/dsh-mcp-manager` and install with one click;
- **[dsh-plugin-marketplace](https://github.com/AwesomeHou/dsh-plugin-marketplace)**: search for `js2hou/dsh-mcp-manager` and install with one click.
### Option 3 Β· dsh CLI
```sh
dsh plugin --profile web add @js2hou/dsh-mcp-manager
```
Or install straight from GitHub (the built `lib/` bundles are committed, so no local build is needed):
```sh
dsh plugin --profile web add github:Js2Hou/dsh-mcp-manager
```
Script install (one-liner: handles the 24h release-age gate and stale mounts, idempotent)
**macOS / Linux** (also Git Bash / WSL on Windows):
```sh
curl -fsSL https://raw.githubusercontent.com/Js2Hou/dsh-mcp-manager/main/scripts/install.sh | bash
```
**Windows (PowerShell 5.1+ / pwsh)**:
```powershell
irm https://raw.githubusercontent.com/Js2Hou/dsh-mcp-manager/main/scripts/install.ps1 | iex
```
Then **hard-refresh the browser** (Cmd/Ctrl+Shift+R) and open **Settings β MCP**. If the MCP tab does not appear, restart DSH once (first-time host mounting).
Manual install / local development
**macOS / Linux (bash)**:
```sh
cd ~/.dsh/profiles/web
# β Exclude a freshly published version from pnpm's 24h minimum-release-age
printf '\nminimumReleaseAgeExclude:\n - @js2hou/dsh-mcp-manager\n' >> pnpm-workspace.yaml
# β‘ Install + auto-mount (npm package; use an absolute link: path for a local checkout)
npx -y --package @deepseek-ai/dsh dsh plugin --profile web add @js2hou/dsh-mcp-manager
```
**Windows (PowerShell)**:
```powershell
cd ~\.dsh\profiles\web
# β Exclude fresh versions (one-time; merge the line if the key already exists)
Add-Content -Path pnpm-workspace.yaml -Value "`nminimumReleaseAgeExclude:`n - @js2hou/dsh-mcp-manager"
# β‘ Install + auto-mount
npx -y --package @deepseek-ai/dsh dsh plugin --profile web add @js2hou/dsh-mcp-manager
```
> `dsh plugin --profile web add` registers the dependency, detects the package's `dsh.bundle.patch`, and adds it to `dsh.profile.bundles` β no manual `cordis.patch.yml` edits needed.
**Local development**: clone the repo and run `bash scripts/install.sh` from its root (Windows: `powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1`); the script detects the checkout and installs it into `~/.dsh/profiles/web` via `link:`. Or pass the path explicitly: `dsh plugin --profile web add "link:C:/absolute/path/dsh-mcp-manager"`.
Update
```sh
dsh plugin --profile web add @js2hou/dsh-mcp-manager
```
Or re-run the one-liner; alternatively bump the version in `~/.dsh/profiles/web/package.json` and run `pnpm install`. Local-checkout mode: `git pull` then `pnpm build` (client changes need only a hard refresh; host changes need a DSH restart).
FAQ
| Symptom | Cause / fix |
|---|---|
| Not found in the plugin marketplace | Marketplace data syncs daily. Search again later, or install via Option 3 (`dsh plugin ...`). |
| `minimum release age` / version < 24h | The published version is younger than 24h. Wait, or re-run (the script appends `minimumReleaseAgeExclude`). |
| "Profile not found" | Run `dsh web` once to initialize `~/.dsh/profiles/web`. |
| **Two MCP tabs** | Double-mount: a stale manual `- insert: ... mcp-manager ...` row still lives in `cordis.patch.yml` β delete it (the script does this automatically). |
| No MCP tab after install | Hard refresh (Cmd/Ctrl+Shift+R); if still missing, restart DSH once (first-time host mounting). |
| Obsidian MCP returns 401 | Check the header format: `Authorization: Bearer ` without surrounding quotes (the form now strips quotes from pasted `"Key": "value"` lines). |
| Config change not applied | All mutations hot-apply via HMR within 1β2s; use the manual refresh button in the page header if needed. |
## π Usage
Open **Settings β MCP**:
- **Add server** β fill in the entry id, `serverName`, transport, and transport-specific fields (`streamable-http`: URL; `stdio`: command / args / env / cwd). The panel validates format and rejects duplicate ids / serverNames.
- Each card shows the live status, target, and tool count, with **Enable / Disable**, **Test** (connectivity probe), **Edit** (inline form), and **Remove**.
- The footer shows the patch file being edited.
## βοΈ Configuration
The plugin's loader row accepts one optional field:
| Field | Description |
|---|---|
| `patchFile` | Absolute path of the user patch layer to edit. Defaults to `$DSH_HOME/profiles/web/cordis.patch.yml`. |
## ποΈ Architecture
- **Host half** (`src/index.ts`) registers a loopback-only Connection RPC channel `/mcp-manager`: `list` (enumerates `@deepseek-ai/dsh-mcp-client` entries via `ctx.loader` + tool counts via `ctx.tools`), `add` / `remove` / `setEnabled` / `update` (edits the profile patch layer, persisted and HMR-applied), `probe` (independent MCP SDK connectivity probe), `patchInfo`. Zero runtime `@deepseek-ai` imports (the js-yaml `!!js` dialect and `isJsExpr` are inlined), so it can be installed from any path.
- **Browser half** (`src/client`) registers the Settings β MCP section (`settings.section` slot, order 18), provides zh/en copy via `ctx.locale`, and talks to the host exclusively over the RPC channel β it never touches the filesystem.
- **Test fixture** β `test/fixtures/mcp-test-server.mjs` is a minimal MCP stdio server for end-to-end verification.
## Development
```bash
pnpm install
pnpm typecheck # tsc --noEmit; tsconfig paths point at your DSH install's lib/types
pnpm build # esbuild: lib/index.js (host) + lib/client.js (ModuleLoader browser bundle)
```
## License
MIT