@dsh-mixxed/dsh-client-ui-settings-mcp
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.jsonis 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):
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:
Clone and build:
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)Install into the profile from the folder that contains the clone (no absolute path needed):
dsh plugin --profile web add ./dsh-client-ui-settings-mcpThe 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.ymlis 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 clientpkgMetacache to notice the new package.
For AI agents
Follow every step, in order:
- Read this README in full (especially Features, Known limitations, and this install section).
- Install the package (npm is preferred): run
dsh plugin --profile <profile> add @dsh-mixxed/dsh-client-ui-settings-mcpin the profile you use (ornpm install @dsh-mixxed/dsh-client-ui-settings-mcpin$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, runnpm install --ignore-scripts && npm run build(produces self-containedlib/index.js+lib/client.js; zero runtime dependencies), then rundsh 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).
- Build/source fallback: clone this repo,
- No manual mount row needed — the package declares
dsh.bundle, sodsh plugin addappends it to the profile's bundle layers automatically (verify withdsh --profile <profile> --dump-config: theui-settings-mcprow must be present). - 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. - Verify:
GET http://127.0.0.1:3080/ui-settings-mcp/api/healthmust 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 (
serverNameis 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) orstdio(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:
{
"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 |
| 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 webbinds to127.0.0.1(the default), the API is open — the single-user local posture. - Network-exposure guard. When
dsh webbinds 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.
Authorizationheaders for a specific MCP server) is configured per server in the add/edit form's Headers field — the API itself needs no token.
Development
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 —
failOnStartupErroris on, so a failed first connect showserrorand 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-httpservers (any HTTP response counts as reachable);stdioservers 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
No comments yet. Be the first to write one.