dsh-mcp-panel 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/README.es.md +50 -99
  3. package/README.hi.md +50 -99
  4. package/README.md +96 -73
  5. package/README.pt.md +50 -99
  6. package/README.zh.md +100 -78
  7. package/THIRD_PARTY_NOTICES.md +11 -0
  8. package/cordis.patch.yml +17 -4
  9. package/docs/optimization-plan-v2.zh.md +325 -0
  10. package/docs/optimization-plan.zh.md +157 -0
  11. package/docs/research-notes.zh.md +114 -0
  12. package/docs/upstream-proposal.md +150 -0
  13. package/lib/client.js +1630 -175
  14. package/lib/client.js.map +1 -1
  15. package/lib/index.js +1269 -56
  16. package/lib/schemas-BhI7GrM5.js +4091 -0
  17. package/lib/typert.host.js +195 -4100
  18. package/lib/types/aggregate.d.ts +18 -1
  19. package/lib/types/aggregate.d.ts.map +1 -1
  20. package/lib/types/client/McpPanelTab.d.ts +12 -6
  21. package/lib/types/client/McpPanelTab.d.ts.map +1 -1
  22. package/lib/types/client/ServerEditor.d.ts +25 -0
  23. package/lib/types/client/ServerEditor.d.ts.map +1 -0
  24. package/lib/types/client/TrialConsole.d.ts +20 -0
  25. package/lib/types/client/TrialConsole.d.ts.map +1 -0
  26. package/lib/types/client/index.d.ts +7 -5
  27. package/lib/types/client/index.d.ts.map +1 -1
  28. package/lib/types/client/locales.d.ts +169 -1
  29. package/lib/types/client/locales.d.ts.map +1 -1
  30. package/lib/types/client/present.d.ts +35 -1
  31. package/lib/types/client/present.d.ts.map +1 -1
  32. package/lib/types/client/remote.d.ts +184 -11
  33. package/lib/types/client/remote.d.ts.map +1 -1
  34. package/lib/types/command.d.ts +38 -3
  35. package/lib/types/command.d.ts.map +1 -1
  36. package/lib/types/config.d.ts +41 -1
  37. package/lib/types/config.d.ts.map +1 -1
  38. package/lib/types/diagnostics.d.ts +55 -0
  39. package/lib/types/diagnostics.d.ts.map +1 -0
  40. package/lib/types/index.d.ts +32 -15
  41. package/lib/types/index.d.ts.map +1 -1
  42. package/lib/types/patch.d.ts +176 -0
  43. package/lib/types/patch.d.ts.map +1 -0
  44. package/lib/types/probe.d.ts.map +1 -1
  45. package/lib/types/service.d.ts +84 -10
  46. package/lib/types/service.d.ts.map +1 -1
  47. package/lib/types/trial.d.ts +72 -0
  48. package/lib/types/trial.d.ts.map +1 -0
  49. package/lib/types/typert.host.d.ts +173 -9
  50. package/lib/types/typert.host.d.ts.map +1 -1
  51. package/lib/types/upstream.d.ts +44 -15
  52. package/lib/types/upstream.d.ts.map +1 -1
  53. package/lib/types/wire.d.ts +528 -31
  54. package/lib/types/wire.d.ts.map +1 -1
  55. package/lib/types/write.d.ts +30 -0
  56. package/lib/types/write.d.ts.map +1 -0
  57. package/package.json +61 -9
  58. package/src/aggregate.ts +79 -2
  59. package/src/client/McpPanelTab.tsx +205 -30
  60. package/src/client/ServerEditor.tsx +290 -0
  61. package/src/client/TrialConsole.tsx +145 -0
  62. package/src/client/index.ts +45 -18
  63. package/src/client/locales.ts +181 -5
  64. package/src/client/present.ts +58 -1
  65. package/src/client/remote.ts +17 -2
  66. package/src/client/styles.ts +233 -0
  67. package/src/command.ts +173 -17
  68. package/src/config.ts +88 -2
  69. package/src/diagnostics.ts +126 -0
  70. package/src/index.ts +49 -16
  71. package/src/patch.ts +493 -0
  72. package/src/probe.ts +1 -1
  73. package/src/service.ts +316 -19
  74. package/src/trial.ts +192 -0
  75. package/src/upstream.ts +45 -15
  76. package/src/wire.ts +295 -13
  77. package/src/write.ts +97 -0
package/README.md CHANGED
@@ -1,54 +1,93 @@
1
1
  # dsh-mcp-panel
2
2
 
3
- **Read-only runtime management panel for the official DeepSeek Harness MCP client — see every MCP server's status, tools, errors, and reconnect counts, without touching your config.**
3
+ **The MCP management console for the official DeepSeek Harness MCP client — add, edit, remove, and trial-call MCP servers from a settings page, with honest status, health diagnostics, and safe, reversible profile writes.**
4
4
 
