winrdp-mcp 0.1.0__tar.gz
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.
- winrdp_mcp-0.1.0/.gitattributes +8 -0
- winrdp_mcp-0.1.0/.github/workflows/ci.yml +53 -0
- winrdp_mcp-0.1.0/.github/workflows/publish.yml +44 -0
- winrdp_mcp-0.1.0/.gitignore +44 -0
- winrdp_mcp-0.1.0/.mcp.json +8 -0
- winrdp_mcp-0.1.0/CHANGELOG.md +109 -0
- winrdp_mcp-0.1.0/CONTRIBUTING.md +68 -0
- winrdp_mcp-0.1.0/LICENSE +21 -0
- winrdp_mcp-0.1.0/NOTICE +22 -0
- winrdp_mcp-0.1.0/PKG-INFO +354 -0
- winrdp_mcp-0.1.0/README.md +307 -0
- winrdp_mcp-0.1.0/claude-config.example.json +14 -0
- winrdp_mcp-0.1.0/docs/ARCHITECTURE.md +406 -0
- winrdp_mcp-0.1.0/docs/PREPARE-SERVER.md +486 -0
- winrdp_mcp-0.1.0/docs/PRODUCTION.md +607 -0
- winrdp_mcp-0.1.0/docs/SECURITY.md +341 -0
- winrdp_mcp-0.1.0/docs/TOOLS.md +1084 -0
- winrdp_mcp-0.1.0/docs/TROUBLESHOOTING.md +496 -0
- winrdp_mcp-0.1.0/dxt/build.ps1 +44 -0
- winrdp_mcp-0.1.0/dxt/manifest.json +53 -0
- winrdp_mcp-0.1.0/pyproject.toml +85 -0
- winrdp_mcp-0.1.0/scripts/enable-winrm.ps1 +27 -0
- winrdp_mcp-0.1.0/server.json +46 -0
- winrdp_mcp-0.1.0/smithery.yaml +42 -0
- winrdp_mcp-0.1.0/tests/conftest.py +16 -0
- winrdp_mcp-0.1.0/tests/test_local_transport.py +42 -0
- winrdp_mcp-0.1.0/tests/test_misc.py +33 -0
- winrdp_mcp-0.1.0/tests/test_ps.py +42 -0
- winrdp_mcp-0.1.0/tests/test_server.py +64 -0
- winrdp_mcp-0.1.0/tests/test_tools_local.py +70 -0
- winrdp_mcp-0.1.0/tests/test_validate.py +41 -0
- winrdp_mcp-0.1.0/tests/test_vault.py +51 -0
- winrdp_mcp-0.1.0/winrdp_mcp/__init__.py +19 -0
- winrdp_mcp-0.1.0/winrdp_mcp/__main__.py +112 -0
- winrdp_mcp-0.1.0/winrdp_mcp/config.py +53 -0
- winrdp_mcp-0.1.0/winrdp_mcp/context.py +165 -0
- winrdp_mcp-0.1.0/winrdp_mcp/elevation.py +275 -0
- winrdp_mcp-0.1.0/winrdp_mcp/log.py +75 -0
- winrdp_mcp-0.1.0/winrdp_mcp/prompts.py +96 -0
- winrdp_mcp-0.1.0/winrdp_mcp/provision.py +320 -0
- winrdp_mcp-0.1.0/winrdp_mcp/ps.py +134 -0
- winrdp_mcp-0.1.0/winrdp_mcp/resources.py +49 -0
- winrdp_mcp-0.1.0/winrdp_mcp/server.py +136 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tooling.py +140 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/__init__.py +46 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/_validate.py +56 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/admin.py +376 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/files.py +282 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/gui.py +372 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/hosts.py +177 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/network.py +113 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/ops.py +116 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/provisioning.py +116 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/rdp.py +212 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/scheduling.py +103 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/scripting.py +217 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/software.py +123 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/system.py +168 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/tunnel.py +127 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/waiters.py +84 -0
- winrdp_mcp-0.1.0/winrdp_mcp/tools/windows.py +185 -0
- winrdp_mcp-0.1.0/winrdp_mcp/transports.py +610 -0
- winrdp_mcp-0.1.0/winrdp_mcp/vault.py +177 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip
|
|
27
|
+
python -m pip install -e ".[dev]"
|
|
28
|
+
|
|
29
|
+
- name: Lint (ruff)
|
|
30
|
+
run: ruff check .
|
|
31
|
+
|
|
32
|
+
- name: Test (pytest)
|
|
33
|
+
run: pytest
|
|
34
|
+
|
|
35
|
+
build:
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
- uses: actions/setup-python@v5
|
|
40
|
+
with:
|
|
41
|
+
python-version: "3.12"
|
|
42
|
+
- name: Build sdist + wheel
|
|
43
|
+
run: |
|
|
44
|
+
python -m pip install --upgrade build
|
|
45
|
+
python -m build
|
|
46
|
+
- name: Check metadata
|
|
47
|
+
run: |
|
|
48
|
+
python -m pip install --upgrade twine
|
|
49
|
+
twine check dist/*
|
|
50
|
+
- uses: actions/upload-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: dist
|
|
53
|
+
path: dist/*
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Publishes on a GitHub Release. Uses PyPI Trusted Publishing (OIDC) — configure the
|
|
4
|
+
# publisher at https://pypi.org/manage/project/winrdp-mcp/settings/publishing/ with:
|
|
5
|
+
# owner: emog33k repo: winrdp-mcp workflow: publish.yml environment: pypi
|
|
6
|
+
# No API token needs to be stored. (To use a token instead, set PYPI_API_TOKEN secret and
|
|
7
|
+
# add `password: ${{ secrets.PYPI_API_TOKEN }}` to the publish step.)
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
release:
|
|
11
|
+
types: [published]
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
- name: Build
|
|
23
|
+
run: |
|
|
24
|
+
python -m pip install --upgrade build twine
|
|
25
|
+
python -m build
|
|
26
|
+
twine check dist/*
|
|
27
|
+
- uses: actions/upload-artifact@v4
|
|
28
|
+
with:
|
|
29
|
+
name: dist
|
|
30
|
+
path: dist/*
|
|
31
|
+
|
|
32
|
+
publish:
|
|
33
|
+
needs: build
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
environment: pypi
|
|
36
|
+
permissions:
|
|
37
|
+
id-token: write # required for Trusted Publishing (OIDC)
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/download-artifact@v4
|
|
40
|
+
with:
|
|
41
|
+
name: dist
|
|
42
|
+
path: dist
|
|
43
|
+
- name: Publish to PyPI
|
|
44
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
*.whl
|
|
9
|
+
|
|
10
|
+
# DXT / MCP Bundle build output (vendored deps + packaged extension)
|
|
11
|
+
dxt/server/lib/
|
|
12
|
+
*.dxt
|
|
13
|
+
|
|
14
|
+
# Virtual environments
|
|
15
|
+
.venv/
|
|
16
|
+
venv/
|
|
17
|
+
env/
|
|
18
|
+
ENV/
|
|
19
|
+
|
|
20
|
+
# Test / tooling caches
|
|
21
|
+
.pytest_cache/
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
.mypy_cache/
|
|
24
|
+
htmlcov/
|
|
25
|
+
.coverage
|
|
26
|
+
.coverage.*
|
|
27
|
+
|
|
28
|
+
# winrdp runtime state (never commit — holds the encrypted inventory + vault key)
|
|
29
|
+
# The real data dir is %APPDATA%\winrdp-mcp (or $WINRDP_HOME); guard against a local copy.
|
|
30
|
+
winrdp-mcp-data/
|
|
31
|
+
*.vault.key
|
|
32
|
+
inventory.json
|
|
33
|
+
|
|
34
|
+
# Local secrets / overrides — keep the checked-in .mcp.json secret-free
|
|
35
|
+
.mcp.local.json
|
|
36
|
+
.env
|
|
37
|
+
*.local
|
|
38
|
+
|
|
39
|
+
# Editors / OS
|
|
40
|
+
.idea/
|
|
41
|
+
.vscode/
|
|
42
|
+
*.swp
|
|
43
|
+
.DS_Store
|
|
44
|
+
Thumbs.db
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to winrdp-mcp are documented here. Format loosely follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/); this project uses semantic versioning.
|
|
5
|
+
|
|
6
|
+
## [0.1.0] — 2026-08-10
|
|
7
|
+
|
|
8
|
+
Initial release. A zero-config MCP server that provisions and fully administers Windows
|
|
9
|
+
RDP boxes (Win10/11, Server 2016–2025) for Claude & Claude Code.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **144 tools** across 15 groups: hosts/fleet, provisioning & UAC, system, scripting,
|
|
13
|
+
files, admin, RDP, software, network, deeper Windows management, native GUI automation,
|
|
14
|
+
wait-for-condition helpers, scheduling/persistence, SSH tunneling, and high-level ops.
|
|
15
|
+
- **MCP prompts** (`prompts.py`) — 5 user-invoked workflows: `provision_and_harden`,
|
|
16
|
+
`diagnose_box`, `security_audit`, `setup_dev_box`, `open_service_locally`.
|
|
17
|
+
- **MCP resources** (`resources.py`) — `winrdp://hosts` (inventory) and
|
|
18
|
+
`winrdp://host/{alias}/info` (compact live box summary).
|
|
19
|
+
- **Tool profiles** — `WINRDP_PROFILE=full|admin|rdp|core` exposes a curated tool set.
|
|
20
|
+
- **Ops tools** (`ops.py`) — `health_report`, `apply_baseline`, `whoami_priv`,
|
|
21
|
+
`failed_logons`, `list_open_ports`.
|
|
22
|
+
- **SSH tunneling** (`tunnel.py`) — `port_forward`/`port_forward_list`/`port_forward_stop`
|
|
23
|
+
to reach a box's loopback service from the operator machine.
|
|
24
|
+
- **Packaging** — installable from PyPI (`pipx install winrdp-mcp`), with manifests for
|
|
25
|
+
Smithery (`smithery.yaml`), the MCP registry (`server.json`), and a Claude Desktop
|
|
26
|
+
extension (`dxt/`), plus CI + trusted-publishing GitHub Actions.
|
|
27
|
+
- **Native GUI automation** (`gui.py`) — drive the interactive RDP desktop with no on-box
|
|
28
|
+
agent: `send_keys`, `type_text`, `mouse_move`/`mouse_click`/`mouse_drag`, `list_windows`,
|
|
29
|
+
`focus_window`, UI Automation (`ui_find`/`ui_invoke`/`ui_set_text`), built-in OCR
|
|
30
|
+
(`ocr_screen`/`find_and_click`), `wait_for_window`, `record_screen` (animated GIF), and
|
|
31
|
+
`gui_script` (a single-call multi-step sequence with mouse/UIA helpers pre-loaded).
|
|
32
|
+
- **Wait-for-condition helpers** (`waiters.py`) — `wait_for_port`, `wait_for_service`,
|
|
33
|
+
`wait_for_process`, `wait_for_file`; polled controller-side so any timeout is safe.
|
|
34
|
+
- **File convenience** — `download_file`, `tail_file`, `edit_file` (find/replace),
|
|
35
|
+
`sync_folder` (zip→upload→expand a local folder), `transfer_between_hosts`.
|
|
36
|
+
- **Scheduling & persistence** (`scheduling.py`) — `schedule_command`, `run_at_startup`,
|
|
37
|
+
and `persist_as_service` (a resilient auto-restarting service via NSSM) / `unpersist_service`.
|
|
38
|
+
- **Zero-config provisioning ladder** — `provision_host` climbs WinRM → SSH → SMB/WMI
|
|
39
|
+
cold-start → paste-once bootstrap, enabling WinRM, opening the firewall, and fixing
|
|
40
|
+
local-admin token filtering on any Windows version.
|
|
41
|
+
- **Real elevation** — full-token execution over WinRM detected via `is_elevated` (direct,
|
|
42
|
+
fast) with a one-shot SYSTEM Scheduled Task fallback for filtered tokens; `as_user` runs
|
|
43
|
+
inside the interactive RDP desktop.
|
|
44
|
+
- **On-demand scripting** — `run_python` (auto-installs Python + pip deps), `run_script`
|
|
45
|
+
(auto interpreter), `run_node`, `pip_install`, `ensure_runtime`.
|
|
46
|
+
- **On-demand tooling** — `stage_tool` (Sysinternals presets / URL / local file),
|
|
47
|
+
`stage_script`, staged-tool cache management.
|
|
48
|
+
- **First-class RDP** — enable/disable, NLA, custom port, session list/disconnect/logoff,
|
|
49
|
+
`tscon` handoff, multi-session, `.rdp` generation, `mstsc` launch, RDP Wrapper, live
|
|
50
|
+
desktop screenshot.
|
|
51
|
+
- **Encrypted multi-host inventory** (Fernet) with tags, active-host targeting, parallel
|
|
52
|
+
`run_on_hosts` fan-out, and `reboot_and_wait`.
|
|
53
|
+
- **Safety annotations** (`readOnlyHint`/`destructiveHint`) on every tool and a tool
|
|
54
|
+
allowlist (`WINRDP_ENABLED_TOOLS` / `WINRDP_DISABLED_TOOLS`).
|
|
55
|
+
- Hybrid deployment: `serve` (controller over stdio) and `agent` (on the box); a CLI with
|
|
56
|
+
`bootstrap`, `add-host`, `list-hosts`, `provision`.
|
|
57
|
+
- Encrypted-at-rest credentials, stderr logging with secret redaction, per-host transport
|
|
58
|
+
security knobs (`winrm_cert_validation`, `ssh_host_key_policy`).
|
|
59
|
+
|
|
60
|
+
### Hardened (from an adversarial code review + a live end-to-end run against a real VDS)
|
|
61
|
+
- Removed a thread-based WinRM timeout watchdog that corrupted the non-thread-safe pywinrm
|
|
62
|
+
session and cascaded HTTP 400s across all subsequent calls.
|
|
63
|
+
- Added transport **self-heal**: reconnect + retry once on a dropped/wedged WinRM
|
|
64
|
+
connection (`RemoteDisconnected` / HTTP 400).
|
|
65
|
+
- Long installs now run **detached** (`run_long` → scheduled task + poll) so a mid-install
|
|
66
|
+
disconnect on a small/busy box doesn't fail them.
|
|
67
|
+
- `list_tasks` made lightweight (the per-task `Get-ScheduledTaskInfo` N+1 could hang and
|
|
68
|
+
drop the connection); details available via `detailed=True`.
|
|
69
|
+
- HTTP-first WinRM ordering (NTLM-encrypted, faster; HTTPS only when `use_ssl`).
|
|
70
|
+
- Argument validation/quoting across all tools; `rdp_connection_file` no longer returns the
|
|
71
|
+
plaintext password; robust `qwinsta` session parsing; BOM-free file appends.
|
|
72
|
+
- Large-script / large-file handling: a `run_ps` script over ~6 KB is staged to a temp
|
|
73
|
+
`.ps1` and run via `-File` (avoids the WSMan/cmd command-line length limit that pywinrm's
|
|
74
|
+
`-EncodedCommand` packing hits, on all transports); the upload chunk was cut to a size
|
|
75
|
+
that stays under that limit after re-encoding.
|
|
76
|
+
- Fast file channel: WinRM uploads/downloads of any size now transparently use a cached
|
|
77
|
+
**SMB** (`ADMIN$`, no install) channel when 445 is reachable, else **SFTP** over SSH,
|
|
78
|
+
falling back to chunked base64 only when neither is available — instant transfers instead
|
|
79
|
+
of many round-trips. `provision_host(fast_transfer=True)` (default) ensures the channel:
|
|
80
|
+
it uses SMB when 445 is open, otherwise installs OpenSSH so SFTP is available.
|
|
81
|
+
|
|
82
|
+
### From production-use feedback
|
|
83
|
+
- `run_powershell`/`run_ps` staging threshold lowered to 2.4 KB so scripts stay under the
|
|
84
|
+
worst-case command-line limit some boxes enforce (staging is cheap over the fast channel).
|
|
85
|
+
- `file_write(binary=True)` writes decoded base64 bytes for arbitrary binary files.
|
|
86
|
+
- `start_process(wait=False)` redirects the background process's stdout/stderr to log files
|
|
87
|
+
(returned as `stdout_log`/`stderr_log`) so silent background failures are diagnosable.
|
|
88
|
+
- `as_user`/GUI ops now detect a Disconnected session and fail with an actionable message
|
|
89
|
+
(reconnect RDP or `rdp_connect_to_console`) instead of running on a non-composed desktop.
|
|
90
|
+
- New `port_forward` / `port_forward_list` / `port_forward_stop`: SSH local tunnels to reach
|
|
91
|
+
a service bound to a box's 127.0.0.1 (which WinRM-launched processes cannot).
|
|
92
|
+
- `run_powershell(detach=True)` / `start_process(detach=True)`: launch a background process
|
|
93
|
+
in a Scheduled Task so it runs OUTSIDE the WinRM Job Object and survives the session close
|
|
94
|
+
(a normal launch dies with the shell — that's why a background server only lived ~1 min).
|
|
95
|
+
- `run_powershell(loopback=True)`: route through a Scheduled Task so the script can reach
|
|
96
|
+
127.0.0.1 — the WinRM network-logon token blocks outbound loopback, the task's logon does
|
|
97
|
+
not. (`file_write` already streams over SFTP/SMB, bypassing the WinRM command channel.)
|
|
98
|
+
- Fixed three latent PowerShell brace-balance / output bugs surfaced by a brace-balance
|
|
99
|
+
audit and live runs: `ensure_remote_dirs` (broke all tool-staging), `tail_file` (returned
|
|
100
|
+
megabytes of provider metadata), and `find_and_click`.
|
|
101
|
+
|
|
102
|
+
- Readable output: PowerShell serializes its progress/information streams into stderr as
|
|
103
|
+
a CLIXML blob. Results are now tidied on every call — real Error/Warning text stays in
|
|
104
|
+
stderr, `Write-Host`/Information output is recovered into stdout (no duplication, no
|
|
105
|
+
loss), and only the progress-bar noise is dropped.
|
|
106
|
+
|
|
107
|
+
### Attribution
|
|
108
|
+
Builds on the MIT-licensed [winremote-mcp](https://github.com/dddabtc/winremote-mcp) and
|
|
109
|
+
[windows-admin-mcp](https://github.com/Cosmicjedi/windows-admin-mcp) — see `NOTICE`.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Contributing to winrdp-mcp
|
|
2
|
+
|
|
3
|
+
Thanks for helping improve winrdp-mcp. This guide covers the dev setup, the quality bar,
|
|
4
|
+
and how to add a tool.
|
|
5
|
+
|
|
6
|
+
## Dev setup
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
git clone <your-fork>
|
|
10
|
+
cd Windows-RDP-MCP
|
|
11
|
+
python -m venv .venv
|
|
12
|
+
# Windows: .venv\Scripts\activate | POSIX: source .venv/bin/activate
|
|
13
|
+
pip install -e ".[dev,bootstrap]"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The controller runs on any OS (Windows/macOS/Linux); the managed targets are Windows.
|
|
17
|
+
|
|
18
|
+
## Quality bar
|
|
19
|
+
|
|
20
|
+
Before opening a PR, all of these must pass:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python -m compileall -q winrdp_mcp # no syntax errors
|
|
24
|
+
ruff check winrdp_mcp tests # lint (F, E, I, W)
|
|
25
|
+
pytest -q # unit tests (30+; Windows-only tests skip elsewhere)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- **Correctness first**, then clarity, then speed. Handle the unhappy paths.
|
|
29
|
+
- **Never** wrap a `pywinrm` call in a thread watchdog — the `Session` is not thread-safe
|
|
30
|
+
and abandoning a call mid-flight corrupts the connection (see `transports.py`). The
|
|
31
|
+
per-call bound is `read_timeout_sec`; a dropped/wedged connection is healed by the
|
|
32
|
+
transport's reconnect-and-retry.
|
|
33
|
+
- **Quote or validate every model-supplied argument** that reaches a command line:
|
|
34
|
+
`ps.ps_string()` for PowerShell literals, `tools/_validate.py` (enum/charset) for values
|
|
35
|
+
spliced raw (paths, names, package ids, enums). Several tools run elevated.
|
|
36
|
+
- **Long operations** (minutes-scale installs) must go through `context.run_long()` so a
|
|
37
|
+
mid-op WinRM disconnect doesn't fail them.
|
|
38
|
+
- **Never** return a secret in a tool result or log it (logs are stderr-only and redacted).
|
|
39
|
+
|
|
40
|
+
## Adding a tool
|
|
41
|
+
|
|
42
|
+
1. Add the function inside the relevant module's `register(mcp, ctx)` in `winrdp_mcp/tools/`.
|
|
43
|
+
2. Decorate with `@mcp.tool`; give it a clear docstring (that IS the model-facing API) and
|
|
44
|
+
an optional `host: Optional[str] = None` first among the box selectors.
|
|
45
|
+
3. Build the PowerShell body with `ps.ps_string()` for any interpolated value; return
|
|
46
|
+
structured data via `ctx.exec_json(...)` (assign `$result`) or `ctx.exec_ps(...)`.
|
|
47
|
+
4. Classify it in `winrdp_mcp/server.py`: add its name to `READONLY` or `DESTRUCTIVE` so it
|
|
48
|
+
gets the right safety annotation.
|
|
49
|
+
5. If it's a new module, register it in `winrdp_mcp/tools/__init__.py`.
|
|
50
|
+
6. Add a unit test (pure logic) and, where practical, a Windows-guarded local test.
|
|
51
|
+
7. Document it in `docs/TOOLS.md`.
|
|
52
|
+
|
|
53
|
+
## Testing against a real box
|
|
54
|
+
|
|
55
|
+
Integration tests are opt-in. Point them at a box you own:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
export WINRDP_TEST_HOST=... WINRDP_TEST_USER=... WINRDP_TEST_PASS=...
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Never commit credentials. Use a throwaway VM; a >= 4 GB / 2 vCPU box avoids the
|
|
62
|
+
resource-thrash slowness small boxes exhibit under sustained WinRM load.
|
|
63
|
+
|
|
64
|
+
## Commit / PR
|
|
65
|
+
|
|
66
|
+
- Small, focused commits with clear messages.
|
|
67
|
+
- Describe the change, the reasoning, and how you verified it.
|
|
68
|
+
- MIT-licensed contributions only; keep the `NOTICE` attributions intact.
|
winrdp_mcp-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 winrdp-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.
|
winrdp_mcp-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
winrdp-mcp
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 winrdp-mcp contributors. MIT License (see LICENSE).
|
|
5
|
+
|
|
6
|
+
This project's feature set, risk-tier model, and optional interactive-desktop UI agent
|
|
7
|
+
build on prior MIT-licensed work, gratefully credited:
|
|
8
|
+
|
|
9
|
+
* winremote-mcp — https://github.com/dddabtc/winremote-mcp
|
|
10
|
+
Copyright (c) 2025 winremote contributors. MIT License.
|
|
11
|
+
Basis for: the on-box tool surface (desktop/registry/services/process/file/network
|
|
12
|
+
tools), the tier1/tier2/tier3 risk model, and the optional `deploy_ui_agent` path,
|
|
13
|
+
which installs and drives winremote-mcp for click/type/OCR desktop control.
|
|
14
|
+
|
|
15
|
+
* windows-admin-mcp — https://github.com/Cosmicjedi/windows-admin-mcp
|
|
16
|
+
Copyright (c) 2025 Cosmicjedi. MIT License.
|
|
17
|
+
Basis for: the WinRM-primary / SSH-fallback remote administration approach and the
|
|
18
|
+
diagnose/execute/troubleshoot tool shape.
|
|
19
|
+
|
|
20
|
+
winrdp-mcp's own additions: zero-config provisioning ladder (WinRM -> SSH -> SMB/WMI
|
|
21
|
+
cold-start -> paste-once bootstrap), real UAC/elevation via one-shot Scheduled Tasks,
|
|
22
|
+
on-demand tool staging, encrypted multi-host inventory, and first-class RDP control.
|