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 +91 -0
- package/LICENSE +21 -0
- package/README.md +347 -2
- package/README.zh.md +295 -0
- package/cordis.patch.yml +66 -0
- package/lib/client.js +731 -0
- package/lib/dependency.js +535 -0
- package/lib/index.js +752 -0
- package/lib/installs.js +196 -0
- package/lib/mirrors.js +236 -0
- package/lib/pypi.js +171 -0
- package/lib/updater.js +496 -0
- package/package.json +60 -4
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
|
-
#
|
|
1
|
+
# dsh-windows-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**English** · [中文](https://github.com/helloHub1212/dsh-windows-mcp/blob/main/README.zh.md)
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/dsh-windows-mcp)
|
|
6
|
+
[](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.
|