winops
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@winopsWhy does the Print Spooler service keep stopping? Can you restart it?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
winops
An MCP agent that diagnoses Windows service and process faults through read-only, least-privilege PowerShell endpoints — and cannot change anything without a human saying yes.
The problem
The easy way to build an ops agent is to hand an LLM a PowerShell session and a system prompt saying "be careful." That gives a model that read an untrusted event log the ability to run anything, and makes "be careful" the only thing between a hallucination and a production outage.
winops assumes the model will eventually be wrong or manipulated, and makes that survivable: it constrains what the agent can even reach, and separately gates the few things that change state.
Related MCP server: DiagBridge MCP
Two independent safety layers
1. The agent can only reach six functions. A PowerShell
JEA
endpoint runs as a RestrictedRemoteServer (NoLanguage mode) exposing exactly
six named, parameter-validated functions. Not Invoke-Expression, not raw
cmdlets, not the filesystem — regardless of what the agent asks for.
Read-only | Mutating (approval-gated) |
|
|
|
|
| |
|
2. The two mutating tools always pause for a human. They're marked
always_require_approval on the MCP tool, so the agent can investigate
freely and forever, but acting requires an explicit yes.
Neither layer trusts the other. A bug in the approval logic still leaves the blast radius at "restart one named service"; a mis-scoped JEA role still can't act without a human. See docs/decisions/0002.
There's a third, quieter layer: invoke.ps1 takes the function name as a
PowerShell [ValidateSet(...)], so even a fully compromised MCP server can
only pick one of six branches — it can't inject a command name.
Architecture
flowchart LR
CLI[winops CLI] --> Agent[Microsoft Agent Framework]
Agent -->|MCPStdioTool| MCP[MCP server]
MCP --> Client[jea.client]
Client -->|powershell.exe, ValidateSet| Session[Invoke-Command]
Session -->|PSRemoting, NoLanguage| JEA[(JEA endpoint)]Full write-up in docs/architecture.md.
Quickstart
One-time setup, in an elevated PowerShell (registers the JEA endpoint,
creates the WinOpsOperators group, enables PSRemoting):
.\jea\register.ps1Verify the endpoint is really constrained before trusting it:
# should work
Invoke-Command -ConfigurationName WinOps -ComputerName localhost -ScriptBlock { Get-WinOpsFailedServices }
# should fail - proof the session is locked down
Invoke-Command -ConfigurationName WinOps -ComputerName localhost -ScriptBlock { Get-ChildItem C:\ }Then:
cp .env.example .env # add OPENAI_API_KEY (or AZURE_ENDPOINT)
uv sync
uv run winops diagnose-service SpoolerThe agent investigates with the read-only tools, then proposes a fix and
waits for y/n before anything runs.
Project status
Area | State |
JEA role files, MCP server, agent, CLI | Built, 13 tests passing |
MCP tool + approval-loop logic | Tested with fakes (no API key needed) |
The JEA endpoint itself | Not yet run — |
Real LLM calls | Not yet run — no API key in the build environment |
Fault-injection evals, audit log, replay | Not built (M4–M6) |
The $using: parameter passing in invoke.ps1 is the documented way to send
values into a NoLanguage session, but it hasn't been exercised against a live
endpoint here — that's the first thing to check after register.ps1.
Why Windows services, not Hyper-V
This was originally scoped around Hyper-V VM faults. Hyper-V isn't available
on Windows Home editions at all — a hard SKU-level restriction, not something
a package manager can install around — so the managed domain moved to services
and processes. Everything that makes the project interesting (MCP, JEA least
privilege, approval-gated mutation) is unchanged; retargeting to Hyper-V means
writing a new WinOpsHelpers.psm1 with Get-VM/Restart-VM and a matching
role capability file. Nothing in jea/client.py, mcp_server.py, or
agent.py mentions services by name. See
docs/decisions/0001.
Safety and limitations
The agent cannot see or touch the filesystem, the registry, other services' configuration, or anything else outside those six functions.
Every JEA session is transcribed to
C:\ProgramData\WinOps\Transcripts.Approval is per-call and never remembered; there's no "approve all".
Tested against a local endpoint. Managing a remote host means pointing
JEA_COMPUTER_NAMEat it and dealing with WinRM auth, which isn't set up here.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Execute PowerShell commands securely with controlled timeouts and input validation. Retrieve syste…
Read-only finance and operations controls for AI agents with evidence and safe next actions.
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Track errors, manage performance alerts, and configure dashboards and monitors
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables remote Windows server administration and troubleshooting via WinRM and SSH PowerShell protocols.6-
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to diagnose Windows computer problems safely through a consent-first, read-only default remote diagnostics bridge.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI clients to perform safe, read-only IT diagnostics and retrieve local runbooks, asset records, and knowledge articles through MCP, with allowlisted network checks and audit logging.MIT
- FlicenseNot gradedqualityBmaintenanceEnables read-only system diagnostics on approved Linux hosts over SSH, with allowlisted commands, bounded output, and secure log access.-