dsh-mcp-hub
Remote MCP servers for DeepSeek Harness: a settings page, connection management, and mcp__<server>__<tool> registration in one plugin 适合需要配置、测试和管理远程 MCP 服务及注册工具的开发者。
同名パッケージの別リポジトリ
インストール
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:Jing494/dsh-mcp-hubドキュメント
README 全文を読む ↗dsh-mcp-hub
Remote MCP servers for DeepSeek Harness — a settings page, connection management, and tool registration in one plugin (host half + browser half, one package, one loader row).
What it does
- Settings → MCP: add / edit / enable-disable / delete servers, test a connection, list the server's tools, and run one call by hand from a JSON argument box.
- Transports:
streamable-http, legacysse, andauto— try streamable first, then fall back to SSE and record which one actually worked. - Tools: every discovered tool is registered as
mcp____, so the model can call it directly. - Allowlist:
toolAllowper server (empty = all tools). - Honest failures: the raw error text is always shown, next to hints for the three usual causes (wrong path, missing auth header, wrong transport).
Requirements
- DeepSeek Harness with the web profile (this plugin renders a Settings page).
- The MCP client SDK shipped with Harness (
@modelcontextprotocol/sdk1.30+, declared as a peer dependency).
Install
This package is not on npm yet; install it from a checkout:
# from the Harness plugin manager, with the absolute package directory
plugin_manager install_bundle /path/to/dsh-mcp-hub
# or with the CLI
dsh plugin add /path/to/dsh-mcp-hub
Then restart DSH once. The MCP entry appears in Settings (between Agent presets and Undo).
The
package.jsondeclares@deepseek-ai/*and@modelcontextprotocol/sdkunderpeerDependencieson purpose: a plugin installed as a workspace link resolves host packages only for names declared there.
Configure
Servers live in this plugin's own volatile config, written by the Settings service:
- id: mcp-hub
name: dsh-mcp-hub
config:
servers:
- id: weather
name: weather # tool namespace: mcp__weather__
enabled: true
transport: auto # auto | http | sse
url: https://example.com/mcp
headers: {} # e.g. { Authorization: "Bearer ..." }
timeoutMs: 15000 # handshake / tools/list budget
toolCallTimeoutMs: 60000 # per tool call
toolAllow: [] # empty = expose every tool
Development
# connection layer against the bundled mock fixture (7 assertions)
node --import ./test/sdk-hook.mjs test/connect.test.mjs
# tool adapter (15), failure diagnostics (10), panel render smoke test (12)
node --import ./test/sdk-hook.mjs test/tools.test.mjs
node test/diagnose.test.mjs
node test/render.test.mjs
node test/secrets.test.mjs
# the fixture itself, both transports
cd mock && PORT=8731 node server.mjs
If the MCP SDK is not resolvable from the checkout, point the tests at it:
DSH_MCP_SDK_BASE=/path/to/@modelcontextprotocol/sdk/dist/esm \
node --import ./test/sdk-hook.mjs test/connect.test.mjs
The repository root is the plugin package (index.js host half, client.js browser half, lib/ transports and tool projection), so it installs directly from a GitHub URL. mock/ is a dependency-free MCP fixture and tools/ holds the uninstall helper.
Releasing
Releases are automated and gated on CI — no personal access token is stored anywhere:
- bump
versioninpackage.json - push to
main - the
testmatrix (node 22 + 24) must pass; then thereleasejob packs the tarball, writesSHA256SUMS, and creates the tag plus the GitHub release
If that version is already tagged the release job skips, so ordinary commits never publish. It authenticates with GitHub's own per-run GITHUB_TOKEN.
Limitations
- Remote only. No
stdio, no local processes. - No OAuth. Header tokens only, and they are stored in the profile patch in plaintext (same as upstream).
- Host code changes need a DSH restart. The HMR plugin watches config files, not plugin modules; client-only changes only need a page reload.
- Uninstall needs one extra step, but it is checked:
remove_bundle(ordsh plugin remove) clears the dependency and the bundle selection and leaves the- id: mcp-hubconfig row plus thelink:symlink behind.node tools/uninstall.mjsrefuses to run while the plugin is still installed, then removes both leftovers and verifies the profile is clean.--dry-run,--keep-config(keep the server list for a reinstall) and--run-cliare supported. - Tool-name collisions are renamed automatically (
_2,_3, …) and shown in the panel; a name that cannot be freed is reported instead of silently dropped. - Secrets: header values are plaintext in the profile patch unless you write a Loader expression by hand, for example
Authorization: !!js \Bearer ${process.env.MCP_TOKEN}``. The panel preserves such expressions across edits (it re-attaches them from the user layer), but it cannot create them for you.
License
MIT — see LICENSE.