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.
- package/LICENSE +201 -0
- package/README.es.md +129 -0
- package/README.hi.md +129 -0
- package/README.md +129 -0
- package/README.pt.md +129 -0
- package/README.zh.md +129 -0
- package/cordis.patch.yml +23 -0
- package/lib/client.js +5045 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +1079 -0
- package/lib/typert.host.js +4261 -0
- package/lib/types/aggregate.d.ts +92 -0
- package/lib/types/aggregate.d.ts.map +1 -0
- package/lib/types/client/McpPanelTab.d.ts +16 -0
- package/lib/types/client/McpPanelTab.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +35 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/locales.d.ts +90 -0
- package/lib/types/client/locales.d.ts.map +1 -0
- package/lib/types/client/present.d.ts +79 -0
- package/lib/types/client/present.d.ts.map +1 -0
- package/lib/types/client/remote.d.ts +119 -0
- package/lib/types/client/remote.d.ts.map +1 -0
- package/lib/types/client/styles.d.ts +12 -0
- package/lib/types/client/styles.d.ts.map +1 -0
- package/lib/types/command.d.ts +122 -0
- package/lib/types/command.d.ts.map +1 -0
- package/lib/types/config.d.ts +63 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/grouping.d.ts +49 -0
- package/lib/types/grouping.d.ts.map +1 -0
- package/lib/types/index.d.ts +41 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/probe.d.ts +67 -0
- package/lib/types/probe.d.ts.map +1 -0
- package/lib/types/sanitize.d.ts +42 -0
- package/lib/types/sanitize.d.ts.map +1 -0
- package/lib/types/service.d.ts +107 -0
- package/lib/types/service.d.ts.map +1 -0
- package/lib/types/typert.host.d.ts +110 -0
- package/lib/types/typert.host.d.ts.map +1 -0
- package/lib/types/upstream.d.ts +67 -0
- package/lib/types/upstream.d.ts.map +1 -0
- package/lib/types/wire.d.ts +342 -0
- package/lib/types/wire.d.ts.map +1 -0
- package/package.json +111 -0
- package/src/aggregate.ts +248 -0
- package/src/client/McpPanelTab.tsx +257 -0
- package/src/client/index.ts +87 -0
- package/src/client/locales.ts +92 -0
- package/src/client/present.ts +127 -0
- package/src/client/remote.ts +35 -0
- package/src/client/styles.ts +235 -0
- package/src/command.ts +387 -0
- package/src/config.ts +110 -0
- package/src/grouping.ts +109 -0
- package/src/index.ts +86 -0
- package/src/probe.ts +198 -0
- package/src/sanitize.ts +115 -0
- package/src/service.ts +279 -0
- package/src/typert.host.ts +25 -0
- package/src/upstream.ts +72 -0
- 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)
|
|
8
|
+
[](https://github.com/topics/dsh-plugin)
|
|
9
|
+
[](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)
|
|
8
|
+
[](https://github.com/topics/dsh-plugin)
|
|
9
|
+
[](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)
|
|
8
|
+
[](https://github.com/topics/dsh-plugin)
|
|
9
|
+
[](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
|