dsh-windows-mcp 0.0.0-stage → 0.1.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 +49 -0
- package/LICENSE +27 -0
- package/README.md +311 -2
- package/README.zh.md +260 -0
- package/cordis.patch.yml +66 -0
- package/lib/client.js +607 -0
- package/lib/dependency.js +469 -0
- package/lib/index.js +625 -0
- package/package.json +60 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
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.1.0] - 2026-10-10
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Carrier bundle that mounts the official in-box MCP client bridge
|
|
12
|
+
(`@deepseek-ai/dsh-mcp-client`) against CursorTouch/Windows-MCP over stdio,
|
|
13
|
+
exposing Windows desktop automation to DeepSeek Harness as
|
|
14
|
+
`mcp__windows__*` tools (screenshot, snapshot, click, type, scroll, move,
|
|
15
|
+
shortcut, wait, wait-for, scrape, multi-select, multi-edit, clipboard,
|
|
16
|
+
process, notification, registry, display inventory, control status).
|
|
17
|
+
- Curated defaults: `App`, `PowerShell` and `FileSystem` excluded (DSH already
|
|
18
|
+
ships shell and file tools, and upstream only supports the App tool reliably
|
|
19
|
+
on English Windows), telemetry disabled, screenshot flash disabled,
|
|
20
|
+
screenshots downscaled to 0.75, 120 s per-call timeout, reconnect enabled.
|
|
21
|
+
- Host half (`lib/index.js`) with a `windows_mcp_doctor` diagnostic tool and a
|
|
22
|
+
single-warning startup audit (missing patch row, missing `uv`/`uvx`).
|
|
23
|
+
- Zero runtime dependencies; `js-yaml` is a dev dependency used only by tests
|
|
24
|
+
to parse the patch file for real.
|
|
25
|
+
- A **Computer Use** switch in the composer tool row (client half,
|
|
26
|
+
`lib/client.js`): renders the number of bridged desktop tools and persists the
|
|
27
|
+
choice in `~/.dsh/dsh-windows-mcp.state.json`. It is **off by default** —
|
|
28
|
+
desktop control is opt-in, so a fresh install does not hand the agent the
|
|
29
|
+
machine until the switch is turned on.
|
|
30
|
+
- Hard enforcement of that switch (host half): while it is off, every
|
|
31
|
+
`mcp__windows__*` tool is filtered out of the prompt assembly the model sees
|
|
32
|
+
and refused by a plain-context `tools.guard()` at dispatch — for every session
|
|
33
|
+
and subagent, live, without a restart. `tools.restrict()` is deliberately not
|
|
34
|
+
used: it requires a per-agent scoped context and throws for tools the bridge
|
|
35
|
+
has not registered yet.
|
|
36
|
+
- An in-app dependency installer (`lib/dependency.js`, plus the
|
|
37
|
+
`plugins.bundle.config` and `plugins.bundle.activation` client slots — the same
|
|
38
|
+
two the official experimental bundles use): dependency state, one install
|
|
39
|
+
button, streamed `uv tool install` output with cancel, and — after a
|
|
40
|
+
successful install — an automatic, backed-up, idempotently marked rewrite of
|
|
41
|
+
the bridge row in the profile's `cordis.patch.yml` that points it at the
|
|
42
|
+
installed executable.
|
|
43
|
+
- Profile targeting for that rewrite, shown in the page as **Patch target**: the
|
|
44
|
+
plugin resolves the profile the host booted (from `DSH_WINDOWS_MCP_PROFILE`,
|
|
45
|
+
`DSH_PROFILE_DIR`, `DSH_PROFILE`, a `--profile` argument or the working
|
|
46
|
+
directory) so an install in a `dsh --profile <name>` host edits *that* profile.
|
|
47
|
+
When several profiles carry the package and the host reports none of them, it
|
|
48
|
+
writes nothing and points at `DSH_WINDOWS_MCP_PROFILE` instead of guessing.
|
|
49
|
+
- GitHub Actions CI running the test suite on Windows and Linux, Node 22 and 24.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
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.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This plugin does not bundle Windows-MCP: at runtime it launches the upstream
|
|
26
|
+
package `windows-mcp` (CursorTouch/Windows-MCP, MIT) and mounts the MCP client
|
|
27
|
+
bridge that ships with DeepSeek Harness. Both remain under their own licenses.
|
package/README.md
CHANGED
|
@@ -1,3 +1,312 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-windows-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Windows desktop automation for [DeepSeek Harness](https://github.com/sandbaseai/deepseek-harness-handbook)** — lets the DSH agent see your screen and drive your PC.
|
|
4
|
+
|
|
5
|
+
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.
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
DSH agent
|
|
9
|
+
└─ tool call mcp__windows__Screenshot
|
|
10
|
+
└─ @deepseek-ai/dsh-mcp-client (in-box, mounted by this plugin's patch row)
|
|
11
|
+
└─ uvx windows-mcp@0.8.8 serve (stdio child process)
|
|
12
|
+
└─ your desktop: UIA tree, Win32 input, screen capture
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## What it gives the agent
|
|
16
|
+
|
|
17
|
+
With the plugin installed and Windows-MCP reachable, these tools appear in the tool list:
|
|
18
|
+
|
|
19
|
+
| Tool | What it does |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `mcp__windows__Screenshot` | Capture the screen; the image lands in the conversation as a real attachment |
|
|
22
|
+
| `mcp__windows__Snapshot` | Capture an accessibility tree (text, no image tokens) |
|
|
23
|
+
| `mcp__windows__DisplayInventory` | Enumerate displays and their geometry |
|
|
24
|
+
| `mcp__windows__Click` / `Move` / `Scroll` | Mouse input |
|
|
25
|
+
| `mcp__windows__Type` / `Shortcut` | Keyboard input |
|
|
26
|
+
| `mcp__windows__Wait` / `WaitFor` | Sleep, or wait until a UI condition holds |
|
|
27
|
+
| `mcp__windows__Scrape` | Extract text from a window |
|
|
28
|
+
| `mcp__windows__MultiSelect` / `MultiEdit` | Batch element selection / batch edits |
|
|
29
|
+
| `mcp__windows__Clipboard` | Read and write the clipboard |
|
|
30
|
+
| `mcp__windows__Process` | List, start and stop processes |
|
|
31
|
+
| `mcp__windows__Notification` | Read notifications |
|
|
32
|
+
| `mcp__windows__Registry` | Read and write registry values |
|
|
33
|
+
| `mcp__windows__ControlStatus` | Control-loop state. **Cannot be disabled** — upstream force-keeps it |
|
|
34
|
+
| `mcp__windows__App` | Launch/switch apps. *Excluded by default* (upstream only supports it reliably on an English Windows install) |
|
|
35
|
+
| `mcp__windows__PowerShell` / `FileSystem` | *Excluded by default* — DSH already ships shell and file tools |
|
|
36
|
+
|
|
37
|
+
Plus one tool of its own, `windows_mcp_doctor`, which explains what is wrong when the `mcp__windows__*` tools are missing.
|
|
38
|
+
|
|
39
|
+
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.
|
|
40
|
+
|
|
41
|
+
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.
|
|
42
|
+
|
|
43
|
+
> **Verified:** Windows 11 + DSH Desktop 0.2.0-rc.2 — the bridged server advertises
|
|
44
|
+
> **18 tools** (the 21 upstream tools minus the three excluded here) and is ready
|
|
45
|
+
> about 1.5 s after launch. The bridge publishes each as `mcp__windows__<ToolName>`.
|
|
46
|
+
|
|
47
|
+
## Requirements
|
|
48
|
+
|
|
49
|
+
- **Windows 10/11.**
|
|
50
|
+
- **DeepSeek Harness Desktop** with the in-box `@deepseek-ai/dsh-mcp-client` bridge (0.2.0-rc.2 or newer).
|
|
51
|
+
- **[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`.
|
|
52
|
+
- **A model that accepts image input** if you want the agent to actually *see* screenshots.
|
|
53
|
+
|
|
54
|
+
### First start vs. later starts
|
|
55
|
+
|
|
56
|
+
`uvx` builds an isolated environment for `windows-mcp` the first time it runs, so
|
|
57
|
+
the initial launch downloads the Python dependencies (tens of MB) and can take
|
|
58
|
+
minutes on a slow connection. The bridge waits roughly a minute per launch and then
|
|
59
|
+
retries, so a cold start may take a few attempts before the tools appear.
|
|
60
|
+
|
|
61
|
+
The server itself is fast once provisioned — measured on Windows 11: **ready about
|
|
62
|
+
1.5 s after launch**. To get that from the very first DSH start, provision once:
|
|
63
|
+
|
|
64
|
+
```powershell
|
|
65
|
+
uv tool install windows-mcp # no time limit; run it once
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
…then point the row at the installed command (`command: windows-mcp`) as described
|
|
69
|
+
in [Override the row from your profile](#override-the-row-from-your-profile) —
|
|
70
|
+
restate the whole `config`, because a patch replaces it. Either way later starts
|
|
71
|
+
reuse the environment `uv` built.
|
|
72
|
+
|
|
73
|
+
## Install
|
|
74
|
+
|
|
75
|
+
The plugin is a normal DSH bundle. Install it with DSH's own plugin manager:
|
|
76
|
+
|
|
77
|
+
1. Open **DSH Desktop → Settings → Plugins**.
|
|
78
|
+
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.
|
|
79
|
+
3. **Restart DSH** so the new patch layer is composed at startup.
|
|
80
|
+
|
|
81
|
+
For non-Electron profiles the CLI does the same thing:
|
|
82
|
+
|
|
83
|
+
```powershell
|
|
84
|
+
dsh plugin --profile <profile> add github:helloHub1212/dsh-windows-mcp
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
> The Electron app owns the `desktop` profile; the CLI refuses every command against it, including read-only ones. Use the GUI for `desktop`.
|
|
88
|
+
|
|
89
|
+
### Install the dependency from the app
|
|
90
|
+
|
|
91
|
+
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:
|
|
92
|
+
|
|
93
|
+
- **Dependency** — `installed 0.8.8`, or *not installed*, or *uv not found*.
|
|
94
|
+
- **Download and install** — runs `uv tool install windows-mcp@<pinned>` once, streams the installer output into the page, and offers **Cancel** while it runs.
|
|
95
|
+
- 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.
|
|
96
|
+
|
|
97
|
+
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).
|
|
98
|
+
|
|
99
|
+
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.
|
|
100
|
+
|
|
101
|
+
## Verify
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
windows_mcp_doctor
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
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:
|
|
108
|
+
|
|
109
|
+
> Take a screenshot of my desktop and tell me what is on screen.
|
|
110
|
+
|
|
111
|
+
## Configuration
|
|
112
|
+
|
|
113
|
+
The defaults live in [`cordis.patch.yml`](cordis.patch.yml). Everything below is set through the `env` block of the `windows-mcp-bridge` row.
|
|
114
|
+
|
|
115
|
+
| Variable | Default here | Effect |
|
|
116
|
+
| --- | --- | --- |
|
|
117
|
+
| `WINDOWS_MCP_SCREENSHOT_SCALE` | `0.75` | Screenshot downscale, `0.1`–`1.0`. The single biggest lever on image token cost. |
|
|
118
|
+
| `WINDOWS_MCP_DISABLE_FLASH` | `1` | Suppresses upstream's orange "control taken over" border on every capture. |
|
|
119
|
+
| `WINDOWS_MCP_SCREENSHOT_BACKEND` | `auto` | Capture backend; see upstream docs before overriding. |
|
|
120
|
+
| `WINDOWS_MCP_MAX_TREE_ELEMENTS` | `500` | Cap on the accessibility-tree size reported by `Snapshot`. |
|
|
121
|
+
| `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)). |
|
|
122
|
+
| `ANONYMIZED_TELEMETRY` | `false` | Upstream defaults to **on** (PostHog). This plugin turns it off. |
|
|
123
|
+
|
|
124
|
+
### Override the row from your profile
|
|
125
|
+
|
|
126
|
+
Do not edit the plugin's own file — patch the row by id from your profile's
|
|
127
|
+
`$DSH_HOME/profiles/<profile>/cordis.patch.yml`, which is composed *after* bundle
|
|
128
|
+
rows and therefore wins.
|
|
129
|
+
|
|
130
|
+
**A patch replaces the whole `config` object; it does not deep-merge it.** The
|
|
131
|
+
loader applies overrides as `target[key] = value` (`applyEntryPatches` in
|
|
132
|
+
`dsh-app-boot`), so a key you leave out is a key you delete: `serverName` is
|
|
133
|
+
required (and names every tool), `transport` is required, `command` is required
|
|
134
|
+
for `stdio`, `url` for `streamable-http`. A patch whose `id` does not exist, or
|
|
135
|
+
whose `name` does not match, is skipped with a warning instead of failing.
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
# $DSH_HOME/profiles/<profile>/cordis.patch.yml — the complete row
|
|
139
|
+
- id: windows-mcp-bridge
|
|
140
|
+
config:
|
|
141
|
+
serverName: windows
|
|
142
|
+
transport: stdio
|
|
143
|
+
command: uvx
|
|
144
|
+
args: [windows-mcp@0.8.8, serve, --exclude-tools, "App,PowerShell,FileSystem"]
|
|
145
|
+
toolCallTimeoutMs: 120000
|
|
146
|
+
failOnStartupError: false
|
|
147
|
+
reconnect: { enabled: true, initialDelayMs: 500, maxDelayMs: 30000, maxAttempts: 10 }
|
|
148
|
+
env:
|
|
149
|
+
ANONYMIZED_TELEMETRY: "false"
|
|
150
|
+
WINDOWS_MCP_DISABLE_FLASH: "1"
|
|
151
|
+
WINDOWS_MCP_SCREENSHOT_SCALE: "0.5"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`--exclude-tools` takes its names as one comma-separated argument
|
|
155
|
+
(`"App,PowerShell,FileSystem"`), and `ControlStatus` is always kept — upstream
|
|
156
|
+
offers no way to exclude it.
|
|
157
|
+
|
|
158
|
+
### Pin a local interpreter instead of `uvx`
|
|
159
|
+
|
|
160
|
+
`uvx` re-resolves the package on every launch. For a reproducible setup, install
|
|
161
|
+
it once (`uv tool install windows-mcp`) or use any Python that already has it,
|
|
162
|
+
and change `command`/`args` in the complete row above:
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
- id: windows-mcp-bridge
|
|
166
|
+
config:
|
|
167
|
+
serverName: windows
|
|
168
|
+
transport: stdio
|
|
169
|
+
command: windows-mcp # or C:\...\python.exe with args: [-m, windows_mcp, serve, ...]
|
|
170
|
+
args: [serve, --exclude-tools, "App,PowerShell,FileSystem"]
|
|
171
|
+
toolCallTimeoutMs: 120000
|
|
172
|
+
failOnStartupError: false
|
|
173
|
+
reconnect: { enabled: true, initialDelayMs: 500, maxDelayMs: 30000, maxAttempts: 10 }
|
|
174
|
+
env: { ANONYMIZED_TELEMETRY: "false", WINDOWS_MCP_DISABLE_FLASH: "1", WINDOWS_MCP_SCREENSHOT_SCALE: "0.75" }
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Use a long-lived HTTP server instead
|
|
178
|
+
|
|
179
|
+
Windows-MCP can also run as a background server. Upstream's `windows-mcp install`
|
|
180
|
+
registers an ONLOGON scheduled task that serves **streamable-http** on
|
|
181
|
+
`127.0.0.1:8000`; switch the row to match — this variant has `url` instead of
|
|
182
|
+
`command`/`args`/`env`:
|
|
183
|
+
|
|
184
|
+
```yaml
|
|
185
|
+
- id: windows-mcp-bridge
|
|
186
|
+
config:
|
|
187
|
+
serverName: windows
|
|
188
|
+
transport: streamable-http
|
|
189
|
+
url: http://127.0.0.1:8000/mcp/ # upstream prints this URL, trailing slash included
|
|
190
|
+
toolCallTimeoutMs: 120000
|
|
191
|
+
failOnStartupError: false
|
|
192
|
+
reconnect: { enabled: true, initialDelayMs: 500, maxDelayMs: 30000, maxAttempts: 10 }
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
There is no `env` field in this variant, so the telemetry and flash defaults no
|
|
196
|
+
longer apply to the server: start it yourself with `ANONYMIZED_TELEMETRY=false`
|
|
197
|
+
and `WINDOWS_MCP_DISABLE_FLASH=1` if you want the same behaviour.
|
|
198
|
+
|
|
199
|
+
This survives DSH restarts and skips per-launch startup cost, at the price of a
|
|
200
|
+
process that outlives the app. Two upstream caveats: `install` binds the
|
|
201
|
+
scheduled task to the interpreter it was run from (installing from a temporary
|
|
202
|
+
`uvx` environment registers a task pointing at a cache directory that `uv` may
|
|
203
|
+
reclaim — install with `uv tool install windows-mcp` or a fixed venv instead),
|
|
204
|
+
and non-loopback hosts refuse to start without `--auth-key`/`--oauth-client-id`
|
|
205
|
+
or an explicit `--allow-insecure-remote`.
|
|
206
|
+
|
|
207
|
+
## Troubleshooting
|
|
208
|
+
|
|
209
|
+
| Symptom | Likely cause and fix |
|
|
210
|
+
| --- | --- |
|
|
211
|
+
| 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. |
|
|
212
|
+
| Tools disappeared after an upgrade | The tool names are `mcp__<serverName>__<tool>`. Changing `serverName` changes every tool name (and breaks the prompt cache prefix). |
|
|
213
|
+
| 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. |
|
|
214
|
+
| `App` tool fails or returns nothing | Upstream documents it as reliable on English Windows installs only; it is excluded by default. |
|
|
215
|
+
| 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. |
|
|
216
|
+
| Screenshot text is unreadable | Raise `WINDOWS_MCP_SCREENSHOT_SCALE` toward `1.0`; upstream caps captures at 1920×1080. |
|
|
217
|
+
|
|
218
|
+
## Security
|
|
219
|
+
|
|
220
|
+
This plugin hands the model your mouse, your keyboard, your clipboard, your
|
|
221
|
+
processes and your registry. Treat installing it as handing over control of the
|
|
222
|
+
desktop session it runs in.
|
|
223
|
+
|
|
224
|
+
What the design does and does not do:
|
|
225
|
+
|
|
226
|
+
- **No network exposure by default.** The default row is stdio: a child process
|
|
227
|
+
connected by pipes, not a listening socket.
|
|
228
|
+
- **Secret hygiene on the child process.** The bridge starts MCP children from a
|
|
229
|
+
scrubbed environment: variable names matching `KEY|PASSWORD|SECRET|TOKEN` and
|
|
230
|
+
**all** `DSH_*` variables are removed before the configured `env` is merged in.
|
|
231
|
+
Credentials should therefore be passed explicitly through the row's `env`, not
|
|
232
|
+
inherited.
|
|
233
|
+
- **No telemetry from this plugin.** Upstream's own PostHog reporting is
|
|
234
|
+
explicitly disabled in the shipped defaults.
|
|
235
|
+
- **Remote serving is upstream's problem, not a hidden default.** If you switch
|
|
236
|
+
to HTTP, upstream enforces loopback host filtering and refuses to start on a
|
|
237
|
+
non-loopback address without an auth key.
|
|
238
|
+
- **This plugin's own routes are not authenticated.** `/dsh-windows-mcp/state`,
|
|
239
|
+
`/prepare`, `/prepare/cancel` and `/bridge` are served by the same web server
|
|
240
|
+
as the UI and do no token check of their own, so do not expose a DSH web host
|
|
241
|
+
that has this plugin on a non-loopback `--host`: anyone who can reach it could
|
|
242
|
+
start an install or rewrite a profile's patch layer.
|
|
243
|
+
|
|
244
|
+
## How it works
|
|
245
|
+
|
|
246
|
+
DeepSeek Harness plugins are loader patches, and a patch row may mount a package
|
|
247
|
+
that lives inside the Electron `app.asar` — the loader resolves official
|
|
248
|
+
`@deepseek-ai/*` names from the Desktop install anchor. Third-party code cannot
|
|
249
|
+
`import` those packages, but it *can* name them in a patch, because the mount
|
|
250
|
+
happens inside the loader rather than inside plugin code. That is the whole trick
|
|
251
|
+
behind this package:
|
|
252
|
+
|
|
253
|
+
```yaml
|
|
254
|
+
- insert:
|
|
255
|
+
- id: windows-mcp-plugin
|
|
256
|
+
name: dsh-windows-mcp # lib/index.js: doctor tool + startup audit
|
|
257
|
+
- id: windows-mcp-bridge
|
|
258
|
+
name: "@deepseek-ai/dsh-mcp-client" # in-box bridge, configured for Windows-MCP
|
|
259
|
+
config: { transport: stdio, command: uvx, args: [windows-mcp@0.8.8, serve, ...] }
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Consequences worth knowing:
|
|
263
|
+
|
|
264
|
+
- The integration is **version-sensitive** in one direction only: the bridge
|
|
265
|
+
config schema belongs to DSH, not to this plugin. `package.json` declares the
|
|
266
|
+
patch; DSH decides how to read it.
|
|
267
|
+
- Image projection is a bridge feature: MCP image blocks are saved as DSH
|
|
268
|
+
attachments and surfaced as native image content. Audio and embedded resources
|
|
269
|
+
degrade to diagnostic text.
|
|
270
|
+
- **MCP prompts are not supported** by the bridge (resources are, on demand).
|
|
271
|
+
|
|
272
|
+
## Development
|
|
273
|
+
|
|
274
|
+
```powershell
|
|
275
|
+
npm install
|
|
276
|
+
npm test # node --test, including a real YAML parse of the patch
|
|
277
|
+
npm run check # node --check lib/index.js
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
To see the composed config without touching a live profile — and without
|
|
281
|
+
restarting DSH — use the dump harness:
|
|
282
|
+
|
|
283
|
+
```powershell
|
|
284
|
+
# one-time: a scratch profile with the real profile's node_modules
|
|
285
|
+
mkdir $env:USERPROFILE\.dsh\profiles\dtest
|
|
286
|
+
copy $env:USERPROFILE\.dsh\profiles\desktop\package.json $env:USERPROFILE\.dsh\profiles\dtest\
|
|
287
|
+
cmd /c mklink /J $env:USERPROFILE\.dsh\profiles\dtest\node_modules $env:USERPROFILE\.dsh\profiles\desktop\node_modules
|
|
288
|
+
|
|
289
|
+
npm run dump
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Layout:
|
|
293
|
+
|
|
294
|
+
```text
|
|
295
|
+
cordis.patch.yml the integration: two insert rows
|
|
296
|
+
lib/index.js host half: windows_mcp_doctor + startup audit (no dependencies)
|
|
297
|
+
test/plugin.test.mjs patch composition + hostile-context tests
|
|
298
|
+
scripts/dump-config.mjs dev helper for composing against a scratch profile
|
|
299
|
+
tools/ zero-dependency debug probes (not published to npm)
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Contributions are welcome; keep `lib/index.js` free of runtime dependencies and
|
|
303
|
+
keep `apply()` throw-proof.
|
|
304
|
+
|
|
305
|
+
## Credits and license
|
|
306
|
+
|
|
307
|
+
MIT — see [LICENSE](LICENSE).
|
|
308
|
+
|
|
309
|
+
- [CursorTouch/Windows-MCP](https://github.com/CursorTouch/Windows-MCP) (MIT) does
|
|
310
|
+
the actual desktop automation. This plugin only wires it up.
|
|
311
|
+
- The MCP client bridge is part of DeepSeek Harness and is not redistributed here.
|
|
312
|
+
- Not affiliated with DeepSeek or with the Windows-MCP authors.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# dsh-windows-mcp
|
|
2
|
+
|
|
3
|
+
**给 [DeepSeek Harness](https://github.com/sandbaseai/deepseek-harness-handbook) 接上 Windows 桌面自动化** —— 让 DSH 的 agent 能"看见"你的屏幕并操作你的电脑。
|
|
4
|
+
|
|
5
|
+
本插件把 [CursorTouch/Windows-MCP](https://github.com/CursorTouch/Windows-MCP) 接到 DSH 上,做法是**挂载 DSH 本体自带的那座 MCP 客户端桥**:不重新实现协议客户端,也不重复打包 MCP SDK。插件本身是一个 *carrier bundle*(只有补丁、没有自己的服务),agent 能用的一切能力都来自官方那座桥。
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
DSH agent
|
|
9
|
+
└─ 工具调用 mcp__windows__Screenshot
|
|
10
|
+
└─ @deepseek-ai/dsh-mcp-client (DSH 内置,由本插件的补丁行挂载)
|
|
11
|
+
└─ uvx windows-mcp@0.8.8 serve (stdio 子进程)
|
|
12
|
+
└─ 你的桌面:UIA 树 / Win32 输入 / 屏幕采集
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## agent 能拿到什么
|
|
16
|
+
|
|
17
|
+
装好插件且 Windows-MCP 可启动后,工具列表里会出现:
|
|
18
|
+
|
|
19
|
+
| 工具 | 作用 |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `mcp__windows__Screenshot` | 截屏;图片会作为**真正的图片附件**进入对话 |
|
|
22
|
+
| `mcp__windows__Snapshot` | 抓取无障碍树(纯文本,不花图片 token) |
|
|
23
|
+
| `mcp__windows__DisplayInventory` | 枚举显示器及其几何信息 |
|
|
24
|
+
| `mcp__windows__Click` / `Move` / `Scroll` | 鼠标输入 |
|
|
25
|
+
| `mcp__windows__Type` / `Shortcut` | 键盘输入 |
|
|
26
|
+
| `mcp__windows__Wait` / `WaitFor` | 等待固定时长,或等到某个界面条件成立 |
|
|
27
|
+
| `mcp__windows__Scrape` | 从窗口里抽取文本 |
|
|
28
|
+
| `mcp__windows__MultiSelect` / `MultiEdit` | 批量选中元素 / 批量编辑 |
|
|
29
|
+
| `mcp__windows__Clipboard` | 读写剪贴板 |
|
|
30
|
+
| `mcp__windows__Process` | 枚举、启动、结束进程 |
|
|
31
|
+
| `mcp__windows__Notification` | 读取通知 |
|
|
32
|
+
| `mcp__windows__Registry` | 读写注册表 |
|
|
33
|
+
| `mcp__windows__ControlStatus` | 控制环状态。**无法关闭**——上游强制保留 |
|
|
34
|
+
| `mcp__windows__App` | 启动/切换应用。*默认排除*(上游只在英文版 Windows 上稳定支持) |
|
|
35
|
+
| `mcp__windows__PowerShell` / `FileSystem` | *默认排除*——DSH 已有 shell 与文件工具 |
|
|
36
|
+
|
|
37
|
+
另外本插件自带一个工具 `windows_mcp_doctor`:当 `mcp__windows__*` 工具缺失时,用它查原因。
|
|
38
|
+
|
|
39
|
+
输入框工具行里还会多出一颗 **Computer Use** 胶囊(就在"访问模式"旁边):显示当前真正注册了几个桌面工具,并在重启后记住你的选择(状态文件:`~/.dsh/dsh-windows-mcp.state.json`)。它默认是**关闭**的——全新安装不会把桌面交给 agent,直到你亲手点亮这颗胶囊。
|
|
40
|
+
|
|
41
|
+
关掉它是一道硬约束,不是提示:桥本身照常运行,但从下一步开始,每个 `mcp__windows__*` 工具都会从模型的工具表里消失;模型即便仍然报得出名字,调用也会在分发时被拒绝——对所有会话和子智能体同时生效,无需重启。重新打开后立即恢复;`windows_mcp_doctor` 始终报告当前开关状态。
|
|
42
|
+
|
|
43
|
+
> **已实测**:Windows 11 + DSH 桌面版 0.2.0-rc.2 下,桥那侧的服务公布 **18 个工具**
|
|
44
|
+
> (上游 21 个减去这里排除的 3 个),启动后约 1.5 秒就绪;每个工具都以
|
|
45
|
+
> `mcp__windows__<工具名>` 出现在模型的工具表里。
|
|
46
|
+
|
|
47
|
+
## 前置条件
|
|
48
|
+
|
|
49
|
+
- **Windows 10/11。**
|
|
50
|
+
- **DeepSeek Harness 桌面版**,且内置 `@deepseek-ai/dsh-mcp-client` 桥(0.2.0-rc.2 及以上)。
|
|
51
|
+
- 运行 DSH 的那个进程能在他自己的 `PATH` 上找到 **[uv](https://docs.astral.sh/uv/)**(`uvx` 靠它拉起 Windows-MCP)。即使没在 `PATH` 上,插件也会额外搜索 `%USERPROFILE%\.local\bin`。
|
|
52
|
+
- 想让 agent 真正**看到**截图,需要**支持图片输入的模型**。
|
|
53
|
+
|
|
54
|
+
### 首次启动 vs 之后每次启动
|
|
55
|
+
|
|
56
|
+
`uvx` 第一次运行时会为 `windows-mcp` 建一个隔离环境,所以**首次**启动要下载几十 MB 的
|
|
57
|
+
Python 依赖,慢网下可能要好几分钟;桥每次启动只等大约一分钟然后重试,因此冷启动可能要
|
|
58
|
+
试几次工具才会出现。
|
|
59
|
+
|
|
60
|
+
依赖装好之后服务本身很快 —— 本机实测(Windows 11)**约 1.5 秒就绪**。想从第一次 DSH
|
|
61
|
+
启动就这么快,先手动装一次:
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
uv tool install windows-mcp # 没有时间限制,跑一次即可
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
然后把该行的 `command` 指向装好的命令(`command: windows-mcp`),写法见
|
|
68
|
+
[从自己的 profile 覆盖这一行](#从自己的-profile-覆盖这一行)——`config` 要**整块重写**,
|
|
69
|
+
补丁是替换不是深合并。之后每次启动都会复用 `uv` 建好的环境。
|
|
70
|
+
|
|
71
|
+
## 安装
|
|
72
|
+
|
|
73
|
+
1. 打开 **DSH 桌面版 → 设置 → 插件**。
|
|
74
|
+
2. 添加本 bundle,目标可以是包名、仓库地址(`github:helloHub1212/dsh-windows-mcp`)或本仓库的本地目录。
|
|
75
|
+
3. **重启 DSH**,让新的补丁层在启动时合成。
|
|
76
|
+
|
|
77
|
+
非 Electron 的 profile 也可以用 CLI 完成同样的事:
|
|
78
|
+
|
|
79
|
+
```powershell
|
|
80
|
+
dsh plugin --profile <profile> add github:helloHub1212/dsh-windows-mcp
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
> Electron 独占 `desktop` profile,CLI 对它**任何**命令都会被拒绝(连只读 dump 也不行)。`desktop` 请走图形界面。
|
|
84
|
+
|
|
85
|
+
### 在应用里直接装依赖
|
|
86
|
+
|
|
87
|
+
Windows-MCP 本身是个 Python 程序,所以 **设置 → 插件 → dsh-windows-mcp** 这一页现在会显示依赖状态并直接帮你装:
|
|
88
|
+
|
|
89
|
+
- **依赖** —— `已安装 0.8.8` / *未安装* / *未找到 uv*;
|
|
90
|
+
- **下载并安装** —— 跑一次 `uv tool install windows-mcp@<锁定版本>`,安装输出实时显示在页面上,过程中可以**取消**;
|
|
91
|
+
- 装完之后,插件会**自己把桥那一行写进你 profile 的 `cordis.patch.yml`**(先做带时间戳的备份,并用成对标记包住,可重复执行)——这样桥启动的是装好的可执行文件,而不是拿 `uvx` 去赌冷缓存。**重启 DSH** 生效。
|
|
92
|
+
|
|
93
|
+
它写进去的就是 [换成固定的解释器](#换成固定的解释器不用-uvx) 里那条行;把标记之间的块删掉就回到 `uvx`。启用 bundle 之后弹的提示用的是同一个面板。
|
|
94
|
+
|
|
95
|
+
面板上还会显示 **写入目标**:手动写入会落到哪个 `cordis.patch.yml`,也就是这个宿主启动的那个 profile(`dsh --profile web` 启动的 web 宿主同样适用)。如果本插件装在多个 profile 里、而宿主没有报告自己启动的是哪一个,插件**不会猜**:它什么都不写并直接说明——给运行 DSH 的进程设 `DSH_WINDOWS_MCP_PROFILE=<profile 名>`(或 profile 的绝对路径)再重试。
|
|
96
|
+
|
|
97
|
+
## 验证
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
windows_mcp_doctor
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
它会打印解析到的 `uv`/`uvx`/`python`、`%USERPROFILE%\.windows-mcp` 的状态、实际生效的 bridge 行,以及真正注册成功的 `mcp__windows__*` 工具名。然后对 agent 说:
|
|
104
|
+
|
|
105
|
+
> 截图我的桌面,告诉我屏幕上有什么。
|
|
106
|
+
|
|
107
|
+
## 配置
|
|
108
|
+
|
|
109
|
+
默认值都在 [`cordis.patch.yml`](cordis.patch.yml),下面这些通过 `windows-mcp-bridge` 那一行的 `env` 调整。
|
|
110
|
+
|
|
111
|
+
| 变量 | 本插件默认 | 作用 |
|
|
112
|
+
| --- | --- | --- |
|
|
113
|
+
| `WINDOWS_MCP_SCREENSHOT_SCALE` | `0.75` | 截图缩放,`0.1`–`1.0`。对图片 token 开销影响最大的一个开关。 |
|
|
114
|
+
| `WINDOWS_MCP_DISABLE_FLASH` | `1` | 关掉上游每次截屏时那圈橙色"控制权已接管"边框。 |
|
|
115
|
+
| `WINDOWS_MCP_SCREENSHOT_BACKEND` | `auto` | 采集后端;覆盖前请先读上游文档。 |
|
|
116
|
+
| `WINDOWS_MCP_MAX_TREE_ELEMENTS` | `500` | `Snapshot` 返回的无障碍树元素上限。 |
|
|
117
|
+
| `WINDOWS_MCP_WATCHDOG` | `off` | 上游看门狗。默认关,因为它的 UIA 事件泵有可能把整个进程带崩([上游 #332](https://github.com/CursorTouch/Windows-MCP/issues/332))。 |
|
|
118
|
+
| `ANONYMIZED_TELEMETRY` | `false` | 上游默认**开启**(PostHog)。本插件关掉。 |
|
|
119
|
+
|
|
120
|
+
### 从自己的 profile 覆盖这一行
|
|
121
|
+
|
|
122
|
+
不要改插件自己的文件——在你 profile 的 `$DSH_HOME/profiles/<profile>/cordis.patch.yml` 里按 id 覆盖即可,它在 bundle 行**之后**合成,因此优先级更高。
|
|
123
|
+
|
|
124
|
+
**补丁是整块替换 `config`,不是深合并。** loader 的应用方式是 `target[key] = value`(`dsh-app-boot` 里的 `applyEntryPatches`),漏写哪个键就等于删掉哪个键:`serverName` 必填(它决定所有工具名)、`transport` 必填、stdio 形态下 `command` 必填、streamable-http 形态下 `url` 必填。`id` 不存在、或 `name` 与目标不匹配的补丁会被**跳过并告警**,而不是报错。
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
# $DSH_HOME/profiles/<profile>/cordis.patch.yml —— 完整的一行
|
|
128
|
+
- id: windows-mcp-bridge
|
|
129
|
+
config:
|
|
130
|
+
serverName: windows
|
|
131
|
+
transport: stdio
|
|
132
|
+
command: uvx
|
|
133
|
+
args: [windows-mcp@0.8.8, serve, --exclude-tools, "App,PowerShell,FileSystem"]
|
|
134
|
+
toolCallTimeoutMs: 120000
|
|
135
|
+
failOnStartupError: false
|
|
136
|
+
reconnect: { enabled: true, initialDelayMs: 500, maxDelayMs: 30000, maxAttempts: 10 }
|
|
137
|
+
env:
|
|
138
|
+
ANONYMIZED_TELEMETRY: "false"
|
|
139
|
+
WINDOWS_MCP_DISABLE_FLASH: "1"
|
|
140
|
+
WINDOWS_MCP_SCREENSHOT_SCALE: "0.5"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`--exclude-tools` 的工具名是一个逗号分隔的参数(`"App,PowerShell,FileSystem"`),而 `ControlStatus` 始终保留——上游没有提供排除它的方式。
|
|
144
|
+
|
|
145
|
+
### 换成固定的解释器(不用 uvx)
|
|
146
|
+
|
|
147
|
+
`uvx` 每次启动都会重新解析包。要可复现,就装一次(`uv tool install windows-mcp`)或用任何一个已经装了它的 Python,然后改上面那份完整 `config` 里的 `command`/`args`:
|
|
148
|
+
|
|
149
|
+
```yaml
|
|
150
|
+
- id: windows-mcp-bridge
|
|
151
|
+
config:
|
|
152
|
+
serverName: windows
|
|
153
|
+
transport: stdio
|
|
154
|
+
command: windows-mcp # 或者 C:\...\python.exe + args: [-m, windows_mcp, serve, ...]
|
|
155
|
+
args: [serve, --exclude-tools, "App,PowerShell,FileSystem"]
|
|
156
|
+
toolCallTimeoutMs: 120000
|
|
157
|
+
failOnStartupError: false
|
|
158
|
+
reconnect: { enabled: true, initialDelayMs: 500, maxDelayMs: 30000, maxAttempts: 10 }
|
|
159
|
+
env: { ANONYMIZED_TELEMETRY: "false", WINDOWS_MCP_DISABLE_FLASH: "1", WINDOWS_MCP_SCREENSHOT_SCALE: "0.75" }
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 换成常驻 HTTP 服务
|
|
163
|
+
|
|
164
|
+
Windows-MCP 也能作为后台服务运行。上游的 `windows-mcp install` 会注册一个 ONLOGON 计划任务,在 `127.0.0.1:8000` 上提供 **streamable-http**;把这一行改成对应形态即可——这个形态用 `url`,没有 `command`/`args`/`env`:
|
|
165
|
+
|
|
166
|
+
```yaml
|
|
167
|
+
- id: windows-mcp-bridge
|
|
168
|
+
config:
|
|
169
|
+
serverName: windows
|
|
170
|
+
transport: streamable-http
|
|
171
|
+
url: http://127.0.0.1:8000/mcp/ # 上游打印的就是这个地址,结尾斜杠属于上游
|
|
172
|
+
toolCallTimeoutMs: 120000
|
|
173
|
+
failOnStartupError: false
|
|
174
|
+
reconnect: { enabled: true, initialDelayMs: 500, maxDelayMs: 30000, maxAttempts: 10 }
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
这个形态没有 `env` 字段,所以遥测与截屏闪框的默认值不再生效:想要同样效果,就在启动服务时自己带上 `ANONYMIZED_TELEMETRY=false` 和 `WINDOWS_MCP_DISABLE_FLASH=1`。
|
|
178
|
+
|
|
179
|
+
好处是跨 DSH 重启存活、省掉每次启动开销,代价是有一个比应用活得更久的进程。两个需要留意的上游限制:`install` 会把计划任务绑到当时使用的解释器上(从临时 `uvx` 环境安装会注册出一个指向 uv 缓存目录、可能被回收的任务——请改用 `uv tool install windows-mcp` 或固定 venv);非 loopback 地址在缺少 `--auth-key`/`--oauth-client-id` 时会拒绝启动(除非显式 `--allow-insecure-remote`)。
|
|
180
|
+
|
|
181
|
+
## 排障
|
|
182
|
+
|
|
183
|
+
| 现象 | 原因与处理 |
|
|
184
|
+
| --- | --- |
|
|
185
|
+
| 完全没有 `mcp__windows__*` 工具 | 跑 `windows_mcp_doctor`。要么 DSH 进程的 `PATH` 里没有 `uvx`,要么首次冷下载还没结束。查 DSH 宿主日志里的 `mcp-client(windows)` 行。 |
|
|
186
|
+
| 升级后工具消失了 | 工具名是 `mcp__<serverName>__<tool>`。改 `serverName` 会改掉全部工具名(并打破 prompt 缓存前缀)。 |
|
|
187
|
+
| 截图返回的是文本 | 当前模型不接受图片输入,或你的 harness 配置里关掉了附件。上游的图片只有在准入成功时才会被投影。 |
|
|
188
|
+
| `App` 工具报错或没反应 | 上游明确说它只在英文版 Windows 上可靠;本插件默认已排除。 |
|
|
189
|
+
| DSH 启动明显变慢 | 桥会在启动时拉起 Windows-MCP(而且先起一个一次性的探测进程)。可以把该行设 `enabled: false`;`failOnStartupError: false` 保证 DSH 其余部分不受影响。 |
|
|
190
|
+
| 截图里的字看不清 | 把 `WINDOWS_MCP_SCREENSHOT_SCALE` 提到接近 `1.0`;上游截图上限是 1920×1080。 |
|
|
191
|
+
|
|
192
|
+
## 安全
|
|
193
|
+
|
|
194
|
+
装上它,等于把鼠标、键盘、剪贴板、进程和注册表交给模型。请按"交出这个桌面会话的控制权"来评估。
|
|
195
|
+
|
|
196
|
+
设计上做了与没做的事:
|
|
197
|
+
|
|
198
|
+
- **默认不监听网络。** 默认行走 stdio:管道连接的子进程,不是监听端口。
|
|
199
|
+
- **子进程环境会清密。** 桥启动 MCP 子进程时会先做环境清洗:名字匹配 `KEY|PASSWORD|SECRET|TOKEN` 的变量、以及**所有 `DSH_*`** 变量都会被删掉,然后才合并配置里的 `env`。所以凭据必须显式写进该行的 `env`,不能指望继承。
|
|
200
|
+
- **本插件不发送遥测。** 上游自己的 PostHog 上报已在默认配置里显式关闭。
|
|
201
|
+
- **远程提供不是隐藏默认值。** 若你切到 HTTP,上游会强制 loopback 主机过滤,非 loopback 且无鉴权时拒绝启动。
|
|
202
|
+
- **本插件自己的路由没有鉴权。** `/dsh-windows-mcp/state`、`/prepare`、`/prepare/cancel`、`/bridge` 由和 UI 同一个 web 服务器提供,自身不做 token 校验。所以装了本插件的 DSH web 宿主**不要**用非 loopback 的 `--host` 暴露:能访问到它的人可以触发安装、或改写某个 profile 的补丁层。
|
|
203
|
+
|
|
204
|
+
## 原理
|
|
205
|
+
|
|
206
|
+
DSH 插件本质是 loader 补丁,而补丁行**可以挂载位于 Electron `app.asar` 里的包**——loader 会从桌面版安装锚点解析官方 `@deepseek-ai/*` 名字。第三方代码不能 `import` 这些包,但可以在补丁里**点名**它们,因为挂载发生在 loader 内部,而不是插件代码内部。这就是本包的全部诀窍:
|
|
207
|
+
|
|
208
|
+
```yaml
|
|
209
|
+
- insert:
|
|
210
|
+
- id: windows-mcp-plugin
|
|
211
|
+
name: dsh-windows-mcp # lib/index.js:doctor 工具 + 启动审计
|
|
212
|
+
- id: windows-mcp-bridge
|
|
213
|
+
name: "@deepseek-ai/dsh-mcp-client" # 内置桥,按 Windows-MCP 配置
|
|
214
|
+
config: { transport: stdio, command: uvx, args: [windows-mcp@0.8.8, serve, ...] }
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
由此带来的几点值得知道:
|
|
218
|
+
|
|
219
|
+
- 集成的版本敏感性**只有一个方向**:bridge 的配置 schema 属于 DSH,不属于本插件。`package.json` 声明补丁,怎么读由 DSH 决定。
|
|
220
|
+
- 图片投影是**桥的功能**:MCP 图片块会被存成 DSH 附件并以原生图片内容呈现;音频与嵌入资源会退化成诊断文本。
|
|
221
|
+
- **MCP prompts 不被桥支持**(资源可以按需读取)。
|
|
222
|
+
|
|
223
|
+
## 开发
|
|
224
|
+
|
|
225
|
+
```powershell
|
|
226
|
+
npm install
|
|
227
|
+
npm test # node --test,包含对补丁文件的真实 YAML 解析
|
|
228
|
+
npm run check # node --check lib/index.js
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
想在不碰任何真实 profile、也不重启 DSH 的前提下看到合成后的配置,用 dump 工具:
|
|
232
|
+
|
|
233
|
+
```powershell
|
|
234
|
+
# 一次性:建一个影子 profile,复用真实 profile 的 node_modules
|
|
235
|
+
mkdir $env:USERPROFILE\.dsh\profiles\dtest
|
|
236
|
+
copy $env:USERPROFILE\.dsh\profiles\desktop\package.json $env:USERPROFILE\.dsh\profiles\dtest\
|
|
237
|
+
cmd /c mklink /J $env:USERPROFILE\.dsh\profiles\dtest\node_modules $env:USERPROFILE\.dsh\profiles\desktop\node_modules
|
|
238
|
+
|
|
239
|
+
npm run dump
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
目录结构:
|
|
243
|
+
|
|
244
|
+
```text
|
|
245
|
+
cordis.patch.yml 集成本体:两行 insert
|
|
246
|
+
lib/index.js 宿主半边:windows_mcp_doctor + 启动审计(零依赖)
|
|
247
|
+
test/plugin.test.mjs 补丁合成测试 + 恶意 ctx 测试
|
|
248
|
+
scripts/dump-config.mjs 面向影子 profile 的合成调试脚本
|
|
249
|
+
tools/ 零依赖调试探针(不发布到 npm)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
欢迎贡献;请保持 `lib/index.js` 无运行时依赖,并保持 `apply()` 永不抛错。
|
|
253
|
+
|
|
254
|
+
## 致谢与许可
|
|
255
|
+
|
|
256
|
+
MIT —— 见 [LICENSE](LICENSE)。
|
|
257
|
+
|
|
258
|
+
- 真正干活的是 [CursorTouch/Windows-MCP](https://github.com/CursorTouch/Windows-MCP)(MIT),本插件只负责接线。
|
|
259
|
+
- MCP 客户端桥属于 DeepSeek Harness,本仓库不重新分发它。
|
|
260
|
+
- 与 DeepSeek 官方及 Windows-MCP 作者均无隶属关系。
|