win-mcp-server
by Chillwind132
README.md
# win-mcp-server
[](LICENSE)
[](https://www.python.org/)
[](Dockerfile)
**A Windows MCP server for remote administration over WinRM/NTLM.** Diagnose, inspect, and manage any AD-joined Windows host from Cursor, Claude Code, Codex, or any MCP (Model Context Protocol) client. Connects using per-user credentials elicited at runtime. Passwords live only in server memory with an idle TTL and are never logged.
- **40+ tools**: filesystem, services, registry, event logs, certificates, processes, network, scheduled tasks, and more
- **Per-user AD identity**: each request carries an `X-AD-User` header; the password is either supplied via the optional `X-AD-Password` header (no prompt) or elicited once and cached in-memory
- **Zero secrets on disk**: no credentials in config files, env vars, or logs
## Example prompts
- "Why is drive C: almost full on `HOST1`?"
- "Check the event log for errors in the last 24 hours."
- "The Print Spooler service stopped, find out why and restart it."
- "Which process is using port 443?"
- "List certificates expiring in the next 30 days."
- "Read `HKLM:\SOFTWARE\MyApp` and show me the current settings."
- "Compare `web.config` between the two app servers."
## Tools
### Session
| Tool | Description |
|------|-------------|
| `connect` | Open a WinRM session to a Windows host and return a `session_id` |
| `disconnect` | Close an active WinRM session |
| `list_sessions` | List active WinRM sessions with usage details |
### Filesystem (read-only)
| Tool | Description |
|------|-------------|
| `list_directory` | List files and directories at a path |
| `find_files` | Recursively find files by wildcard pattern |
| `read_file` | Read file contents as numbered lines |
| `search_file_content` | Grep-like text search in a file or across a directory |
| `file_info` | JSON metadata for a file or directory |
| `compare_files` | Line-by-line diff of two files |
### System diagnostics (read-only)
| Tool | Description |
|------|-------------|
| `get_event_log` | Windows Event Log: crashes, service failures, auth errors |
| `get_services` | Services summary or full JSON detail per service |
| `list_processes` | Processes sorted by CPU, memory, or handles |
| `get_system_info` | OS version, uptime, RAM, CPU count, domain, timezone |
| `get_disk_space` | Disk space for all fixed drives |
| `get_perf_snapshot` | Averaged CPU, memory, disk I/O, network snapshot |
| `get_registry` | Read a registry key or value (read-only) |
| `get_certificates` | Personal store certificates sorted by days until expiry |
| `get_network_config` | Per-NIC IP, gateway, and DNS configuration |
| `test_network` | ICMP ping or TCP port test from the remote host |
### Identity & configuration (read-only)
| Tool | Description |
|------|-------------|
| `get_environment_variables` | Environment variables by scope |
| `get_scheduled_tasks` | Scheduled tasks with last/next run and result |
| `get_local_users` | Local user accounts with status and last logon |
| `get_user_groups` | Local group memberships |
| `get_security_context` | Current session identity, groups, privileges (`whoami /all`) |
| `get_permissions` | File/folder ACL entries |
### Network & software (read-only)
| Tool | Description |
|------|-------------|
| `get_tcp_connections` | Active TCP connections with owning process |
| `get_dns_cache` | Local DNS client cache |
| `get_installed_software` | Installed software from 64-bit and 32-bit uninstall keys |
| `resolve_dns_name` | DNS resolution chain from the remote server |
### SFTP (read-only, from the Windows host)
| Tool | Description |
|------|-------------|
| `sftp_connect` | Validate and cache SFTP credentials, returning an `sftp_session_id` |
| `sftp_disconnect` | Drop a cached SFTP credential set |
| `sftp_list_sessions` | List active SFTP sessions |
| `sftp_list_directory` | List a directory on a remote SFTP server |
| `sftp_stat` | JSON metadata for one remote path |
| `sftp_read_file` | Read a remote text file as numbered lines |
### Write operations (all require user confirmation)
| Tool | Description |
|------|-------------|
| `restart_service` / `stop_service` / `start_service` | Manage services with before/after state |
| `kill_process` | Force-terminate a process by PID |
| `set_registry` | Set a registry value showing old vs new |
| `copy_file` / `rename_file` / `move_file` | File operations (no overwrite unless requested) |
| `create_directory` | Create a directory and missing parents |
| `delete_file` / `delete_directory` | Delete with metadata/size shown in the prompt |
| `compress_archive` / `expand_archive` | Create or extract `.zip` archives |
| `flush_dns` | Clear the DNS client cache |
| `invoke_http_request` | HTTP request from the remote server |
## Quick Start
```bash
docker compose -f docker-compose.yml -p win-mcp up -d --build --force-recreate
```
## Client setup
`X-AD-User` is required. `X-AD-Password` is optional: omit it and the server prompts for the password once via MCP elicitation, caching it in memory.
### Cursor (`mcp.json`)
```json
{
"mcpServers": {
"win-mcp": {
"type": "http",
"url": "http://localhost:8005/mcp",
"headers": {
"X-AD-User": "<your-ad-username>",
"X-AD-Password": "<your-ad-password>"
}
}
}
}
```
### Claude Code
```bash
claude mcp add --transport http win-mcp http://localhost:8005/mcp \
--header "X-AD-User: <your-ad-username>" \
--header "X-AD-Password: <your-ad-password>"
```
### Codex (`~/.codex/config.toml`)
```toml
[mcp_servers.win-mcp]
url = "http://localhost:8005/mcp"
http_headers = { "X-AD-User" = "<your-ad-username>", "X-AD-Password" = "<your-ad-password>" }
```
Any other MCP client works the same way: point it at the streamable HTTP endpoint and pass the headers.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues