Bundle
@dsh-mixxed/dsh-client-ui-settings-mcp
MCP server manager for DeepSeek Harness: manage MCP servers from the Web settings page, stored globally in $DSH_HOME/ui-settings-mcp.json, connected/disconnected at runtime.
- Source
- dsh-mixxed
- stars
- 1 stars
- License
- MIT
- Updated
- Updated 5 days ago
Readme
# @dsh-mixxed/dsh-client-ui-settings-mcp
[English](README.md) | [中文](README.zh.md) · [](https://www.npmjs.com/package/@dsh-mixxed/dsh-client-ui-settings-mcp) · [](LICENSE)
Manage **MCP servers** right from the DeepSeek Harness Web settings page — add, edit, enable/disable, reconnect and delete servers at runtime, with live status, automatic reconnect and config-file hot sync.
## Features
- **Web settings UI** — a dedicated "MCP Server Manager" page: server cards with live status, an add/edit form, and two-step delete protection.
- **Runtime connections** — servers connect/disconnect on the fly; tools are registered globally as `mcp__<serverName>__<tool>` for every session.
- **Tool inspector** — each server card can be expanded to list the live tool names and descriptions the server exposes.
- **Live status** — reachability probing so a closed server shows **offline** instead of a stale "connected"; a stuck connection times out after 30 s.
- **Auto-reconnect** — a failed initial connect retries with exponential backoff (3 s → 60 s); pressing refresh retries immediately.
- **Enable/disable** — switch a server off to disconnect and unload its tools; switch it on to reconnect.
- **Config file hot sync** — `$DSH_HOME/ui-settings-mcp.json` is watched; external edits take effect within ~1 s, no restart needed.
- **Themes & i18n** — follows DSH light/dark mode (and `--dsw-alias-*` token overrides from appearance plugins); UI ships in **简体中文 / English**.
## Screenshot

## Install
### For humans
**Option 1 — from npm (easiest):**
```sh
dsh plugin --profile web add @dsh-mixxed/dsh-client-ui-settings-mcp
```
The package declares `dsh.bundle`, so `dsh plugin add` installs it and **automatically appends it to the profile's `dsh.profile.bundles` layer stack** — the plugin row mounts on the next boot. No manual `cordis.patch.yml` editing.
Upgrading an install that predates the bundle declaration: remove the legacy `ui-settings-mcp` row from `$DSH_HOME/profiles/<name>/cordis.patch.yml` — the bundle layer now supplies it, and leaving both would mount the id twice.
**Option 2 — from source:**
1. Clone and build:
```sh
git clone https://github.com/dsh-mixxed/dsh-client-ui-settings-mcp.git
cd dsh-client-ui-settings-mcp && npm install && npm run build # lib/ is generated by esbuild (prepack does it on publish)
```
2. Install into the profile from the folder that contains the clone (no absolute path needed):
```sh
dsh plugin --profile web add ./dsh-client-ui-settings-mcp
```
The local package also declares `dsh.bundle`, so the profile-layer auto-mount above applies the same way.
**Then** — **restart `dsh web`** and hard-refresh the browser page (`Ctrl+Shift+R`) so the new `__DSH_BOOT__` loads, then open **Settings → MCP Server Manager** and add your first server.
> Note: hot reload of `cordis.patch.yml` is disabled on the Web surface (DSH's shared HMR row is off), so configuration changes need a restart. Plugin-set changes (new rows) need a restart for the client `pkgMeta` cache to notice the new package.
### For AI agents
Follow every step, in order:
1. **Read this README in full** (especially *Features*, *Known limitations*, and this install section).
2. **Install the package** (npm is preferred): run `dsh plugin --profile <profile> add @dsh-mixxed/dsh-client-ui-settings-mcp` in the profile you use (or `npm install @dsh-mixxed/dsh-client-ui-settings-mcp` in `$DSH_HOME/profiles/<profile>` and use Option 2 below for the file layout).
- **Build/source fallback**: clone this repo, `cd dsh-client-ui-settings-mcp`, run `npm install --ignore-scripts && npm run build` (produces self-contained `lib/index.js` + `lib/client.js`; zero runtime dependencies), then run `dsh plugin --profile <profile> add <path-to-clone>` from the clone's parent directory (or link the folder into `$DSH_HOME/profiles/<profile>/node_modules/@dsh-mixxed/dsh-client-ui-settings-mcp` — directory junction on Windows, symlink on POSIX).
3. **No manual mount row needed** — the package declares `dsh.bundle`, so `dsh plugin add` appends it to the profile's bundle layers automatically (verify with `dsh --profile <profile> --dump-config`: the `ui-settings-mcp` row must be present).
4. **Restart `dsh web`** (Web-surface config hot reload is disabled) and tell the user to **hard-refresh** the browser so the settings page shows the new section.
5. **Verify**: `GET http://127.0.0.1:3080/ui-settings-mcp/api/health` must return `{"ok":true,"name":"ui-settings-mcp","version":"<x.y.z>",...}`.
## Usage
Open **Settings → MCP Server Manager**:
- **Server cards** show the name, transport, status badge and endpoint; disabled cards are dimmed.
- **Tool inspector** — click "Show tools (n)" on a card to expand the live list of that server's tool names and descriptions.
- **Enable/disable switch** — disabling disconnects immediately and unloads the server's tools.
- **Reconnect** — waits for the connection result and refreshes automatically (configurable wait, default 15 s).
- **Edit** — change transport / URL / command / headers (`serverName` is immutable); saving hot-reconfigures the live connection.
- **Delete** — lives at the top of the edit page, behind a two-step confirm (3 s window).
- **Add** — `streamable-http` (URL + optional headers) or `stdio` (command + args), with a configurable connection-wait timeout.
### Statuses
| Status | Meaning |
|---|---|
| Connected (n tools) | tools are registered |
| Connecting | handshake / reconnecting in progress |
| Offline | was connected, but the server process is unreachable (probed) |
| Error | initial connect failed (reason shown) or 30 s connect timeout |
| Disabled | switched off — not connected, no tools |
### Configuration file
`$DSH_HOME/ui-settings-mcp.json` — shared by every profile and session:
```json
{
"version": 1,
"servers": [
{ "serverName": "my-server", "transport": "streamable-http", "url": "http://127.0.0.1:8080/mcp", "enabled": true }
]
}
```
The file is **watched live**: manual edits (add / remove / change / enable) take effect within ~1 s; `POST /ui-settings-mcp/api/reload` triggers it on demand.
### HTTP API
| Method | Path | Purpose |
|---|---|---|
| GET | `/ui-settings-mcp/api/health` | liveness + version + store path |
| GET | `/ui-settings-mcp/api/servers` | list with live (probed) status |
| GET | `/ui-settings-mcp/api/servers/<name>` | single server |
| POST | `/ui-settings-mcp/api/servers` | add & connect |
| POST | `/ui-settings-mcp/api/servers/<name>/update` | update config & hot-reconnect (`serverName` immutable) |
| POST | `/ui-settings-mcp/api/servers/<name>/toggle` | enable / disable (`{"enabled": true|false}`) |
| POST | `/ui-settings-mcp/api/servers/<name>/reconnect` | disconnect & reconnect |
| DELETE | `/ui-settings-mcp/api/servers/<name>` | disconnect & delete |
| POST | `/ui-settings-mcp/api/reload` | re-read the config file from disk |
## Security
The `/ui-settings-mcp/*` API can start `stdio` servers — i.e. execute arbitrary commands — so it is gated by the bind address:
- **Loopback-only by default.** When `dsh web` binds to `127.0.0.1` (the default), the API is open — the single-user local posture.
- **Network-exposure guard.** When `dsh web` binds to a non-loopback address (`--host 0.0.0.0`), the manager logs a loud error and **rejects all `/ui-settings-mcp/*` requests** (403) because stdio servers execute arbitrary commands. There is no remote-management path.
- Per-server authentication (e.g. `Authorization` headers for a specific MCP server) is configured per server in the add/edit form's **Headers** field — the API itself needs no token.
## Development
```sh
npm install # build-only devDependencies
npm run build # esbuild: lib/index.js (host, fully bundled) + lib/client.js (browser)
npm run watch # watch the client bundle (works with dsh-client-hmr)
```
**Publishing**: bump `version` in `package.json`, then `npm publish` (the `prepack` script builds `lib/` automatically before packing; the package ships `lib/`, `cordis.patch.yml` (the `dsh.bundle` patch layer), both READMEs + LICENSE).
No runtime dependencies: the host half inlines `@deepseek-ai/dsh-mcp-client`, the MCP SDK and `cross-spawn`; the browser half is a closure-factory bundle served by DSH's client module system.
## Known limitations
- **Initial failure retries with backoff, not instantly** — `failOnStartupError` is on, so a failed first connect shows `error` and retries up to every 60 s; once connected, mcp-client's own reconnect handles drops.
- **Reachability probing is HTTP-level** — a GET with a 2.5 s timeout for `streamable-http` servers (any HTTP response counts as reachable); `stdio` servers are not probed.
- **Tools only** — MCP Resources/Prompts are not bridged (same as the official mcp-client).
- **Loopback-only management** — `/ui-settings-mcp/*` has no user accounts or remote-management path; when the web server binds to a non-loopback address all requests are rejected (see *Security*; stdio servers execute arbitrary commands).
- **Some MCP servers allow only one active client** (e.g. Godot MCP) — a second connection is rejected until the first is released.
## License
MIT
Install
dsh plugin --profile web add github:dsh-mixxed/dsh-client-ui-settings-mcp
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-mixxed-dsh-client-ui-settings-mcp from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.