5
5
  [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
6
6
 
7
7
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
8
+ [![npm](https://img.shields.io/npm/v/dsh-mcp-panel)](https://www.npmjs.com/package/dsh-mcp-panel)
9
+ [![downloads](https://img.shields.io/npm/dm/dsh-mcp-panel)](https://www.npmjs.com/package/dsh-mcp-panel)
10
+ [![CI](https://github.com/PerryLink/dsh-mcp-panel/actions/workflows/ci.yml/badge.svg)](https://github.com/PerryLink/dsh-mcp-panel/actions/workflows/ci.yml)
8
11
  [![dsh-plugin](https://img.shields.io/badge/ecosystem-dsh--plugin-8b5cf6)](https://github.com/topics/dsh-plugin)
9
12
  [![deepseek-harness](https://img.shields.io/badge/runtime-deepseek--harness-4f46e5)](https://github.com/deepseek-ai/deepseek-harness)
10
13
 
11
- > 🔭 **Observability-first.** [`@deepseek-ai/dsh-mcp-client`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/mcp/mcp-client) keeps its connection state private — logs only. This plugin shows everything it *can* observe (config, tool registry, loader state) and says **"unknown"** for what it cannot, instead of guessing. It also proposes the minimal upstream seam that would make status real: see the [upstream proposal](docs/upstream-proposal.md).
14
+ ## Architecture: official client = bridge, this plugin = console
12
15
 
13
- ## Compatibility
16
+ [`@deepseek-ai/dsh-mcp-client`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/mcp/mcp-client) is the **only bridge**: one plugin instance per MCP server, configured as a hand-written `cordis.yml` row, connecting the transport, syncing tools, and registering `mcp__<server>__<tool>` names. This plugin never replaces it — it is the **experience layer on top**:
14
17
 
15
- - **Runtime**: DeepSeek Harness ≥ `0.1.0-rc.5` (peer dependencies pin the `0.1.0-rc.6` package line).
16
- - **Last verified**: 2026-08-14 against a source checkout of deepseek-harness (workspace packages at `0.1.0-rc.5`, mainline `7b9644f`) — headless `/mcp` end-to-end plus a live web profile; evidence in [docs/research-notes.zh.md](docs/research-notes.zh.md). Re-verified the same day against mainline `47f9438` with the `mcp/status` seam branch (`feat/mcp-client-status-observability-seam`): a real `server-everything` row renders `status: connected (source: upstream-event)` through the packed plugin, plus the launcher-faithful compat flow; record in [docs/optimization-plan-v2.zh.md](docs/optimization-plan-v2.zh.md).
18
+ ```
19
+ ┌────────────────────────────────────────────┐
20
+ profile │ cordis.yml / cordis.patch.yml │
21
+ composition │ - id: mcp-github │
22
+ (one row per │ name: '@deepseek-ai/dsh-mcp-client' │
23
+ server, hand- │ config: { serverName, transport, … } │
24
+ written) │ - id: mcp-panel │
25
+ │ name: dsh-mcp-panel ◄── this plugin │
26
+ └───────────────┬────────────────────────────┘
27
+ │
28
+ ┌───────────────────────────┴───────────────────────────┐
29
+ │ │
30
+ ┌────▼──────────────┐ ┌───────────────────────────┐ │
31
+ │ @deepseek-ai/dsh- │ │ dsh-mcp-panel (console) │ │
32
+ │ mcp-client │ │ │ │
33
+ │ • transport │ │ • /mcp command │ │
34
+ │ • tool sync │ │ • Settings → Plugins → │ │
35
+ │ • mcp__* tools │◄──────►│ MCP tab: CRUD, trial │ │
36
+ │ • mcp/status seam │ status │ • health diagnostics │ │
37
+ └───────────────────┘ │ • probes, capabilities │ │
38
+ └───────────────────────────┘ │
39
+ ```
40
+
41
+ The console **reads** the client through its shipped `mcp/status` observability seam (event + `mcpStatus` query service), the tool registry, and the loader; it **writes** only the profile's patch layer — append-only, approval-gated, always backed up. Transport, OAuth, and protocol stay untouched.
42
+
43
+ ## Console vs. hand-written cordis.yml
44
+
45
+ | | Hand-written cordis.yml | dsh-mcp-panel console |
46
+ |---|---|---|
47
+ | Add a server | Edit YAML, mind indent/quoting | Form → patch fragment → **copy** or **write** (approval + auto backup) |
48
+ | Edit a server | Edit YAML, restart/hot-reload | Form pre-filled from the live row; unchanged secrets keep their raw values host-side |
49
+ | Remove a server | Delete the row | `set disabled: true` operation (the patch vocabulary has no remove) — re-enableable anytime |
50
+ | See status | Read logs | Badges + reconnects + last error, live from the `mcp/status` seam |
51
+ | Try a tool | Ask the model to call it | Trial console → official `ctx.tools.execute()` pipeline (permission & approval stay in force) |
52
+ | Diagnose failures | Grep logs | `/mcp <server> health` with derived self-heal suggestions |
53
+ | Mistakes | Manual revert | Every write is append-only and leaves a timestamped backup |
54
+
55
+ The console's output IS `cordis.patch.yml` vocabulary — the same lines you would write by hand, generated, previewed, and applied safely.
17
56
 
18
57
  ## What you get
19
58
 
20
- | Surface | What it shows |
59
+ | Surface | What it does |
21
60
  |---|---|
22
- | **`/mcp` command** | transport, target, tool count, connection status, last error, reconnect count — model-readable, session-log reconstructable, bilingual (`outputLanguage: en\|zh`) |
23
- | **Settings → Plugins → MCP tab** | the same snapshot read-only, with status badges, expandable tool lists, sanitized errors, probe results |
24
- | **Panel probe button** | one-click connectivity probe of one streamable-http server from the tab; results stay panel-only |
25
- | **Passive probes** | optional background reachability badges per server, kept separate from connection status |
26
- | **Auto refresh** | the host suggests a refresh interval (`refreshIntervalMs`); the tab polls and pauses while hidden |
27
- | **`/mcp <server> disable\|enable`** | the exact `cordis.patch.yml` line to apply — a *suggestion*, never a write |
28
- | **`mcp_probe` tool** | one-shot Streamable HTTP connectivity probe as a background job; results are **panel-only** |
61
+ | **`/mcp` command** | one row per server: transport, target, tool count, connection status (from the upstream seam; `unknown` when unobserved), last error, reconnect count — model-readable, session-log reconstructable, five output languages |
62
+ | **`/mcp <server> tools`** | model-visible `mcp__*` tool names + descriptions |
63
+ | **`/mcp <server> health`** | derived self-heal suggestions (ENOENT → missing dependency, ECONNREFUSED, timeouts, 401/403/404, DNS, rate limit, reconnect exhaustion…); exit code / stderr tail honestly labeled *pending upstream support* until the client exposes them |
64
+ | **`/mcp <server> call <tool> [json]`** | trial-call through the **official tool pipeline** — pre-execute permission policy, approval (routed through the command's agent), guards, post-execute all apply |
65
+ | **`/mcp <server> disable\|enable`** | the exact `set` patch line, as before |
66
+ | **Settings → Plugins → MCP tab** | status cards with badges, diagnostics, probes, plus the three consoles below |
67
+ | **Server CRUD** | add/edit/remove forms → `insert`/`set`/`set disabled` fragments → clipboard copy or approval-gated write with automatic backups (`cordis.patch.yml.bak-<ts>`, newest `backupCount` kept) |
68
+ | **Tool trial console** | server → `mcp__*` tool → JSON args → canonical JSON result + rendered content; capped by `trialMaxResultChars`; panel-only, never model context |
69
+ | **Capabilities board** | Resources / Prompts availability, feature-detected; both read *pending upstream support* today (the official client bridges tools only) |
70
+ | **Probes** | one-click / passive Streamable HTTP connectivity probes (panel-only results) |
29
71
 
30
72
  ## Quick start
31
73
 
32
74
  ```sh
33
- dsh plugin --profile web add github:PerryLink/dsh-mcp-panel#v0.2.0
75
+ # git channel (builds via the package's prepare script)
76
+ dsh plugin --profile web add github:PerryLink/dsh-mcp-panel#v0.4.0
77
+ # npm channel (published tarball, no build approval needed)
78
+ dsh plugin --profile web add dsh-mcp-panel@0.4.0
34
79
  ```
35
80
 
36
- Then restart (or let the web surface hot-reload its `cordis.patch.yml`) and:
81
+ Then restart (or let the web surface hot-reload `cordis.patch.yml`) and open **Settings → Plugins → MCP**, or run:
37
82
 
38
83
  ```text
39
84
  /mcp
40
85
  /mcp everything tools
41
- /mcp everything disable
42
- ```
43
-
44
- ```text
45
- MCP servers (1):
46
- - everything [mcp-everything] stdio node …/server-everything/dist/index.js
47
- | 13 tools | enabled | status: unknown (source: derived) | reconnects: — | last error: —
86
+ /mcp everything health
87
+ /mcp everything call echo '{"message": "hi"}'
48
88
  ```
49
89
 
50
- Manual install: put `dsh-mcp-panel` into the profile's `node_modules` (or the shared
51
- `$DSH_HOME/profiles/node_modules` fallback) and add the row to `cordis.patch.yml`:
90
+ Manual install: put `dsh-mcp-panel` into the profile's `node_modules` (or the shared `$DSH_HOME/profiles/node_modules` fallback) and add the row to `cordis.patch.yml`:
52
91
 
53
92
  ```yaml
54
93
  - insert:
@@ -56,7 +95,6 @@ Manual install: put `dsh-mcp-panel` into the profile's `node_modules` (or the sh
56
95
  name: dsh-mcp-panel
57
96
  config:
58
97
  probeEnabled: true
59
- probeTimeoutMs: 10000
60
98
  ```
61
99
 
62
100
  ### Uninstall
@@ -67,63 +105,48 @@ Manual install: put `dsh-mcp-panel` into the profile's `node_modules` (or the sh
67
105
 
68
106
  ## Honest by contract
69
107
 
70
- - **Read-only.** No configuration file is ever written. `disable`/`enable` prints a suggestion you apply yourself.
71
- - **No fake status.** Connection fields without upstream data read `unknown` / `—`, with `statusSource: derived`.
72
- - **Sanitized display.** URL query credentials, userinfo passwords, header values, bearer tokens, and JWTs are redacted before rendering; configured `headers` never enter any snapshot.
73
- - **Panel-only results.** Probe details live in the settings tab, never in model context; `/mcp` output is the model-readable surface and is fully reconstructable from the session log.
74
- - **No mcp-client changes.** Transport, OAuth, and protocol stay untouched — the observability gap is covered by the [upstream proposal](docs/upstream-proposal.md), which this plugin already consumes (typed `mcp/status` event + `mcpStatus` query service, feature-detected at runtime).
108
+ - **The bridge stays the bridge.** No transport, OAuth, or protocol changes; one mcp-client row per server, exactly as hand-written.
109
+ - **No fake status.** Connection fields without upstream observations read `unknown` / `—` with `statusSource: 'derived'`; exit codes / stderr tails are never invented.
110
+ - **Sanitized display.** URL query credentials, userinfo passwords, header values, bearer tokens, and JWTs are redacted before rendering; configured `headers` never enter any snapshot; env/header **values** never leave the host (the editor sees keys only).
111
+ - **Writes are append-only, approval-gated, and backed up.** The console never rewrites `cordis.patch.yml`: it appends generated operations. When an approval service exists and the caller's session has a live agent inside an open turn, the write asks `ctx.approval` (only `allowed-once` proceeds); otherwise the explicit interactive confirmation is the approval channel. `writeEnabled: false` is a hard kill switch.
112
+ - **No prompt injection.** The panel registers **no prompt sections**; its only model-facing text is the two tool/command descriptions, in the official client's minimal style.
75
113
 
76
- ## Configuration
114
+ ## Config
77
115
 
78
- | Field | Default | Description |
116
+ | Key | Default | Description |
79
117
  |---|---|---|
80
- | `probeEnabled` | `true` | Register the `mcp_probe` tool (needs `ctx.jobs` in the composition) |
81
- | `probeTimeoutMs` | `10000` | Per-probe timeout |
82
- | `maxProbes` | `10` | Cap on probe records shown in the panel |
83
- | `refreshIntervalMs` | `0` | Suggested panel refresh interval in ms (`0` = on demand only) |
84
- | `outputLanguage` | `en` | Output language of the `/mcp` command (`en` \| `zh` \| `es` \| `pt` \| `hi`) |
85
- | `passiveProbeEnabled` | `false` | Periodically probe streamable-http servers in the background |
86
- | `passiveProbeIntervalMs` | `60000` | Passive probe interval in milliseconds |
87
-
88
- ## Permissions & data
89
-
90
- - **Reads**: loader entries, the tool registry (`mcp__<server>__` names), and — when upstream ships it — `mcp/status` events.
91
- - **Writes**: none. No configuration file is ever modified.
92
- - **Network**: only the one-shot `mcp_probe` (and the optional passive probe) POSTs one MCP `initialize` request to endpoints you configured; configured headers are used for the request and are never displayed or logged.
93
- - No telemetry, no external services, no background work beyond the optional probe timers.
94
-
95
- ## Troubleshooting
96
-
97
- - Row not visible? Run `dsh web --dump-config` and check that the `mcp-panel` insert landed with a unique id.
98
- - Panel shows `status: unknown (source: derived)` — expected until the upstream seam lands; see [docs/upstream-proposal.md](docs/upstream-proposal.md).
99
- - Panel looks stale? Set `refreshIntervalMs` to a positive value (e.g. `5000`) in the `mcp-panel` config row to poll automatically.
100
- - Boot log shows a FAILED `mcp-panel` fiber — the package must resolve from the profile (bare `name: dsh-mcp-panel` resolves via the profile's `node_modules` or the shared fallback).
101
- - Rollback: remove the row (see Uninstall).
102
-
103
- ## Security
104
-
105
- Found a security issue? Open a GitHub issue **without** pasting secrets, keys, or tokens — redact everything first. This plugin holds the credentials of your configured MCP servers only in memory for probe requests; they never reach logs or snapshots.
106
-
107
- ## How it works
108
-
109
- - **Host half** — a `mcpPanel` Typert Remote service assembles the snapshot from three read-only sources: loader rows (`@deepseek-ai/dsh-mcp-client` entries), `ctx.tools.schemas()` grouped by the `mcp__<server>__` namespace, and upstream `mcp/status` observations. The hand-written `./typert` manifest registers `mcpPanel/status` with the gateway; `zod` is bundled, so the host bundle is self-contained.
110
- - **Browser half** — a `dsh.client` bundle (served at `/plugins/dsh-mcp-panel/client.js`) mounts the same descriptor via `ctx.remote.$mount` and registers a read-only `settings.plugins.tab` entry (`id: mcp`). The presenter is a pure function; styles are scoped and token-driven.
111
- - **The `/mcp` command** goes through the standard command registry — every line lands in `command/run` + `command/done` session events.
118
+ | `probeEnabled` | `true` | register the `mcp_probe` background-job tool (panel-only results) |
119
+ | `probeTimeoutMs` | `10000` | per-probe timeout in ms |
120
+ | `maxProbes` | `10` | probe records shown in the panel |
121
+ | `refreshIntervalMs` | `0` | suggested panel refresh in ms; `0` = on demand |
122
+ | `outputLanguage` | `en` | `/mcp` output language: `en\|zh\|es\|pt\|hi` |
123
+ | `passiveProbeEnabled` | `false` | periodically probe streamable-http servers |
124
+ | `passiveProbeIntervalMs` | `60000` | passive probe interval in ms |
125
+ | `trialEnabled` | `true` | tool trial console (settings tab + `/mcp call`) |
126
+ | `trialTimeoutMs` | `120000` | panel-side deadline per trial call |
127
+ | `trialMaxResultChars` | `60000` | cap on the trial result payload |
128
+ | `writeEnabled` | `true` | kill switch: `false` rejects every profile write (copy still works) |
129
+ | `backupCount` | `5` | `cordis.patch.yml` backups retained per write |
130
+
131
+ ## Resources & Prompts
132
+
133
+ The official client documents *"Tools are the only bridged MCP capability"* — Resources and Prompts are deferred. The console feature-detects a proposed upstream catalog seam and will show read-only lists the day it ships; until then the capabilities board marks both **pending upstream support** (see the harness `docs/upstream-proposal.md` addendum for the follow-up proposals).
112
134
 
113
135
  ## Development
114
136
 
115
137
  ```sh
116
- pnpm install
117
- pnpm run typecheck
118
- pnpm test # 96 tests: sanitizer extremes, grouping, aggregation tolerance, command output (5 languages), probe gating, client wiring, presenter
119
- pnpm run build # tsc declarations → lib/types; tsdown → lib/index.js + lib/typert.host.js + lib/client.js
120
- pnpm run verify:self-contained
121
- pnpm pack
138
+ pnpm run typecheck && pnpm run typecheck:ci && pnpm test && pnpm run build && pnpm run verify:self-contained && pnpm run verify:artifacts && pnpm pack
122
139
  ```
123
140
 
124
- Verification against a real harness checkout:
125
- `node --import tsx/esm scripts/verify-headless.mjs` boots the full web profile in process (ephemeral port) and prints the exact `/mcp`, `/mcp <server> tools`, and `/mcp <server> disable` output.
141
+ - `src/patch.ts` — validation, keep-semantics merge, YAML fragment rendering (pure).
142
+ - `src/write.ts` — backup + append + retention (the only file-write module).
143
+ - `src/trial.ts` — official-pipeline trial calls via `ctx.tools.execute()`.
144
+ - `src/diagnostics.ts` — error-pattern → suggestion mapping (pure).
145
+ - `src/client/` — the settings console (server editor, trial console, diagnostics).
146
+ - `scripts/verify-headless.mjs` boots the real web profile and prints exact `/mcp` output.
147
+
148
+ Releases: `node scripts/release.mjs <x.y.z>` runs the full gate, commits, and tags `v<x.y.z>` locally (never pushes).
126
149
 
127
150
  ## License
128
151
 
129
- [Apache License 2.0](LICENSE) © 2026 dsh-mcp-panel contributors
152
+ Apache-2.0 — see [LICENSE](LICENSE).
package/README.pt.md CHANGED
@@ -1,129 +1,80 @@
1
1
  # dsh-mcp-panel
2
2
 
3
- **Painel de gerenciamento em tempo de execução, somente leitura, para o cliente MCP oficial do DeepSeek Harness: veja status, ferramentas, erros e contadores de reconexão de cada servidor MCP sem tocar na sua configuração.**
3
+ **Console de gerenciamento MCP para o cliente MCP oficial do DeepSeek Harness: adicione, edite, remova e teste servidores MCP numa página de configurações, com status honesto, diagnósticos de saúde e gravações de perfil seguras e reversíveis.**
4
4
 
5
5
  [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
6
6
 
7
7
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
8
+ [![npm](https://img.shields.io/npm/v/dsh-mcp-panel)](https://www.npmjs.com/package/dsh-mcp-panel)
9
+ [![CI](https://github.com/PerryLink/dsh-mcp-panel/actions/workflows/ci.yml/badge.svg)](https://github.com/PerryLink/dsh-mcp-panel/actions/workflows/ci.yml)
8
10
  [![dsh-plugin](https://img.shields.io/badge/ecosystem-dsh--plugin-8b5cf6)](https://github.com/topics/dsh-plugin)
9
- [![deepseek-harness](https://img.shields.io/badge/runtime-deepseek--harness-4f46e5)](https://github.com/deepseek-ai/deepseek-harness)
10
11
 
11
- > 🔭 **Observabilidade em primeiro lugar.** [`@deepseek-ai/dsh-mcp-client`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/mcp/mcp-client) mantém seu estado de conexão privado — apenas logs. Este plugin mostra tudo o que *consegue* observar (configuração, registro de ferramentas, estado do Loader) e diz **"unknown"** para o que não consegue, em vez de adivinhar. Ele também propõe a costura mínima que tornaria o status real: veja a [proposta upstream](docs/upstream-proposal.md).
12
+ ## Arquitetura: o cliente oficial é a ponte; este plugin é o console
12
13
 
13
- ## Compatibilidade
14
+ [`@deepseek-ai/dsh-mcp-client`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/mcp/mcp-client) é a **única ponte**: uma instância por servidor MCP, configurada como linha escrita à mão no `cordis.yml`, que conecta o transporte, sincroniza ferramentas e registra os nomes `mcp__<servidor>__<ferramenta>`. Este plugin nunca a substitui: é a **camada de experiência** por cima:
14
15
 
15
- - **Runtime**: DeepSeek Harness ≥ `0.1.0-rc.5` (as peerDependencies fixam a linha `0.1.0-rc.6`).
16
- - **Última verificação**: 2026-08-14 contra um checkout do código-fonte do deepseek-harness (pacotes do workspace em `0.1.0-rc.5`, mainline `7b9644f`) — `/mcp` headless de ponta a ponta mais um perfil web ao vivo; evidências em [docs/research-notes.zh.md](docs/research-notes.zh.md). Reverificado no mesmo dia contra mainline `47f9438` com o ramo da costura `mcp/status` (`feat/mcp-client-status-observability-seam`): uma linha real de `server-everything` mostra `status: connected (source: upstream-event)` através do plugin empacotado, além do fluxo de compatibilidade fiel ao lançador; registro em [docs/optimization-plan-v2.zh.md](docs/optimization-plan-v2.zh.md).
17
-
18
- ## O que você ganha
19
-
20
- | Superfície | O que mostra |
21
- |---|---|
22
- | **Comando `/mcp`** | transporte, alvo, contagem de ferramentas, status de conexão, último erro, contador de reconexões — legível pelo modelo e reconstruível pelo log, bilíngue (`outputLanguage: en\|zh`) |
23
- | **Configurações → Plugins → aba MCP** | o mesmo snapshot somente leitura, com selos de status, listas expansíveis de ferramentas, erros sanitizados e resultados de sondas |
24
- | **Botão de sonda do painel** | sonda de conectividade em um clique para um servidor streamable-http a partir da aba; os resultados continuam somente do painel |
25
- | **Sondas passivas** | selos de alcançabilidade opcionais em segundo plano por servidor, separados do status de conexão |
26
- | **Atualização automática** | o host sugere um intervalo de atualização (`refreshIntervalMs`); a aba consulta e pausa enquanto oculta |
27
- | **`/mcp <server> disable\|enable`** | a linha exata de `cordis.patch.yml` a aplicar — uma *sugestão*, nunca uma escrita |
28
- | **Ferramenta `mcp_probe`** | sonda de conectividade de uso único para Streamable HTTP como tarefa em segundo plano; resultados são **somente do painel** |
29
-
30
- ## Início rápido
31
-
32
- ```sh
33
- dsh plugin --profile web add github:PerryLink/dsh-mcp-panel#v0.2.0
34
- ```
35
-
36
- Reinicie (ou deixe a superfície web recarregar seu `cordis.patch.yml`) e execute:
37
-
38
- ```text
39
- /mcp
40
- /mcp everything tools
41
- /mcp everything disable
42
- ```
43
-
44
- ```text
45
- MCP servers (1):
46
- - everything [mcp-everything] stdio node …/server-everything/dist/index.js
47
- | 13 tools | enabled | status: unknown (source: derived) | reconnects: — | last error: —
48
16
  ```
49
-
50
- Instalação manual: coloque `dsh-mcp-panel` no `node_modules` do perfil (ou no
51
- respaldo compartilhado `$DSH_HOME/profiles/node_modules`) e adicione a linha a `cordis.patch.yml`:
52
-
53
- ```yaml
54
- - insert:
55
- - id: mcp-panel
56
- name: dsh-mcp-panel
57
- config:
58
- probeEnabled: true
59
- probeTimeoutMs: 10000
17
+ profile/composição dsh-mcp-client (ponte) dsh-mcp-panel (console)
18
+ - id: mcp-github • transporte • comando /mcp
19
+ name: '@deepseek-ai/…' • sincronização de tools • Configurações → Plugins →
20
+ config: { serverName, … } • ferramentas mcp__* MCP: CRUD, banco de testes,
21
+ - id: mcp-panel • seam mcp/status ◄─status─► diagnósticos, sondas
22
+ name: dsh-mcp-panel
60
23
  ```
61
24
 
62
- ### Desinstalação
63
-
64
- 1. Remova a linha `mcp-panel` de `cordis.patch.yml` (a superfície web a recarrega em quente; outras superfícies reiniciam).
65
- 2. Apague o pacote do `node_modules` do perfil (ou do respaldo compartilhado `profiles/node_modules`).
66
- 3. Confirme com `dsh web --dump-config` que nenhuma linha `mcp-panel` restou.
25
+ O console **lê** pelo seam `mcp/status` (evento + serviço `mcpStatus`), pelo registro de ferramentas e pelo loader; **escreve** apenas na camada de patches do perfil: somente anexa, com aprovação e backup automático. Transporte, OAuth e protocolo permanecem intocados.
67
26
 
68
- ## Honestidade por contrato
27
+ ## Console vs. cordis.yml escrito à mão
69
28
 
70
- - **Somente leitura.** Nenhum arquivo de configuração é gravado. `disable`/`enable` imprime uma sugestão que você aplica.
71
- - **Sem status falso.** Campos de conexão sem dados upstream mostram `unknown` / `—`, com `statusSource: derived`.
72
- - **Exibição sanitizada.** Credenciais em query strings, senhas userinfo, valores de cabeçalhos, tokens bearer e JWTs são removidos antes da renderização; os `headers` configurados nunca entram em nenhum snapshot.
73
- - **Resultados somente do painel.** Os detalhes das sondas ficam na aba de configurações, nunca no contexto do modelo; `/mcp` é a superfície legível pelo modelo e é totalmente reconstruível a partir do log da sessão.
74
- - **Sem mudanças no mcp-client.** Transporte, OAuth e protocolo permanecem intactos — a lacuna de observabilidade é coberta pela [proposta upstream](docs/upstream-proposal.md), que este plugin já consome (evento tipado `mcp/status` + serviço de consulta `mcpStatus`, detectados em tempo de execução).
75
-
76
- ## Configuração
77
-
78
- | Campo | Padrão | Descrição |
29
+ | | cordis.yml à mão | Console dsh-mcp-panel |
79
30
  |---|---|---|
80
- | `probeEnabled` | `true` | Registra a ferramenta `mcp_probe` (requer `ctx.jobs` na composição) |
81
- | `probeTimeoutMs` | `10000` | Tempo limite por sonda |
82
- | `maxProbes` | `10` | Limite de registros de sonda exibidos no painel |
83
- | `refreshIntervalMs` | `0` | Intervalo de atualização sugerido para o painel em ms (`0` = somente sob demanda) |
84
- | `outputLanguage` | `en` | Idioma de saída do comando `/mcp` (`en` \| `zh` \| `es` \| `pt` \| `hi`) |
85
- | `passiveProbeEnabled` | `false` | Sondear periodicamente servidores streamable-http em segundo plano |
86
- | `passiveProbeIntervalMs` | `60000` | Intervalo da sonda passiva em milissegundos |
31
+ | Adicionar servidor | Editar YAML | Formulário → fragmento de patch → **copiar** ou **gravar** (aprovação + backup) |
32
+ | Editar servidor | Editar YAML e reiniciar | Formulário pré-preenchido; segredos inalterados preservam o valor no host |
33
+ | Remover servidor | Apagar a linha | Operação `set disabled: true` (o vocabulário de patches não tem remove); re-habilitável |
34
+ | Ver status | Ler logs | Selos + reconexões + último erro, ao vivo do `mcp/status` |
35
+ | Testar uma ferramenta | Pedir ao modelo | Banco de testes → pipeline oficial `ctx.tools.execute()` (permissões e aprovação em vigor) |
36
+ | Diagnosticar | grep de logs | `/mcp <servidor> health` com sugestões derivadas |
87
37
 
88
- ## Permissões e dados
38
+ ## O que você ganha
89
39
 
90
- - **Lê**: linhas do Loader, o registro de ferramentas (nomes `mcp__<server>__`) e, quando o upstream implementar, eventos `mcp/status`.
91
- - **Escreve**: nada. Nenhum arquivo de configuração é modificado.
92
- - **Rede**: apenas a sonda de uso único `mcp_probe` (e a sonda passiva opcional) envia uma requisição MCP `initialize` para os endpoints que você configurou; os cabeçalhos configurados são usados na requisição e nunca são exibidos nem registrados.
93
- - Sem telemetria, sem serviços externos, sem trabalho em segundo plano além dos temporizadores de sonda opcionais.
40
+ - **`/mcp`**: uma linha por servidor — transporte, destino, contagem de ferramentas, status de conexão (honesto: `unknown` sem dados upstream), último erro, reconexões; legível pelo modelo, reconstruível do log da sessão, cinco idiomas de saída.
41
+ - **`/mcp <servidor> tools | health | call <tool> [json] | disable | enable`**: lista de ferramentas; diagnósticos derivados (ENOENT → dependência ausente, ECONNREFUSED, timeouts, 401/403/404, DNS, rate limit, reconexão esgotada); chamada de teste pelo **pipeline oficial** (permissões + aprovação em vigor); sugestões de patch exatas.
42
+ - **Configurações → Plugins → MCP**: cartões de status com selos e diagnósticos, **CRUD de servidores** (fragmentos `insert`/`set`/`set disabled`, cópia para a área de transferência ou gravação com aprovação e backup `cordis.patch.yml.bak-<ts>`), **banco de testes de ferramentas** (JSON canônico + conteúdo renderizado, limitado por `trialMaxResultChars`, somente painel) e o **painel de capacidades**: Resources e Prompts marcados como *aguardando suporte upstream* (hoje o cliente oficial só pontua ferramentas).
43
+ - **Sondas**: conectividade Streamable HTTP com um clique ou passiva (resultados somente do painel).
94
44
 
95
- ## Solução de problemas
45
+ ## Início rápido
96
46
 
97
- - A linha não aparece? Rode `dsh web --dump-config` e confira se o insert `mcp-panel` foi aplicado com um id único.
98
- - O painel mostra `status: unknown (source: derived)` — esperado até a costura upstream aterrissar; veja [docs/upstream-proposal.md](docs/upstream-proposal.md).
99
- - O painel parece desatualizado? Defina `refreshIntervalMs` com um valor positivo (ex.: `5000`) na linha de configuração `mcp-panel` para consultar automaticamente.
100
- - O log de boot mostra um fiber `mcp-panel` FAILED — o pacote precisa resolver a partir do perfil (o `name: dsh-mcp-panel` simples resolve via o `node_modules` do perfil ou o respaldo compartilhado).
101
- - Rollback: remova a linha (ver Desinstalação).
47
+ ```sh
48
+ dsh plugin --profile web add github:PerryLink/dsh-mcp-panel#v0.4.0
49
+ # ou pelo canal npm:
50
+ dsh plugin --profile web add dsh-mcp-panel@0.4.0
51
+ ```
102
52
 
103
- ## Segurança
53
+ Reinicie (ou deixe a superfície web recarregar o `cordis.patch.yml`) e abra **Configurações → Plugins → MCP**, ou execute `/mcp`.
104
54
 
105
- Encontrou um problema de segurança? Abra uma issue no GitHub **sem** colar segredos, chaves ou tokens — redija tudo antes. Este plugin mantém as credenciais dos seus servidores MCP configurados apenas em memória para as requisições de sonda; elas nunca chegam a logs ou snapshots.
55
+ ## Honesto por contrato
106
56
 
107
- ## Como funciona
57
+ - **A ponte continua sendo a ponte**: nenhuma mudança de transporte/OAuth/protocolo.
58
+ - **Sem status falso**: `unknown` / `—` com `statusSource: 'derived'` sem dados upstream; códigos de saída e stderr nunca inventados (marcados *aguardando suporte upstream*).
59
+ - **Exibição saneada**: credenciais em URLs, userinfo, valores de headers, tokens bearer e JWTs redigidos; os **valores** de env/headers nunca saem do host (o editor vê apenas chaves).
60
+ - **Gravações somente-anexar, com aprovação e backup**: o console nunca reescreve o `cordis.patch.yml`; havendo serviço de aprovação e um agente em turno aberto, pergunta ao `ctx.approval` (apenas `allowed-once` prossegue); caso contrário, a confirmação interativa é o canal de aprovação. `writeEnabled: false` é o interruptor de segurança.
61
+ - **Sem injeção de prompts**: o console não registra seções de prompt; apenas as descrições de suas duas ferramentas/comandos, no estilo minimalista do cliente oficial.
108
62
 
109
- - **Metade host** — um serviço Typert Remote `mcpPanel` monta o snapshot a partir de três fontes somente leitura: linhas do Loader (entradas `@deepseek-ai/dsh-mcp-client`), `ctx.tools.schemas()` agrupadas pelo namespace `mcp__<server>__`, e observações upstream `mcp/status`. O manifesto `./typert` escrito à mão registra `mcpPanel/status` no gateway; o `zod` é empacotado, então a metade host é autocontida.
110
- - **Metade navegador** — um bundle `dsh.client` (servido em `/plugins/dsh-mcp-panel/client.js`) monta o mesmo descritor via `ctx.remote.$mount` e registra uma entrada `settings.plugins.tab` somente leitura (`id: mcp`). O apresentador é uma função pura; os estilos têm escopo e usam tokens de tema.
111
- - **O comando `/mcp`** passa pelo registro de comandos padrão — cada linha cai nos eventos de sessão `command/run` + `command/done`.
63
+ ## Config
112
64
 
113
- ## Desenvolvimento
65
+ | Chave | Valor | Descrição |
66
+ |---|---|---|
67
+ | `probeEnabled` / `probeTimeoutMs` / `maxProbes` | `true` / `10000` / `10` | ferramenta de sonda, prazo, registros exibidos |
68
+ | `refreshIntervalMs` | `0` | atualização sugerida do painel (`0` = sob demanda) |
69
+ | `outputLanguage` | `en` | idioma do `/mcp`: `en\|zh\|es\|pt\|hi` |
70
+ | `passiveProbeEnabled` / `passiveProbeIntervalMs` | `false` / `60000` | sondas passivas e seu intervalo |
71
+ | `trialEnabled` / `trialTimeoutMs` / `trialMaxResultChars` | `true` / `120000` / `60000` | banco de testes e seus limites |
72
+ | `writeEnabled` / `backupCount` | `true` / `5` | interruptor de gravações; backups retidos |
114
73
 
115
- ```sh
116
- pnpm install
117
- pnpm run typecheck
118
- pnpm test # 96 testes: extremos do sanitizador, agrupamento, tolerância de agregação, saída do comando (5 idiomas), controle de sondas, fiação do cliente, apresentador
119
- pnpm run build # declarações tsc → lib/types; tsdown → lib/index.js + lib/typert.host.js + lib/client.js
120
- pnpm run verify:self-contained
121
- pnpm pack
122
- ```
74
+ ## Resources e Prompts
123
75
 
124
- Verificação contra um checkout real do harness:
125
- `node --import tsx/esm scripts/verify-headless.mjs` inicializa o perfil web completo em processo (porta efêmera) e imprime a saída exata de `/mcp`, `/mcp <server> tools` e `/mcp <server> disable`.
76
+ O cliente oficial documenta "Tools are the only bridged MCP capability": ambos estão adiados. O console detecta um seam de catálogo proposto e exibirá listas somente-leitura quando chegar; até lá o painel marca *aguardando suporte upstream* (adendo em `docs/upstream-proposal.md` do harness).
126
77
 
127
78
  ## Licença
128
79
 
129
- [Apache License 2.0](LICENSE) © 2026 colaboradores do dsh-mcp-panel
80
+ Apache-2.0 — veja [LICENSE](LICENSE).