dsh-windows-mcp 0.0.0-stage → 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/CHANGELOG.md ADDED
@@ -0,0 +1,91 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.2.0] - 2026-10-24
8
+
9
+ ### Added
10
+
11
+ - **Windows-MCP version management** (`lib/updater.js`, `lib/installs.js`): the
12
+ plugin checks the mirrors for the newest stable `windows-mcp`, installs a
13
+ version **side by side** under `$DSH_HOME/dsh-windows-mcp/toolchain/<version>`
14
+ (each version its own `UV_TOOL_DIR`, so nothing is overwritten), rewrites the
15
+ bridge row to the freshly installed executable, and keeps the replaced version
16
+ so **Roll back** switches back to it without downloading anything. The check
17
+ result, active/previous version and the install history are persisted in
18
+ `$DSH_HOME/dsh-windows-mcp.versions.json`. Checks run on boot and are cached
19
+ for six hours.
20
+ - **Fast-mirror selection for the Python dependency** (`lib/mirrors.js`,
21
+ `lib/pypi.js`): PyPI plus the USTC, Aliyun, Tencent Cloud, Huawei Cloud,
22
+ Nanjing University and TUNA mirrors are probed with a 96 KiB ranged read and
23
+ ranked by measured throughput; the install uses the fastest working mirror and
24
+ falls back to the next candidate on failure.
25
+ - On the plugin page: running version, newest version, kept versions, the
26
+ measured mirror speed, and **Check for updates** / **Update to vX** / **Roll
27
+ back to vPrev** actions, with the streamed `uv` log.
28
+ - `tools/update-e2e.mjs`, a maintainer harness that runs the real check, install,
29
+ activation and rollback against this machine's profile (never published).
30
+
31
+ ### Changed
32
+
33
+ - `createPrepare` / the prepare route now install into the managed tool root
34
+ through `UV_TOOL_DIR`, support a chosen `--default-index` mirror, and resolve
35
+ the executable from the version that was installed.
36
+ - `uv` installs set `UV_CONCURRENT_DOWNLOADS=4`, `UV_HTTP_RETRIES=3` and
37
+ `UV_HTTP_TIMEOUT=600`: at uv's default of eight parallel downloads the mirrors
38
+ answer HTTP 429 and the install fails.
39
+ - The bridge-row writer, the doctor report and the `/state` payload all report
40
+ which side is live (`managed` vs the global `uv-tool` install).
41
+
42
+ ### Fixed
43
+
44
+ - The PyPI index parser dropped files whose link carried a `#sha256=…` fragment
45
+ (every wheel on a real mirror), so the newest version looked missing.
46
+ - The version pin regex stopped at YAML punctuation but not at the backtick used
47
+ in the written block's prose comment.
48
+
49
+ ## [0.1.0] - 2026-10-11
50
+
51
+ ### Added
52
+
53
+ - Carrier bundle that mounts the official in-box MCP client bridge
54
+ (`@deepseek-ai/dsh-mcp-client`) against CursorTouch/Windows-MCP over stdio,
55
+ exposing Windows desktop automation to DeepSeek Harness as
56
+ `mcp__windows__*` tools (screenshot, snapshot, click, type, scroll, move,
57
+ shortcut, wait, wait-for, scrape, multi-select, multi-edit, clipboard,
58
+ process, notification, registry, display inventory, control status).
59
+ - Curated defaults: `App`, `PowerShell` and `FileSystem` excluded (DSH already
60
+ ships shell and file tools, and upstream only supports the App tool reliably
61
+ on English Windows), telemetry disabled, screenshot flash disabled,
62
+ screenshots downscaled to 0.75, 120 s per-call timeout, reconnect enabled.
63
+ - Host half (`lib/index.js`) with a `windows_mcp_doctor` diagnostic tool and a
64
+ single-warning startup audit (missing patch row, missing `uv`/`uvx`).
65
+ - Zero runtime dependencies; `js-yaml` is a dev dependency used only by tests
66
+ to parse the patch file for real.
67
+ - A **Computer Use** switch in the composer tool row (client half,
68
+ `lib/client.js`): renders the number of bridged desktop tools and persists the
69
+ choice in `~/.dsh/dsh-windows-mcp.state.json`. It is **off by default** —
70
+ desktop control is opt-in, so a fresh install does not hand the agent the
71
+ machine until the switch is turned on.
72
+ - Hard enforcement of that switch (host half): while it is off, every
73
+ `mcp__windows__*` tool is filtered out of the prompt assembly the model sees
74
+ and refused by a plain-context `tools.guard()` at dispatch — for every session
75
+ and subagent, live, without a restart. `tools.restrict()` is deliberately not
76
+ used: it requires a per-agent scoped context and throws for tools the bridge
77
+ has not registered yet.
78
+ - An in-app dependency installer (`lib/dependency.js`, plus the
79
+ `plugins.bundle.config` and `plugins.bundle.activation` client slots — the same
80
+ two the official experimental bundles use): dependency state, one install
81
+ button, streamed `uv tool install` output with cancel, and — after a
82
+ successful install — an automatic, backed-up, idempotently marked rewrite of
83
+ the bridge row in the profile's `cordis.patch.yml` that points it at the
84
+ installed executable.
85
+ - Profile targeting for that rewrite, shown in the page as **Patch target**: the
86
+ plugin resolves the profile the host booted (from `DSH_WINDOWS_MCP_PROFILE`,
87
+ `DSH_PROFILE_DIR`, `DSH_PROFILE`, a `--profile` argument or the working
88
+ directory) so an install in a `dsh --profile <name>` host edits *that* profile.
89
+ When several profiles carry the package and the host reports none of them, it
90
+ writes nothing and points at `DSH_WINDOWS_MCP_PROFILE` instead of guessing.
91
+ - GitHub Actions CI running the test suite on Windows and Linux, Node 22 and 24.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-windows-mcp contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,348 @@
1
- # Temporary Holding Version
1
+ # dsh-windows-mcp
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **English** · [中文](https://github.com/helloHub1212/dsh-windows-mcp/blob/main/README.zh.md)
4
+
5
+ [![npm version](https://img.shields.io/npm/v/dsh-windows-mcp.svg)](https://www.npmjs.com/package/dsh-windows-mcp)
6
+ [![CI](https://github.com/helloHub1212/dsh-windows-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/helloHub1212/dsh-windows-mcp/actions/workflows/ci.yml)
7
+
8
+ **Windows desktop automation for [DeepSeek Harness](https://github.com/sandbaseai/deepseek-harness-handbook)** — lets the DSH agent see your screen and drive your PC.
9
+
10
+ This plugin connects [CursorTouch/Windows-MCP](https://github.com/CursorTouch/Windows-MCP) to DSH by mounting one loader row against the **MCP client bridge that already ships inside DeepSeek Harness**. There is no reimplemented protocol client and no second copy of the MCP SDK: the plugin is a *carrier bundle*, and everything you can do comes from the official bridge.
11
+
12
+ ```text
13
+ DSH agent
14
+ └─ tool call mcp__windows__Screenshot
15
+ └─ @deepseek-ai/dsh-mcp-client (in-box, mounted by this plugin's patch row)
16
+ └─ uvx windows-mcp@0.8.8 serve (stdio child process)
17
+ └─ your desktop: UIA tree, Win32 input, screen capture
18
+ ```
19
+
20
+ ## What it gives the agent
21
+
22
+ With the plugin installed and Windows-MCP reachable, these tools appear in the tool list:
23
+
24
+ | Tool | What it does |
25
+ | --- | --- |
26
+ | `mcp__windows__Screenshot` | Capture the screen; the image lands in the conversation as a real attachment |
27
+ | `mcp__windows__Snapshot` | Capture an accessibility tree (text, no image tokens) |
28
+ | `mcp__windows__DisplayInventory` | Enumerate displays and their geometry |
29
+ | `mcp__windows__Click` / `Move` / `Scroll` | Mouse input |
30
+ | `mcp__windows__Type` / `Shortcut` | Keyboard input |
31
+ | `mcp__windows__Wait` / `WaitFor` | Sleep, or wait until a UI condition holds |
32
+ | `mcp__windows__Scrape` | Extract text from a window |
33
+ | `mcp__windows__MultiSelect` / `MultiEdit` | Batch element selection / batch edits |
34
+ | `mcp__windows__Clipboard` | Read and write the clipboard |
35
+ | `mcp__windows__Process` | List, start and stop processes |
36
+ | `mcp__windows__Notification` | Read notifications |
37
+ | `mcp__windows__Registry` | Read and write registry values |
38
+ | `mcp__windows__ControlStatus` | Control-loop state. **Cannot be disabled** — upstream force-keeps it |
39
+ | `mcp__windows__App` | Launch/switch apps. *Excluded by default* (upstream only supports it reliably on an English Windows install) |
40
+ | `mcp__windows__PowerShell` / `FileSystem` | *Excluded by default* — DSH already ships shell and file tools |
41
+
42
+ Plus one tool of its own, `windows_mcp_doctor`, which explains what is wrong when the `mcp__windows__*` tools are missing.
43
+
44
+ The composer also gains a **Computer Use** pill, next to the permission control: it shows how many desktop tools are actually registered and remembers your choice across restarts (state file: `~/.dsh/dsh-windows-mcp.state.json`). It starts **off** — a fresh install never hands the agent your desktop until you switch the pill on yourself.
45
+
46
+ Switching it off is a hard switch, not a hint. The bridge keeps running, but from the next step on every `mcp__windows__*` tool is filtered out of the tool list the model sees, and a call that still names one is refused at dispatch — in every session and subagent, live, with no restart. Switch it back on and they return immediately; `windows_mcp_doctor` always reports which way it is set.
47
+
48
+ > **Verified:** Windows 11 + DSH Desktop 0.2.0-rc.2 — the bridged server advertises
49
+ > **18 tools** (the 21 upstream tools minus the three excluded here) and is ready
50
+ > about 1.5 s after launch. The bridge publishes each as `mcp__windows__<ToolName>`.
51
+
52
+ ## Requirements
53
+
54
+ - **Windows 10/11.**
55
+ - **DeepSeek Harness Desktop** with the in-box `@deepseek-ai/dsh-mcp-client` bridge (0.2.0-rc.2 or newer).
56
+ - **[uv](https://docs.astral.sh/uv/)** on the `PATH` of the process that runs DSH — this is how `uvx` launches Windows-MCP. `%USERPROFILE%\.local\bin` is searched even when it is not on `PATH`.
57
+ - **A model that accepts image input** if you want the agent to actually *see* screenshots.
58
+
59
+ ### First start vs. later starts
60
+
61
+ `uvx` builds an isolated environment for `windows-mcp` the first time it runs, so
62
+ the initial launch downloads the Python dependencies (tens of MB) and can take
63
+ minutes on a slow connection. The bridge waits roughly a minute per launch and then
64
+ retries, so a cold start may take a few attempts before the tools appear.
65
+
66
+ The server itself is fast once provisioned — measured on Windows 11: **ready about
67
+ 1.5 s after launch**. To get that from the very first DSH start, provision once:
68
+
69
+ ```powershell
70
+ uv tool install windows-mcp # no time limit; run it once
71
+ ```
72
+
73
+ …then point the row at the installed command (`command: windows-mcp`) as described
74
+ in [Override the row from your profile](#override-the-row-from-your-profile) —
75
+ restate the whole `config`, because a patch replaces it. Either way later starts
76
+ reuse the environment `uv` built.
77
+
78
+ ## Install
79
+
80
+ The plugin is a normal DSH bundle. Install it with DSH's own plugin manager:
81
+
82
+ 1. Open **DSH Desktop → Settings → Plugins**.
83
+ 2. Add the bundle, pointing at either the published package name, the repository (`github:helloHub1212/dsh-windows-mcp`), or a local checkout of this repo.
84
+ 3. **Restart DSH** so the new patch layer is composed at startup.
85
+
86
+ For non-Electron profiles the CLI does the same thing:
87
+
88
+ ```powershell
89
+ dsh plugin --profile <profile> add github:helloHub1212/dsh-windows-mcp
90
+ ```
91
+
92
+ > The Electron app owns the `desktop` profile; the CLI refuses every command against it, including read-only ones. Use the GUI for `desktop`.
93
+
94
+ ### Install the dependency from the app
95
+
96
+ Windows-MCP itself is a Python program, so its bundle page in **Settings → Plugins → dsh-windows-mcp** shows the dependency state and installs it for you:
97
+
98
+ - **Dependency** — `installed 0.8.8`, or *not installed*, or *uv not found*.
99
+ - **Download and install** — runs `uv tool install windows-mcp@<pinned>` once, streams the installer output into the page, and offers **Cancel** while it runs.
100
+ - When it finishes, the plugin **writes the bridge row into your profile's `cordis.patch.yml` itself** — after a timestamped backup, inside idempotent markers — so the bridge launches the installed executable instead of racing `uvx` against a cold cache. **Restart DSH** to apply that.
101
+
102
+ The block it writes is exactly the row documented under [Pin a local interpreter instead of `uvx`](#pin-a-local-interpreter-instead-of-uvx); delete the marked block to go back to `uvx`. The same page is what you land on after enabling the bundle (the activation prompt reuses it).
103
+
104
+ The page also shows the **Patch target**: the `cordis.patch.yml` a manual write would touch, which is the profile this host booted — including a `dsh --profile web` host. If this package sits in more than one profile and the host does not report which one it started, the plugin writes nothing and says so instead of guessing: set `DSH_WINDOWS_MCP_PROFILE=<profile name>` (or an absolute profile directory) for the process that runs DSH and retry.
105
+
106
+ ### Update Windows-MCP, and roll back
107
+
108
+ The same page manages the upstream version, so an upgrade never means reinstalling the dependency by hand:
109
+
110
+ - **It checks by itself.** On boot, and whenever the page asks, the plugin probes the PyPI mirrors, takes the fastest one that answers and reads its `windows-mcp` index. The result is cached for six hours in `$DSH_HOME/dsh-windows-mcp.versions.json`, so restarts do not hammer the network.
111
+ - **Versions live side by side.** Every version is installed into its own tool root, `$DSH_HOME/dsh-windows-mcp/toolchain/<version>/windows-mcp`, through `UV_TOOL_DIR`. Activating a version only rewrites the bridge row (backed up, as above): no reinstall, and the previous version stays on disk.
112
+ - **Update in one click.** **Update to vX** downloads that version from the fastest mirror that works, verifies the executable and its `dist-info`, then activates it — the panel names the running version and the mirror it came from.
113
+ - **Roll back the same way.** **Roll back to vPrev** points the bridge back at the version the active one replaced; nothing is downloaded.
114
+
115
+ Only the managed installs are touched: until you install one, the bridge keeps using the global `uv tool` installation, and the panel says which side is live (`uv-tool` vs `managed`).
116
+
117
+ ### Fast mirrors for the Python dependency
118
+
119
+ The check measures all seven candidates — PyPI plus the USTC, Aliyun, Tencent Cloud, Huawei Cloud, Nanjing University and TUNA mirrors — with a 96 KiB ranged read, and ranks them by throughput. An install uses the fastest mirror that works and falls back to the next one when a mirror fails, with `UV_CONCURRENT_DOWNLOADS=4`, `UV_HTTP_RETRIES=3` and `UV_HTTP_TIMEOUT=600`, because mirrors rate-limit uv's default of eight parallel downloads (HTTP 429). A mirror that has blocked this network is ranked out instead of failing the install; the measured speed is shown per mirror in the panel.
120
+
121
+ ## Verify
122
+
123
+ ```text
124
+ windows_mcp_doctor
125
+ ```
126
+
127
+ Prints the resolved `uv`/`uvx`/`python`, the state of `%USERPROFILE%\.windows-mcp`, the effective bridge row, and the `mcp__windows__*` tools that are actually registered. Then ask the agent:
128
+
129
+ > Take a screenshot of my desktop and tell me what is on screen.
130
+
131
+ ## Configuration
132
+
133
+ The defaults live in [`cordis.patch.yml`](cordis.patch.yml). Everything below is set through the `env` block of the `windows-mcp-bridge` row.
134
+
135
+ | Variable | Default here | Effect |
136
+ | --- | --- | --- |
137
+ | `WINDOWS_MCP_SCREENSHOT_SCALE` | `0.75` | Screenshot downscale, `0.1`–`1.0`. The single biggest lever on image token cost. |
138
+ | `WINDOWS_MCP_DISABLE_FLASH` | `1` | Suppresses upstream's orange "control taken over" border on every capture. |
139
+ | `WINDOWS_MCP_SCREENSHOT_BACKEND` | `auto` | Capture backend; see upstream docs before overriding. |
140
+ | `WINDOWS_MCP_MAX_TREE_ELEMENTS` | `500` | Cap on the accessibility-tree size reported by `Snapshot`. |
141
+ | `WINDOWS_MCP_WATCHDOG` | `off` | Upstream watchdog. Off by default because the UIA event pump can take the whole process down ([upstream #332](https://github.com/CursorTouch/Windows-MCP/issues/332)). |
142
+ | `ANONYMIZED_TELEMETRY` | `false` | Upstream defaults to **on** (PostHog). This plugin turns it off. |
143
+
144
+ ### Override the row from your profile
145
+
146
+ Do not edit the plugin's own file — patch the row by id from your profile's
147
+ `$DSH_HOME/profiles/<profile>/cordis.patch.yml`, which is composed *after* bundle
148
+ rows and therefore wins.
149
+
150
+ **A patch replaces the whole `config` object; it does not deep-merge it.** The
151
+ loader applies overrides as `target[key] = value` (`applyEntryPatches` in
152
+ `dsh-app-boot`), so a key you leave out is a key you delete: `serverName` is
153
+ required (and names every tool), `transport` is required, `command` is required
154
+ for `stdio`, `url` for `streamable-http`. A patch whose `id` does not exist, or
155
+ whose `name` does not match, is skipped with a warning instead of failing.
156
+
157
+ ```yaml
158
+ # $DSH_HOME/profiles/<profile>/cordis.patch.yml — the complete row
159
+ - id: windows-mcp-bridge
160
+ config:
161
+ serverName: windows
162
+ transport: stdio
163
+ command: uvx
164
+ args: [windows-mcp@0.8.8, serve, --exclude-tools, "App,PowerShell,FileSystem"]
165
+ toolCallTimeoutMs: 120000
166
+ failOnStartupError: false
167
+ reconnect: { enabled: true, initialDelayMs: 500, maxDelayMs: 30000, maxAttempts: 10 }
168
+ env:
169
+ ANONYMIZED_TELEMETRY: "false"
170
+ WINDOWS_MCP_DISABLE_FLASH: "1"
171
+ WINDOWS_MCP_SCREENSHOT_SCALE: "0.5"
172
+ ```
173
+
174
+ `--exclude-tools` takes its names as one comma-separated argument
175
+ (`"App,PowerShell,FileSystem"`), and `ControlStatus` is always kept — upstream
176
+ offers no way to exclude it.
177
+
178
+ ### Pin a local interpreter instead of `uvx`
179
+
180
+ `uvx` re-resolves the package on every launch. For a reproducible setup, install
181
+ it once (`uv tool install windows-mcp`) or use any Python that already has it,
182
+ and change `command`/`args` in the complete row above:
183
+
184
+ ```yaml
185
+ - id: windows-mcp-bridge
186
+ config:
187
+ serverName: windows
188
+ transport: stdio
189
+ command: windows-mcp # or C:\...\python.exe with args: [-m, windows_mcp, serve, ...]
190
+ args: [serve, --exclude-tools, "App,PowerShell,FileSystem"]
191
+ toolCallTimeoutMs: 120000
192
+ failOnStartupError: false
193
+ reconnect: { enabled: true, initialDelayMs: 500, maxDelayMs: 30000, maxAttempts: 10 }
194
+ env: { ANONYMIZED_TELEMETRY: "false", WINDOWS_MCP_DISABLE_FLASH: "1", WINDOWS_MCP_SCREENSHOT_SCALE: "0.75" }
195
+ ```
196
+
197
+ ### Use a long-lived HTTP server instead
198
+
199
+ Windows-MCP can also run as a background server. Upstream's `windows-mcp install`
200
+ registers an ONLOGON scheduled task that serves **streamable-http** on
201
+ `127.0.0.1:8000`; switch the row to match — this variant has `url` instead of
202
+ `command`/`args`/`env`:
203
+
204
+ ```yaml
205
+ - id: windows-mcp-bridge
206
+ config:
207
+ serverName: windows
208
+ transport: streamable-http
209
+ url: http://127.0.0.1:8000/mcp/ # upstream prints this URL, trailing slash included
210
+ toolCallTimeoutMs: 120000
211
+ failOnStartupError: false
212
+ reconnect: { enabled: true, initialDelayMs: 500, maxDelayMs: 30000, maxAttempts: 10 }
213
+ ```
214
+
215
+ There is no `env` field in this variant, so the telemetry and flash defaults no
216
+ longer apply to the server: start it yourself with `ANONYMIZED_TELEMETRY=false`
217
+ and `WINDOWS_MCP_DISABLE_FLASH=1` if you want the same behaviour.
218
+
219
+ This survives DSH restarts and skips per-launch startup cost, at the price of a
220
+ process that outlives the app. Two upstream caveats: `install` binds the
221
+ scheduled task to the interpreter it was run from (installing from a temporary
222
+ `uvx` environment registers a task pointing at a cache directory that `uv` may
223
+ reclaim — install with `uv tool install windows-mcp` or a fixed venv instead),
224
+ and non-loopback hosts refuse to start without `--auth-key`/`--oauth-client-id`
225
+ or an explicit `--allow-insecure-remote`.
226
+
227
+ ## Troubleshooting
228
+
229
+ | Symptom | Likely cause and fix |
230
+ | --- | --- |
231
+ | No `mcp__windows__*` tools at all | Run `windows_mcp_doctor`. Either `uvx` is not on the PATH DSH sees, or the first cold download is still running. Check the DSH host log for `mcp-client(windows)` lines. |
232
+ | Tools disappeared after an upgrade | The tool names are `mcp__<serverName>__<tool>`. Changing `serverName` changes every tool name (and breaks the prompt cache prefix). |
233
+ | Screenshots come back as text | The active model does not accept image input, or attachments are disabled in your harness configuration. Upstream images are only projected when admission succeeds. |
234
+ | `App` tool fails or returns nothing | Upstream documents it as reliable on English Windows installs only; it is excluded by default. |
235
+ | DSH takes noticeably longer to boot | The bridge starts Windows-MCP at boot (and starts a throwaway probe process first). Set the row's `enabled: false`, or `failOnStartupError: false` keeps the rest of DSH unaffected. |
236
+ | Screenshot text is unreadable | Raise `WINDOWS_MCP_SCREENSHOT_SCALE` toward `1.0`; upstream caps captures at 1920×1080. |
237
+
238
+ ## Security
239
+
240
+ This plugin hands the model your mouse, your keyboard, your clipboard, your
241
+ processes and your registry. Treat installing it as handing over control of the
242
+ desktop session it runs in.
243
+
244
+ What the design does and does not do:
245
+
246
+ - **No network exposure by default.** The default row is stdio: a child process
247
+ connected by pipes, not a listening socket.
248
+ - **Secret hygiene on the child process.** The bridge starts MCP children from a
249
+ scrubbed environment: variable names matching `KEY|PASSWORD|SECRET|TOKEN` and
250
+ **all** `DSH_*` variables are removed before the configured `env` is merged in.
251
+ Credentials should therefore be passed explicitly through the row's `env`, not
252
+ inherited.
253
+ - **No telemetry from this plugin.** Upstream's own PostHog reporting is
254
+ explicitly disabled in the shipped defaults.
255
+ - **Remote serving is upstream's problem, not a hidden default.** If you switch
256
+ to HTTP, upstream enforces loopback host filtering and refuses to start on a
257
+ non-loopback address without an auth key.
258
+ - **This plugin's own routes are not authenticated.** `/dsh-windows-mcp/state`,
259
+ `/prepare`, `/prepare/cancel` and `/bridge` are served by the same web server
260
+ as the UI and do no token check of their own, so do not expose a DSH web host
261
+ that has this plugin on a non-loopback `--host`: anyone who can reach it could
262
+ start an install or rewrite a profile's patch layer.
263
+
264
+ ## How it works
265
+
266
+ DeepSeek Harness plugins are loader patches, and a patch row may mount a package
267
+ that lives inside the Electron `app.asar` — the loader resolves official
268
+ `@deepseek-ai/*` names from the Desktop install anchor. Third-party code cannot
269
+ `import` those packages, but it *can* name them in a patch, because the mount
270
+ happens inside the loader rather than inside plugin code. That is the whole trick
271
+ behind this package:
272
+
273
+ ```yaml
274
+ - insert:
275
+ - id: windows-mcp-plugin
276
+ name: dsh-windows-mcp # lib/index.js: doctor tool + startup audit
277
+ - id: windows-mcp-bridge
278
+ name: "@deepseek-ai/dsh-mcp-client" # in-box bridge, configured for Windows-MCP
279
+ config: { transport: stdio, command: uvx, args: [windows-mcp@0.8.8, serve, ...] }
280
+ ```
281
+
282
+ Consequences worth knowing:
283
+
284
+ - The integration is **version-sensitive** in one direction only: the bridge
285
+ config schema belongs to DSH, not to this plugin. `package.json` declares the
286
+ patch; DSH decides how to read it.
287
+ - Image projection is a bridge feature: MCP image blocks are saved as DSH
288
+ attachments and surfaced as native image content. Audio and embedded resources
289
+ degrade to diagnostic text.
290
+ - **MCP prompts are not supported** by the bridge (resources are, on demand).
291
+
292
+ ## Development
293
+
294
+ ```powershell
295
+ npm install
296
+ npm test # node --test, including a real YAML parse of the patch
297
+ npm run check # node --check lib/index.js
298
+ ```
299
+
300
+ To see the composed config without touching a live profile — and without
301
+ restarting DSH — use the dump harness:
302
+
303
+ ```powershell
304
+ # one-time: a scratch profile with the real profile's node_modules
305
+ mkdir $env:USERPROFILE\.dsh\profiles\dtest
306
+ copy $env:USERPROFILE\.dsh\profiles\desktop\package.json $env:USERPROFILE\.dsh\profiles\dtest\
307
+ cmd /c mklink /J $env:USERPROFILE\.dsh\profiles\dtest\node_modules $env:USERPROFILE\.dsh\profiles\desktop\node_modules
308
+
309
+ npm run dump
310
+ ```
311
+
312
+ Layout:
313
+
314
+ ```text
315
+ cordis.patch.yml the integration: two insert rows
316
+ lib/index.js host half: routes + windows_mcp_doctor + startup audit (no dependencies)
317
+ lib/dependency.js dependency state, uv invocation, profile bridge-row writer
318
+ lib/pypi.js PyPI index parsing and version maths (pure functions)
319
+ lib/mirrors.js mirror candidates, ranged speed probe, ranking
320
+ lib/installs.js per-version tool roots and the versions state file
321
+ lib/updater.js version manager: check / install / activate / roll back
322
+ lib/client.js web half: composer switch + plugin panel
323
+ test/plugin.test.mjs patch composition + hostile-context + panel tests
324
+ test/update.test.mjs version maths, mirror ranking, isolation and rollback state machine
325
+ scripts/dump-config.mjs dev helper for composing against a scratch profile
326
+ tools/ zero-dependency debug probes (not published to npm)
327
+ ```
328
+
329
+ To exercise the update path for real — real mirrors, real `uv`, real profile
330
+ write — use the e2e harness:
331
+
332
+ ```powershell
333
+ node tools/update-e2e.mjs --check # probe the mirrors, read the newest stable version
334
+ node tools/update-e2e.mjs --install 0.8.8 # download, activate, rewrite the bridge row
335
+ node tools/update-e2e.mjs --rollback
336
+ ```
337
+
338
+ Contributions are welcome; keep `lib/index.js` free of runtime dependencies and
339
+ keep `apply()` throw-proof.
340
+
341
+ ## Credits and license
342
+
343
+ MIT — see [LICENSE](LICENSE).
344
+
345
+ - [CursorTouch/Windows-MCP](https://github.com/CursorTouch/Windows-MCP) (MIT) does
346
+ the actual desktop automation. This plugin only wires it up.
347
+ - The MCP client bridge is part of DeepSeek Harness and is not redistributed here.
348
+ - Not affiliated with DeepSeek or with the Windows-MCP authors.