dsh-mcp-panel 0.2.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 (63) hide show
  1. package/LICENSE +201 -0
  2. package/README.es.md +129 -0
  3. package/README.hi.md +129 -0
  4. package/README.md +129 -0
  5. package/README.pt.md +129 -0
  6. package/README.zh.md +129 -0
  7. package/cordis.patch.yml +23 -0
  8. package/lib/client.js +5045 -0
  9. package/lib/client.js.map +1 -0
  10. package/lib/index.js +1079 -0
  11. package/lib/typert.host.js +4261 -0
  12. package/lib/types/aggregate.d.ts +92 -0
  13. package/lib/types/aggregate.d.ts.map +1 -0
  14. package/lib/types/client/McpPanelTab.d.ts +16 -0
  15. package/lib/types/client/McpPanelTab.d.ts.map +1 -0
  16. package/lib/types/client/index.d.ts +35 -0
  17. package/lib/types/client/index.d.ts.map +1 -0
  18. package/lib/types/client/locales.d.ts +90 -0
  19. package/lib/types/client/locales.d.ts.map +1 -0
  20. package/lib/types/client/present.d.ts +79 -0
  21. package/lib/types/client/present.d.ts.map +1 -0
  22. package/lib/types/client/remote.d.ts +119 -0
  23. package/lib/types/client/remote.d.ts.map +1 -0
  24. package/lib/types/client/styles.d.ts +12 -0
  25. package/lib/types/client/styles.d.ts.map +1 -0
  26. package/lib/types/command.d.ts +122 -0
  27. package/lib/types/command.d.ts.map +1 -0
  28. package/lib/types/config.d.ts +63 -0
  29. package/lib/types/config.d.ts.map +1 -0
  30. package/lib/types/grouping.d.ts +49 -0
  31. package/lib/types/grouping.d.ts.map +1 -0
  32. package/lib/types/index.d.ts +41 -0
  33. package/lib/types/index.d.ts.map +1 -0
  34. package/lib/types/probe.d.ts +67 -0
  35. package/lib/types/probe.d.ts.map +1 -0
  36. package/lib/types/sanitize.d.ts +42 -0
  37. package/lib/types/sanitize.d.ts.map +1 -0
  38. package/lib/types/service.d.ts +107 -0
  39. package/lib/types/service.d.ts.map +1 -0
  40. package/lib/types/typert.host.d.ts +110 -0
  41. package/lib/types/typert.host.d.ts.map +1 -0
  42. package/lib/types/upstream.d.ts +67 -0
  43. package/lib/types/upstream.d.ts.map +1 -0
  44. package/lib/types/wire.d.ts +342 -0
  45. package/lib/types/wire.d.ts.map +1 -0
  46. package/package.json +111 -0
  47. package/src/aggregate.ts +248 -0
  48. package/src/client/McpPanelTab.tsx +257 -0
  49. package/src/client/index.ts +87 -0
  50. package/src/client/locales.ts +92 -0
  51. package/src/client/present.ts +127 -0
  52. package/src/client/remote.ts +35 -0
  53. package/src/client/styles.ts +235 -0
  54. package/src/command.ts +387 -0
  55. package/src/config.ts +110 -0
  56. package/src/grouping.ts +109 -0
  57. package/src/index.ts +86 -0
  58. package/src/probe.ts +198 -0
  59. package/src/sanitize.ts +115 -0
  60. package/src/service.ts +279 -0
  61. package/src/typert.host.ts +25 -0
  62. package/src/upstream.ts +72 -0
  63. package/src/wire.ts +221 -0
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 dsh-mcp-panel contributors
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.es.md ADDED
@@ -0,0 +1,129 @@
1
+ # dsh-mcp-panel
2
+
3
+ **Panel de gestión en tiempo de ejecución, de solo lectura, para el cliente MCP oficial de DeepSeek Harness: consulta el estado, las herramientas, los errores y los contadores de reconexión de cada servidor MCP sin tocar tu configuración.**
4
+
5
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
6
+
7
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
8
+ [![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
+ > 🔭 **La observabilidad primero.** [`@deepseek-ai/dsh-mcp-client`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/mcp/mcp-client) mantiene privado su estado de conexión: solo registra logs. Este plugin muestra todo lo que *sí* puede observar (configuración, registro de herramientas, estado del Loader) y dice **"unknown"** para lo que no puede, en lugar de adivinar. También propone la costura mínima que haría el estado real: consulta la [propuesta upstream](docs/upstream-proposal.md).
12
+
13
+ ## Compatibilidad
14
+
15
+ - **Runtime**: DeepSeek Harness ≥ `0.1.0-rc.5` (las peerDependencies fijan la línea `0.1.0-rc.6`).
16
+ - **Última verificación**: 2026-08-14 contra un checkout del código fuente de deepseek-harness (paquetes del workspace en `0.1.0-rc.5`, mainline `7b9644f`) — `/mcp` headless de extremo a extremo más un perfil web en vivo; evidencia en [docs/research-notes.zh.md](docs/research-notes.zh.md). Reverificado el mismo día contra mainline `47f9438` con la rama de la costura `mcp/status` (`feat/mcp-client-status-observability-seam`): una fila real de `server-everything` muestra `status: connected (source: upstream-event)` a través del plugin empaquetado, más el flujo de compatibilidad fiel al lanzador; registro en [docs/optimization-plan-v2.zh.md](docs/optimization-plan-v2.zh.md).
17
+
18
+ ## Qué obtienes
19
+
20
+ | Superficie | Qué muestra |
21
+ |---|---|
22
+ | **Comando `/mcp`** | transporte, destino, número de herramientas, estado de conexión, último error, contador de reconexiones — legible por el modelo y reconstruible desde el log, bilingüe (`outputLanguage: en\|zh`) |
23
+ | **Ajustes → Plugins → pestaña MCP** | la misma instantánea en solo lectura, con insignias de estado, listas de herramientas expandibles, errores saneados y resultados de sondas |
24
+ | **Botón de sonda del panel** | sonda de conectividad de un clic para un servidor streamable-http desde la pestaña; los resultados siguen siendo solo del panel |
25
+ | **Sondas pasivas** | insignias de alcanzabilidad opcionales en segundo plano por servidor, separadas del estado de conexión |
26
+ | **Refresco automático** | el host sugiere un intervalo de refresco (`refreshIntervalMs`); la pestaña consulta y se pausa mientras está oculta |
27
+ | **`/mcp <server> disable\|enable`** | la línea exacta de `cordis.patch.yml` a aplicar — una *sugerencia*, nunca una escritura |
28
+ | **Herramienta `mcp_probe`** | sonda de conectividad de un solo uso para Streamable HTTP como tarea en segundo plano; los resultados son **solo del panel** |
29
+
30
+ ## Inicio rápido
31
+
32
+ ```sh
33
+ dsh plugin --profile web add github:PerryLink/dsh-mcp-panel#v0.2.0
34
+ ```
35
+
36
+ Reinicia (o deja que la superficie web recargue su `cordis.patch.yml`) y ejecuta:
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
+ ```
49
+
50
+ Instalación manual: coloca `dsh-mcp-panel` en el `node_modules` del perfil (o en el
51
+ respaldo compartido `$DSH_HOME/profiles/node_modules`) y añade la fila 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
60
+ ```
61
+
62
+ ### Desinstalación
63
+
64
+ 1. Quita la fila `mcp-panel` de `cordis.patch.yml` (la superficie web la recarga en caliente; otras superficies se reinician).
65
+ 2. Elimina el paquete del `node_modules` del perfil (o del respaldo compartido `profiles/node_modules`).
66
+ 3. Verifica con `dsh web --dump-config` que no quede ninguna fila `mcp-panel`.
67
+
68
+ ## Honestidad por contrato
69
+
70
+ - **Solo lectura.** Nunca se escribe ningún archivo de configuración. `disable`/`enable` imprime una sugerencia que tú aplicas.
71
+ - **Sin estado falso.** Los campos de conexión sin datos upstream muestran `unknown` / `—`, con `statusSource: derived`.
72
+ - **Visualización saneada.** Las credenciales en query strings, contraseñas userinfo, valores de cabeceras, tokens bearer y JWT se redactan antes de renderizar; las `headers` configuradas nunca entran en ninguna instantánea.
73
+ - **Resultados solo del panel.** Los detalles de las sondas viven en la pestaña de ajustes, nunca en el contexto del modelo; `/mcp` es la superficie legible por el modelo y es totalmente reconstruible desde el log de sesión.
74
+ - **Sin cambios en mcp-client.** Transporte, OAuth y protocolo quedan intactos — la brecha de observabilidad la cubre la [propuesta upstream](docs/upstream-proposal.md), que este plugin ya consume (evento tipado `mcp/status` + servicio de consulta `mcpStatus`, detectados en tiempo de ejecución).
75
+
76
+ ## Configuración
77
+
78
+ | Campo | Por defecto | Descripción |
79
+ |---|---|---|
80
+ | `probeEnabled` | `true` | Registra la herramienta `mcp_probe` (requiere `ctx.jobs` en la composición) |
81
+ | `probeTimeoutMs` | `10000` | Tiempo límite por sonda |
82
+ | `maxProbes` | `10` | Límite de registros de sonda mostrados en el panel |
83
+ | `refreshIntervalMs` | `0` | Intervalo de refresco sugerido para el panel en ms (`0` = solo bajo demanda) |
84
+ | `outputLanguage` | `en` | Idioma de salida del comando `/mcp` (`en` \| `zh` \| `es` \| `pt` \| `hi`) |
85
+ | `passiveProbeEnabled` | `false` | Sondear periódicamente servidores streamable-http en segundo plano |
86
+ | `passiveProbeIntervalMs` | `60000` | Intervalo de la sonda pasiva en milisegundos |
87
+
88
+ ## Permisos y datos
89
+
90
+ - **Lee**: filas del Loader, el registro de herramientas (nombres `mcp__<server>__`) y, cuando upstream lo implemente, eventos `mcp/status`.
91
+ - **Escribe**: nada. Ningún archivo de configuración se modifica jamás.
92
+ - **Red**: solo la sonda de un solo uso `mcp_probe` (y la sonda pasiva opcional) envía una petición MCP `initialize` a los endpoints que tú configuraste; las cabeceras configuradas se usan para la petición y nunca se muestran ni registran.
93
+ - Sin telemetría, sin servicios externos, sin trabajo en segundo plano salvo los temporizadores de sonda opcionales.
94
+
95
+ ## Solución de problemas
96
+
97
+ - ¿La fila no aparece? Ejecuta `dsh web --dump-config` y comprueba que el insert `mcp-panel` se aplicó con un id único.
98
+ - El panel muestra `status: unknown (source: derived)` — esperado hasta que la costura upstream aterrice; consulta [docs/upstream-proposal.md](docs/upstream-proposal.md).
99
+ - ¿El panel se ve desactualizado? Establece `refreshIntervalMs` a un valor positivo (p. ej. `5000`) en la fila de configuración `mcp-panel` para consultar automáticamente.
100
+ - El log de arranque muestra un fiber `mcp-panel` FAILED — el paquete debe resolverse desde el perfil (el `name: dsh-mcp-panel` desnudo se resuelve vía el `node_modules` del perfil o el respaldo compartido).
101
+ - Rollback: quita la fila (ver Desinstalación).
102
+
103
+ ## Seguridad
104
+
105
+ ¿Encontraste un problema de seguridad? Abre un issue de GitHub **sin** pegar secretos, claves o tokens — redáctalo todo primero. Este plugin mantiene las credenciales de tus servidores MCP configurados solo en memoria para las peticiones de sonda; nunca llegan a logs ni instantáneas.
106
+
107
+ ## Cómo funciona
108
+
109
+ - **Mitad host** — un servicio Typert Remote `mcpPanel` ensambla la instantánea desde tres fuentes de solo lectura: filas del Loader (entradas `@deepseek-ai/dsh-mcp-client`), `ctx.tools.schemas()` agrupadas por el espacio de nombres `mcp__<server>__`, y observaciones upstream `mcp/status`. El manifiesto `./typert` escrito a mano registra `mcpPanel/status` en el gateway; `zod` se incluye en el bundle, de modo que la mitad host es autocontenida.
110
+ - **Mitad navegador** — un bundle `dsh.client` (servido en `/plugins/dsh-mcp-panel/client.js`) monta el mismo descriptor mediante `ctx.remote.$mount` y registra una entrada `settings.plugins.tab` de solo lectura (`id: mcp`). El presentador es una función pura; los estilos tienen alcance y usan tokens de tema.
111
+ - **El comando `/mcp`** pasa por el registro de comandos estándar — cada línea aterriza en los eventos de sesión `command/run` + `command/done`.
112
+
113
+ ## Desarrollo
114
+
115
+ ```sh
116
+ pnpm install
117
+ pnpm run typecheck
118
+ pnpm test # 96 pruebas: extremos del saneador, agrupación, tolerancia de agregación, salida del comando (5 idiomas), control de sondas, cableado del cliente, presentador
119
+ pnpm run build # declaraciones tsc → lib/types; tsdown → lib/index.js + lib/typert.host.js + lib/client.js
120
+ pnpm run verify:self-contained
121
+ pnpm pack
122
+ ```
123
+
124
+ Verificación contra un checkout real del harness:
125
+ `node --import tsx/esm scripts/verify-headless.mjs` arranca el perfil web completo en proceso (puerto efímero) e imprime la salida exacta de `/mcp`, `/mcp <server> tools` y `/mcp <server> disable`.
126
+
127
+ ## Licencia
128
+
129
+ [Apache License 2.0](LICENSE) © 2026 colaboradores de dsh-mcp-panel
package/README.hi.md ADDED
@@ -0,0 +1,129 @@
1
+ # dsh-mcp-panel
2
+
3
+ **DeepSeek Harness के आधिकारिक MCP क्लाइंट के लिए रीड-ओनली रनटाइम प्रबंधन पैनल — हर MCP सर्वर का स्टेटस, टूल, एरर और रीकनेक्ट काउंट देखें, बिना अपनी कॉन्फ़िगरेशन छुए।**
4
+
5
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
6
+
7
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
8
+ [![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
+ > 🔭 **ऑब्ज़र्वेबिलिटी सबसे पहले।** [`@deepseek-ai/dsh-mcp-client`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/mcp/mcp-client) अपना कनेक्शन स्टेट निजी रखता है — सिर्फ़ लॉग। यह प्लगइन वह सब दिखाता है जो *देखा जा सकता है* (कॉन्फ़िगरेशन, टूल रजिस्ट्री, Loader स्टेट) और जो नहीं देखा जा सकता उसके लिए अनुमान लगाने की बजाय साफ़-साफ़ **"unknown"** कहता है। यह वह न्यूनतम अपस्ट्रीम सीम भी प्रस्तावित करता है जिससे स्टेटस वास्तविक बनेगा: देखें [upstream proposal](docs/upstream-proposal.md)।
12
+
13
+ ## संगतता
14
+
15
+ - **रनटाइम**: DeepSeek Harness ≥ `0.1.0-rc.5` (peerDependencies `0.1.0-rc.6` पैकेज लाइन पिन करती हैं)।
16
+ - **अंतिम सत्यापन**: 2026-08-14, deepseek-harness के सोर्स checkout के विरुद्ध (workspace पैकेज `0.1.0-rc.5`, mainline `7b9644f`) — headless `/mcp` एंड-टू-एंड + लाइव वेब प्रोफ़ाइल; प्रमाण [docs/research-notes.zh.md](docs/research-notes.zh.md) में। उसी दिन mainline `47f9438` + `mcp/status` सीम ब्रांच (`feat/mcp-client-status-observability-seam`) के विरुद्ध पुनः सत्यापित: असली `server-everything` पंक्ति पैक किए गए प्लगइन से `status: connected (source: upstream-event)` दिखाती है, साथ ही लॉन्चर-समतुल्य संगतता प्रवाह; रिकॉर्ड [docs/optimization-plan-v2.zh.md](docs/optimization-plan-v2.zh.md) में।
17
+
18
+ ## आपको क्या मिलता है
19
+
20
+ | सतह | क्या दिखाती है |
21
+ |---|---|
22
+ | **`/mcp` कमांड** | ट्रांसपोर्ट, टार्गेट, टूल काउंट, कनेक्शन स्टेटस, अंतिम एरर, रीकनेक्ट काउंट — मॉडल-रीडेबल और लॉग से रीकंस्ट्रक्टेबल, द्विभाषी (`outputLanguage: en\|zh`) |
23
+ | **सेटिंग्स → प्लगइन्स → MCP टैब** | वही स्नैपशॉट रीड-ओनली: स्टेटस बैज, विस्तार योग्य टूल सूचियाँ, सैनिटाइज़्ड एरर, प्रोब परिणाम |
24
+ | **पैनल प्रोब बटन** | टैब से एक streamable-http सर्वर की एक-क्लिक कनेक्टिविटी प्रोब; परिणाम केवल पैनल में रहते हैं |
25
+ | **पैसिव प्रोब** | प्रति सर्वर वैकल्पिक बैकग्राउंड रीचेबिलिटी बैज, कनेक्शन स्टेटस से अलग |
26
+ | **ऑटो रिफ्रेश** | होस्ट एक रिफ्रेश अंतराल सुझाता है (`refreshIntervalMs`); टैब पोल करता है और छिपा होने पर रुक जाता है |
27
+ | **`/mcp <server> disable\|enable`** | लागू करने के लिए सटीक `cordis.patch.yml` लाइन — एक *सुझाव*, कभी लिखावट नहीं |
28
+ | **`mcp_probe` टूल** | Streamable HTTP एंडपॉइंट की एक-बार कनेक्टिविटी प्रोब (बैकग्राउंड जॉब); परिणाम **केवल पैनल में** |
29
+
30
+ ## त्वरित शुरुआत
31
+
32
+ ```sh
33
+ dsh plugin --profile web add github:PerryLink/dsh-mcp-panel#v0.2.0
34
+ ```
35
+
36
+ फिर रीस्टार्ट करें (या वेब सतह को अपनी `cordis.patch.yml` हॉट-रीलोड करने दें) और चलाएँ:
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
+ ```
49
+
50
+ मैन्युअल इंस्टॉल: `dsh-mcp-panel` को प्रोफ़ाइल के `node_modules` (या साझा
51
+ `$DSH_HOME/profiles/node_modules` फ़ॉलबैक) में रखें और `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
60
+ ```
61
+
62
+ ### अनइंस्टॉल
63
+
64
+ 1. `cordis.patch.yml` से `mcp-panel` लाइन हटाएँ (वेब सतह इसे हॉट-रीलोड करती है; अन्य सतहें रीस्टार्ट करें)।
65
+ 2. प्रोफ़ाइल के `node_modules` (या साझा `profiles/node_modules` फ़ॉलबैक) से पैकेज हटाएँ।
66
+ 3. `dsh web --dump-config` से पुष्टि करें कि कोई `mcp-panel` लाइन नहीं बची।
67
+
68
+ ## अनुबंध द्वारा ईमानदारी
69
+
70
+ - **रीड-ओनली।** कोई कॉन्फ़िगरेशन फ़ाइल कभी नहीं लिखी जाती। `disable`/`enable` एक सुझाव छापता है जिसे आप स्वयं लागू करते हैं।
71
+ - **नकली स्टेटस नहीं।** अपस्ट्रीम डेटा के बिना कनेक्शन फ़ील्ड `unknown` / `—` दिखाते हैं, साथ में `statusSource: derived`।
72
+ - **सैनिटाइज़्ड प्रदर्शन।** URL क्वेरी क्रेडेंशियल, userinfo पासवर्ड, हेडर मान, बियरर टोकन और JWT रेंडरिंग से पहले हटा दिए जाते हैं; कॉन्फ़िगर किए गए `headers` किसी भी स्नैपशॉट में नहीं जाते।
73
+ - **केवल-पैनल परिणाम।** प्रोब विवरण सेटिंग्स टैब में रहते हैं, मॉडल संदर्भ में कभी नहीं; `/mcp` आउटपुट मॉडल-रीडेबल सतह है और सेशन लॉग से पूरी तरह रीकंस्ट्रक्टेबल है।
74
+ - **mcp-client में कोई बदलाव नहीं।** ट्रांसपोर्ट, OAuth और प्रोटोकॉल अछूते रहते हैं — ऑब्ज़र्वेबिलिटी का अंतर [upstream proposal](docs/upstream-proposal.md) से ढका जाता है, जिसे यह प्लगइन पहले से उपभोग करता है (टाइप्ड `mcp/status` इवेंट + `mcpStatus` क्वेरी सेवा, रनटाइम फ़ीचर-डिटेक्शन)।
75
+
76
+ ## कॉन्फ़िगरेशन
77
+
78
+ | फ़ील्ड | डिफ़ॉल्ट | विवरण |
79
+ |---|---|---|
80
+ | `probeEnabled` | `true` | `mcp_probe` टूल पंजीकृत करें (रचना में `ctx.jobs` चाहिए) |
81
+ | `probeTimeoutMs` | `10000` | प्रति प्रोब समय-सीमा |
82
+ | `maxProbes` | `10` | पैनल में दिखाए जाने वाले प्रोब रिकॉर्ड की सीमा |
83
+ | `refreshIntervalMs` | `0` | पैनल के लिए सुझाया गया रिफ्रेश अंतराल (ms; `0` = केवल मांग पर) |
84
+ | `outputLanguage` | `en` | `/mcp` कमांड की आउटपुट भाषा (`en` \| `zh` \| `es` \| `pt` \| `hi`) |
85
+ | `passiveProbeEnabled` | `false` | streamable-http सर्वरों की बैकग्राउंड में आवधिक प्रोब |
86
+ | `passiveProbeIntervalMs` | `60000` | पैसिव प्रोब अंतराल (मिलीसेकंड) |
87
+
88
+ ## अनुमतियाँ और डेटा
89
+
90
+ - **पढ़ता है**: Loader पंक्तियाँ, टूल रजिस्ट्री (`mcp__<server>__` नाम), और upstream लागू होने पर `mcp/status` इवेंट।
91
+ - **लिखता है**: कुछ नहीं। कोई कॉन्फ़िगरेशन फ़ाइल कभी संशोधित नहीं होती।
92
+ - **नेटवर्क**: केवल एक-बार `mcp_probe` (और वैकल्पिक पैसिव प्रोब) आपके कॉन्फ़िगर किए एंडपॉइंट्स पर एक MCP `initialize` अनुरोध भेजती है; कॉन्फ़िगर किए हेडर केवल अनुरोध के लिए उपयोग होते हैं और कभी प्रदर्शित या लॉग नहीं होते।
93
+ - कोई टेलीमेट्री नहीं, कोई बाहरी सेवा नहीं, वैकल्पिक प्रोब टाइमर के अलावा कोई बैकग्राउंड कार्य नहीं।
94
+
95
+ ## समस्या निवारण
96
+
97
+ - लाइन दिखाई नहीं दे रही? `dsh web --dump-config` चलाएँ और जाँचें कि `mcp-panel` insert अद्वितीय id के साथ लागू हुआ।
98
+ - पैनल `status: unknown (source: derived)` दिखाता है — upstream सीम आने तक अपेक्षित; देखें [docs/upstream-proposal.md](docs/upstream-proposal.md)।
99
+ - पैनल पुराना लग रहा है? `mcp-panel` कॉन्फ़िग लाइन में `refreshIntervalMs` को सकारात्मक मान (जैसे `5000`) पर सेट करें ताकि स्वतः पोल हो।
100
+ - बूट लॉग में FAILED `mcp-panel` fiber — पैकेज को प्रोफ़ाइल से रिज़ॉल्व होना चाहिए (बेयर `name: dsh-mcp-panel` प्रोफ़ाइल के `node_modules` या साझा फ़ॉलबैक से रिज़ॉल्व होता है)।
101
+ - रोलबैक: लाइन हटाएँ (अनइंस्टॉल देखें)।
102
+
103
+ ## सुरक्षा
104
+
105
+ सुरक्षा समस्या मिली? GitHub issue खोलें **बिना** सीक्रेट, की या टोकन चिपकाए — पहले सब रिडैक्ट करें। यह प्लगइन आपके कॉन्फ़िगर किए MCP सर्वरों की क्रेडेंशियल केवल प्रोब अनुरोधों के लिए मेमोरी में रखता है; वे कभी लॉग या स्नैपशॉट तक नहीं पहुँचते।
106
+
107
+ ## यह कैसे काम करता है
108
+
109
+ - **होस्ट आधा** — एक `mcpPanel` Typert Remote सेवा तीन रीड-ओनली स्रोतों से स्नैपशॉट बनाती है: Loader पंक्तियाँ (`@deepseek-ai/dsh-mcp-client` एंट्री), `mcp__<server>__` नेमस्पेस से समूहित `ctx.tools.schemas()`, और अपस्ट्रीम `mcp/status` ऑब्ज़र्वेशन। हाथ से लिखा `./typert` मैनिफ़ेस्ट `mcpPanel/status` को गेटवे में पंजीकृत करता है; `zod` बंडल में शामिल है, इसलिए होस्ट आधा स्व-निहित है।
110
+ - **ब्राउज़र आधा** — एक `dsh.client` बंडल (`/plugins/dsh-mcp-panel/client.js` पर सर्व किया गया) उसी डिस्क्रिप्टर को `ctx.remote.$mount` से माउंट करता है और रीड-ओनली `settings.plugins.tab` एंट्री (`id: mcp`) पंजीकृत करता है। प्रेज़ेंटर एक शुद्ध फ़ंक्शन है; स्टाइल स्कोप्ड हैं और थीम टोकन का उपयोग करते हैं।
111
+ - **`/mcp` कमांड** मानक कमांड रजिस्ट्री से गुज़रता है — हर पंक्ति `command/run` + `command/done` सेशन इवेंट में दर्ज होती है।
112
+
113
+ ## विकास
114
+
115
+ ```sh
116
+ pnpm install
117
+ pnpm run typecheck
118
+ pnpm test # 96 टेस्ट: सैनिटाइज़र चरम मामले, समूहन, एग्रीगेशन सहनशीलता, कमांड आउटपुट (5 भाषाएँ), प्रोब गेटिंग, क्लाइंट वायरिंग, प्रेज़ेंटर
119
+ pnpm run build # tsc डिक्लेरेशन → lib/types; tsdown → lib/index.js + lib/typert.host.js + lib/client.js
120
+ pnpm run verify:self-contained
121
+ pnpm pack
122
+ ```
123
+
124
+ असली harness checkout के विरुद्ध सत्यापन:
125
+ `node --import tsx/esm scripts/verify-headless.mjs` पूरे वेब प्रोफ़ाइल को प्रोसेस में बूट करता है (क्षणिक पोर्ट) और `/mcp`, `/mcp <server> tools`, `/mcp <server> disable` का सटीक आउटपुट छापता है।
126
+
127
+ ## लाइसेंस
128
+
129
+ [Apache License 2.0](LICENSE) © 2026 dsh-mcp-panel योगदानकर्ता
package/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # dsh-mcp-panel
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.**
4
+
5
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
6
+
7
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
8
+ [![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
+ > 🔭 **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).
12
+
13
+ ## Compatibility
14
+
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).
17
+
18
+ ## What you get
19
+
20
+ | Surface | What it shows |
21
+ |---|---|
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** |
29
+
30
+ ## Quick start
31
+
32
+ ```sh
33
+ dsh plugin --profile web add github:PerryLink/dsh-mcp-panel#v0.2.0
34
+ ```
35
+
36
+ Then restart (or let the web surface hot-reload its `cordis.patch.yml`) and:
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
+ ```
49
+
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`:
52
+
53
+ ```yaml
54
+ - insert:
55
+ - id: mcp-panel
56
+ name: dsh-mcp-panel
57
+ config:
58
+ probeEnabled: true
59
+ probeTimeoutMs: 10000
60
+ ```
61
+
62
+ ### Uninstall
63
+
64
+ 1. Remove the `mcp-panel` row from `cordis.patch.yml` (the web surface hot-reloads it; other surfaces restart).
65
+ 2. Delete the package from the profile's `node_modules` (or the shared `profiles/node_modules` fallback).
66
+ 3. Verify with `dsh web --dump-config` that no `mcp-panel` row remains.
67
+
68
+ ## Honest by contract
69
+
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).
75
+
76
+ ## Configuration
77
+
78
+ | Field | Default | Description |
79
+ |---|---|---|
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.
112
+
113
+ ## Development
114
+
115
+ ```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
122
+ ```
123
+
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.
126
+
127
+ ## License
128
+
129
+ [Apache License 2.0](LICENSE) © 2026 dsh-mcp-panel contributors